ostd/arch/x86/irq/
mod.rs

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