1 | // SPDX-License-Identifier: GPL-3.0-or-later |
2 | // Common header for LAPIC and IOAPIC |
3 | |
4 | #pragma once |
5 | |
6 | #include <mos/types.h> |
7 | |
8 | #define APIC_REG_LAPIC_ID 0x20 |
9 | typedef enum |
10 | { |
11 | APIC_DELIVER_MODE_NORMAL = 0, |
12 | APIC_DELIVER_MODE_LOWEST_PRIORITY = 1, |
13 | APIC_DELIVER_MODE_SMI = 2, |
14 | APIC_DELIVER_MODE_NMI = 4, |
15 | APIC_DELIVER_MODE_INIT = 5, |
16 | APIC_DELIVER_MODE_INIT_DEASSERT = APIC_DELIVER_MODE_INIT, |
17 | APIC_DELIVER_MODE_STARTUP = 6, |
18 | } lapic_delivery_mode_t; |
19 | |
20 | typedef enum |
21 | { |
22 | LAPIC_DEST_MODE_PHYSICAL = 0, |
23 | LAPIC_DEST_MODE_LOGICAL = 1, |
24 | } lapic_dest_mode_t; |
25 | |
26 | typedef enum |
27 | { |
28 | LAPIC_SHORTHAND_NONE = 0, |
29 | LAPIC_SHORTHAND_SELF = 1, |
30 | LAPIC_SHORTHAND_ALL = 2, |
31 | LAPIC_SHORTHAND_ALL_EXCLUDING_SELF = 3, |
32 | } lapic_shorthand_t; |
33 | |
34 | void lapic_enable(void); |
35 | void lapic_interrupt(u8 vec, u8 dest, lapic_delivery_mode_t delivery_mode, lapic_dest_mode_t dest_mode, lapic_shorthand_t shorthand); |
36 | void lapic_interrupt_full(u8 vec, u8 dest, lapic_delivery_mode_t dliv_mode, lapic_dest_mode_t dstmode, bool lvl, bool trigger, lapic_shorthand_t sh); |
37 | |
38 | u32 lapic_read32(u32 offset); |
39 | u64 lapic_read64(u32 offset); |
40 | void lapic_write32(u32 offset, u32 value); |
41 | void lapic_write64(u32 offset, u64 value); |
42 | |
43 | void lapic_eoi(void); |
44 | |
45 | should_inline u8 lapic_get_id(void) |
46 | { |
47 | // https://stackoverflow.com/a/71756491 |
48 | // https://github.com/rust-osdev/apic/blob/master/src/registers.rs |
49 | // shift 24 because the ID is in the upper 8 bits |
50 | return lapic_read32(APIC_REG_LAPIC_ID) >> 24; |
51 | } |
52 | |
53 | typedef enum |
54 | { |
55 | IOAPIC_TRIGGER_MODE_EDGE = 0, |
56 | IOAPIC_TRIGGER_MODE_LEVEL = 1, |
57 | } ioapic_trigger_mode_t; |
58 | |
59 | typedef enum |
60 | { |
61 | IOAPIC_POLARITY_ACTIVE_HIGH = 0, |
62 | IOAPIC_POLARITY_ACTIVE_LOW = 1, |
63 | } ioapic_polarity_t; |
64 | |
65 | void ioapic_init(void); |
66 | void ioapic_enable_with_mode(u32 irq, u32 cpu, ioapic_trigger_mode_t trigger_mode, ioapic_polarity_t polarity); |
67 | void ioapic_disable(u32 irq); |
68 | |
69 | void lapic_set_timer(u32 initial_count); |
70 | |
71 | should_inline void ioapic_enable_interrupt(u32 irq, u32 lapic_id) |
72 | { |
73 | ioapic_enable_with_mode(irq, cpu: lapic_id, trigger_mode: IOAPIC_TRIGGER_MODE_EDGE, polarity: IOAPIC_POLARITY_ACTIVE_HIGH); |
74 | } |
75 | |