From 9d9515c39934e194abfc54f938696cc626247922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Fri, 23 Feb 2018 22:19:47 +0100 Subject: [PATCH] Read and save data from MADT --- src/kernel/drivers/acpi.c | 71 +++++++++++++++++++++++++++++++++++++++ src/kernel/include/smp.h | 23 +++++++++++++ 2 files changed, 94 insertions(+) diff --git a/src/kernel/drivers/acpi.c b/src/kernel/drivers/acpi.c index 8ee5c0c..17368f9 100644 --- a/src/kernel/drivers/acpi.c +++ b/src/kernel/drivers/acpi.c @@ -29,6 +29,43 @@ struct sdt uint8_t data[]; }__attribute__((packed)); +struct madt +{ + uint32_t lic_address; + uint32_t flags; + uint8_t data[]; +}__attribute__((packed)); +struct madt_entry +{ + uint8_t type; + uint8_t len; + union{ + struct { + uint8_t id; + uint8_t apic; + uint32_t flags; + }__attribute__((packed)) lapic; + struct { + uint8_t id; + uint8_t _; + uint32_t addr; + uint32_t base; + }__attribute__((packed)) ioapic; + struct { + uint8_t bus; + uint8_t source; + uint32_t target; + uint16_t flags; + }__attribute__((packed)) interrupt; + }; +}__attribute__((packed)); + +#define MADT_CPU 0 +#define MADT_IOAPIC 1 +#define MADT_INT 2 + +struct acpi_info acpi_info = {0}; + static struct rsdp *find_rsdp() { uintptr_t ebda_start = *(uint16_t *)P2V(0x40e); @@ -59,6 +96,38 @@ static struct rsdp *find_rsdp() return 0; } +static void parse_madt(struct madt *madt, uint32_t len) +{ + uintptr_t end = (uintptr_t)madt + len; + struct madt_entry *e = (void *)madt->data; + debug_info("Local Interrupt Controller: %x\n", madt->lic_address); + while((uintptr_t)e < end) + { + int i; + switch(e->type) + { + case MADT_CPU: + i = acpi_info.num_cpus; + acpi_info.cpu[i].id = e->lapic.id; + acpi_info.cpu[i].apic = e->lapic.apic; + acpi_info.num_cpus++; + break; + case MADT_IOAPIC: + i = acpi_info.num_ioapic; + acpi_info.ioapic[i].id = e->ioapic.id; + acpi_info.ioapic[i].addr = e->ioapic.addr; + acpi_info.ioapic[i].base = e->ioapic.base; + acpi_info.num_ioapic++; + break; + case MADT_INT: + acpi_info.int_map[e->interrupt.source] = e->interrupt.target; + break; + } + debug_info(" MADT: type:%d len:%d\n", e->type, e->len); + e = incptr(e, e->len); + } +} + static void parse_sdt(struct sdt *sdt, uint8_t revision) { uint32_t *p32 = (void *)sdt->data; @@ -70,6 +139,8 @@ static void parse_sdt(struct sdt *sdt, uint8_t revision) debug_info("Found table: "); debug_putsn((char *)table->signature, 4); debug_printf("\n"); + if(!memcmp(table->signature, "APIC", 4)) + parse_madt((void *)table->data, table->len); } } diff --git a/src/kernel/include/smp.h b/src/kernel/include/smp.h index 2ab42f7..f8450fb 100644 --- a/src/kernel/include/smp.h +++ b/src/kernel/include/smp.h @@ -1,3 +1,26 @@ #pragma once +#include + +#define MAX_CPUS 16 +#define MAX_IOAPIC 4 + +struct acpi_info +{ + int num_cpus; + struct { + uint8_t id; + uint8_t apic; + } cpu[MAX_CPUS]; + + int num_ioapic; + struct { + uint8_t id; + uint32_t addr; + uint32_t base; + } ioapic[MAX_IOAPIC]; + + uint32_t int_map[255]; +}; +extern struct acpi_info acpi_info; void acpi_init();