feat/kernel: Added MADT support and SMP
This commit is contained in:
parent
aeda945087
commit
cdceef1da7
7 changed files with 98 additions and 19 deletions
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
|
@ -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
44
kernel/src/arch/smp.c
Normal 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
10
kernel/src/arch/smp.h
Normal 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
|
|
@ -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)))
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue