diff --git a/devices/src/interrupt_controller.rs b/devices/src/interrupt_controller.rs index 2b6f4a671..fe4f75908 100644 --- a/devices/src/interrupt_controller.rs +++ b/devices/src/interrupt_controller.rs @@ -7,8 +7,6 @@ use std::result; #[derive(Debug)] pub enum Error { - /// Invalid destination mode. - InvalidDestinationMode, /// Invalid trigger mode. InvalidTriggerMode, /// Invalid delivery mode. diff --git a/devices/src/ioapic.rs b/devices/src/ioapic.rs index 25ceb9e43..bb3a904ba 100644 --- a/devices/src/ioapic.rs +++ b/devices/src/ioapic.rs @@ -67,10 +67,12 @@ fn trigger_mode(entry: RedirectionTableEntry) -> u8 { fn interrupt_mask(entry: RedirectionTableEntry) -> u8 { ((entry >> 16) & 0x1u64) as u8 } -fn destination_field_physical(entry: RedirectionTableEntry) -> u8 { - ((entry >> 56) & 0xfu64) as u8 -} -fn destination_field_logical(entry: RedirectionTableEntry) -> u8 { +fn destination_field(entry: RedirectionTableEntry) -> u8 { + // When the destination mode is physical, the destination field should only + // be defined through bits 56-59, as defined in the IOAPIC specification. + // But from the APIC specification, the APIC ID is always defined on 8 bits + // no matter which destination mode is selected. That's why we always + // retrieve the destination field based on bits 56-63. ((entry >> 56) & 0xffu64) as u8 } fn set_delivery_status(entry: &mut RedirectionTableEntry, val: u8) { @@ -100,12 +102,6 @@ const IOWIN_OFF: u8 = 0x10; const IOWIN_SCALE: u8 = 0x2; const REG_MAX_OFFSET: u8 = IOWIN_OFF + (NUM_IOAPIC_PINS as u8 * 2) - 1; -#[repr(u8)] -enum DestinationMode { - Physical = 0, - Logical = 1, -} - #[repr(u8)] enum TriggerMode { Edge = 0, @@ -294,11 +290,7 @@ impl Ioapic { // Validate Destination Mode value, and retrieve Destination ID let destination_mode = destination_mode(entry); - let destination_id: u8 = match destination_mode { - x if x == DestinationMode::Physical as u8 => destination_field_physical(entry), - x if x == DestinationMode::Logical as u8 => destination_field_logical(entry), - _ => return Err(Error::InvalidDestinationMode), - }; + let destination_id = destination_field(entry); // When this bit is set, the message is directed to the processor with // the lowest interrupt priority among processors that can receive the