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
7// TODO: APIC
8
9use crate::lib::sync::irq_mutex::IrqMutex;
10use pic8259::ChainedPics;
11
12/// I/O port for sending commands (including ISR read) to the master PIC.
13pub const PIC_MASTER_CMD_PORT: u16 = 0x20;
14
15/// Vector offset for master-PIC IRQs after remapping; IRQ `n` fires at `PIC_MASTER_OFFSET + n`.
16pub const PIC_MASTER_OFFSET: u8 = 0x20;
17
18/// Vector offset for slave-PIC IRQs after remapping; IRQ `n` fires at `PIC_SLAVE_OFFSET + (n - 8)`.
19pub const PIC_SLAVE_OFFSET: u8 = 0x28;
20
21/// The chained master+slave PIC pair, lockable from IRQ handlers.
22static CHAINED_PICS: IrqMutex<ChainedPics> = IrqMutex::new(
23    unsafe { ChainedPics::new(PIC_MASTER_OFFSET, PIC_SLAVE_OFFSET) }
24);
25
26/// Initialize and remap the PIC, then enable only IRQ0 (PIT timer).
27pub fn init() {
28    let mut _lock = CHAINED_PICS.lock();
29    unsafe {
30        _lock.initialize();
31        _lock.write_masks(0xFF, 0xFF);
32    }
33}
34
35/// Send an End-of-Interrupt (EOI) for the vector that fired; every hardware IRQ
36/// handler must call this before returning or that IRQ line stays blocked.
37pub fn end_of_interrupt(intr_vec: u8) {
38    let mut _lock = CHAINED_PICS.lock();
39
40    unsafe {
41        _lock.notify_end_of_interrupt(intr_vec);
42    }
43}