Skip to main content

kernel/arch/x86_64/interrupts/
pic.rs

1// SPDX-License-Identifier: GPL-3.0-only
2//! 8259 Programmable Interrupt Controller (PIC): remaps hardware IRQ vectors and
3//! signals end-of-interrupt.
4//!
5//! Authors: MarioS271
6
7use pic8259;
8use crate::types::irq_mutex::IrqMutex;
9
10/// I/O port for sending commands (including ISR read) to the master PIC.
11pub const PIC_MASTER_CMD_PORT: u16 = 0x20;
12
13/// Vector offset for master-PIC IRQs after remapping; IRQ `n` fires at `PIC_MASTER_OFFSET + n`.
14pub const PIC_MASTER_OFFSET: u8 = 0x20;
15
16/// Vector offset for slave-PIC IRQs after remapping; IRQ `n` fires at `PIC_SLAVE_OFFSET + (n - 8)`.
17pub const PIC_SLAVE_OFFSET: u8 = 0x28;
18
19/// The chained master+slave PIC pair, lockable from IRQ handlers.
20static CHAINED_PICS: IrqMutex<pic8259::ChainedPics> = IrqMutex::new(unsafe { pic8259::ChainedPics::new(PIC_MASTER_OFFSET, PIC_SLAVE_OFFSET) });
21
22/// Initialize and remap the PIC, then enable only IRQ0 (PIT timer).
23pub fn init() {
24    let mut _lock = CHAINED_PICS.lock();
25    unsafe {
26        _lock.initialize();
27        _lock.write_masks(0xFE, 0xFF);
28    }
29}
30
31/// Send an End-of-Interrupt (EOI) for the vector that fired; every hardware IRQ
32/// handler must call this before returning or that IRQ line stays blocked.
33pub fn end_of_interrupt(intr_vec: u8) {
34    let mut _lock = CHAINED_PICS.lock();
35
36    unsafe {
37        _lock.notify_end_of_interrupt(intr_vec);
38    }
39}