1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2023 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker
5*bb4ee6a4SAndroid Build Coastguard Worker //! RISC-V 64-bit architecture support.
6*bb4ee6a4SAndroid Build Coastguard Worker
7*bb4ee6a4SAndroid Build Coastguard Worker #![cfg(target_arch = "riscv64")]
8*bb4ee6a4SAndroid Build Coastguard Worker
9*bb4ee6a4SAndroid Build Coastguard Worker use std::collections::BTreeMap;
10*bb4ee6a4SAndroid Build Coastguard Worker use std::io::{self};
11*bb4ee6a4SAndroid Build Coastguard Worker use std::path::PathBuf;
12*bb4ee6a4SAndroid Build Coastguard Worker use std::sync::mpsc;
13*bb4ee6a4SAndroid Build Coastguard Worker use std::sync::Arc;
14*bb4ee6a4SAndroid Build Coastguard Worker
15*bb4ee6a4SAndroid Build Coastguard Worker use arch::get_serial_cmdline;
16*bb4ee6a4SAndroid Build Coastguard Worker use arch::CpuSet;
17*bb4ee6a4SAndroid Build Coastguard Worker use arch::DtbOverlay;
18*bb4ee6a4SAndroid Build Coastguard Worker use arch::FdtPosition;
19*bb4ee6a4SAndroid Build Coastguard Worker use arch::GetSerialCmdlineError;
20*bb4ee6a4SAndroid Build Coastguard Worker use arch::RunnableLinuxVm;
21*bb4ee6a4SAndroid Build Coastguard Worker use arch::VmComponents;
22*bb4ee6a4SAndroid Build Coastguard Worker use arch::VmImage;
23*bb4ee6a4SAndroid Build Coastguard Worker use base::Event;
24*bb4ee6a4SAndroid Build Coastguard Worker use base::SendTube;
25*bb4ee6a4SAndroid Build Coastguard Worker use base::Tube;
26*bb4ee6a4SAndroid Build Coastguard Worker use devices::serial_device::SerialHardware;
27*bb4ee6a4SAndroid Build Coastguard Worker use devices::serial_device::SerialParameters;
28*bb4ee6a4SAndroid Build Coastguard Worker use devices::Bus;
29*bb4ee6a4SAndroid Build Coastguard Worker use devices::BusDeviceObj;
30*bb4ee6a4SAndroid Build Coastguard Worker use devices::BusError;
31*bb4ee6a4SAndroid Build Coastguard Worker use devices::BusType;
32*bb4ee6a4SAndroid Build Coastguard Worker use devices::IrqChipRiscv64;
33*bb4ee6a4SAndroid Build Coastguard Worker use devices::PciAddress;
34*bb4ee6a4SAndroid Build Coastguard Worker use devices::PciConfigMmio;
35*bb4ee6a4SAndroid Build Coastguard Worker use devices::PciDevice;
36*bb4ee6a4SAndroid Build Coastguard Worker use devices::PciRootCommand;
37*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "gdb")]
38*bb4ee6a4SAndroid Build Coastguard Worker use gdbstub::arch::Arch;
39*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "gdb")]
40*bb4ee6a4SAndroid Build Coastguard Worker use gdbstub_arch::riscv::Riscv64 as GdbArch;
41*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::CoreRegister;
42*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::CpuConfigRiscv64;
43*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::Hypervisor;
44*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::ProtectionType;
45*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::TimerRegister;
46*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::VcpuInitRiscv64;
47*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::VcpuRegister;
48*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::VcpuRiscv64;
49*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::Vm;
50*bb4ee6a4SAndroid Build Coastguard Worker use hypervisor::VmRiscv64;
51*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(windows)]
52*bb4ee6a4SAndroid Build Coastguard Worker use jail::FakeMinijailStub as Minijail;
53*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(any(target_os = "android", target_os = "linux"))]
54*bb4ee6a4SAndroid Build Coastguard Worker use minijail::Minijail;
55*bb4ee6a4SAndroid Build Coastguard Worker use remain::sorted;
56*bb4ee6a4SAndroid Build Coastguard Worker use resources::AddressRange;
57*bb4ee6a4SAndroid Build Coastguard Worker use resources::SystemAllocator;
58*bb4ee6a4SAndroid Build Coastguard Worker use resources::SystemAllocatorConfig;
59*bb4ee6a4SAndroid Build Coastguard Worker use sync::Condvar;
60*bb4ee6a4SAndroid Build Coastguard Worker use sync::Mutex;
61*bb4ee6a4SAndroid Build Coastguard Worker use thiserror::Error;
62*bb4ee6a4SAndroid Build Coastguard Worker use vm_control::BatteryType;
63*bb4ee6a4SAndroid Build Coastguard Worker use vm_memory::GuestAddress;
64*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "gdb")]
65*bb4ee6a4SAndroid Build Coastguard Worker use vm_memory::GuestMemory;
66*bb4ee6a4SAndroid Build Coastguard Worker use vm_memory::MemoryRegionOptions;
67*bb4ee6a4SAndroid Build Coastguard Worker
68*bb4ee6a4SAndroid Build Coastguard Worker mod fdt;
69*bb4ee6a4SAndroid Build Coastguard Worker
70*bb4ee6a4SAndroid Build Coastguard Worker // We place the kernel at offset 8MB
71*bb4ee6a4SAndroid Build Coastguard Worker const RISCV64_KERNEL_OFFSET: u64 = 0x20_0000;
72*bb4ee6a4SAndroid Build Coastguard Worker const RISCV64_INITRD_ALIGN: u64 = 8;
73*bb4ee6a4SAndroid Build Coastguard Worker const RISCV64_FDT_ALIGN: u64 = 0x40_0000;
74*bb4ee6a4SAndroid Build Coastguard Worker
75*bb4ee6a4SAndroid Build Coastguard Worker // Maximum Linux riscv kernel command line size (arch/riscv/include/uapi/asm/setup.h).
76*bb4ee6a4SAndroid Build Coastguard Worker const RISCV64_CMDLINE_MAX_SIZE: usize = 1024;
77*bb4ee6a4SAndroid Build Coastguard Worker
78*bb4ee6a4SAndroid Build Coastguard Worker // This indicates the start of DRAM inside the physical address space.
79*bb4ee6a4SAndroid Build Coastguard Worker const RISCV64_PHYS_MEM_START: u64 = 0x8000_0000;
80*bb4ee6a4SAndroid Build Coastguard Worker
81*bb4ee6a4SAndroid Build Coastguard Worker // PCI MMIO configuration region base address.
82*bb4ee6a4SAndroid Build Coastguard Worker const RISCV64_PCI_CFG_BASE: u64 = 0x1_0000;
83*bb4ee6a4SAndroid Build Coastguard Worker // PCI MMIO configuration region size.
84*bb4ee6a4SAndroid Build Coastguard Worker const RISCV64_PCI_CFG_SIZE: u64 = 0x100_0000;
85*bb4ee6a4SAndroid Build Coastguard Worker // This is the base address of MMIO devices.
86*bb4ee6a4SAndroid Build Coastguard Worker const RISCV64_MMIO_BASE: u64 = 0x0300_0000;
87*bb4ee6a4SAndroid Build Coastguard Worker // Size of the whole MMIO region.
88*bb4ee6a4SAndroid Build Coastguard Worker const RISCV64_MMIO_SIZE: u64 = 0x10_0000;
89*bb4ee6a4SAndroid Build Coastguard Worker
90*bb4ee6a4SAndroid Build Coastguard Worker const RISCV64_FDT_MAX_SIZE: u64 = 0x1_0000;
91*bb4ee6a4SAndroid Build Coastguard Worker
get_kernel_addr() -> GuestAddress92*bb4ee6a4SAndroid Build Coastguard Worker fn get_kernel_addr() -> GuestAddress {
93*bb4ee6a4SAndroid Build Coastguard Worker GuestAddress(RISCV64_PHYS_MEM_START + RISCV64_KERNEL_OFFSET)
94*bb4ee6a4SAndroid Build Coastguard Worker }
95*bb4ee6a4SAndroid Build Coastguard Worker
96*bb4ee6a4SAndroid Build Coastguard Worker const RISCV64_IRQ_BASE: u32 = 1;
97*bb4ee6a4SAndroid Build Coastguard Worker
98*bb4ee6a4SAndroid Build Coastguard Worker #[sorted]
99*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Error, Debug)]
100*bb4ee6a4SAndroid Build Coastguard Worker pub enum Error {
101*bb4ee6a4SAndroid Build Coastguard Worker #[error("unable to clone an Event: {0}")]
102*bb4ee6a4SAndroid Build Coastguard Worker CloneEvent(base::Error),
103*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to clone IRQ chip: {0}")]
104*bb4ee6a4SAndroid Build Coastguard Worker CloneIrqChip(base::Error),
105*bb4ee6a4SAndroid Build Coastguard Worker #[error("the given kernel command line was invalid: {0}")]
106*bb4ee6a4SAndroid Build Coastguard Worker Cmdline(kernel_cmdline::Error),
107*bb4ee6a4SAndroid Build Coastguard Worker #[error("unable to make an Event: {0}")]
108*bb4ee6a4SAndroid Build Coastguard Worker CreateEvent(base::Error),
109*bb4ee6a4SAndroid Build Coastguard Worker #[error("FDT could not be created: {0}")]
110*bb4ee6a4SAndroid Build Coastguard Worker CreateFdt(cros_fdt::Error),
111*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to create a PCI root hub: {0}")]
112*bb4ee6a4SAndroid Build Coastguard Worker CreatePciRoot(arch::DeviceRegistrationError),
113*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to create platform bus: {0}")]
114*bb4ee6a4SAndroid Build Coastguard Worker CreatePlatformBus(arch::DeviceRegistrationError),
115*bb4ee6a4SAndroid Build Coastguard Worker #[error("unable to create serial devices: {0}")]
116*bb4ee6a4SAndroid Build Coastguard Worker CreateSerialDevices(arch::DeviceRegistrationError),
117*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to create socket: {0}")]
118*bb4ee6a4SAndroid Build Coastguard Worker CreateSocket(io::Error),
119*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to create VCPU: {0}")]
120*bb4ee6a4SAndroid Build Coastguard Worker CreateVcpu(base::Error),
121*bb4ee6a4SAndroid Build Coastguard Worker #[error("vm created wrong kind of vcpu")]
122*bb4ee6a4SAndroid Build Coastguard Worker DowncastVcpu,
123*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to finalize devices: {0}")]
124*bb4ee6a4SAndroid Build Coastguard Worker FinalizeDevices(base::Error),
125*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to finalize IRQ chip: {0}")]
126*bb4ee6a4SAndroid Build Coastguard Worker FinalizeIrqChip(base::Error),
127*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to get serial cmdline: {0}")]
128*bb4ee6a4SAndroid Build Coastguard Worker GetSerialCmdline(GetSerialCmdlineError),
129*bb4ee6a4SAndroid Build Coastguard Worker #[error("Failed to get the timer base frequency: {0}")]
130*bb4ee6a4SAndroid Build Coastguard Worker GetTimebase(base::Error),
131*bb4ee6a4SAndroid Build Coastguard Worker #[error("Image type not supported on riscv")]
132*bb4ee6a4SAndroid Build Coastguard Worker ImageTypeUnsupported,
133*bb4ee6a4SAndroid Build Coastguard Worker #[error("initrd could not be loaded: {0}")]
134*bb4ee6a4SAndroid Build Coastguard Worker InitrdLoadFailure(arch::LoadImageError),
135*bb4ee6a4SAndroid Build Coastguard Worker #[error("kernel could not be loaded: {0}")]
136*bb4ee6a4SAndroid Build Coastguard Worker KernelLoadFailure(arch::LoadImageError),
137*bb4ee6a4SAndroid Build Coastguard Worker #[error("PCI mem region not configurable on riscv (yet)")]
138*bb4ee6a4SAndroid Build Coastguard Worker PciMemNotConfigurable,
139*bb4ee6a4SAndroid Build Coastguard Worker #[error("protected vms not supported on riscv (yet)")]
140*bb4ee6a4SAndroid Build Coastguard Worker ProtectedVmUnsupported,
141*bb4ee6a4SAndroid Build Coastguard Worker #[error("ramoops address is different from high_mmio_base: {0} vs {1}")]
142*bb4ee6a4SAndroid Build Coastguard Worker RamoopsAddress(u64, u64),
143*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to register irq fd: {0}")]
144*bb4ee6a4SAndroid Build Coastguard Worker RegisterIrqfd(base::Error),
145*bb4ee6a4SAndroid Build Coastguard Worker #[error("error registering PCI bus: {0}")]
146*bb4ee6a4SAndroid Build Coastguard Worker RegisterPci(BusError),
147*bb4ee6a4SAndroid Build Coastguard Worker #[error("error registering virtual socket device: {0}")]
148*bb4ee6a4SAndroid Build Coastguard Worker RegisterVsock(arch::DeviceRegistrationError),
149*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to set device attr: {0}")]
150*bb4ee6a4SAndroid Build Coastguard Worker SetDeviceAttr(base::Error),
151*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to set register: {0}")]
152*bb4ee6a4SAndroid Build Coastguard Worker SetReg(base::Error),
153*bb4ee6a4SAndroid Build Coastguard Worker #[error("Timebase frequency too large")]
154*bb4ee6a4SAndroid Build Coastguard Worker TimebaseTooLarge,
155*bb4ee6a4SAndroid Build Coastguard Worker #[error("this function isn't supported")]
156*bb4ee6a4SAndroid Build Coastguard Worker Unsupported,
157*bb4ee6a4SAndroid Build Coastguard Worker #[error("failed to initialize VCPU: {0}")]
158*bb4ee6a4SAndroid Build Coastguard Worker VcpuInit(base::Error),
159*bb4ee6a4SAndroid Build Coastguard Worker }
160*bb4ee6a4SAndroid Build Coastguard Worker
161*bb4ee6a4SAndroid Build Coastguard Worker pub type Result<T> = std::result::Result<T, Error>;
162*bb4ee6a4SAndroid Build Coastguard Worker
163*bb4ee6a4SAndroid Build Coastguard Worker pub struct ArchMemoryLayout {}
164*bb4ee6a4SAndroid Build Coastguard Worker
165*bb4ee6a4SAndroid Build Coastguard Worker pub struct Riscv64;
166*bb4ee6a4SAndroid Build Coastguard Worker
167*bb4ee6a4SAndroid Build Coastguard Worker impl arch::LinuxArch for Riscv64 {
168*bb4ee6a4SAndroid Build Coastguard Worker type Error = Error;
169*bb4ee6a4SAndroid Build Coastguard Worker type ArchMemoryLayout = ArchMemoryLayout;
170*bb4ee6a4SAndroid Build Coastguard Worker
arch_memory_layout( components: &VmComponents, ) -> std::result::Result<Self::ArchMemoryLayout, Self::Error>171*bb4ee6a4SAndroid Build Coastguard Worker fn arch_memory_layout(
172*bb4ee6a4SAndroid Build Coastguard Worker components: &VmComponents,
173*bb4ee6a4SAndroid Build Coastguard Worker ) -> std::result::Result<Self::ArchMemoryLayout, Self::Error> {
174*bb4ee6a4SAndroid Build Coastguard Worker if components.pci_config.mem.is_some() {
175*bb4ee6a4SAndroid Build Coastguard Worker return Err(Error::PciMemNotConfigurable);
176*bb4ee6a4SAndroid Build Coastguard Worker }
177*bb4ee6a4SAndroid Build Coastguard Worker Ok(ArchMemoryLayout {})
178*bb4ee6a4SAndroid Build Coastguard Worker }
179*bb4ee6a4SAndroid Build Coastguard Worker
180*bb4ee6a4SAndroid Build Coastguard Worker /// Returns a Vec of the valid memory addresses.
181*bb4ee6a4SAndroid Build Coastguard Worker /// These should be used to configure the GuestMemory structure for the platfrom.
guest_memory_layout( components: &VmComponents, _arch_memory_layout: &Self::ArchMemoryLayout, _hypervisor: &impl Hypervisor, ) -> std::result::Result<Vec<(GuestAddress, u64, MemoryRegionOptions)>, Self::Error>182*bb4ee6a4SAndroid Build Coastguard Worker fn guest_memory_layout(
183*bb4ee6a4SAndroid Build Coastguard Worker components: &VmComponents,
184*bb4ee6a4SAndroid Build Coastguard Worker _arch_memory_layout: &Self::ArchMemoryLayout,
185*bb4ee6a4SAndroid Build Coastguard Worker _hypervisor: &impl Hypervisor,
186*bb4ee6a4SAndroid Build Coastguard Worker ) -> std::result::Result<Vec<(GuestAddress, u64, MemoryRegionOptions)>, Self::Error> {
187*bb4ee6a4SAndroid Build Coastguard Worker Ok(vec![(
188*bb4ee6a4SAndroid Build Coastguard Worker GuestAddress(RISCV64_PHYS_MEM_START),
189*bb4ee6a4SAndroid Build Coastguard Worker components.memory_size,
190*bb4ee6a4SAndroid Build Coastguard Worker Default::default(),
191*bb4ee6a4SAndroid Build Coastguard Worker )])
192*bb4ee6a4SAndroid Build Coastguard Worker }
193*bb4ee6a4SAndroid Build Coastguard Worker
get_system_allocator_config<V: Vm>( vm: &V, _arch_memory_layout: &Self::ArchMemoryLayout, ) -> SystemAllocatorConfig194*bb4ee6a4SAndroid Build Coastguard Worker fn get_system_allocator_config<V: Vm>(
195*bb4ee6a4SAndroid Build Coastguard Worker vm: &V,
196*bb4ee6a4SAndroid Build Coastguard Worker _arch_memory_layout: &Self::ArchMemoryLayout,
197*bb4ee6a4SAndroid Build Coastguard Worker ) -> SystemAllocatorConfig {
198*bb4ee6a4SAndroid Build Coastguard Worker let (high_mmio_base, high_mmio_size) =
199*bb4ee6a4SAndroid Build Coastguard Worker get_high_mmio_base_size(vm.get_memory().memory_size(), vm.get_guest_phys_addr_bits());
200*bb4ee6a4SAndroid Build Coastguard Worker SystemAllocatorConfig {
201*bb4ee6a4SAndroid Build Coastguard Worker io: None,
202*bb4ee6a4SAndroid Build Coastguard Worker low_mmio: AddressRange::from_start_and_size(RISCV64_MMIO_BASE, RISCV64_MMIO_SIZE)
203*bb4ee6a4SAndroid Build Coastguard Worker .expect("invalid mmio region"),
204*bb4ee6a4SAndroid Build Coastguard Worker high_mmio: AddressRange::from_start_and_size(high_mmio_base, high_mmio_size)
205*bb4ee6a4SAndroid Build Coastguard Worker .expect("invalid high mmio region"),
206*bb4ee6a4SAndroid Build Coastguard Worker platform_mmio: None,
207*bb4ee6a4SAndroid Build Coastguard Worker first_irq: RISCV64_IRQ_BASE,
208*bb4ee6a4SAndroid Build Coastguard Worker }
209*bb4ee6a4SAndroid Build Coastguard Worker }
210*bb4ee6a4SAndroid Build Coastguard Worker
build_vm<V, Vcpu>( mut components: VmComponents, _arch_memory_layout: &Self::ArchMemoryLayout, _vm_evt_wrtube: &SendTube, system_allocator: &mut SystemAllocator, serial_parameters: &BTreeMap<(SerialHardware, u8), SerialParameters>, serial_jail: Option<Minijail>, (_bat_type, _bat_jail): (Option<BatteryType>, Option<Minijail>), mut vm: V, ramoops_region: Option<arch::pstore::RamoopsRegion>, devices: Vec<(Box<dyn BusDeviceObj>, Option<Minijail>)>, irq_chip: &mut dyn IrqChipRiscv64, vcpu_ids: &mut Vec<usize>, _dump_device_tree_blob: Option<PathBuf>, _debugcon_jail: Option<Minijail>, #[cfg(feature = "swap")] swap_controller: &mut Option<swap::SwapController>, _guest_suspended_cvar: Option<Arc<(Mutex<bool>, Condvar)>>, device_tree_overlays: Vec<DtbOverlay>, fdt_position: Option<FdtPosition>, _no_pmu: bool, ) -> std::result::Result<RunnableLinuxVm<V, Vcpu>, Self::Error> where V: VmRiscv64, Vcpu: VcpuRiscv64,211*bb4ee6a4SAndroid Build Coastguard Worker fn build_vm<V, Vcpu>(
212*bb4ee6a4SAndroid Build Coastguard Worker mut components: VmComponents,
213*bb4ee6a4SAndroid Build Coastguard Worker _arch_memory_layout: &Self::ArchMemoryLayout,
214*bb4ee6a4SAndroid Build Coastguard Worker _vm_evt_wrtube: &SendTube,
215*bb4ee6a4SAndroid Build Coastguard Worker system_allocator: &mut SystemAllocator,
216*bb4ee6a4SAndroid Build Coastguard Worker serial_parameters: &BTreeMap<(SerialHardware, u8), SerialParameters>,
217*bb4ee6a4SAndroid Build Coastguard Worker serial_jail: Option<Minijail>,
218*bb4ee6a4SAndroid Build Coastguard Worker (_bat_type, _bat_jail): (Option<BatteryType>, Option<Minijail>),
219*bb4ee6a4SAndroid Build Coastguard Worker mut vm: V,
220*bb4ee6a4SAndroid Build Coastguard Worker ramoops_region: Option<arch::pstore::RamoopsRegion>,
221*bb4ee6a4SAndroid Build Coastguard Worker devices: Vec<(Box<dyn BusDeviceObj>, Option<Minijail>)>,
222*bb4ee6a4SAndroid Build Coastguard Worker irq_chip: &mut dyn IrqChipRiscv64,
223*bb4ee6a4SAndroid Build Coastguard Worker vcpu_ids: &mut Vec<usize>,
224*bb4ee6a4SAndroid Build Coastguard Worker _dump_device_tree_blob: Option<PathBuf>,
225*bb4ee6a4SAndroid Build Coastguard Worker _debugcon_jail: Option<Minijail>,
226*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "swap")] swap_controller: &mut Option<swap::SwapController>,
227*bb4ee6a4SAndroid Build Coastguard Worker _guest_suspended_cvar: Option<Arc<(Mutex<bool>, Condvar)>>,
228*bb4ee6a4SAndroid Build Coastguard Worker device_tree_overlays: Vec<DtbOverlay>,
229*bb4ee6a4SAndroid Build Coastguard Worker fdt_position: Option<FdtPosition>,
230*bb4ee6a4SAndroid Build Coastguard Worker _no_pmu: bool,
231*bb4ee6a4SAndroid Build Coastguard Worker ) -> std::result::Result<RunnableLinuxVm<V, Vcpu>, Self::Error>
232*bb4ee6a4SAndroid Build Coastguard Worker where
233*bb4ee6a4SAndroid Build Coastguard Worker V: VmRiscv64,
234*bb4ee6a4SAndroid Build Coastguard Worker Vcpu: VcpuRiscv64,
235*bb4ee6a4SAndroid Build Coastguard Worker {
236*bb4ee6a4SAndroid Build Coastguard Worker if components.hv_cfg.protection_type == ProtectionType::Protected {
237*bb4ee6a4SAndroid Build Coastguard Worker return Err(Error::ProtectedVmUnsupported);
238*bb4ee6a4SAndroid Build Coastguard Worker }
239*bb4ee6a4SAndroid Build Coastguard Worker
240*bb4ee6a4SAndroid Build Coastguard Worker let mem = vm.get_memory().clone();
241*bb4ee6a4SAndroid Build Coastguard Worker
242*bb4ee6a4SAndroid Build Coastguard Worker let mmio_bus = Arc::new(Bus::new(BusType::Mmio));
243*bb4ee6a4SAndroid Build Coastguard Worker
244*bb4ee6a4SAndroid Build Coastguard Worker // Riscv doesn't really use the io bus like x86, so just create an empty bus.
245*bb4ee6a4SAndroid Build Coastguard Worker let io_bus = Arc::new(Bus::new(BusType::Io));
246*bb4ee6a4SAndroid Build Coastguard Worker
247*bb4ee6a4SAndroid Build Coastguard Worker let com_evt_1_3 = Event::new().map_err(Error::CreateEvent)?;
248*bb4ee6a4SAndroid Build Coastguard Worker let com_evt_2_4 = Event::new().map_err(Error::CreateEvent)?;
249*bb4ee6a4SAndroid Build Coastguard Worker let serial_devices = arch::add_serial_devices(
250*bb4ee6a4SAndroid Build Coastguard Worker components.hv_cfg.protection_type,
251*bb4ee6a4SAndroid Build Coastguard Worker &mmio_bus,
252*bb4ee6a4SAndroid Build Coastguard Worker // TODO: the IRQ numbers are bogus since the events aren't actually wired up
253*bb4ee6a4SAndroid Build Coastguard Worker (0, &com_evt_1_3),
254*bb4ee6a4SAndroid Build Coastguard Worker (0, &com_evt_2_4),
255*bb4ee6a4SAndroid Build Coastguard Worker serial_parameters,
256*bb4ee6a4SAndroid Build Coastguard Worker serial_jail,
257*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "swap")]
258*bb4ee6a4SAndroid Build Coastguard Worker swap_controller,
259*bb4ee6a4SAndroid Build Coastguard Worker )
260*bb4ee6a4SAndroid Build Coastguard Worker .map_err(Error::CreateSerialDevices)?;
261*bb4ee6a4SAndroid Build Coastguard Worker
262*bb4ee6a4SAndroid Build Coastguard Worker let (pci_devices, others): (Vec<_>, Vec<_>) = devices
263*bb4ee6a4SAndroid Build Coastguard Worker .into_iter()
264*bb4ee6a4SAndroid Build Coastguard Worker .partition(|(dev, _)| dev.as_pci_device().is_some());
265*bb4ee6a4SAndroid Build Coastguard Worker let pci_devices = pci_devices
266*bb4ee6a4SAndroid Build Coastguard Worker .into_iter()
267*bb4ee6a4SAndroid Build Coastguard Worker .map(|(dev, jail_orig)| (dev.into_pci_device().unwrap(), jail_orig))
268*bb4ee6a4SAndroid Build Coastguard Worker .collect();
269*bb4ee6a4SAndroid Build Coastguard Worker let (pci, pci_irqs, mut pid_debug_label_map, _amls, _gpe_scope_amls) =
270*bb4ee6a4SAndroid Build Coastguard Worker arch::generate_pci_root(
271*bb4ee6a4SAndroid Build Coastguard Worker pci_devices,
272*bb4ee6a4SAndroid Build Coastguard Worker irq_chip.as_irq_chip_mut(),
273*bb4ee6a4SAndroid Build Coastguard Worker Arc::clone(&mmio_bus),
274*bb4ee6a4SAndroid Build Coastguard Worker GuestAddress(RISCV64_PCI_CFG_BASE),
275*bb4ee6a4SAndroid Build Coastguard Worker 8,
276*bb4ee6a4SAndroid Build Coastguard Worker Arc::clone(&io_bus),
277*bb4ee6a4SAndroid Build Coastguard Worker system_allocator,
278*bb4ee6a4SAndroid Build Coastguard Worker &mut vm,
279*bb4ee6a4SAndroid Build Coastguard Worker devices::IMSIC_MAX_INT_IDS as usize,
280*bb4ee6a4SAndroid Build Coastguard Worker None,
281*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "swap")]
282*bb4ee6a4SAndroid Build Coastguard Worker swap_controller,
283*bb4ee6a4SAndroid Build Coastguard Worker )
284*bb4ee6a4SAndroid Build Coastguard Worker .map_err(Error::CreatePciRoot)?;
285*bb4ee6a4SAndroid Build Coastguard Worker
286*bb4ee6a4SAndroid Build Coastguard Worker let pci_root = Arc::new(Mutex::new(pci));
287*bb4ee6a4SAndroid Build Coastguard Worker let pci_bus = Arc::new(Mutex::new(PciConfigMmio::new(pci_root.clone(), 8)));
288*bb4ee6a4SAndroid Build Coastguard Worker let (platform_devices, _others): (Vec<_>, Vec<_>) = others
289*bb4ee6a4SAndroid Build Coastguard Worker .into_iter()
290*bb4ee6a4SAndroid Build Coastguard Worker .partition(|(dev, _)| dev.as_platform_device().is_some());
291*bb4ee6a4SAndroid Build Coastguard Worker
292*bb4ee6a4SAndroid Build Coastguard Worker let platform_devices = platform_devices
293*bb4ee6a4SAndroid Build Coastguard Worker .into_iter()
294*bb4ee6a4SAndroid Build Coastguard Worker .map(|(dev, jail_orig)| (*(dev.into_platform_device().unwrap()), jail_orig))
295*bb4ee6a4SAndroid Build Coastguard Worker .collect();
296*bb4ee6a4SAndroid Build Coastguard Worker let (platform_devices, mut platform_pid_debug_label_map, dev_resources) =
297*bb4ee6a4SAndroid Build Coastguard Worker arch::sys::linux::generate_platform_bus(
298*bb4ee6a4SAndroid Build Coastguard Worker platform_devices,
299*bb4ee6a4SAndroid Build Coastguard Worker irq_chip.as_irq_chip_mut(),
300*bb4ee6a4SAndroid Build Coastguard Worker &mmio_bus,
301*bb4ee6a4SAndroid Build Coastguard Worker system_allocator,
302*bb4ee6a4SAndroid Build Coastguard Worker &mut vm,
303*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "swap")]
304*bb4ee6a4SAndroid Build Coastguard Worker swap_controller,
305*bb4ee6a4SAndroid Build Coastguard Worker components.hv_cfg.protection_type,
306*bb4ee6a4SAndroid Build Coastguard Worker )
307*bb4ee6a4SAndroid Build Coastguard Worker .map_err(Error::CreatePlatformBus)?;
308*bb4ee6a4SAndroid Build Coastguard Worker pid_debug_label_map.append(&mut platform_pid_debug_label_map);
309*bb4ee6a4SAndroid Build Coastguard Worker
310*bb4ee6a4SAndroid Build Coastguard Worker let mut cmdline = get_base_linux_cmdline();
311*bb4ee6a4SAndroid Build Coastguard Worker
312*bb4ee6a4SAndroid Build Coastguard Worker if let Some(ramoops_region) = ramoops_region {
313*bb4ee6a4SAndroid Build Coastguard Worker arch::pstore::add_ramoops_kernel_cmdline(&mut cmdline, &ramoops_region)
314*bb4ee6a4SAndroid Build Coastguard Worker .map_err(Error::Cmdline)?;
315*bb4ee6a4SAndroid Build Coastguard Worker }
316*bb4ee6a4SAndroid Build Coastguard Worker
317*bb4ee6a4SAndroid Build Coastguard Worker mmio_bus
318*bb4ee6a4SAndroid Build Coastguard Worker .insert(pci_bus, RISCV64_PCI_CFG_BASE, RISCV64_PCI_CFG_SIZE)
319*bb4ee6a4SAndroid Build Coastguard Worker .map_err(Error::RegisterPci)?;
320*bb4ee6a4SAndroid Build Coastguard Worker
321*bb4ee6a4SAndroid Build Coastguard Worker get_serial_cmdline(&mut cmdline, serial_parameters, "mmio", &serial_devices)
322*bb4ee6a4SAndroid Build Coastguard Worker .map_err(Error::GetSerialCmdline)?;
323*bb4ee6a4SAndroid Build Coastguard Worker for param in components.extra_kernel_params {
324*bb4ee6a4SAndroid Build Coastguard Worker cmdline.insert_str(¶m).map_err(Error::Cmdline)?;
325*bb4ee6a4SAndroid Build Coastguard Worker }
326*bb4ee6a4SAndroid Build Coastguard Worker
327*bb4ee6a4SAndroid Build Coastguard Worker // Event used by PMDevice to notify crosvm that guest OS is trying to suspend.
328*bb4ee6a4SAndroid Build Coastguard Worker let (suspend_tube_send, suspend_tube_recv) = Tube::directional_pair().unwrap();
329*bb4ee6a4SAndroid Build Coastguard Worker
330*bb4ee6a4SAndroid Build Coastguard Worker // separate out image loading from other setup to get a specific error for
331*bb4ee6a4SAndroid Build Coastguard Worker // image loading
332*bb4ee6a4SAndroid Build Coastguard Worker let initrd;
333*bb4ee6a4SAndroid Build Coastguard Worker let kernel_initrd_end = match components.vm_image {
334*bb4ee6a4SAndroid Build Coastguard Worker VmImage::Bios(ref _bios) => {
335*bb4ee6a4SAndroid Build Coastguard Worker return Err(Error::ImageTypeUnsupported);
336*bb4ee6a4SAndroid Build Coastguard Worker }
337*bb4ee6a4SAndroid Build Coastguard Worker VmImage::Kernel(ref mut kernel_image) => {
338*bb4ee6a4SAndroid Build Coastguard Worker let kernel_size = arch::load_image(&mem, kernel_image, get_kernel_addr(), u64::MAX)
339*bb4ee6a4SAndroid Build Coastguard Worker .map_err(Error::KernelLoadFailure)?;
340*bb4ee6a4SAndroid Build Coastguard Worker let kernel_end = get_kernel_addr().offset() + kernel_size as u64;
341*bb4ee6a4SAndroid Build Coastguard Worker initrd = match components.initrd_image {
342*bb4ee6a4SAndroid Build Coastguard Worker Some(initrd_file) => {
343*bb4ee6a4SAndroid Build Coastguard Worker let mut initrd_file = initrd_file;
344*bb4ee6a4SAndroid Build Coastguard Worker let initrd_addr =
345*bb4ee6a4SAndroid Build Coastguard Worker (kernel_end + (RISCV64_INITRD_ALIGN - 1)) & !(RISCV64_INITRD_ALIGN - 1);
346*bb4ee6a4SAndroid Build Coastguard Worker let initrd_max_size =
347*bb4ee6a4SAndroid Build Coastguard Worker components.memory_size - (initrd_addr - RISCV64_PHYS_MEM_START);
348*bb4ee6a4SAndroid Build Coastguard Worker let initrd_addr = GuestAddress(initrd_addr);
349*bb4ee6a4SAndroid Build Coastguard Worker let initrd_size =
350*bb4ee6a4SAndroid Build Coastguard Worker arch::load_image(&mem, &mut initrd_file, initrd_addr, initrd_max_size)
351*bb4ee6a4SAndroid Build Coastguard Worker .map_err(Error::InitrdLoadFailure)?;
352*bb4ee6a4SAndroid Build Coastguard Worker Some((initrd_addr, initrd_size))
353*bb4ee6a4SAndroid Build Coastguard Worker }
354*bb4ee6a4SAndroid Build Coastguard Worker None => None,
355*bb4ee6a4SAndroid Build Coastguard Worker };
356*bb4ee6a4SAndroid Build Coastguard Worker if let Some((initrd_addr, initrd_size)) = initrd {
357*bb4ee6a4SAndroid Build Coastguard Worker initrd_addr.offset() + initrd_size as u64 - RISCV64_PHYS_MEM_START
358*bb4ee6a4SAndroid Build Coastguard Worker } else {
359*bb4ee6a4SAndroid Build Coastguard Worker kernel_end - RISCV64_PHYS_MEM_START
360*bb4ee6a4SAndroid Build Coastguard Worker }
361*bb4ee6a4SAndroid Build Coastguard Worker }
362*bb4ee6a4SAndroid Build Coastguard Worker };
363*bb4ee6a4SAndroid Build Coastguard Worker
364*bb4ee6a4SAndroid Build Coastguard Worker // Creates vcpus early as the irqchip needs them created to attach interrupts.
365*bb4ee6a4SAndroid Build Coastguard Worker let vcpu_count = components.vcpu_count;
366*bb4ee6a4SAndroid Build Coastguard Worker let mut vcpus = Vec::with_capacity(vcpu_count);
367*bb4ee6a4SAndroid Build Coastguard Worker for vcpu_id in 0..vcpu_count {
368*bb4ee6a4SAndroid Build Coastguard Worker let vcpu: Vcpu = *vm
369*bb4ee6a4SAndroid Build Coastguard Worker .create_vcpu(vcpu_id)
370*bb4ee6a4SAndroid Build Coastguard Worker .map_err(Error::CreateVcpu)?
371*bb4ee6a4SAndroid Build Coastguard Worker .downcast::<Vcpu>()
372*bb4ee6a4SAndroid Build Coastguard Worker .map_err(|_| Error::DowncastVcpu)?;
373*bb4ee6a4SAndroid Build Coastguard Worker vcpus.push(vcpu);
374*bb4ee6a4SAndroid Build Coastguard Worker vcpu_ids.push(vcpu_id);
375*bb4ee6a4SAndroid Build Coastguard Worker }
376*bb4ee6a4SAndroid Build Coastguard Worker
377*bb4ee6a4SAndroid Build Coastguard Worker irq_chip.finalize().map_err(Error::FinalizeIrqChip)?;
378*bb4ee6a4SAndroid Build Coastguard Worker
379*bb4ee6a4SAndroid Build Coastguard Worker irq_chip
380*bb4ee6a4SAndroid Build Coastguard Worker .finalize_devices(system_allocator, &io_bus, &mmio_bus)
381*bb4ee6a4SAndroid Build Coastguard Worker .map_err(Error::FinalizeDevices)?;
382*bb4ee6a4SAndroid Build Coastguard Worker let (aia_num_ids, aia_num_sources) = irq_chip.get_num_ids_sources();
383*bb4ee6a4SAndroid Build Coastguard Worker
384*bb4ee6a4SAndroid Build Coastguard Worker let pci_cfg = fdt::PciConfigRegion {
385*bb4ee6a4SAndroid Build Coastguard Worker base: RISCV64_PCI_CFG_BASE,
386*bb4ee6a4SAndroid Build Coastguard Worker size: RISCV64_PCI_CFG_SIZE,
387*bb4ee6a4SAndroid Build Coastguard Worker };
388*bb4ee6a4SAndroid Build Coastguard Worker
389*bb4ee6a4SAndroid Build Coastguard Worker let pci_ranges: Vec<fdt::PciRange> = system_allocator
390*bb4ee6a4SAndroid Build Coastguard Worker .mmio_pools()
391*bb4ee6a4SAndroid Build Coastguard Worker .iter()
392*bb4ee6a4SAndroid Build Coastguard Worker .map(|range| fdt::PciRange {
393*bb4ee6a4SAndroid Build Coastguard Worker space: fdt::PciAddressSpace::Memory64,
394*bb4ee6a4SAndroid Build Coastguard Worker bus_address: range.start,
395*bb4ee6a4SAndroid Build Coastguard Worker cpu_physical_address: range.start,
396*bb4ee6a4SAndroid Build Coastguard Worker size: range.len().unwrap(),
397*bb4ee6a4SAndroid Build Coastguard Worker prefetchable: false,
398*bb4ee6a4SAndroid Build Coastguard Worker })
399*bb4ee6a4SAndroid Build Coastguard Worker .collect();
400*bb4ee6a4SAndroid Build Coastguard Worker
401*bb4ee6a4SAndroid Build Coastguard Worker assert!(
402*bb4ee6a4SAndroid Build Coastguard Worker matches!(fdt_position, None | Some(FdtPosition::AfterPayload)),
403*bb4ee6a4SAndroid Build Coastguard Worker "fdt_position={fdt_position:?} not supported"
404*bb4ee6a4SAndroid Build Coastguard Worker );
405*bb4ee6a4SAndroid Build Coastguard Worker let fdt_offset = (kernel_initrd_end + (RISCV64_FDT_ALIGN - 1)) & !(RISCV64_FDT_ALIGN - 1);
406*bb4ee6a4SAndroid Build Coastguard Worker
407*bb4ee6a4SAndroid Build Coastguard Worker let timebase_freq: u32 = vcpus[0]
408*bb4ee6a4SAndroid Build Coastguard Worker .get_one_reg(VcpuRegister::Timer(TimerRegister::TimebaseFrequency))
409*bb4ee6a4SAndroid Build Coastguard Worker .map_err(Error::GetTimebase)?
410*bb4ee6a4SAndroid Build Coastguard Worker .try_into()
411*bb4ee6a4SAndroid Build Coastguard Worker .map_err(|_| Error::TimebaseTooLarge)?;
412*bb4ee6a4SAndroid Build Coastguard Worker
413*bb4ee6a4SAndroid Build Coastguard Worker fdt::create_fdt(
414*bb4ee6a4SAndroid Build Coastguard Worker RISCV64_FDT_MAX_SIZE as usize,
415*bb4ee6a4SAndroid Build Coastguard Worker &mem,
416*bb4ee6a4SAndroid Build Coastguard Worker pci_irqs,
417*bb4ee6a4SAndroid Build Coastguard Worker pci_cfg,
418*bb4ee6a4SAndroid Build Coastguard Worker &pci_ranges,
419*bb4ee6a4SAndroid Build Coastguard Worker dev_resources,
420*bb4ee6a4SAndroid Build Coastguard Worker components.vcpu_count as u32,
421*bb4ee6a4SAndroid Build Coastguard Worker fdt_offset,
422*bb4ee6a4SAndroid Build Coastguard Worker aia_num_ids,
423*bb4ee6a4SAndroid Build Coastguard Worker aia_num_sources,
424*bb4ee6a4SAndroid Build Coastguard Worker cmdline
425*bb4ee6a4SAndroid Build Coastguard Worker .as_str_with_max_len(RISCV64_CMDLINE_MAX_SIZE - 1)
426*bb4ee6a4SAndroid Build Coastguard Worker .map_err(Error::Cmdline)?,
427*bb4ee6a4SAndroid Build Coastguard Worker initrd,
428*bb4ee6a4SAndroid Build Coastguard Worker timebase_freq,
429*bb4ee6a4SAndroid Build Coastguard Worker device_tree_overlays,
430*bb4ee6a4SAndroid Build Coastguard Worker )
431*bb4ee6a4SAndroid Build Coastguard Worker .map_err(Error::CreateFdt)?;
432*bb4ee6a4SAndroid Build Coastguard Worker
433*bb4ee6a4SAndroid Build Coastguard Worker let vcpu_init = vec![
434*bb4ee6a4SAndroid Build Coastguard Worker VcpuInitRiscv64::new(GuestAddress(fdt_offset + RISCV64_PHYS_MEM_START));
435*bb4ee6a4SAndroid Build Coastguard Worker vcpu_count
436*bb4ee6a4SAndroid Build Coastguard Worker ];
437*bb4ee6a4SAndroid Build Coastguard Worker
438*bb4ee6a4SAndroid Build Coastguard Worker Ok(RunnableLinuxVm {
439*bb4ee6a4SAndroid Build Coastguard Worker vm,
440*bb4ee6a4SAndroid Build Coastguard Worker vcpu_count: components.vcpu_count,
441*bb4ee6a4SAndroid Build Coastguard Worker vcpus: Some(vcpus),
442*bb4ee6a4SAndroid Build Coastguard Worker vcpu_init,
443*bb4ee6a4SAndroid Build Coastguard Worker vcpu_affinity: components.vcpu_affinity,
444*bb4ee6a4SAndroid Build Coastguard Worker no_smt: false,
445*bb4ee6a4SAndroid Build Coastguard Worker irq_chip: irq_chip.try_box_clone().map_err(Error::CloneIrqChip)?,
446*bb4ee6a4SAndroid Build Coastguard Worker io_bus,
447*bb4ee6a4SAndroid Build Coastguard Worker mmio_bus,
448*bb4ee6a4SAndroid Build Coastguard Worker pid_debug_label_map,
449*bb4ee6a4SAndroid Build Coastguard Worker resume_notify_devices: Vec::new(),
450*bb4ee6a4SAndroid Build Coastguard Worker root_config: pci_root,
451*bb4ee6a4SAndroid Build Coastguard Worker platform_devices,
452*bb4ee6a4SAndroid Build Coastguard Worker hotplug_bus: BTreeMap::new(),
453*bb4ee6a4SAndroid Build Coastguard Worker rt_cpus: components.rt_cpus,
454*bb4ee6a4SAndroid Build Coastguard Worker delay_rt: components.delay_rt,
455*bb4ee6a4SAndroid Build Coastguard Worker suspend_tube: (Arc::new(Mutex::new(suspend_tube_send)), suspend_tube_recv),
456*bb4ee6a4SAndroid Build Coastguard Worker bat_control: None,
457*bb4ee6a4SAndroid Build Coastguard Worker pm: None,
458*bb4ee6a4SAndroid Build Coastguard Worker devices_thread: None,
459*bb4ee6a4SAndroid Build Coastguard Worker vm_request_tubes: Vec::new(),
460*bb4ee6a4SAndroid Build Coastguard Worker })
461*bb4ee6a4SAndroid Build Coastguard Worker }
462*bb4ee6a4SAndroid Build Coastguard Worker
configure_vcpu<V: Vm>( _vm: &V, _hypervisor: &dyn Hypervisor, _irq_chip: &mut dyn IrqChipRiscv64, vcpu: &mut dyn VcpuRiscv64, _vcpu_init: VcpuInitRiscv64, vcpu_id: usize, _num_cpus: usize, cpu_config: Option<CpuConfigRiscv64>, ) -> std::result::Result<(), Self::Error>463*bb4ee6a4SAndroid Build Coastguard Worker fn configure_vcpu<V: Vm>(
464*bb4ee6a4SAndroid Build Coastguard Worker _vm: &V,
465*bb4ee6a4SAndroid Build Coastguard Worker _hypervisor: &dyn Hypervisor,
466*bb4ee6a4SAndroid Build Coastguard Worker _irq_chip: &mut dyn IrqChipRiscv64,
467*bb4ee6a4SAndroid Build Coastguard Worker vcpu: &mut dyn VcpuRiscv64,
468*bb4ee6a4SAndroid Build Coastguard Worker _vcpu_init: VcpuInitRiscv64,
469*bb4ee6a4SAndroid Build Coastguard Worker vcpu_id: usize,
470*bb4ee6a4SAndroid Build Coastguard Worker _num_cpus: usize,
471*bb4ee6a4SAndroid Build Coastguard Worker cpu_config: Option<CpuConfigRiscv64>,
472*bb4ee6a4SAndroid Build Coastguard Worker ) -> std::result::Result<(), Self::Error> {
473*bb4ee6a4SAndroid Build Coastguard Worker vcpu.set_one_reg(VcpuRegister::Core(CoreRegister::Pc), get_kernel_addr().0)
474*bb4ee6a4SAndroid Build Coastguard Worker .map_err(Self::Error::SetReg)?;
475*bb4ee6a4SAndroid Build Coastguard Worker vcpu.set_one_reg(VcpuRegister::Core(CoreRegister::A0), vcpu_id as u64)
476*bb4ee6a4SAndroid Build Coastguard Worker .map_err(Self::Error::SetReg)?;
477*bb4ee6a4SAndroid Build Coastguard Worker vcpu.set_one_reg(
478*bb4ee6a4SAndroid Build Coastguard Worker VcpuRegister::Core(CoreRegister::A1),
479*bb4ee6a4SAndroid Build Coastguard Worker cpu_config.unwrap().fdt_address.0,
480*bb4ee6a4SAndroid Build Coastguard Worker )
481*bb4ee6a4SAndroid Build Coastguard Worker .map_err(Self::Error::SetReg)?;
482*bb4ee6a4SAndroid Build Coastguard Worker
483*bb4ee6a4SAndroid Build Coastguard Worker Ok(())
484*bb4ee6a4SAndroid Build Coastguard Worker }
485*bb4ee6a4SAndroid Build Coastguard Worker
register_pci_device<V: VmRiscv64, Vcpu: VcpuRiscv64>( _linux: &mut RunnableLinuxVm<V, Vcpu>, _device: Box<dyn PciDevice>, _minijail: Option<Minijail>, _resources: &mut SystemAllocator, _tube: &mpsc::Sender<PciRootCommand>, #[cfg(feature = "swap")] _swap_controller: &mut Option<swap::SwapController>, ) -> std::result::Result<PciAddress, Self::Error>486*bb4ee6a4SAndroid Build Coastguard Worker fn register_pci_device<V: VmRiscv64, Vcpu: VcpuRiscv64>(
487*bb4ee6a4SAndroid Build Coastguard Worker _linux: &mut RunnableLinuxVm<V, Vcpu>,
488*bb4ee6a4SAndroid Build Coastguard Worker _device: Box<dyn PciDevice>,
489*bb4ee6a4SAndroid Build Coastguard Worker _minijail: Option<Minijail>,
490*bb4ee6a4SAndroid Build Coastguard Worker _resources: &mut SystemAllocator,
491*bb4ee6a4SAndroid Build Coastguard Worker _tube: &mpsc::Sender<PciRootCommand>,
492*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "swap")] _swap_controller: &mut Option<swap::SwapController>,
493*bb4ee6a4SAndroid Build Coastguard Worker ) -> std::result::Result<PciAddress, Self::Error> {
494*bb4ee6a4SAndroid Build Coastguard Worker // hotplug function isn't verified on Riscv64, so set it unsupported here.
495*bb4ee6a4SAndroid Build Coastguard Worker Err(Error::Unsupported)
496*bb4ee6a4SAndroid Build Coastguard Worker }
497*bb4ee6a4SAndroid Build Coastguard Worker
get_host_cpu_frequencies_khz() -> Result<BTreeMap<usize, Vec<u32>>>498*bb4ee6a4SAndroid Build Coastguard Worker fn get_host_cpu_frequencies_khz() -> Result<BTreeMap<usize, Vec<u32>>> {
499*bb4ee6a4SAndroid Build Coastguard Worker Ok(BTreeMap::new())
500*bb4ee6a4SAndroid Build Coastguard Worker }
501*bb4ee6a4SAndroid Build Coastguard Worker
get_host_cpu_max_freq_khz() -> Result<BTreeMap<usize, u32>>502*bb4ee6a4SAndroid Build Coastguard Worker fn get_host_cpu_max_freq_khz() -> Result<BTreeMap<usize, u32>> {
503*bb4ee6a4SAndroid Build Coastguard Worker Ok(BTreeMap::new())
504*bb4ee6a4SAndroid Build Coastguard Worker }
505*bb4ee6a4SAndroid Build Coastguard Worker
get_host_cpu_capacity() -> Result<BTreeMap<usize, u32>>506*bb4ee6a4SAndroid Build Coastguard Worker fn get_host_cpu_capacity() -> Result<BTreeMap<usize, u32>> {
507*bb4ee6a4SAndroid Build Coastguard Worker Ok(BTreeMap::new())
508*bb4ee6a4SAndroid Build Coastguard Worker }
509*bb4ee6a4SAndroid Build Coastguard Worker
get_host_cpu_clusters() -> Result<Vec<CpuSet>>510*bb4ee6a4SAndroid Build Coastguard Worker fn get_host_cpu_clusters() -> Result<Vec<CpuSet>> {
511*bb4ee6a4SAndroid Build Coastguard Worker Ok(Vec::new())
512*bb4ee6a4SAndroid Build Coastguard Worker }
513*bb4ee6a4SAndroid Build Coastguard Worker }
514*bb4ee6a4SAndroid Build Coastguard Worker
515*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(feature = "gdb")]
516*bb4ee6a4SAndroid Build Coastguard Worker impl<T: VcpuRiscv64> arch::GdbOps<T> for Riscv64 {
517*bb4ee6a4SAndroid Build Coastguard Worker type Error = Error;
518*bb4ee6a4SAndroid Build Coastguard Worker
read_memory( _vcpu: &T, _guest_mem: &GuestMemory, _vaddr: GuestAddress, _len: usize, ) -> Result<Vec<u8>>519*bb4ee6a4SAndroid Build Coastguard Worker fn read_memory(
520*bb4ee6a4SAndroid Build Coastguard Worker _vcpu: &T,
521*bb4ee6a4SAndroid Build Coastguard Worker _guest_mem: &GuestMemory,
522*bb4ee6a4SAndroid Build Coastguard Worker _vaddr: GuestAddress,
523*bb4ee6a4SAndroid Build Coastguard Worker _len: usize,
524*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<Vec<u8>> {
525*bb4ee6a4SAndroid Build Coastguard Worker unimplemented!();
526*bb4ee6a4SAndroid Build Coastguard Worker }
527*bb4ee6a4SAndroid Build Coastguard Worker
write_memory( _vcpu: &T, _guest_mem: &GuestMemory, _vaddr: GuestAddress, _buf: &[u8], ) -> Result<()>528*bb4ee6a4SAndroid Build Coastguard Worker fn write_memory(
529*bb4ee6a4SAndroid Build Coastguard Worker _vcpu: &T,
530*bb4ee6a4SAndroid Build Coastguard Worker _guest_mem: &GuestMemory,
531*bb4ee6a4SAndroid Build Coastguard Worker _vaddr: GuestAddress,
532*bb4ee6a4SAndroid Build Coastguard Worker _buf: &[u8],
533*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<()> {
534*bb4ee6a4SAndroid Build Coastguard Worker unimplemented!();
535*bb4ee6a4SAndroid Build Coastguard Worker }
536*bb4ee6a4SAndroid Build Coastguard Worker
read_registers(_vcpu: &T) -> Result<<GdbArch as Arch>::Registers>537*bb4ee6a4SAndroid Build Coastguard Worker fn read_registers(_vcpu: &T) -> Result<<GdbArch as Arch>::Registers> {
538*bb4ee6a4SAndroid Build Coastguard Worker unimplemented!();
539*bb4ee6a4SAndroid Build Coastguard Worker }
540*bb4ee6a4SAndroid Build Coastguard Worker
write_registers(_vcpu: &T, _regs: &<GdbArch as Arch>::Registers) -> Result<()>541*bb4ee6a4SAndroid Build Coastguard Worker fn write_registers(_vcpu: &T, _regs: &<GdbArch as Arch>::Registers) -> Result<()> {
542*bb4ee6a4SAndroid Build Coastguard Worker unimplemented!();
543*bb4ee6a4SAndroid Build Coastguard Worker }
544*bb4ee6a4SAndroid Build Coastguard Worker
read_register(_vcpu: &T, _reg_id: <GdbArch as Arch>::RegId) -> Result<Vec<u8>>545*bb4ee6a4SAndroid Build Coastguard Worker fn read_register(_vcpu: &T, _reg_id: <GdbArch as Arch>::RegId) -> Result<Vec<u8>> {
546*bb4ee6a4SAndroid Build Coastguard Worker unimplemented!();
547*bb4ee6a4SAndroid Build Coastguard Worker }
548*bb4ee6a4SAndroid Build Coastguard Worker
write_register(_vcpu: &T, _reg_id: <GdbArch as Arch>::RegId, _data: &[u8]) -> Result<()>549*bb4ee6a4SAndroid Build Coastguard Worker fn write_register(_vcpu: &T, _reg_id: <GdbArch as Arch>::RegId, _data: &[u8]) -> Result<()> {
550*bb4ee6a4SAndroid Build Coastguard Worker unimplemented!();
551*bb4ee6a4SAndroid Build Coastguard Worker }
552*bb4ee6a4SAndroid Build Coastguard Worker
enable_singlestep(_vcpu: &T) -> Result<()>553*bb4ee6a4SAndroid Build Coastguard Worker fn enable_singlestep(_vcpu: &T) -> Result<()> {
554*bb4ee6a4SAndroid Build Coastguard Worker unimplemented!();
555*bb4ee6a4SAndroid Build Coastguard Worker }
556*bb4ee6a4SAndroid Build Coastguard Worker
get_max_hw_breakpoints(_vcpu: &T) -> Result<usize>557*bb4ee6a4SAndroid Build Coastguard Worker fn get_max_hw_breakpoints(_vcpu: &T) -> Result<usize> {
558*bb4ee6a4SAndroid Build Coastguard Worker unimplemented!();
559*bb4ee6a4SAndroid Build Coastguard Worker }
560*bb4ee6a4SAndroid Build Coastguard Worker
set_hw_breakpoints(_vcpu: &T, _breakpoints: &[GuestAddress]) -> Result<()>561*bb4ee6a4SAndroid Build Coastguard Worker fn set_hw_breakpoints(_vcpu: &T, _breakpoints: &[GuestAddress]) -> Result<()> {
562*bb4ee6a4SAndroid Build Coastguard Worker unimplemented!();
563*bb4ee6a4SAndroid Build Coastguard Worker }
564*bb4ee6a4SAndroid Build Coastguard Worker }
565*bb4ee6a4SAndroid Build Coastguard Worker
get_high_mmio_base_size(mem_size: u64, guest_phys_addr_bits: u8) -> (u64, u64)566*bb4ee6a4SAndroid Build Coastguard Worker fn get_high_mmio_base_size(mem_size: u64, guest_phys_addr_bits: u8) -> (u64, u64) {
567*bb4ee6a4SAndroid Build Coastguard Worker let guest_phys_end = 1u64 << guest_phys_addr_bits;
568*bb4ee6a4SAndroid Build Coastguard Worker let high_mmio_base = RISCV64_PHYS_MEM_START + mem_size;
569*bb4ee6a4SAndroid Build Coastguard Worker let size = guest_phys_end
570*bb4ee6a4SAndroid Build Coastguard Worker .checked_sub(high_mmio_base)
571*bb4ee6a4SAndroid Build Coastguard Worker .unwrap_or_else(|| {
572*bb4ee6a4SAndroid Build Coastguard Worker panic!(
573*bb4ee6a4SAndroid Build Coastguard Worker "guest_phys_end {:#x} < high_mmio_base {:#x}",
574*bb4ee6a4SAndroid Build Coastguard Worker guest_phys_end, high_mmio_base,
575*bb4ee6a4SAndroid Build Coastguard Worker );
576*bb4ee6a4SAndroid Build Coastguard Worker });
577*bb4ee6a4SAndroid Build Coastguard Worker (high_mmio_base, size)
578*bb4ee6a4SAndroid Build Coastguard Worker }
579*bb4ee6a4SAndroid Build Coastguard Worker
get_base_linux_cmdline() -> kernel_cmdline::Cmdline580*bb4ee6a4SAndroid Build Coastguard Worker fn get_base_linux_cmdline() -> kernel_cmdline::Cmdline {
581*bb4ee6a4SAndroid Build Coastguard Worker let mut cmdline = kernel_cmdline::Cmdline::new();
582*bb4ee6a4SAndroid Build Coastguard Worker cmdline.insert_str("panic=-1").unwrap();
583*bb4ee6a4SAndroid Build Coastguard Worker cmdline
584*bb4ee6a4SAndroid Build Coastguard Worker }
585