Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions crates/vm-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use tracing::debug;
use tracing_subscriber::EnvFilter;
use vm_bootloader::boot_loader::BootLoaderBuilder;
use vm_core::virt::Virt;
use vm_machine::vm::VmBuilder;
use vm_machine::vm_builder::VmBuilder;

use crate::cmd::Accel;
use crate::cmd::Command;
Expand All @@ -20,13 +20,13 @@ where
V: Virt,
Loader: BootLoaderBuilder<V>,
{
let vm_builder = VmBuilder::<V>::new(
let vm_builder = VmBuilder::new(
parse_memory(&args.memory)?,
args.cpus,
args.device.into_iter().map(Into::into).collect(),
args.gdb,
);
let mut vm = vm_builder.build()?;
let mut vm = vm_builder.build::<V>()?;

let bootloader = Loader::new(args.kernel, args.initramfs, args.cmdline);

Expand Down
1 change: 1 addition & 0 deletions crates/vm-machine/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ mod firmware;

pub mod error;
pub mod vm;
pub mod vm_builder;
92 changes: 4 additions & 88 deletions crates/vm-machine/src/vm.rs
Original file line number Diff line number Diff line change
@@ -1,104 +1,20 @@
use std::marker::PhantomData;
use std::sync::Arc;
use std::sync::Mutex;

use vm_bootloader::boot_loader::BootLoader;
use vm_core::arch::layout::MemoryLayout;
use vm_core::debug::gdbstub::GdbStub;
use vm_core::device::device_manager::DeviceManager;
use vm_core::device::mmio::MmioLayout;
use vm_core::virt::Virt;
use vm_device::device::Device;
use vm_mm::allocator::MemoryContainer;
use vm_mm::manager::MemoryAddressSpace;
use vm_mm::region::MemoryRegion;

use crate::device::InitDevice;
use crate::error::Error;
use crate::error::Result;

pub struct VmBuilder<V> {
memory_size: usize,
vcpus: usize,
devices: Vec<Device>,
gdb_port: Option<u16>,
_mark: PhantomData<V>,
}

impl<V> VmBuilder<V> {
pub fn new(
memory_size: usize,
vcpus: usize,
devices: Vec<Device>,
gdb_port: Option<u16>,
) -> Self {
VmBuilder {
memory_size,
vcpus,
devices,
gdb_port,
_mark: PhantomData,
}
}
}

pub struct Vm<V: Virt> {
memory: Arc<Mutex<MemoryAddressSpace<V::Memory>>>,
virt: V,
device_manager: Arc<Mutex<DeviceManager>>,
gdb_stub: Option<GdbStub>,
}

impl<V> VmBuilder<V>
where
V: Virt,
{
fn init_mm<C>(&self, ram_base: u64) -> Result<MemoryAddressSpace<C>>
where
C: MemoryContainer,
{
let memory_region = MemoryRegion::placeholder(ram_base, self.memory_size);

let mut memory_regions = MemoryAddressSpace::default();
memory_regions
.try_insert(memory_region)
.map_err(|_| Error::InitMemory("Failed to insert memory_region".to_string()))?;

Ok(memory_regions)
}

pub fn build(self) -> Result<Vm<V>> {
let mut virt = V::new(self.vcpus)?;

let layout = virt.get_layout().clone();
let mmio_layout = MmioLayout::new(layout.get_mmio_start(), layout.get_mmio_len());

let irq_chip = if !self.devices.iter().any(Device::is_irq_chip) {
Some(virt.init_irq()?)
} else {
None
};

let mut memory = self.init_mm(layout.get_ram_base())?;
virt.init_memory(&mmio_layout, &mut memory, self.memory_size as u64)?;
let memory = Arc::new(Mutex::new(memory));

virt.post_init()?;

let mut device_manager = DeviceManager::new(mmio_layout);
device_manager
.init_devices(memory.clone(), self.devices, irq_chip)
.map_err(|err| Error::InitDevice(err.to_string()))?;

let vm = Vm {
memory,
virt,
device_manager: Arc::new(Mutex::new(device_manager)),
gdb_stub: self.gdb_port.map(GdbStub::new),
};

Ok(vm)
}
pub(crate) memory: Arc<Mutex<MemoryAddressSpace<V::Memory>>>,
pub(crate) virt: V,
pub(crate) device_manager: Arc<Mutex<DeviceManager>>,
pub(crate) gdb_stub: Option<GdbStub>,
}

impl<V> Vm<V>
Expand Down
90 changes: 90 additions & 0 deletions crates/vm-machine/src/vm_builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use std::sync::Arc;
use std::sync::Mutex;

use vm_core::arch::layout::MemoryLayout;
use vm_core::debug::gdbstub::GdbStub;
use vm_core::device::device_manager::DeviceManager;
use vm_core::device::mmio::MmioLayout;
use vm_core::virt::Virt;
use vm_device::device::Device;
use vm_mm::allocator::MemoryContainer;
use vm_mm::manager::MemoryAddressSpace;
use vm_mm::region::MemoryRegion;

use crate::device::InitDevice;
use crate::error::Error;
use crate::error::Result;
use crate::vm::Vm;

pub struct VmBuilder {
memory_size: usize,
vcpus: usize,
devices: Vec<Device>,
gdb_port: Option<u16>,
}

impl VmBuilder {
pub fn new(
memory_size: usize,
vcpus: usize,
devices: Vec<Device>,
gdb_port: Option<u16>,
) -> Self {
VmBuilder {
memory_size,
vcpus,
devices,
gdb_port,
}
}

pub fn build<V>(self) -> Result<Vm<V>>
where
V: Virt,
{
let mut virt = V::new(self.vcpus)?;

let layout = virt.get_layout().clone();
let mmio_layout = MmioLayout::new(layout.get_mmio_start(), layout.get_mmio_len());

let irq_chip = if !self.devices.iter().any(Device::is_irq_chip) {
Some(virt.init_irq()?)
} else {
None
};

let mut memory = self.init_mm(layout.get_ram_base())?;
virt.init_memory(&mmio_layout, &mut memory, self.memory_size as u64)?;
let memory = Arc::new(Mutex::new(memory));

virt.post_init()?;

let mut device_manager = DeviceManager::new(mmio_layout);
device_manager
.init_devices(memory.clone(), self.devices, irq_chip)
.map_err(|err| Error::InitDevice(err.to_string()))?;

let vm = Vm {
memory,
virt,
device_manager: Arc::new(Mutex::new(device_manager)),
gdb_stub: self.gdb_port.map(GdbStub::new),
};

Ok(vm)
}

fn init_mm<C>(&self, ram_base: u64) -> Result<MemoryAddressSpace<C>>
where
C: MemoryContainer,
{
let memory_region = MemoryRegion::placeholder(ram_base, self.memory_size);

let mut memory_regions = MemoryAddressSpace::default();
memory_regions
.try_insert(memory_region)
.map_err(|_| Error::InitMemory("Failed to insert memory_region".to_string()))?;

Ok(memory_regions)
}
}
Loading