(&mut self, val: u32)
| 250 | } |
| 251 | |
| 252 | fn ioapic_write(&mut self, val: u32) { |
| 253 | debug!("IOAPIC_W reg 0x{:x}, val 0x{:x}", self.reg_sel, val); |
| 254 | |
| 255 | match self.reg_sel as u8 { |
| 256 | IOAPIC_REG_VERSION => { |
| 257 | if val == 0 { |
| 258 | // Windows writes zero here (see #1791) |
| 259 | } else { |
| 260 | error!( |
| 261 | "IOAPIC: invalid write to version register (0x{:x}): 0x{:x}", |
| 262 | self.reg_sel, val |
| 263 | ); |
| 264 | } |
| 265 | } |
| 266 | IOAPIC_REG_ID => self.id_reg = (val >> 24) & 0xf, |
| 267 | IOWIN_OFF..=REG_MAX_OFFSET => { |
| 268 | let (index, is_high_bits) = decode_irq_from_selector(self.reg_sel as u8); |
| 269 | if index > NUM_IOAPIC_PINS { |
| 270 | warn!("IOAPIC index out of range: {index}"); |
| 271 | return; |
| 272 | } |
| 273 | if is_high_bits { |
| 274 | self.reg_entries[index] &= 0xffff_ffff; |
| 275 | self.reg_entries[index] |= u64::from(val) << 32; |
| 276 | } else { |
| 277 | // Ensure not to override read-only bits: |
| 278 | // - Delivery Status (bit 12) |
| 279 | // - Remote IRR (bit 14) |
| 280 | self.reg_entries[index] &= 0xffff_ffff_0000_5000; |
| 281 | self.reg_entries[index] |= u64::from(val) & 0xffff_afff; |
| 282 | } |
| 283 | // The entry must be updated through the interrupt source |
| 284 | // group. |
| 285 | if let Err(e) = self.update_entry(index, true) { |
| 286 | error!("Failed updating IOAPIC entry: {e:?}"); |
| 287 | } |
| 288 | // Store the information this IRQ is now being used. |
| 289 | self.used_entries[index] = true; |
| 290 | } |
| 291 | _ => error!( |
| 292 | "IOAPIC: invalid write to register offset 0x{:x}", |
| 293 | self.reg_sel |
| 294 | ), |
| 295 | } |
| 296 | } |
| 297 | |
| 298 | fn ioapic_read(&self) -> u32 { |
| 299 | debug!("IOAPIC_R reg 0x{:x}", self.reg_sel); |
no test coverage detected