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
9typedef 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
20typedef enum
21{
22 LAPIC_DEST_MODE_PHYSICAL = 0,
23 LAPIC_DEST_MODE_LOGICAL = 1,
24} lapic_dest_mode_t;
25
26typedef 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
34void lapic_enable(void);
35void lapic_interrupt(u8 vec, u8 dest, lapic_delivery_mode_t delivery_mode, lapic_dest_mode_t dest_mode, lapic_shorthand_t shorthand);
36void 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
38u32 lapic_read32(u32 offset);
39u64 lapic_read64(u32 offset);
40void lapic_write32(u32 offset, u32 value);
41void lapic_write64(u32 offset, u64 value);
42
43void lapic_eoi(void);
44
45should_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
53typedef enum
54{
55 IOAPIC_TRIGGER_MODE_EDGE = 0,
56 IOAPIC_TRIGGER_MODE_LEVEL = 1,
57} ioapic_trigger_mode_t;
58
59typedef enum
60{
61 IOAPIC_POLARITY_ACTIVE_HIGH = 0,
62 IOAPIC_POLARITY_ACTIVE_LOW = 1,
63} ioapic_polarity_t;
64
65void ioapic_init(void);
66void ioapic_enable_with_mode(u32 irq, u32 cpu, ioapic_trigger_mode_t trigger_mode, ioapic_polarity_t polarity);
67void ioapic_disable(u32 irq);
68
69void lapic_set_timer(u32 initial_count);
70
71should_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