| 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.hpp> |
| 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 | |