xref: /aosp_15_r20/external/crosvm/riscv64/src/lib.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
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(&param).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