acpi/platform/interrupt.rs
1use crate::ManagedSlice;
2use core::alloc::Allocator;
3
4#[derive(Debug, Clone, Copy)]
5pub struct IoApic {
6 pub id: u8,
7 /// The physical address at which to access this I/O APIC.
8 pub address: u32,
9 /// The global system interrupt number where this I/O APIC's inputs start.
10 pub global_system_interrupt_base: u32,
11}
12
13#[derive(Debug, Clone, Copy)]
14pub struct NmiLine {
15 pub processor: NmiProcessor,
16 pub line: LocalInterruptLine,
17}
18
19/// Indicates which local interrupt line will be utilized by an external interrupt. Specifically,
20/// these lines directly correspond to their requisite LVT entries in a processor's APIC.
21#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22pub enum LocalInterruptLine {
23 Lint0,
24 Lint1,
25}
26
27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28pub enum NmiProcessor {
29 All,
30 ProcessorUid(u32),
31}
32
33/// Polarity indicates what signal mode the interrupt line needs to be in to be considered 'active'.
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35pub enum Polarity {
36 SameAsBus,
37 ActiveHigh,
38 ActiveLow,
39}
40
41/// Trigger mode of an interrupt, describing how the interrupt is triggered.
42///
43/// When an interrupt is `Edge` triggered, it is triggered exactly once, when the interrupt
44/// signal goes from its opposite polarity to its active polarity.
45///
46/// For `Level` triggered interrupts, a continuous signal is emitted so long as the interrupt
47/// is in its active polarity.
48///
49/// `SameAsBus`-triggered interrupts will utilize the same interrupt triggering as the system bus
50/// they communicate across.
51#[derive(Debug, Clone, Copy, PartialEq, Eq)]
52pub enum TriggerMode {
53 SameAsBus,
54 Edge,
55 Level,
56}
57
58/// Describes a difference in the mapping of an ISA interrupt to how it's mapped in other interrupt
59/// models. For example, if a device is connected to ISA IRQ 0 and IOAPIC input 2, an override will
60/// appear mapping source 0 to GSI 2. Currently these will only be created for ISA interrupt
61/// sources.
62#[derive(Debug, Clone, Copy)]
63pub struct InterruptSourceOverride {
64 pub isa_source: u8,
65 pub global_system_interrupt: u32,
66 pub polarity: Polarity,
67 pub trigger_mode: TriggerMode,
68}
69
70/// Describes a Global System Interrupt that should be enabled as non-maskable. Any source that is
71/// non-maskable can not be used by devices.
72#[derive(Debug, Clone, Copy)]
73pub struct NmiSource {
74 pub global_system_interrupt: u32,
75 pub polarity: Polarity,
76 pub trigger_mode: TriggerMode,
77}
78
79#[derive(Debug, Clone)]
80pub struct Apic<'a, A>
81where
82 A: Allocator,
83{
84 pub local_apic_address: u64,
85 pub io_apics: ManagedSlice<'a, IoApic, A>,
86 pub local_apic_nmi_lines: ManagedSlice<'a, NmiLine, A>,
87 pub interrupt_source_overrides: ManagedSlice<'a, InterruptSourceOverride, A>,
88 pub nmi_sources: ManagedSlice<'a, NmiSource, A>,
89
90 /// If this field is set, you must remap and mask all the lines of the legacy PIC, even if
91 /// you choose to use the APIC. It's recommended that you do this even if ACPI does not
92 /// require you to.
93 pub also_has_legacy_pics: bool,
94}
95
96impl<'a, A> Apic<'a, A>
97where
98 A: Allocator,
99{
100 pub(crate) fn new(
101 local_apic_address: u64,
102 io_apics: ManagedSlice<'a, IoApic, A>,
103 local_apic_nmi_lines: ManagedSlice<'a, NmiLine, A>,
104 interrupt_source_overrides: ManagedSlice<'a, InterruptSourceOverride, A>,
105 nmi_sources: ManagedSlice<'a, NmiSource, A>,
106 also_has_legacy_pics: bool,
107 ) -> Self {
108 Self {
109 local_apic_address,
110 io_apics,
111 local_apic_nmi_lines,
112 interrupt_source_overrides,
113 nmi_sources,
114 also_has_legacy_pics,
115 }
116 }
117}
118
119#[derive(Debug, Clone)]
120#[non_exhaustive]
121pub enum InterruptModel<'a, A>
122where
123 A: Allocator,
124{
125 /// This model is only chosen when the MADT does not describe another interrupt model. On `x86_64` platforms,
126 /// this probably means only the legacy i8259 PIC is present.
127 Unknown,
128
129 /// Describes an interrupt controller based around the Advanced Programmable Interrupt Controller (any of APIC,
130 /// XAPIC, or X2APIC). These are likely to be found on x86 and x86_64 systems and are made up of a Local APIC
131 /// for each core and one or more I/O APICs to handle external interrupts.
132 Apic(Apic<'a, A>),
133}