(
id: String,
apic_address: GuestAddress,
interrupt_manager: &dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>,
state: Option<&IoapicState>,
)
| 189 | |
| 190 | impl Ioapic { |
| 191 | pub fn new( |
| 192 | id: String, |
| 193 | apic_address: GuestAddress, |
| 194 | interrupt_manager: &dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>, |
| 195 | state: Option<&IoapicState>, |
| 196 | ) -> Result<Ioapic> { |
| 197 | let interrupt_source_group = interrupt_manager |
| 198 | .create_group(MsiIrqGroupConfig { |
| 199 | base: 0, |
| 200 | count: NUM_IOAPIC_PINS as InterruptIndex, |
| 201 | }) |
| 202 | .map_err(Error::CreateInterruptSourceGroup)?; |
| 203 | |
| 204 | let (id_reg, reg_sel, reg_entries, used_entries, apic_address) = if let Some(state) = &state |
| 205 | { |
| 206 | ( |
| 207 | state.id_reg, |
| 208 | state.reg_sel, |
| 209 | state.reg_entries, |
| 210 | state.used_entries, |
| 211 | GuestAddress(state.apic_address), |
| 212 | ) |
| 213 | } else { |
| 214 | ( |
| 215 | 0, |
| 216 | 0, |
| 217 | [0x10000; NUM_IOAPIC_PINS], |
| 218 | [false; NUM_IOAPIC_PINS], |
| 219 | apic_address, |
| 220 | ) |
| 221 | }; |
| 222 | |
| 223 | // The IOAPIC is created with entries already masked. The guest will be |
| 224 | // in charge of unmasking them if/when necessary. |
| 225 | let ioapic = Ioapic { |
| 226 | id, |
| 227 | id_reg, |
| 228 | reg_sel, |
| 229 | reg_entries, |
| 230 | used_entries, |
| 231 | apic_address, |
| 232 | interrupt_source_group, |
| 233 | }; |
| 234 | |
| 235 | // When restoring the Ioapic, we must enable used entries. |
| 236 | if state.is_some() { |
| 237 | for (irq, entry) in ioapic.used_entries.iter().enumerate() { |
| 238 | if *entry { |
| 239 | ioapic.update_entry(irq, false)?; |
| 240 | } |
| 241 | } |
| 242 | |
| 243 | ioapic |
| 244 | .interrupt_source_group |
| 245 | .set_gsi() |
| 246 | .map_err(Error::UpdateInterrupt)?; |
| 247 | } |
| 248 |
nothing calls this directly
no test coverage detected