ostd/arch/x86/irq/
mod.rs

1// SPDX-License-Identifier: MPL-2.0
2
3//! Interrupts.
4
5pub(super) mod chip;
6pub(super) mod ipi;
7mod ops;
8mod remapping;
9
10pub use chip::{IRQ_CHIP, IrqChip, MappedIrqLine};
11pub(crate) use ipi::{HwCpuId, send_ipi};
12pub(crate) use ops::{
13    disable_local, disable_local_and_halt, enable_local, enable_local_and_halt, is_local_enabled,
14};
15pub(crate) use remapping::IrqRemapping;
16
17use crate::arch::{cpu, kernel};
18
19// Intel(R) 64 and IA-32 rchitectures Software Developer's Manual,
20// Volume 3A, Section 6.2 says "Vector numbers in the range 32 to 255
21// are designated as user-defined interrupts and are not reserved by
22// the Intel 64 and IA-32 architecture."
23pub(crate) const IRQ_NUM_MIN: u8 = 32;
24pub(crate) const IRQ_NUM_MAX: u8 = 255;
25
26/// An IRQ line with additional information that helps acknowledge the interrupt
27/// on hardware.
28///
29/// On x86-64, it's the hardware (i.e., the I/O APIC and local APIC) that routes
30/// the interrupt to the IRQ line. Therefore, the software does not need to
31/// maintain additional information about the original hardware interrupt.
32pub(crate) struct HwIrqLine {
33    irq_num: u8,
34}
35
36impl HwIrqLine {
37    pub(super) fn new(irq_num: u8) -> Self {
38        Self { irq_num }
39    }
40
41    pub(crate) fn irq_num(&self) -> u8 {
42        self.irq_num
43    }
44
45    pub(crate) fn ack(&self) {
46        debug_assert!(!cpu::context::CpuException::is_cpu_exception(
47            self.irq_num as usize
48        ));
49        // TODO: We're in the interrupt context, so `disable_preempt()` is not
50        // really necessary here.
51        kernel::apic::get_or_init(&crate::task::disable_preempt() as _).eoi();
52    }
53}