(&self, irq: usize, set_gsi: bool)
| 334 | } |
| 335 | |
| 336 | fn update_entry(&self, irq: usize, set_gsi: bool) -> Result<()> { |
| 337 | let entry = self.reg_entries[irq]; |
| 338 | |
| 339 | // Validate Destination Mode value, and retrieve Destination ID |
| 340 | let destination_mode = destination_mode(entry); |
| 341 | let destination_id = destination_field(entry); |
| 342 | |
| 343 | // When this bit is set, the message is directed to the processor with |
| 344 | // the lowest interrupt priority among processors that can receive the |
| 345 | // interrupt. |
| 346 | let redirection_hint: u8 = 1; |
| 347 | |
| 348 | // Generate MSI message address |
| 349 | let low_addr: u32 = self.apic_address.0 as u32 |
| 350 | | (u32::from(destination_id) << 12) |
| 351 | | (u32::from(redirection_hint) << 3) |
| 352 | | (u32::from(destination_mode) << 2); |
| 353 | |
| 354 | // Validate Trigger Mode value |
| 355 | let trigger_mode = trigger_mode(entry); |
| 356 | match trigger_mode { |
| 357 | x if (x == TriggerMode::Edge as u8) || (x == TriggerMode::Level as u8) => {} |
| 358 | _ => return Err(Error::InvalidTriggerMode), |
| 359 | } |
| 360 | |
| 361 | // Validate Delivery Mode value |
| 362 | let delivery_mode = delivery_mode(entry); |
| 363 | match delivery_mode { |
| 364 | x if (x == DeliveryMode::Fixed as u8) |
| 365 | || (x == DeliveryMode::Lowest as u8) |
| 366 | || (x == DeliveryMode::Smi as u8) |
| 367 | || (x == DeliveryMode::RemoteRead as u8) |
| 368 | || (x == DeliveryMode::Nmi as u8) |
| 369 | || (x == DeliveryMode::Init as u8) |
| 370 | || (x == DeliveryMode::Startup as u8) |
| 371 | || (x == DeliveryMode::External as u8) => {} |
| 372 | _ => return Err(Error::InvalidDeliveryMode), |
| 373 | } |
| 374 | |
| 375 | // Generate MSI message data |
| 376 | let data: u32 = (u32::from(trigger_mode) << 15) |
| 377 | | (u32::from(remote_irr(entry)) << 14) |
| 378 | | (u32::from(delivery_mode) << 8) |
| 379 | | u32::from(vector(entry)); |
| 380 | |
| 381 | let config = MsiIrqSourceConfig { |
| 382 | high_addr: 0x0, |
| 383 | low_addr, |
| 384 | data, |
| 385 | devid: 0, |
| 386 | }; |
| 387 | |
| 388 | self.interrupt_source_group |
| 389 | .update( |
| 390 | irq as InterruptIndex, |
| 391 | InterruptSourceConfig::MsiIrq(config), |
| 392 | interrupt_mask(entry) == 1, |
| 393 | set_gsi, |
no test coverage detected