diff options
| author | Aleksa Vuckovic <aleksav013@gmail.com> | 2023-01-24 01:55:35 +0100 |
|---|---|---|
| committer | Aleksa Vuckovic <aleksav013@gmail.com> | 2023-01-24 01:55:35 +0100 |
| commit | 95d1eb6d381b3eeaf0a8c3de57d5ee554229bcd6 (patch) | |
| tree | 6433c3dc56fbfe60bac8d0de4d933fdac1270b48 /kernel/src/apic | |
| parent | 32d96c66c088a58d80acf251d9576d0ed2e1b78c (diff) | |
parsing RSDP & MADT
Diffstat (limited to 'kernel/src/apic')
| -rw-r--r-- | kernel/src/apic/madt.c | 72 | ||||
| -rw-r--r-- | kernel/src/apic/rsdp.c | 68 |
2 files changed, 140 insertions, 0 deletions
diff --git a/kernel/src/apic/madt.c b/kernel/src/apic/madt.c new file mode 100644 index 0000000..b88b788 --- /dev/null +++ b/kernel/src/apic/madt.c @@ -0,0 +1,72 @@ +#include <madt.h> +#include <heap.h> +#include <libk/string.h> +#include <libk/stdio.h> + +void parse_madt() +{ + uint64_t* madt_addr = find_sys_table_addr("APIC"); + + if (madt_addr == NULL) { + printf("MADT NOT FOUND\n"); + return; + } + + struct MADT* madt = (struct MADT*)kalloc(sizeof(struct MADT)); + memcpy(madt, madt_addr, sizeof(struct MADT)); + + for (size_t curr_size = sizeof(struct MADT); curr_size < madt->h.Length;) { + struct MADT_type_header* m = (struct MADT_type_header*)kalloc(sizeof(struct MADT_type_header)); + memcpy(m, (uint64_t*)((uint64_t)madt_addr + (uint64_t)curr_size), sizeof(struct MADT_type_header)); + uint8_t type = m->type; + uint8_t len = m->len; + kfree(m); + + if (type == 0) { + // Processor Local APIC + struct MADT_cpu_local_apic* cpu = (struct MADT_cpu_local_apic*)kalloc(sizeof(struct MADT_cpu_local_apic)); + memcpy(cpu, (uint64_t*)((uint64_t)madt_addr + (uint64_t)curr_size), sizeof(struct MADT_cpu_local_apic)); + + printf("found cpu: acpi_id: 0x%x, apic_id: 0x%x, flags: 0x%x\n", cpu->acpi_id, cpu->apic_id, cpu->flags); + kfree(cpu); + } else if (type == 1) { + // I/O APIC + struct MADT_io_apic* io = (struct MADT_io_apic*)kalloc(sizeof(struct MADT_io_apic)); + memcpy(io, (uint64_t*)((uint64_t)madt_addr + (uint64_t)curr_size), sizeof(struct MADT_io_apic)); + + printf("found io: apic_id: 0x%x, addr: 0x%x, int_base: 0x%x\n", io->apic_id, io->io_apic_addr, io->int_base); + kfree(io); + } else if (type == 2) { + // IO/APIC Interrupt Source Override + struct MADT_io_apic_int* io_apic_int = (struct MADT_io_apic_int*)kalloc(sizeof(struct MADT_io_apic_int)); + memcpy(io_apic_int, (uint64_t*)((uint64_t)madt_addr + (uint64_t)curr_size), sizeof(struct MADT_io_apic_int)); + + printf("found io_apic_int: bus: 0x%x, irq_source: 0x%x, global_sys_int: 0x%x, flags: 0x%x\n", io_apic_int->bus_source, io_apic_int->irq_source, io_apic_int->global_sys_int, io_apic_int->flags); + kfree(io_apic_int); + } else if (type == 3) { + // IO/APIC Non-maskable interrupt source + printf("MADT entry of type %d\n", type); + } else if (type == 4) { + // Local APIC Non-maskable interrupts + struct MADT_lapic_nmi* lapic_nmi = (struct MADT_lapic_nmi*)kalloc(sizeof(struct MADT_lapic_nmi)); + memcpy(lapic_nmi, (uint64_t*)((uint64_t)madt_addr + (uint64_t)curr_size), sizeof(struct MADT_lapic_nmi)); + + printf("found lapic_nmi: acpi_cpu_id: 0x%x, flags: 0x%x, lint: 0x%x\n", lapic_nmi->acpi_cpu_id, lapic_nmi->flags, lapic_nmi->lint); + kfree(lapic_nmi); + } else if (type == 5) { + // Local APIC Address Override + struct MADT_lapic_addr* lapic_addr = (struct MADT_lapic_addr*)kalloc(sizeof(struct MADT_lapic_addr)); + memcpy(lapic_addr, (uint64_t*)((uint64_t)madt_addr + (uint64_t)curr_size), sizeof(struct MADT_lapic_addr)); + + printf("found lapic: addr: 0x%x\n", lapic_addr->phys_addr); + kfree(lapic_addr); + } else if (type == 9) { + // Processor Local x2APIC + printf("MADT entry of type %d\n", type); + } else { + // ERROR + printf("ERROR: MADT entry of type %d\n", type); + } + curr_size += len; + } +} diff --git a/kernel/src/apic/rsdp.c b/kernel/src/apic/rsdp.c new file mode 100644 index 0000000..ebecd66 --- /dev/null +++ b/kernel/src/apic/rsdp.c @@ -0,0 +1,68 @@ +#include <rsdp.h> +#include <heap.h> +#include <paging.h> +#include <libk/string.h> +#include <libk/stdio.h> + +uint64_t* find_rsdp() +{ + map_addr(0x0, 0x0, FLAG_PRESENT); + const char* rsdp_cs = "RSD PTR "; + for (uint64_t i = 0x10; i < 0x100000; i += 0x10) { + char *x = (char*)i; + uint8_t ind = 1; + for (size_t j = 0; j < strlen(rsdp_cs); j++) { + if (rsdp_cs[j] != x[j]) { + ind = 0; + break; + } + } + if (ind) { + return (uint64_t*)i; + } + } + return NULL; +} + +uint64_t* find_sys_table_addr(const char* signature) +{ + uint64_t* rsdp = find_rsdp(); + + if (rsdp == NULL) { + printf("RSDP NOT FOUND\n"); + return NULL; + } + + struct RSDP_descriptor* rsdp_desc = (struct RSDP_descriptor*)rsdp; + map_addr(rsdp_desc->RsdtAddress, rsdp_desc->RsdtAddress, FLAG_PRESENT); + + struct ACPI_header* rsdt = (struct ACPI_header*)kalloc(sizeof(struct ACPI_header)); + memcpy(rsdt, (uint64_t*)(uint64_t)rsdp_desc->RsdtAddress, sizeof(struct ACPI_header)); + + uint32_t entries = (rsdt->Length - (uint32_t)sizeof(struct ACPI_header)) / 4; + + for (size_t i = 0; i < entries; i++) { + uint32_t na_addr = (uint32_t)rsdp_desc->RsdtAddress + (uint32_t)sizeof(struct ACPI_header) + (uint32_t)i * 4; + uint32_t addr; + memcpy(&addr, (uint64_t*)(uint64_t)na_addr, 4); + + struct ACPI_header* t = (struct ACPI_header*)kalloc(sizeof(struct ACPI_header)); + memcpy(t, (uint64_t*)(uint64_t)addr, sizeof(struct ACPI_header)); + + int ind = 1; + for (size_t j = 0; j < 4; j++) { + if (t->Signature[j] != signature[j]) + ind = 0; + } + if (ind) { + kfree(t); + kfree(rsdt); + return (uint64_t*)(uint64_t)addr; + } + + kfree(t); + } + + kfree(rsdt); + return NULL; +} |
