(id: String, snapshot: Option<&Snapshot>)
| 67 | |
| 68 | impl PvPanicDevice { |
| 69 | pub fn new(id: String, snapshot: Option<&Snapshot>) -> Result<Self, PvPanicError> { |
| 70 | let pci_configuration_state = vm_migration::state_from_id(snapshot, PCI_CONFIGURATION_ID) |
| 71 | .map_err(|e| { |
| 72 | PvPanicError::RetrievePciConfigurationState(anyhow!( |
| 73 | "Failed to get PciConfigurationState from Snapshot: {e}" |
| 74 | )) |
| 75 | })?; |
| 76 | |
| 77 | let mut configuration = PciConfiguration::new( |
| 78 | PVPANIC_VENDOR_ID, |
| 79 | PVPANIC_DEVICE_ID, |
| 80 | 0x1, // modern pci devices |
| 81 | PciClassCode::BaseSystemPeripheral, |
| 82 | &PvPanicSubclass::Other, |
| 83 | None, |
| 84 | PciHeaderType::Device, |
| 85 | 0, |
| 86 | 0, |
| 87 | None, |
| 88 | pci_configuration_state, |
| 89 | ); |
| 90 | |
| 91 | let command: [u8; 2] = [0x03, 0x01]; |
| 92 | let bar_reprogram = configuration.write_config_register(1, 0, &command); |
| 93 | assert!( |
| 94 | bar_reprogram.is_empty(), |
| 95 | "No bar reprogrammig is expected from writing to the COMMAND register" |
| 96 | ); |
| 97 | |
| 98 | let state: Option<PvPanicDeviceState> = snapshot |
| 99 | .as_ref() |
| 100 | .map(|s| s.to_state()) |
| 101 | .transpose() |
| 102 | .map_err(|e| { |
| 103 | PvPanicError::CreatePvPanicDevice(anyhow!( |
| 104 | "Failed to get PvPanicDeviceState from Snapshot: {e}" |
| 105 | )) |
| 106 | })?; |
| 107 | let events = if let Some(state) = state { |
| 108 | state.events |
| 109 | } else { |
| 110 | PVPANIC_PANICKED | PVPANIC_CRASH_LOADED |
| 111 | }; |
| 112 | |
| 113 | let pvpanic_device = PvPanicDevice { |
| 114 | id, |
| 115 | events, |
| 116 | configuration, |
| 117 | bar_regions: vec![], |
| 118 | }; |
| 119 | |
| 120 | Ok(pvpanic_device) |
| 121 | } |
| 122 | |
| 123 | pub fn event_to_string(&self, event: u8) -> String { |
| 124 | if event == PVPANIC_PANICKED { |
nothing calls this directly
no test coverage detected