From fc64ccb7a49e6c43a9970813dc9ca31e8fa950cd Mon Sep 17 00:00:00 2001 From: Matheus Date: Thu, 4 May 2023 19:57:43 -0300 Subject: [PATCH] apic: ioapic set irq --- kernel-src/arch/x86-64/apic.c | 37 +++++++++++++++++++++++++++ kernel-src/include/x86-64/arch/apic.h | 2 ++ 2 files changed, 39 insertions(+) diff --git a/kernel-src/arch/x86-64/apic.c b/kernel-src/arch/x86-64/apic.c index 8b9fb259..be8e0c8d 100644 --- a/kernel-src/arch/x86-64/apic.c +++ b/kernel-src/arch/x86-64/apic.c @@ -65,6 +65,14 @@ typedef struct { uint8_t lint; } __attribute__((packed)) lapicnmientry_t; +typedef struct { + listheader_t header; + uint8_t bus; + uint8_t irq; + uint32_t gsi; + uint16_t flags; +} __attribute__((packed)) ioapicoverride_t; + typedef struct { void *addr; int base; @@ -83,6 +91,14 @@ static size_t iocount; static size_t lapiccount; static size_t lapicnmicount; +static ioapicdesc_t *ioapicfromgsi(int gsi) { + for (int i = 0; i < iocount; ++i) { + if (ioapics[i].base <= gsi && ioapics[i].top > gsi) + return &ioapics[i]; + } + return NULL; +} + static inline listheader_t *getnext(listheader_t *header) { uintptr_t ptr = (uintptr_t)header; return (listheader_t *)(ptr + header->length); @@ -149,6 +165,27 @@ static void writeiored(void *ioapic, uint8_t entry, uint8_t vector, uint8_t deli writeioapic(ioapic, 0x11 + entry * 2, (uint32_t)dest << 24); } +void arch_ioapic_setirq(uint8_t irq, uint8_t vector, uint8_t proc, bool masked) { + // default settings for ISA irqs + uint8_t polarity = 1; // active high + uint8_t trigger = 0; // edge triggered + for (uintmax_t i = 0; i < overridecount; ++i) { + ioapicoverride_t *override = getentry(ACPI_MADT_TYPE_OVERRIDE, i); + if (override->irq != irq) + continue; + + polarity = override->flags & 2 ? 1 : 0; // active low + trigger = override->flags & 8 ? 1 : 0; // level triggered + irq = override->irq; + break; + } + + ioapicdesc_t* ioapic = ioapicfromgsi(irq); + __assert(ioapic); + irq = irq - ioapic->base; + writeiored(ioapic->addr, irq, vector, 0, 0, polarity, trigger, masked ? 1 : 0, proc); +} + static void spurious(isr_t *self, context_t *ctx) { __assert(!"Spurious interrupt"); } diff --git a/kernel-src/include/x86-64/arch/apic.h b/kernel-src/include/x86-64/arch/apic.h index 8a505354..03892667 100644 --- a/kernel-src/include/x86-64/arch/apic.h +++ b/kernel-src/include/x86-64/arch/apic.h @@ -4,5 +4,7 @@ void arch_apic_timerinit(); void arch_apic_init(); void arch_apic_initap(); +void arch_apic_eoi(); +void arch_ioapic_setirq(uint8_t gsi, uint8_t vector, uint8_t proc, bool masked); #endif