Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(x86_64): make raw IDT methods public #487

Merged
merged 1 commit into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions hal-x86_64/src/interrupt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ impl hal_core::interrupt::Control for Idt {
($self:ident, $h:ty, $($vector:path => fn $name:ident($($rest:tt)+),)+) => {
$(
gen_code_faults! {@ $name($($rest)+); }
$self.set_isr($vector, $name::<$h> as *const ());
$self.register_isr($vector, $name::<$h> as *const ());
)+
};
(@ $name:ident($kind:literal);) => {
Expand Down Expand Up @@ -575,32 +575,32 @@ impl hal_core::interrupt::Control for Idt {
}

// other exceptions, not mapped to the "code fault" handler
self.set_isr(Self::PAGE_FAULT, page_fault_isr::<H> as *const ());
self.set_isr(Self::INVALID_TSS, invalid_tss_isr::<H> as *const ());
self.set_isr(
self.register_isr(Self::PAGE_FAULT, page_fault_isr::<H> as *const ());
self.register_isr(Self::INVALID_TSS, invalid_tss_isr::<H> as *const ());
self.register_isr(
Self::SEGMENT_NOT_PRESENT,
segment_not_present_isr::<H> as *const (),
);
self.set_isr(
self.register_isr(
Self::STACK_SEGMENT_FAULT,
stack_segment_isr::<H> as *const (),
);
self.set_isr(Self::GENERAL_PROTECTION_FAULT, gpf_isr::<H> as *const ());
self.set_isr(Self::DOUBLE_FAULT, double_fault_isr::<H> as *const ());
self.register_isr(Self::GENERAL_PROTECTION_FAULT, gpf_isr::<H> as *const ());
self.register_isr(Self::DOUBLE_FAULT, double_fault_isr::<H> as *const ());

// === hardware interrupts ===
// ISA standard hardware interrupts mapped on both the PICs and IO APIC
// interrupt models.
self.set_isr(Self::PIC_PIT_TIMER, pit_timer_isr::<H> as *const ());
self.set_isr(Self::IOAPIC_PIT_TIMER, pit_timer_isr::<H> as *const ());
self.set_isr(Self::PIC_PS2_KEYBOARD, keyboard_isr::<H> as *const ());
self.set_isr(Self::IOAPIC_PS2_KEYBOARD, keyboard_isr::<H> as *const ());
self.register_isr(Self::PIC_PIT_TIMER, pit_timer_isr::<H> as *const ());
self.register_isr(Self::IOAPIC_PIT_TIMER, pit_timer_isr::<H> as *const ());
self.register_isr(Self::PIC_PS2_KEYBOARD, keyboard_isr::<H> as *const ());
self.register_isr(Self::IOAPIC_PS2_KEYBOARD, keyboard_isr::<H> as *const ());
// local APIC specific hardware itnerrupts
self.set_isr(Self::LOCAL_APIC_SPURIOUS, spurious_isr as *const ());
self.set_isr(Self::LOCAL_APIC_TIMER, apic_timer_isr::<H> as *const ());
self.register_isr(Self::LOCAL_APIC_SPURIOUS, spurious_isr as *const ());
self.register_isr(Self::LOCAL_APIC_TIMER, apic_timer_isr::<H> as *const ());

// vector 69 (nice) is reserved by the HAL for testing the IDT.
self.set_isr(69, test_isr::<H> as *const ());
self.register_isr(69, test_isr::<H> as *const ());

Ok(())
}
Expand Down
89 changes: 79 additions & 10 deletions hal-x86_64/src/interrupt/idt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl bits::FromBits<u8> for GateKind {
// === impl Idt ===

impl Idt {
pub(super) const NUM_VECTORS: usize = 256;
pub const NUM_VECTORS: usize = 256;

/// Divide-by-zero interrupt (#D0)
pub const DIVIDE_BY_ZERO: usize = 0;
Expand Down Expand Up @@ -155,26 +155,95 @@ impl Idt {
/// Chosen by fair die roll, guaranteed to be random.
pub const DOUBLE_FAULT_IST_OFFSET: usize = 4;

/// PIC Programmable Interval Timer (PIT) interrupt vector mapped by
/// [`Controller::enable_hardware_interrupts`].
///
/// Systems which do not use that function to initialize the PICs may
/// map this interrupt to a different IDT vector.
///
/// [`Controller::enable_hardware_interrupts`]: super::Controller::enable_hardware_interrupts
pub const PIC_PIT_TIMER: usize = Self::PIC_BIG_START;

/// PIC PS/2 interrupt vector mapped by
/// [`Controller::enable_hardware_interrupts`].
///
/// Systems which do not use that function to initialize the PICs may
/// map this interrupt to a different IDT vector.
///
/// [`Controller::enable_hardware_interrupts`]: super::Controller::enable_hardware_interrupts
pub const PIC_PS2_KEYBOARD: usize = Self::PIC_BIG_START + 1;

pub(super) const LOCAL_APIC_TIMER: usize = (Self::NUM_VECTORS - 2);
pub(super) const LOCAL_APIC_SPURIOUS: usize = (Self::NUM_VECTORS - 1);
pub(super) const PIC_BIG_START: usize = 0x20;
pub(super) const PIC_LITTLE_START: usize = 0x28;
/// Local APIC timer interrupt vector mapped by
/// [`Controller::enable_hardware_interrupts`].
///
/// Systems which do not use that function to initialize the local APIC may
/// map this interrupt to a different IDT vector.
///
/// [`Controller::enable_hardware_interrupts`]: super::Controller::enable_hardware_interrupts
pub const LOCAL_APIC_TIMER: usize = (Self::NUM_VECTORS - 2);

/// Local APIC spurious interrupt vector mapped by
/// [`Controller::enable_hardware_interrupts`].
///
/// Systems which do not use that function to initialize the local APIC may
/// map this interrupt to a different IDT vector.
///
/// [`Controller::enable_hardware_interrupts`]: super::Controller::enable_hardware_interrupts
pub const LOCAL_APIC_SPURIOUS: usize = (Self::NUM_VECTORS - 1);

/// Base of the primary PIC's interrupt vector region mapped by
/// [`Controller::enable_hardware_interrupts`].
///
/// Systems which do not use that function to initialize the PICs may
/// map this interrupt to a different IDT vector.
///
/// [`Controller::enable_hardware_interrupts`]: super::Controller::enable_hardware_interrupts
pub const PIC_BIG_START: usize = 0x20;

/// Base of the secondary PIC's interrupt vector region mapped by
/// [`Controller::enable_hardware_interrupts`].
///
/// Systems which do not use that function to initialize the PICs may
/// map this interrupt to a different IDT vector.
///
/// [`Controller::enable_hardware_interrupts`]: super::Controller::enable_hardware_interrupts
pub const PIC_LITTLE_START: usize = 0x28;
// put the IOAPIC right after the PICs
pub(super) const IOAPIC_START: usize = 0x30;
pub(super) const IOAPIC_PIT_TIMER: usize = Self::IOAPIC_START + IoApic::PIT_TIMER_IRQ as usize;
pub(super) const IOAPIC_PS2_KEYBOARD: usize =
Self::IOAPIC_START + IoApic::PS2_KEYBOARD_IRQ as usize;

/// Base of the IOAPIC's interrupt vector region mapped by
/// [`Controller::enable_hardware_interrupts`].
///
/// Systems which do not use that function to initialize the IOAPIC may
/// map this interrupt to a different IDT vector.
///
/// [`Controller::enable_hardware_interrupts`]: super::Controller::enable_hardware_interrupts
pub const IOAPIC_START: usize = 0x30;

/// IOAPIC Programmable Interval Timer (PIT) interrupt vector region mapped
/// by [`Controller::enable_hardware_interrupts`].
///
/// Systems which do not use that function to initialize the IOAPIC may
/// map this interrupt to a different IDT vector.
///
/// [`Controller::enable_hardware_interrupts`]: super::Controller::enable_hardware_interrupts
pub const IOAPIC_PIT_TIMER: usize = Self::IOAPIC_START + IoApic::PIT_TIMER_IRQ as usize;

/// IOAPIC PS/2 keyboard interrupt vector mapped by
/// [`Controller::enable_hardware_interrupts`].
///
/// Systems which do not use that function to initialize the IOAPIC may
/// map this interrupt to a different IDT vector.
///
/// [`Controller::enable_hardware_interrupts`]: super::Controller::enable_hardware_interrupts
pub const IOAPIC_PS2_KEYBOARD: usize = Self::IOAPIC_START + IoApic::PS2_KEYBOARD_IRQ as usize;

pub const fn new() -> Self {
Self {
descriptors: [Descriptor::null(); Self::NUM_VECTORS],
}
}

pub(super) fn set_isr(&mut self, vector: usize, isr: *const ()) {
pub fn register_isr(&mut self, vector: usize, isr: *const ()) {
let descr = self.descriptors[vector].set_handler(isr);
if vector == Self::DOUBLE_FAULT {
descr.set_ist_offset(Self::DOUBLE_FAULT_IST_OFFSET as u8);
Expand Down
Loading