devices: ioapic: Always retrieve destination field on 8 bits

When the destination mode is physical, the destination field should
only be defined through bits 56-59, as defined in the IOAPIC spec. 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.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2020-10-01 14:37:52 +02:00 committed by Rob Bradford
parent a8c2d70869
commit 9dffc5da5c
2 changed files with 7 additions and 17 deletions

View File

@ -7,8 +7,6 @@ use std::result;
#[derive(Debug)]
pub enum Error {
/// Invalid destination mode.
InvalidDestinationMode,
/// Invalid trigger mode.
InvalidTriggerMode,
/// Invalid delivery mode.

View File

@ -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