feat/kernel: Re-added MADT
This commit is contained in:
parent
8516143538
commit
a6b98d6fb6
5 changed files with 174 additions and 6 deletions
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -23,7 +23,8 @@
|
||||||
"string_view": "c",
|
"string_view": "c",
|
||||||
"lapic.h": "c",
|
"lapic.h": "c",
|
||||||
"spinlock.h": "c",
|
"spinlock.h": "c",
|
||||||
"fb.h": "c"
|
"fb.h": "c",
|
||||||
|
"acpi.h": "c"
|
||||||
},
|
},
|
||||||
"editor.formatOnPaste": true,
|
"editor.formatOnPaste": true,
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
MAKEFLAGS += -rR
|
MAKEFLAGS += -rR
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
|
|
||||||
QEMUFLAGS := -serial stdio -smp 4
|
QEMUFLAGS := -smp 4
|
||||||
USER_QEMUFLAGS ?=
|
USER_QEMUFLAGS ?=
|
||||||
IMAGE_NAME := release/emk
|
IMAGE_NAME := release/emk
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ all: $(IMAGE_NAME).iso
|
||||||
.PHONY: run
|
.PHONY: run
|
||||||
run: $(IMAGE_NAME).iso ovmf/ovmf-code-x86_64.fd
|
run: $(IMAGE_NAME).iso ovmf/ovmf-code-x86_64.fd
|
||||||
@qemu-system-x86_64 \
|
@qemu-system-x86_64 \
|
||||||
-M q35 \
|
-M q35 -serial stdio \
|
||||||
-drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-x86_64.fd,readonly=on \
|
-drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-x86_64.fd,readonly=on \
|
||||||
-cdrom $(IMAGE_NAME).iso \
|
-cdrom $(IMAGE_NAME).iso \
|
||||||
$(QEMUFLAGS)
|
$(QEMUFLAGS)
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#endif // FLANTERM_SUPPORT
|
#endif // FLANTERM_SUPPORT
|
||||||
#include <arch/smp.h>
|
#include <arch/smp.h>
|
||||||
#include <sys/acpi.h>
|
#include <sys/acpi.h>
|
||||||
|
#include <sys/acpi/madt.h>
|
||||||
|
|
||||||
__attribute__((used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3);
|
__attribute__((used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3);
|
||||||
__attribute__((used, section(".limine_requests"))) static volatile struct limine_memmap_request memmap_request = {
|
__attribute__((used, section(".limine_requests"))) static volatile struct limine_memmap_request memmap_request = {
|
||||||
|
@ -167,7 +168,7 @@ void emk_entry(void)
|
||||||
*c = 32;
|
*c = 32;
|
||||||
kfree(c);
|
kfree(c);
|
||||||
|
|
||||||
/* Setup ACPI (and TODO APIC) */
|
/* Setup ACPI */
|
||||||
rsdp_response = rsdp_request.response;
|
rsdp_response = rsdp_request.response;
|
||||||
if (!rsdp_response)
|
if (!rsdp_response)
|
||||||
{
|
{
|
||||||
|
@ -175,10 +176,16 @@ void emk_entry(void)
|
||||||
}
|
}
|
||||||
acpi_init();
|
acpi_init();
|
||||||
|
|
||||||
|
/* Disable legacy PIC to prepare for APIC */
|
||||||
|
outb(0x21, 0xff);
|
||||||
|
outb(0xA1, 0xff);
|
||||||
|
|
||||||
|
/* Setup APIC */
|
||||||
|
madt_init();
|
||||||
|
|
||||||
/* Finished */
|
/* Finished */
|
||||||
log_early("%s", LOG_SEPARATOR);
|
log_early("%s", LOG_SEPARATOR);
|
||||||
uint32_t uptime = 0;
|
log_early("Finished initializing EMK v1.0, took ? seconds"); /* Still not usermode, so keep using log_early */
|
||||||
log_early("Finished initializing EMK v1.0, took %d seconds", uptime); /* Still not usermode, so keep using log_early */
|
|
||||||
|
|
||||||
hlt();
|
hlt();
|
||||||
}
|
}
|
56
kernel/src/sys/acpi/madt.c
Normal file
56
kernel/src/sys/acpi/madt.c
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/* EMK 1.0 Copyright (c) 2025 Piraterna */
|
||||||
|
#include <sys/acpi/madt.h>
|
||||||
|
#include <sys/acpi.h>
|
||||||
|
#include <sys/kpanic.h>
|
||||||
|
#include <util/log.h>
|
||||||
|
|
||||||
|
acpi_madt_ioapic_t *madt_ioapic_list[256] = {0};
|
||||||
|
acpi_madt_ioapic_src_ovr_t *madt_iso_list[256] = {0};
|
||||||
|
|
||||||
|
uint32_t madt_ioapic_len = 0;
|
||||||
|
uint32_t madt_iso_len = 0;
|
||||||
|
|
||||||
|
uint64_t lapic_addr = 0;
|
||||||
|
|
||||||
|
void madt_init()
|
||||||
|
{
|
||||||
|
acpi_madt_t *madt = (acpi_madt_t *)acpi_find_table("APIC");
|
||||||
|
if (!madt)
|
||||||
|
{
|
||||||
|
kpanic(NULL, "Failed to find MADT table");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (madt->sdt.length < sizeof(acpi_madt_t))
|
||||||
|
{
|
||||||
|
kpanic(NULL, "MADT table is too small");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t offset = 0;
|
||||||
|
while (offset < madt->sdt.length - sizeof(acpi_madt_t))
|
||||||
|
{
|
||||||
|
acpi_madt_entry_t *entry = (acpi_madt_entry_t *)(madt->table + offset);
|
||||||
|
|
||||||
|
if (entry->length == 0 || offset + entry->length > madt->sdt.length - sizeof(acpi_madt_t))
|
||||||
|
{
|
||||||
|
kpanic(NULL, "Invalid MADT entry length or overflow");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry->type == MADT_ENTRY_IOAPIC)
|
||||||
|
{
|
||||||
|
if (madt_ioapic_len < 256)
|
||||||
|
madt_ioapic_list[madt_ioapic_len++] = (acpi_madt_ioapic_t *)entry;
|
||||||
|
}
|
||||||
|
else if (entry->type == MADT_ENTRY_IOAPIC_SRC_OVR)
|
||||||
|
{
|
||||||
|
if (madt_iso_len < 256)
|
||||||
|
madt_iso_list[madt_iso_len++] = (acpi_madt_ioapic_src_ovr_t *)entry;
|
||||||
|
}
|
||||||
|
else if (entry->type == MADT_ENTRY_LAPIC_ADDR_OVR)
|
||||||
|
{
|
||||||
|
lapic_addr = ((acpi_madt_lapic_addr_ovr_t *)entry)->lapic_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += entry->length;
|
||||||
|
}
|
||||||
|
log_early("MADT parsed: %u IOAPIC(s), %u ISO(s), LAPIC addr: 0x%lx", madt_ioapic_len, madt_iso_len, lapic_addr);
|
||||||
|
}
|
104
kernel/src/sys/acpi/madt.h
Normal file
104
kernel/src/sys/acpi/madt.h
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
/* EMK 1.0 Copyright (c) 2025 Piraterna */
|
||||||
|
#ifndef MADT_H
|
||||||
|
#define MADT_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/acpi.h>
|
||||||
|
|
||||||
|
#define MADT_ENTRY_LAPIC 0 /* Local APIC */
|
||||||
|
#define MADT_ENTRY_IOAPIC 1 /* I/O APIC */
|
||||||
|
#define MADT_ENTRY_IOAPIC_SRC_OVR 2 /* I/O APIC Interrupt Source Override */
|
||||||
|
#define MADT_ENTRY_IOAPIC_NMI_SRC 3 /* I/O APIC Non-Maskable Interrupt Source */
|
||||||
|
#define MADT_ENTRY_LAPIC_NMI 4 /* Local APIC Non-Maskable Interrupt */
|
||||||
|
#define MADT_ENTRY_LAPIC_ADDR_OVR 5 /* Local APIC Address Override */
|
||||||
|
#define MADT_ENTRY_LX2APIC 9 /* Local x2APIC */
|
||||||
|
|
||||||
|
typedef struct acpi_madt
|
||||||
|
{
|
||||||
|
acpi_sdt_header_t sdt;
|
||||||
|
uint32_t lapic_base;
|
||||||
|
uint32_t flags;
|
||||||
|
char table[];
|
||||||
|
} __attribute__((packed)) acpi_madt_t;
|
||||||
|
|
||||||
|
typedef struct acpi_madt_entry
|
||||||
|
{
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t length;
|
||||||
|
} __attribute__((packed)) acpi_madt_entry_t;
|
||||||
|
|
||||||
|
/* Entry Type 0: Processor Local APIC */
|
||||||
|
typedef struct acpi_madt_lapic
|
||||||
|
{
|
||||||
|
acpi_madt_entry_t header;
|
||||||
|
uint8_t acpi_proc_id; /* ACPI Processor ID */
|
||||||
|
uint8_t apic_id; /* APIC ID */
|
||||||
|
uint32_t flags; /* Bit 0: Processor Enabled, Bit 1: Online Capable */
|
||||||
|
} __attribute__((packed)) acpi_madt_lapic_t;
|
||||||
|
|
||||||
|
/* Entry Type 1: I/O APIC */
|
||||||
|
typedef struct acpi_madt_ioapic
|
||||||
|
{
|
||||||
|
acpi_madt_entry_t header;
|
||||||
|
uint8_t ioapic_id; /* I/O APIC's ID */
|
||||||
|
uint8_t reserved; /* Reserved (0) */
|
||||||
|
uint32_t ioapic_addr; /* I/O APIC Address */
|
||||||
|
uint32_t gsi_base; /* Global System Interrupt Base */
|
||||||
|
} __attribute__((packed)) acpi_madt_ioapic_t;
|
||||||
|
|
||||||
|
/* Entry Type 2: I/O APIC Interrupt Source Override */
|
||||||
|
typedef struct acpi_madt_ioapic_src_ovr
|
||||||
|
{
|
||||||
|
acpi_madt_entry_t header;
|
||||||
|
uint8_t bus_source; /* Bus Source */
|
||||||
|
uint8_t irq_source; /* IRQ Source */
|
||||||
|
uint32_t gsi; /* Global System Interrupt */
|
||||||
|
uint16_t flags; /* Flags */
|
||||||
|
} __attribute__((packed)) acpi_madt_ioapic_src_ovr_t;
|
||||||
|
|
||||||
|
/* Entry Type 3: I/O APIC Non-Maskable Interrupt Source */
|
||||||
|
typedef struct acpi_madt_ioapic_nmi_src
|
||||||
|
{
|
||||||
|
acpi_madt_entry_t header;
|
||||||
|
uint8_t nmi_source; /* NMI Source */
|
||||||
|
uint8_t reserved; /* Reserved */
|
||||||
|
uint16_t flags; /* Flags */
|
||||||
|
uint32_t gsi; /* Global System Interrupt */
|
||||||
|
} __attribute__((packed)) acpi_madt_ioapic_nmi_src_t;
|
||||||
|
|
||||||
|
/* Entry Type 4: Local APIC Non-Maskable Interrupt */
|
||||||
|
typedef struct acpi_madt_lapic_nmi
|
||||||
|
{
|
||||||
|
acpi_madt_entry_t header;
|
||||||
|
uint8_t acpi_proc_id; /* ACPI Processor ID (0xFF for all processors) */
|
||||||
|
uint16_t flags; /* Flags */
|
||||||
|
uint8_t lint; /* LINT# (0 or 1) */
|
||||||
|
} __attribute__((packed)) acpi_madt_lapic_nmi_t;
|
||||||
|
|
||||||
|
/* Entry Type 5: Local APIC Address Override */
|
||||||
|
typedef struct acpi_madt_lapic_addr_ovr
|
||||||
|
{
|
||||||
|
acpi_madt_entry_t header;
|
||||||
|
uint16_t reserved; /* Reserved */
|
||||||
|
uint64_t lapic_addr; /* 64-bit Physical Address of Local APIC */
|
||||||
|
} __attribute__((packed)) acpi_madt_lapic_addr_ovr_t;
|
||||||
|
|
||||||
|
/* Entry Type 9: Processor Local x2APIC */
|
||||||
|
typedef struct acpi_madt_lx2apic
|
||||||
|
{
|
||||||
|
acpi_madt_entry_t header;
|
||||||
|
uint16_t reserved;
|
||||||
|
uint32_t x2apic_id; /* Processor's Local x2APIC ID */
|
||||||
|
uint32_t flags; /* Flags (same as Local APIC) */
|
||||||
|
uint32_t acpi_id; /* ACPI ID */
|
||||||
|
} __attribute__((packed)) acpi_madt_lx2apic_t;
|
||||||
|
|
||||||
|
extern acpi_madt_ioapic_t *madt_ioapic_list[256];
|
||||||
|
extern acpi_madt_ioapic_src_ovr_t *madt_iso_list[256];
|
||||||
|
extern uint32_t madt_ioapic_len;
|
||||||
|
extern uint32_t madt_iso_len;
|
||||||
|
extern uint64_t lapic_addr;
|
||||||
|
|
||||||
|
void madt_init();
|
||||||
|
|
||||||
|
#endif // MADT_H
|
Loading…
Add table
Add a link
Reference in a new issue