summaryrefslogtreecommitdiff
path: root/kernel/src/apic/madt.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/src/apic/madt.c')
-rw-r--r--kernel/src/apic/madt.c72
1 files changed, 72 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;
+ }
+}