Skip to content
Open
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
12 changes: 7 additions & 5 deletions src/arch/x86_64/kernel/interrupts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use x86_64::structures::idt::InterruptDescriptorTable;
pub use x86_64::structures::idt::InterruptStackFrame as ExceptionStackFrame;

use crate::arch::x86_64::kernel::core_local::{core_scheduler, increment_irq_counter};
use crate::arch::x86_64::kernel::pic::PIC1_OFFSET;
use crate::arch::x86_64::kernel::{apic, processor};
use crate::arch::x86_64::mm::paging::{BasePageSize, PageSize, page_fault_handler};
use crate::arch::x86_64::swapgs;
Expand Down Expand Up @@ -91,11 +92,12 @@ pub(crate) fn enable_and_wait() {
pub(crate) fn install() {
let mut idt = IDT.lock();

set_general_handler!(&mut *idt, abort, 0..32);
set_general_handler!(&mut *idt, handle_interrupt, 32..);
set_general_handler!(&mut *idt, abort, 0..PIC1_OFFSET);
set_general_handler!(&mut *idt, handle_interrupt, PIC1_OFFSET..PIC1_OFFSET + 16);
set_general_handler!(&mut *idt, abort, PIC1_OFFSET + 16..);

unsafe {
for i in 32..=255 {
for i in PIC1_OFFSET..PIC1_OFFSET + 16 {
let addr = idt[i].handler_addr();
idt[i].set_handler_addr(addr).set_stack_index(0);
}
Expand Down Expand Up @@ -175,7 +177,7 @@ fn handle_interrupt(stack_frame: ExceptionStackFrame, index: u8, _error_code: Op
use crate::scheduler::PerCoreSchedulerExt;

if let Some(handlers) = IRQ_HANDLERS.get()
&& let Some(map) = handlers.get(&(index - 32))
&& let Some(map) = handlers.get(&(index - PIC1_OFFSET))
{
for handler in map.iter() {
handler();
Expand Down Expand Up @@ -336,7 +338,7 @@ extern "x86-interrupt" fn virtualization_exception(stack_frame: ExceptionStackFr

pub(crate) fn add_irq_name(irq_number: u8, name: &'static str) {
debug!("Register name \"{name}\" for interrupt {irq_number}");
IRQ_NAMES.lock().insert(32 + irq_number, name);
IRQ_NAMES.lock().insert(PIC1_OFFSET + irq_number, name);
}

fn get_irq_name(irq_number: u8) -> Option<&'static str> {
Expand Down
36 changes: 28 additions & 8 deletions src/arch/x86_64/kernel/pic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,20 @@ const PIC1_DATA: Port<u8> = Port::new(0x21);
const PIC2_COMMAND: Port<u8> = Port::new(0xa0);
const PIC2_DATA: Port<u8> = Port::new(0xa1);

pub const PIC1_INTERRUPT_OFFSET: u8 = 32;
const PIC2_INTERRUPT_OFFSET: u8 = 40;
/// PIC1 interrupt offset.
///
/// Vectors 0 through 31 in the IDT are defined or reserved by the
/// architecture. Thus, user-defined interrupts are vectors 32 through 255. We
/// choose to map the 16 interrupts by the two PICs at the beginning of the
/// user-defined interrupts.
pub const PIC1_OFFSET: u8 = 32;

/// PIC2 interrupt offset.
///
/// Each PIC handles 8 interrupts.
/// We set up the two PICs to be contiguous.
const PIC2_OFFSET: u8 = PIC1_OFFSET + 8;

const SPURIOUS_IRQ_NUMBER: u8 = 7;

/// End-Of-Interrupt Command for an Intel 8259 Programmable Interrupt Controller (PIC).
Expand Down Expand Up @@ -42,10 +54,10 @@ pub fn init() {
// This is especially true for real hardware. So provide a handler for them.
unsafe {
let mut idt = IDT.lock();
idt[PIC1_INTERRUPT_OFFSET + SPURIOUS_IRQ_NUMBER]
idt[PIC1_OFFSET + SPURIOUS_IRQ_NUMBER]
.set_handler_fn(spurious_interrupt_on_master)
.set_stack_index(0);
idt[PIC2_INTERRUPT_OFFSET + SPURIOUS_IRQ_NUMBER]
idt[PIC2_OFFSET + SPURIOUS_IRQ_NUMBER]
.set_handler_fn(spurious_interrupt_on_slave)
.set_stack_index(0);

Expand All @@ -65,8 +77,8 @@ pub fn init() {
pic2_command.write(0x11);

// Map PIC1 to interrupt numbers >= 32 and PIC2 to interrupt numbers >= 40.
pic1_data.write(PIC1_INTERRUPT_OFFSET);
pic2_data.write(PIC2_INTERRUPT_OFFSET);
pic1_data.write(PIC1_OFFSET);
pic2_data.write(PIC2_OFFSET);

// Configure PIC1 as master and PIC2 as slave.
pic1_data.write(0x04);
Expand Down Expand Up @@ -102,8 +114,16 @@ extern "x86-interrupt" fn spurious_interrupt_on_slave(stack_frame: ExceptionStac
}

fn edit_mask(int_no: u8, insert: bool) {
let mut port = if int_no >= 40 { PIC2_DATA } else { PIC1_DATA };
let offset = if int_no >= 40 { 40 } else { 32 };
let mut port = if int_no >= PIC2_OFFSET {
PIC2_DATA
} else {
PIC1_DATA
};
let offset = if int_no >= PIC2_OFFSET {
PIC2_OFFSET
} else {
PIC1_OFFSET
};

unsafe {
let mask = port.read();
Expand Down
2 changes: 1 addition & 1 deletion src/arch/x86_64/kernel/pit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use x86_64::instructions::port::Port;
use crate::arch::x86_64::kernel::pic;

const PIT_CLOCK: u64 = 1_193_182;
pub const PIT_INTERRUPT_NUMBER: u8 = pic::PIC1_INTERRUPT_OFFSET;
pub const PIT_INTERRUPT_NUMBER: u8 = pic::PIC1_OFFSET;

const PIT_CHANNEL0_DATA: Port<u8> = Port::new(0x40);
const PIT_CHANNEL1_DATA: Port<u8> = Port::new(0x41);
Expand Down
2 changes: 1 addition & 1 deletion src/drivers/pci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ impl<T: ConfigRegionAccess> PciDevice<T> {
None
}
1..=4 => {
// PCI specification v3 footnote 43
// PCI specification v3: Section 6.2.4 - footnote 43
#[cfg(target_arch = "x86_64")]
if matches!(line, 16..254) {
error!("Reserved IRQ number");
Expand Down
Loading