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