1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2022 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 //! pvpanic is a simulated device, through which a guest panic event is sent to a VMM. 6*bb4ee6a4SAndroid Build Coastguard Worker //! This was initially developed for qemu with linux in-tree drivers and opensource 7*bb4ee6a4SAndroid Build Coastguard Worker //! driver for windows also exist now. 8*bb4ee6a4SAndroid Build Coastguard Worker //! <https://fossies.org/linux/qemu/docs/specs/pvpanic.txt> 9*bb4ee6a4SAndroid Build Coastguard Worker //! 10*bb4ee6a4SAndroid Build Coastguard Worker //! This implementation emulates pci interface for pvpanic virtual device. 11*bb4ee6a4SAndroid Build Coastguard Worker 12*bb4ee6a4SAndroid Build Coastguard Worker // TODO(218575411): Support pvpanic on windows crosvm. 13*bb4ee6a4SAndroid Build Coastguard Worker #![cfg_attr(windows, allow(dead_code))] 14*bb4ee6a4SAndroid Build Coastguard Worker 15*bb4ee6a4SAndroid Build Coastguard Worker use std::fmt; 16*bb4ee6a4SAndroid Build Coastguard Worker 17*bb4ee6a4SAndroid Build Coastguard Worker use anyhow::Context; 18*bb4ee6a4SAndroid Build Coastguard Worker use base::error; 19*bb4ee6a4SAndroid Build Coastguard Worker use base::RawDescriptor; 20*bb4ee6a4SAndroid Build Coastguard Worker use base::SendTube; 21*bb4ee6a4SAndroid Build Coastguard Worker use base::SharedMemory; 22*bb4ee6a4SAndroid Build Coastguard Worker use base::VmEventType; 23*bb4ee6a4SAndroid Build Coastguard Worker use resources::Alloc; 24*bb4ee6a4SAndroid Build Coastguard Worker use resources::AllocOptions; 25*bb4ee6a4SAndroid Build Coastguard Worker use resources::SystemAllocator; 26*bb4ee6a4SAndroid Build Coastguard Worker 27*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::pci_configuration::PciBarConfiguration; 28*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::pci_configuration::PciBarPrefetchable; 29*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::pci_configuration::PciBarRegionType; 30*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::pci_configuration::PciClassCode; 31*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::pci_configuration::PciConfiguration; 32*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::pci_configuration::PciHeaderType; 33*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::pci_configuration::PciOtherSubclass; 34*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::pci_device; 35*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::pci_device::BarRange; 36*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::pci_device::PciDevice; 37*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::pci_device::Result; 38*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::PciAddress; 39*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::PciBarIndex; 40*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::PciDeviceError; 41*bb4ee6a4SAndroid Build Coastguard Worker use crate::pci::PCI_VENDOR_ID_REDHAT; 42*bb4ee6a4SAndroid Build Coastguard Worker use crate::Suspendable; 43*bb4ee6a4SAndroid Build Coastguard Worker 44*bb4ee6a4SAndroid Build Coastguard Worker const PCI_DEVICE_ID_REDHAT_PVPANIC: u16 = 0x0011; 45*bb4ee6a4SAndroid Build Coastguard Worker const PCI_PVPANIC_REVISION_ID: u8 = 1; 46*bb4ee6a4SAndroid Build Coastguard Worker 47*bb4ee6a4SAndroid Build Coastguard Worker const PVPANIC_BAR_INDEX: PciBarIndex = 0; 48*bb4ee6a4SAndroid Build Coastguard Worker const PVPANIC_REG_SIZE: u64 = 0x10; 49*bb4ee6a4SAndroid Build Coastguard Worker 50*bb4ee6a4SAndroid Build Coastguard Worker // Guest panicked 51*bb4ee6a4SAndroid Build Coastguard Worker pub const PVPANIC_PANICKED: u8 = 1 << 0; 52*bb4ee6a4SAndroid Build Coastguard Worker // Guest kexeced crash kernel 53*bb4ee6a4SAndroid Build Coastguard Worker pub const PVPANIC_CRASH_LOADED: u8 = 1 << 1; 54*bb4ee6a4SAndroid Build Coastguard Worker 55*bb4ee6a4SAndroid Build Coastguard Worker const PVPANIC_CAPABILITIES: u8 = PVPANIC_PANICKED | PVPANIC_CRASH_LOADED; 56*bb4ee6a4SAndroid Build Coastguard Worker 57*bb4ee6a4SAndroid Build Coastguard Worker #[repr(u8)] 58*bb4ee6a4SAndroid Build Coastguard Worker #[derive(PartialEq, Eq)] 59*bb4ee6a4SAndroid Build Coastguard Worker pub enum PvPanicCode { 60*bb4ee6a4SAndroid Build Coastguard Worker Panicked = PVPANIC_PANICKED, 61*bb4ee6a4SAndroid Build Coastguard Worker CrashLoaded = PVPANIC_CRASH_LOADED, 62*bb4ee6a4SAndroid Build Coastguard Worker Unknown = 0xFF, 63*bb4ee6a4SAndroid Build Coastguard Worker } 64*bb4ee6a4SAndroid Build Coastguard Worker 65*bb4ee6a4SAndroid Build Coastguard Worker impl PvPanicCode { from_u8(val: u8) -> PvPanicCode66*bb4ee6a4SAndroid Build Coastguard Worker pub fn from_u8(val: u8) -> PvPanicCode { 67*bb4ee6a4SAndroid Build Coastguard Worker match val { 68*bb4ee6a4SAndroid Build Coastguard Worker PVPANIC_PANICKED => PvPanicCode::Panicked, 69*bb4ee6a4SAndroid Build Coastguard Worker PVPANIC_CRASH_LOADED => PvPanicCode::CrashLoaded, 70*bb4ee6a4SAndroid Build Coastguard Worker _ => PvPanicCode::Unknown, 71*bb4ee6a4SAndroid Build Coastguard Worker } 72*bb4ee6a4SAndroid Build Coastguard Worker } 73*bb4ee6a4SAndroid Build Coastguard Worker } 74*bb4ee6a4SAndroid Build Coastguard Worker 75*bb4ee6a4SAndroid Build Coastguard Worker impl fmt::Display for PvPanicCode { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result76*bb4ee6a4SAndroid Build Coastguard Worker fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 77*bb4ee6a4SAndroid Build Coastguard Worker match self { 78*bb4ee6a4SAndroid Build Coastguard Worker PvPanicCode::Panicked => write!(f, "Guest panicked"), 79*bb4ee6a4SAndroid Build Coastguard Worker PvPanicCode::CrashLoaded => write!(f, "Guest panicked and crash kernel loaded"), 80*bb4ee6a4SAndroid Build Coastguard Worker PvPanicCode::Unknown => write!(f, "Guest panicked with unknown code"), 81*bb4ee6a4SAndroid Build Coastguard Worker } 82*bb4ee6a4SAndroid Build Coastguard Worker } 83*bb4ee6a4SAndroid Build Coastguard Worker } 84*bb4ee6a4SAndroid Build Coastguard Worker 85*bb4ee6a4SAndroid Build Coastguard Worker pub struct PvPanicPciDevice { 86*bb4ee6a4SAndroid Build Coastguard Worker pci_address: Option<PciAddress>, 87*bb4ee6a4SAndroid Build Coastguard Worker config_regs: PciConfiguration, 88*bb4ee6a4SAndroid Build Coastguard Worker evt_wrtube: SendTube, 89*bb4ee6a4SAndroid Build Coastguard Worker } 90*bb4ee6a4SAndroid Build Coastguard Worker 91*bb4ee6a4SAndroid Build Coastguard Worker impl PvPanicPciDevice { new(evt_wrtube: SendTube) -> PvPanicPciDevice92*bb4ee6a4SAndroid Build Coastguard Worker pub fn new(evt_wrtube: SendTube) -> PvPanicPciDevice { 93*bb4ee6a4SAndroid Build Coastguard Worker let config_regs = PciConfiguration::new( 94*bb4ee6a4SAndroid Build Coastguard Worker PCI_VENDOR_ID_REDHAT, 95*bb4ee6a4SAndroid Build Coastguard Worker PCI_DEVICE_ID_REDHAT_PVPANIC, 96*bb4ee6a4SAndroid Build Coastguard Worker PciClassCode::Other, 97*bb4ee6a4SAndroid Build Coastguard Worker &PciOtherSubclass::Other, 98*bb4ee6a4SAndroid Build Coastguard Worker None, 99*bb4ee6a4SAndroid Build Coastguard Worker PciHeaderType::Device, 100*bb4ee6a4SAndroid Build Coastguard Worker 0xFF, 101*bb4ee6a4SAndroid Build Coastguard Worker 0xFF, 102*bb4ee6a4SAndroid Build Coastguard Worker PCI_PVPANIC_REVISION_ID, 103*bb4ee6a4SAndroid Build Coastguard Worker ); 104*bb4ee6a4SAndroid Build Coastguard Worker 105*bb4ee6a4SAndroid Build Coastguard Worker Self { 106*bb4ee6a4SAndroid Build Coastguard Worker pci_address: None, 107*bb4ee6a4SAndroid Build Coastguard Worker config_regs, 108*bb4ee6a4SAndroid Build Coastguard Worker evt_wrtube, 109*bb4ee6a4SAndroid Build Coastguard Worker } 110*bb4ee6a4SAndroid Build Coastguard Worker } 111*bb4ee6a4SAndroid Build Coastguard Worker } 112*bb4ee6a4SAndroid Build Coastguard Worker 113*bb4ee6a4SAndroid Build Coastguard Worker impl PciDevice for PvPanicPciDevice { debug_label(&self) -> String114*bb4ee6a4SAndroid Build Coastguard Worker fn debug_label(&self) -> String { 115*bb4ee6a4SAndroid Build Coastguard Worker "PvPanic".to_owned() 116*bb4ee6a4SAndroid Build Coastguard Worker } 117*bb4ee6a4SAndroid Build Coastguard Worker allocate_address(&mut self, resources: &mut SystemAllocator) -> Result<PciAddress>118*bb4ee6a4SAndroid Build Coastguard Worker fn allocate_address(&mut self, resources: &mut SystemAllocator) -> Result<PciAddress> { 119*bb4ee6a4SAndroid Build Coastguard Worker if self.pci_address.is_none() { 120*bb4ee6a4SAndroid Build Coastguard Worker self.pci_address = match resources.allocate_pci(0, self.debug_label()) { 121*bb4ee6a4SAndroid Build Coastguard Worker Some(Alloc::PciBar { 122*bb4ee6a4SAndroid Build Coastguard Worker bus, 123*bb4ee6a4SAndroid Build Coastguard Worker dev, 124*bb4ee6a4SAndroid Build Coastguard Worker func, 125*bb4ee6a4SAndroid Build Coastguard Worker bar: _, 126*bb4ee6a4SAndroid Build Coastguard Worker }) => Some(PciAddress { bus, dev, func }), 127*bb4ee6a4SAndroid Build Coastguard Worker _ => None, 128*bb4ee6a4SAndroid Build Coastguard Worker } 129*bb4ee6a4SAndroid Build Coastguard Worker } 130*bb4ee6a4SAndroid Build Coastguard Worker self.pci_address.ok_or(PciDeviceError::PciAllocationFailed) 131*bb4ee6a4SAndroid Build Coastguard Worker } 132*bb4ee6a4SAndroid Build Coastguard Worker allocate_io_bars(&mut self, resources: &mut SystemAllocator) -> Result<Vec<BarRange>>133*bb4ee6a4SAndroid Build Coastguard Worker fn allocate_io_bars(&mut self, resources: &mut SystemAllocator) -> Result<Vec<BarRange>> { 134*bb4ee6a4SAndroid Build Coastguard Worker let address = self 135*bb4ee6a4SAndroid Build Coastguard Worker .pci_address 136*bb4ee6a4SAndroid Build Coastguard Worker .expect("allocate_address must be called prior to allocate_io_bars"); 137*bb4ee6a4SAndroid Build Coastguard Worker let mut ranges: Vec<BarRange> = Vec::new(); 138*bb4ee6a4SAndroid Build Coastguard Worker let pvpanic_reg_addr = resources 139*bb4ee6a4SAndroid Build Coastguard Worker .allocate_mmio( 140*bb4ee6a4SAndroid Build Coastguard Worker PVPANIC_REG_SIZE, 141*bb4ee6a4SAndroid Build Coastguard Worker Alloc::PciBar { 142*bb4ee6a4SAndroid Build Coastguard Worker bus: address.bus, 143*bb4ee6a4SAndroid Build Coastguard Worker dev: address.dev, 144*bb4ee6a4SAndroid Build Coastguard Worker func: address.func, 145*bb4ee6a4SAndroid Build Coastguard Worker bar: PVPANIC_BAR_INDEX as u8, 146*bb4ee6a4SAndroid Build Coastguard Worker }, 147*bb4ee6a4SAndroid Build Coastguard Worker "pvpanic_reg".to_string(), 148*bb4ee6a4SAndroid Build Coastguard Worker AllocOptions::new() 149*bb4ee6a4SAndroid Build Coastguard Worker .max_address(u32::MAX.into()) 150*bb4ee6a4SAndroid Build Coastguard Worker .align(PVPANIC_REG_SIZE), 151*bb4ee6a4SAndroid Build Coastguard Worker ) 152*bb4ee6a4SAndroid Build Coastguard Worker .map_err(|e| pci_device::Error::IoAllocationFailed(PVPANIC_REG_SIZE, e))?; 153*bb4ee6a4SAndroid Build Coastguard Worker let pvpanic_config = PciBarConfiguration::new( 154*bb4ee6a4SAndroid Build Coastguard Worker PVPANIC_BAR_INDEX, 155*bb4ee6a4SAndroid Build Coastguard Worker PVPANIC_REG_SIZE, 156*bb4ee6a4SAndroid Build Coastguard Worker PciBarRegionType::Memory32BitRegion, 157*bb4ee6a4SAndroid Build Coastguard Worker PciBarPrefetchable::NotPrefetchable, 158*bb4ee6a4SAndroid Build Coastguard Worker ) 159*bb4ee6a4SAndroid Build Coastguard Worker .set_address(pvpanic_reg_addr); 160*bb4ee6a4SAndroid Build Coastguard Worker self.config_regs 161*bb4ee6a4SAndroid Build Coastguard Worker .add_pci_bar(pvpanic_config) 162*bb4ee6a4SAndroid Build Coastguard Worker .map_err(|e| pci_device::Error::IoRegistrationFailed(pvpanic_reg_addr, e))?; 163*bb4ee6a4SAndroid Build Coastguard Worker ranges.push(BarRange { 164*bb4ee6a4SAndroid Build Coastguard Worker addr: pvpanic_reg_addr, 165*bb4ee6a4SAndroid Build Coastguard Worker size: PVPANIC_REG_SIZE, 166*bb4ee6a4SAndroid Build Coastguard Worker prefetchable: false, 167*bb4ee6a4SAndroid Build Coastguard Worker }); 168*bb4ee6a4SAndroid Build Coastguard Worker 169*bb4ee6a4SAndroid Build Coastguard Worker Ok(ranges) 170*bb4ee6a4SAndroid Build Coastguard Worker } 171*bb4ee6a4SAndroid Build Coastguard Worker keep_rds(&self) -> Vec<RawDescriptor>172*bb4ee6a4SAndroid Build Coastguard Worker fn keep_rds(&self) -> Vec<RawDescriptor> { 173*bb4ee6a4SAndroid Build Coastguard Worker Vec::new() 174*bb4ee6a4SAndroid Build Coastguard Worker } 175*bb4ee6a4SAndroid Build Coastguard Worker get_bar_configuration(&self, bar_num: usize) -> Option<PciBarConfiguration>176*bb4ee6a4SAndroid Build Coastguard Worker fn get_bar_configuration(&self, bar_num: usize) -> Option<PciBarConfiguration> { 177*bb4ee6a4SAndroid Build Coastguard Worker self.config_regs.get_bar_configuration(bar_num) 178*bb4ee6a4SAndroid Build Coastguard Worker } 179*bb4ee6a4SAndroid Build Coastguard Worker read_config_register(&self, reg_idx: usize) -> u32180*bb4ee6a4SAndroid Build Coastguard Worker fn read_config_register(&self, reg_idx: usize) -> u32 { 181*bb4ee6a4SAndroid Build Coastguard Worker self.config_regs.read_reg(reg_idx) 182*bb4ee6a4SAndroid Build Coastguard Worker } 183*bb4ee6a4SAndroid Build Coastguard Worker write_config_register(&mut self, reg_idx: usize, offset: u64, data: &[u8])184*bb4ee6a4SAndroid Build Coastguard Worker fn write_config_register(&mut self, reg_idx: usize, offset: u64, data: &[u8]) { 185*bb4ee6a4SAndroid Build Coastguard Worker self.config_regs.write_reg(reg_idx, offset, data); 186*bb4ee6a4SAndroid Build Coastguard Worker } 187*bb4ee6a4SAndroid Build Coastguard Worker setup_pci_config_mapping( &mut self, shmem: &SharedMemory, base: usize, len: usize, ) -> Result<bool>188*bb4ee6a4SAndroid Build Coastguard Worker fn setup_pci_config_mapping( 189*bb4ee6a4SAndroid Build Coastguard Worker &mut self, 190*bb4ee6a4SAndroid Build Coastguard Worker shmem: &SharedMemory, 191*bb4ee6a4SAndroid Build Coastguard Worker base: usize, 192*bb4ee6a4SAndroid Build Coastguard Worker len: usize, 193*bb4ee6a4SAndroid Build Coastguard Worker ) -> Result<bool> { 194*bb4ee6a4SAndroid Build Coastguard Worker self.config_regs 195*bb4ee6a4SAndroid Build Coastguard Worker .setup_mapping(shmem, base, len) 196*bb4ee6a4SAndroid Build Coastguard Worker .map(|_| true) 197*bb4ee6a4SAndroid Build Coastguard Worker .map_err(PciDeviceError::MmioSetup) 198*bb4ee6a4SAndroid Build Coastguard Worker } 199*bb4ee6a4SAndroid Build Coastguard Worker read_bar(&mut self, bar_index: PciBarIndex, offset: u64, data: &mut [u8])200*bb4ee6a4SAndroid Build Coastguard Worker fn read_bar(&mut self, bar_index: PciBarIndex, offset: u64, data: &mut [u8]) { 201*bb4ee6a4SAndroid Build Coastguard Worker data[0] = if bar_index == PVPANIC_BAR_INDEX && offset == 0 && data.len() == 1 { 202*bb4ee6a4SAndroid Build Coastguard Worker PVPANIC_CAPABILITIES 203*bb4ee6a4SAndroid Build Coastguard Worker } else { 204*bb4ee6a4SAndroid Build Coastguard Worker 0 205*bb4ee6a4SAndroid Build Coastguard Worker }; 206*bb4ee6a4SAndroid Build Coastguard Worker } 207*bb4ee6a4SAndroid Build Coastguard Worker write_bar(&mut self, bar_index: PciBarIndex, offset: u64, data: &[u8])208*bb4ee6a4SAndroid Build Coastguard Worker fn write_bar(&mut self, bar_index: PciBarIndex, offset: u64, data: &[u8]) { 209*bb4ee6a4SAndroid Build Coastguard Worker if bar_index != PVPANIC_BAR_INDEX || offset != 0 || data.len() != 1 { 210*bb4ee6a4SAndroid Build Coastguard Worker return; 211*bb4ee6a4SAndroid Build Coastguard Worker } 212*bb4ee6a4SAndroid Build Coastguard Worker 213*bb4ee6a4SAndroid Build Coastguard Worker if let Err(e) = self 214*bb4ee6a4SAndroid Build Coastguard Worker .evt_wrtube 215*bb4ee6a4SAndroid Build Coastguard Worker .send::<VmEventType>(&VmEventType::Panic(data[0])) 216*bb4ee6a4SAndroid Build Coastguard Worker { 217*bb4ee6a4SAndroid Build Coastguard Worker error!("Failed to write to the event tube: {}", e); 218*bb4ee6a4SAndroid Build Coastguard Worker } 219*bb4ee6a4SAndroid Build Coastguard Worker } 220*bb4ee6a4SAndroid Build Coastguard Worker } 221*bb4ee6a4SAndroid Build Coastguard Worker 222*bb4ee6a4SAndroid Build Coastguard Worker impl Suspendable for PvPanicPciDevice { snapshot(&mut self) -> anyhow::Result<serde_json::Value>223*bb4ee6a4SAndroid Build Coastguard Worker fn snapshot(&mut self) -> anyhow::Result<serde_json::Value> { 224*bb4ee6a4SAndroid Build Coastguard Worker self.config_regs 225*bb4ee6a4SAndroid Build Coastguard Worker .snapshot() 226*bb4ee6a4SAndroid Build Coastguard Worker .context("failed to serialize PvPanicPciDevice") 227*bb4ee6a4SAndroid Build Coastguard Worker } 228*bb4ee6a4SAndroid Build Coastguard Worker restore(&mut self, data: serde_json::Value) -> anyhow::Result<()>229*bb4ee6a4SAndroid Build Coastguard Worker fn restore(&mut self, data: serde_json::Value) -> anyhow::Result<()> { 230*bb4ee6a4SAndroid Build Coastguard Worker self.config_regs 231*bb4ee6a4SAndroid Build Coastguard Worker .restore(data) 232*bb4ee6a4SAndroid Build Coastguard Worker .context("failed to deserialize PvPanicPciDevice") 233*bb4ee6a4SAndroid Build Coastguard Worker } 234*bb4ee6a4SAndroid Build Coastguard Worker sleep(&mut self) -> anyhow::Result<()>235*bb4ee6a4SAndroid Build Coastguard Worker fn sleep(&mut self) -> anyhow::Result<()> { 236*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 237*bb4ee6a4SAndroid Build Coastguard Worker } 238*bb4ee6a4SAndroid Build Coastguard Worker wake(&mut self) -> anyhow::Result<()>239*bb4ee6a4SAndroid Build Coastguard Worker fn wake(&mut self) -> anyhow::Result<()> { 240*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 241*bb4ee6a4SAndroid Build Coastguard Worker } 242*bb4ee6a4SAndroid Build Coastguard Worker } 243*bb4ee6a4SAndroid Build Coastguard Worker 244*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(test)] 245*bb4ee6a4SAndroid Build Coastguard Worker mod test { 246*bb4ee6a4SAndroid Build Coastguard Worker use base::Tube; 247*bb4ee6a4SAndroid Build Coastguard Worker use resources::AddressRange; 248*bb4ee6a4SAndroid Build Coastguard Worker use resources::SystemAllocator; 249*bb4ee6a4SAndroid Build Coastguard Worker use resources::SystemAllocatorConfig; 250*bb4ee6a4SAndroid Build Coastguard Worker 251*bb4ee6a4SAndroid Build Coastguard Worker use super::*; 252*bb4ee6a4SAndroid Build Coastguard Worker 253*bb4ee6a4SAndroid Build Coastguard Worker #[test] pvpanic_read_write()254*bb4ee6a4SAndroid Build Coastguard Worker fn pvpanic_read_write() { 255*bb4ee6a4SAndroid Build Coastguard Worker let mut allocator = SystemAllocator::new( 256*bb4ee6a4SAndroid Build Coastguard Worker SystemAllocatorConfig { 257*bb4ee6a4SAndroid Build Coastguard Worker io: Some(AddressRange { 258*bb4ee6a4SAndroid Build Coastguard Worker start: 0x1000, 259*bb4ee6a4SAndroid Build Coastguard Worker end: 0xffff, 260*bb4ee6a4SAndroid Build Coastguard Worker }), 261*bb4ee6a4SAndroid Build Coastguard Worker low_mmio: AddressRange { 262*bb4ee6a4SAndroid Build Coastguard Worker start: 0x2000_0000, 263*bb4ee6a4SAndroid Build Coastguard Worker end: 0x2fffffff, 264*bb4ee6a4SAndroid Build Coastguard Worker }, 265*bb4ee6a4SAndroid Build Coastguard Worker high_mmio: AddressRange { 266*bb4ee6a4SAndroid Build Coastguard Worker start: 0x1_0000_0000, 267*bb4ee6a4SAndroid Build Coastguard Worker end: 0x1_0fff_ffff, 268*bb4ee6a4SAndroid Build Coastguard Worker }, 269*bb4ee6a4SAndroid Build Coastguard Worker platform_mmio: None, 270*bb4ee6a4SAndroid Build Coastguard Worker first_irq: 5, 271*bb4ee6a4SAndroid Build Coastguard Worker }, 272*bb4ee6a4SAndroid Build Coastguard Worker None, 273*bb4ee6a4SAndroid Build Coastguard Worker &[], 274*bb4ee6a4SAndroid Build Coastguard Worker ) 275*bb4ee6a4SAndroid Build Coastguard Worker .unwrap(); 276*bb4ee6a4SAndroid Build Coastguard Worker 277*bb4ee6a4SAndroid Build Coastguard Worker let (evt_wrtube, evt_rdtube) = Tube::directional_pair().unwrap(); 278*bb4ee6a4SAndroid Build Coastguard Worker let mut device = PvPanicPciDevice::new(evt_wrtube); 279*bb4ee6a4SAndroid Build Coastguard Worker 280*bb4ee6a4SAndroid Build Coastguard Worker assert!(device.allocate_address(&mut allocator).is_ok()); 281*bb4ee6a4SAndroid Build Coastguard Worker assert!(device.allocate_io_bars(&mut allocator).is_ok()); 282*bb4ee6a4SAndroid Build Coastguard Worker 283*bb4ee6a4SAndroid Build Coastguard Worker let mut data: [u8; 1] = [0; 1]; 284*bb4ee6a4SAndroid Build Coastguard Worker 285*bb4ee6a4SAndroid Build Coastguard Worker // Read from an invalid addr 286*bb4ee6a4SAndroid Build Coastguard Worker device.read_bar(0, 1, &mut data); 287*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(data[0], 0); 288*bb4ee6a4SAndroid Build Coastguard Worker 289*bb4ee6a4SAndroid Build Coastguard Worker // Read from the valid addr 290*bb4ee6a4SAndroid Build Coastguard Worker device.read_bar(0, 0, &mut data); 291*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(data[0], PVPANIC_CAPABILITIES); 292*bb4ee6a4SAndroid Build Coastguard Worker 293*bb4ee6a4SAndroid Build Coastguard Worker // Write to the valid addr. 294*bb4ee6a4SAndroid Build Coastguard Worker data[0] = PVPANIC_CRASH_LOADED; 295*bb4ee6a4SAndroid Build Coastguard Worker device.write_bar(0, 0, &data); 296*bb4ee6a4SAndroid Build Coastguard Worker 297*bb4ee6a4SAndroid Build Coastguard Worker // Verify the event 298*bb4ee6a4SAndroid Build Coastguard Worker let val = evt_rdtube.recv::<VmEventType>().unwrap(); 299*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(val, VmEventType::Panic(PVPANIC_CRASH_LOADED)); 300*bb4ee6a4SAndroid Build Coastguard Worker } 301*bb4ee6a4SAndroid Build Coastguard Worker } 302