1
0
Fork 0

feat/kernel: Added MADT support and SMP

This commit is contained in:
Kevin Alavik 2025-05-16 19:45:59 +02:00
parent aeda945087
commit cdceef1da7
Signed by: cmpsb
GPG key ID: 10D1CC0526FDC6D7
7 changed files with 98 additions and 19 deletions

View file

@ -18,6 +18,8 @@
"nanoprintf.h": "c",
"flanterm.h": "c",
"serial.h": "c",
"kpanic.h": "c"
"kpanic.h": "c",
"smp.h": "c",
"string_view": "c"
}
}

44
kernel/src/arch/smp.c Normal file
View file

@ -0,0 +1,44 @@
/* EMK 1.0 Copyright (c) 2025 Piraterna */
#include <arch/smp.h>
#include <boot/limine.h>
#include <boot/emk.h>
#include <util/log.h>
uint32_t bootstrap_lapic_id = 0;
uint32_t cpu_count = 0;
uint32_t ctr = 0;
void smp_entry(struct limine_mp_info *smp_info)
{
log_early("CPU %d started", smp_info->processor_id);
__atomic_fetch_add(&ctr, 1, __ATOMIC_SEQ_CST);
while (1)
;
}
void smp_init()
{
bootstrap_lapic_id = mp_response->bsp_lapic_id;
cpu_count = mp_response->cpu_count;
for (uint64_t i = 0; i < cpu_count; i++)
{
if (mp_response->cpus[i]->lapic_id != bootstrap_lapic_id)
{
uint32_t old_ctr = __atomic_load_n(&ctr, __ATOMIC_SEQ_CST);
__atomic_store_n(&mp_response->cpus[i]->goto_address, smp_entry,
__ATOMIC_SEQ_CST);
while (__atomic_load_n(&ctr, __ATOMIC_SEQ_CST) == old_ctr)
;
}
else
{
log_early("CPU %d is the bootstrap processor", i);
}
}
}

10
kernel/src/arch/smp.h Normal file
View file

@ -0,0 +1,10 @@
/* EMK 1.0 Copyright (c) 2025 Piraterna */
#ifndef SMP_H
#define SMP_H
#include <stdint.h>
extern uint32_t bootstrap_lapic_id;
void smp_init();
#endif // SMP_H

View file

@ -16,6 +16,7 @@ extern uint64_t kphys;
extern uint64_t kstack_top;
extern vctx_t *kvm_ctx;
extern struct limine_rsdp_response *rsdp_response;
extern struct limine_mp_response *mp_response;
#define HIGHER_HALF(ptr) ((void *)((uint64_t)(ptr) < hhdm_offset ? (uint64_t)(ptr) + hhdm_offset : (uint64_t)(ptr)))
#define PHYSICAL(ptr) ((void *)((uint64_t)(ptr) >= hhdm_offset ? (uint64_t)(ptr) - hhdm_offset : (uint64_t)(ptr)))

View file

@ -19,6 +19,7 @@
#endif // FLANTERM_SUPPORT
#include <sys/acpi.h>
#include <sys/acpi/madt.h>
#include <arch/smp.h>
__attribute__((used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3);
__attribute__((used, section(".limine_requests"))) static volatile struct limine_memmap_request memmap_request = {
@ -51,6 +52,7 @@ uint64_t kphys = 0;
uint64_t kstack_top = 0;
vctx_t *kvm_ctx = NULL;
struct limine_rsdp_response *rsdp_response = NULL;
struct limine_mp_response *mp_response = NULL;
#if FLANTERM_SUPPORT
struct flanterm_context *ft_ctx = NULL;
@ -166,6 +168,15 @@ void emk_entry(void)
kfree(c);
log_early("Initialized kernel heap");
/* Setup SMP */
if (!mp_request.response)
{
kpanic(NULL, "Failed to get MP request");
}
mp_response = mp_request.response;
smp_init();
/* Setup ACPI and APIC */
rsdp_response = rsdp_request.response;
if (!rsdp_response)
@ -179,13 +190,5 @@ void emk_entry(void)
madt_init();
log_early("Initialized APIC");
/* Setup SMP */
if (!mp_request.response)
{
kpanic(NULL, "Failed to get MP request");
}
log_early("%d available cores", mp_request.response->cpu_count);
hlt();
}

View file

@ -19,23 +19,36 @@ void madt_init()
kpanic(NULL, "Failed to find MADT table");
}
uint64_t offset = 0;
int i = 0;
while (1)
if (madt->sdt.length < sizeof(acpi_madt_t))
{
if (offset > madt->sdt.length - sizeof(acpi_madt_t))
break;
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->type == 0)
i++;
else if (entry->type == MADT_ENTRY_IOAPIC)
madt_ioapic_list[madt_ioapic_len++] = (acpi_madt_ioapic_t *)entry;
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)
madt_iso_list[madt_iso_len++] = (acpi_madt_ioapic_src_ovr_t *)entry;
{
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 = (uint64_t *)((acpi_madt_lapic_addr_ovr_t *)entry)->lapic_addr;
}
offset += entry->length;
}
}

View file

@ -93,6 +93,12 @@ typedef struct acpi_madt_lx2apic
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