From e1b8ae10a3f96430cfb176ce52645e36b9ff1444 Mon Sep 17 00:00:00 2001 From: "Chloe M." Date: Thu, 30 Apr 2026 19:05:02 -0400 Subject: [PATCH] sp1/amd64: irqchip: Add IRQ chip descriptor lists Signed-off-by: Chloe M. --- usr/src/sp1/amd64/io/irqchip.c | 64 ++++++++++++++++++++++++++++++++ usr/src/sp1/head/amd64/irqchip.h | 42 +++++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/usr/src/sp1/amd64/io/irqchip.c b/usr/src/sp1/amd64/io/irqchip.c index 14e4787..7098a0d 100644 --- a/usr/src/sp1/amd64/io/irqchip.c +++ b/usr/src/sp1/amd64/io/irqchip.c @@ -16,6 +16,7 @@ #include #include #include +#include #define pr_trace(fmt, ...) \ printf("irqchip: " fmt, ##__VA_ARGS__) @@ -23,6 +24,40 @@ /* Online capable */ #define LAPIC_ONLCAP BIT(1) +/* I/O APIC */ +static struct irqchip ioapic_list[MAX_IOAPIC]; +static size_t ioapic_count = 0; + +/* Local APIC */ +static struct irqchip lapic_list[MAX_LAPIC]; +static size_t lapic_count = 0; + +/* + * Add a Local APIC descriptor + */ +static inline void +irqchip_lapic_append(const struct irqchip *irqchip) +{ + if (lapic_count >= MAX_LAPIC) { + return; + } + + lapic_list[lapic_count++] = *irqchip; +} + +/* + * Add an I/O APIC descriptor + */ +static inline void +irqchip_ioapic_append(const struct irqchip *irqchip) +{ + if (ioapic_count >= MAX_IOAPIC) { + return; + } + + ioapic_list[ioapic_count++] = *irqchip; +} + /* * Print information about a Local APIC unit */ @@ -63,6 +98,7 @@ irqchip_print_ioapic(struct ioapic *ioapic) status_t md_irqchip_init(void) { + struct irqchip chip; struct acpi_madt *madt; struct local_apic *lapic; struct ioapic *ioapic; @@ -84,13 +120,41 @@ md_irqchip_init(void) case APIC_TYPE_LOCAL_APIC: lapic = (struct local_apic *)hdr; irqchip_print_lapic(lapic); + + chip.mmio = pma_to_vma(madt->lapic_addr); + chip.apic_id = lapic->apic_id; + irqchip_lapic_append(&chip); break; case APIC_TYPE_IO_APIC: ioapic = (struct ioapic *)hdr; irqchip_print_ioapic(ioapic); + + chip.mmio = pma_to_vma(ioapic->ioapic_addr); + chip.apic_id = ioapic->ioapic_id; + irqchip_lapic_append(&chip); break; } cur += hdr->length; } } + +struct irqchip * +md_ioapic_index(size_t index) +{ + if (index >= ioapic_count) { + return NULL; + } + + return &ioapic_list[index]; +} + +struct irqchip * +md_lapic_index(size_t index) +{ + if (index >= lapic_count) { + return NULL; + } + + return &lapic_list[index]; +} diff --git a/usr/src/sp1/head/amd64/irqchip.h b/usr/src/sp1/head/amd64/irqchip.h index e57bbc8..4f5826b 100644 --- a/usr/src/sp1/head/amd64/irqchip.h +++ b/usr/src/sp1/head/amd64/irqchip.h @@ -14,9 +14,51 @@ #include +#define MAX_IOAPIC 8 +#define MAX_LAPIC 64 + +/* + * @IRQCHIP_NONE: This IRQ chip has no type + * @IRQCHIP_LAPIC: This IRQ chip is a Local APIC + * @IRQCHIP_IOAPIC: This IRQ chip is an I/O APIC + */ +typedef enum { + IRQCHIP_NONE, + IRQCHIP_LAPIC, + IRQCHIP_IOAPIC +} irqchip_type_t; + +/* + * Represents a platform interrupt controller + * chip + * + * @type: IRQ chip type + * @apic_id: APIC ID + * @mmio: Memory mapped I/O address + */ +struct irqchip { + irqchip_type_t type; + uint8_t apic_id; + void *mmio; +}; + /* * Initialize platform interrupt controller chips */ status_t md_irqchip_init(void); +/* + * Obtain an I/O APIC descriptor by index + * + * @index: Index of entry to obtain + */ +struct irqchip *md_ioapic_index(size_t index); + +/* + * Obtain an Local APIC descriptor by index + * + * @index: Index of entry to obtain + */ +struct irqchip *md_lapic_index(size_t index); + #endif /* !_MACHINE_IRQCHIP_H_ */