1
0
Fork 0

feat/kernel: Started on basic bootstrap ACPI

This commit is contained in:
Kevin Alavik 2025-05-15 22:34:16 +02:00
parent 0aa7a96f7c
commit 4151de51d9
No known key found for this signature in database
GPG key ID: 9DFC5F718C8BF2DF
7 changed files with 208 additions and 0 deletions

View file

@ -53,11 +53,13 @@ endif
CPPFLAGS := -I../external -I$(SRCDIR) -MMD -MP -DLIMINE_API_REVISION=3
IMPLICIT_SRCS :=
ifneq ($(MAKECMDGOALS),menuconfig)
ifeq ($(CONFIG_KERNEL_HEAP_FF),y)
IMPLICIT_SRCS += src/mm/heap/ff.c
else
$(error Error: No heap algorithm was defined. Please run "make menuconfig" and select one.)
endif
endif
ifeq ($(CONFIG_ENABLE_FLANTERM),y)
IMPLICIT_SRCS += ../external/flanterm/flanterm.c

View file

@ -15,6 +15,7 @@ extern uint64_t kvirt;
extern uint64_t kphys;
extern uint64_t kstack_top;
extern vctx_t *kvm_ctx;
extern struct limine_rsdp_response *rsdp_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

@ -17,6 +17,7 @@
#include <flanterm/flanterm.h>
#include <flanterm/backends/fb.h>
#endif // FLANTERM_SUPPORT
#include <sys/acpi.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 = {
@ -33,6 +34,9 @@ __attribute__((used, section(".limine_requests"))) volatile struct limine_frameb
.id = LIMINE_FRAMEBUFFER_REQUEST,
.response = 0};
#endif // FLANTERM_SUPPORT
__attribute__((used, section(".limine_requests"))) static volatile struct limine_rsdp_request rsdp_request = {
.revision = 0,
.id = LIMINE_RSDP_REQUEST};
__attribute__((used, section(".limine_requests_start"))) static volatile LIMINE_REQUESTS_START_MARKER;
__attribute__((used, section(".limine_requests_end"))) static volatile LIMINE_REQUESTS_END_MARKER;
@ -42,6 +46,7 @@ uint64_t kvirt = 0;
uint64_t kphys = 0;
uint64_t kstack_top = 0;
vctx_t *kvm_ctx = NULL;
struct limine_rsdp_response *rsdp_response = NULL;
#if FLANTERM_SUPPORT
struct flanterm_context *ft_ctx = NULL;
@ -89,6 +94,7 @@ void emk_entry(void)
idt_init();
log_early("Initialized IDT");
/* Setup physical memory*/
if (!hhdm_request.response)
{
kpanic(NULL, "Failed to get HHDM request");
@ -156,5 +162,14 @@ void emk_entry(void)
kfree(c);
log_early("Initialized kernel heap");
/* Setup ACPI and APIC */
rsdp_response = rsdp_request.response;
if (!rsdp_response)
{
kpanic(NULL, "Failed to get RSDP request");
}
acpi_init();
log_early("Initialized ACPI");
hlt();
}

View file

@ -64,3 +64,22 @@ int memcmp(const void *s1, const void *s2, size_t n)
return 0;
}
int strncmp(const char *s1, const char *s2, size_t n)
{
while (n > 0 && *s1 && *s2)
{
if (*s1 != *s2)
{
return (unsigned char)*s1 - (unsigned char)*s2;
}
s1++;
s2++;
n--;
}
if (n == 0)
{
return 0;
}
return (unsigned char)*s1 - (unsigned char)*s2;
}

View file

@ -10,4 +10,6 @@ void *memset(void *s, int c, size_t n);
void *memmove(void *dest, const void *src, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
int strncmp(const char *s1, const char *s2, size_t n);
#endif // STRING_H

122
kernel/src/sys/acpi.c Normal file
View file

@ -0,0 +1,122 @@
/* EMK 1.0 Copyright (c) 2025 Piraterna */
#include <sys/acpi.h>
#include <boot/emk.h>
#include <lib/string.h>
#include <util/log.h>
#include <sys/kpanic.h>
static int acpi_uses_xsdt = 0;
static void *acpi_rsdt_ptr = NULL;
static uint8_t acpi_checksum(void *ptr, size_t len)
{
uint8_t sum = 0;
uint8_t *data = (uint8_t *)ptr;
for (size_t i = 0; i < len; i++)
{
sum += data[i];
}
return sum;
}
static int acpi_validate_rsdp(acpi_rsdp_t *rsdp)
{
return acpi_checksum(rsdp, sizeof(acpi_rsdp_t)) == 0;
}
static int acpi_validate_xsdp(acpi_xsdp_t *xsdp)
{
if (acpi_checksum(xsdp, sizeof(acpi_rsdp_t)) != 0)
return 0;
if (acpi_checksum(xsdp, xsdp->length) != 0)
return 0;
return 1;
}
void acpi_init(void)
{
if (!rsdp_response || !rsdp_response->address)
{
kpanic(NULL, "No RSDP provided");
}
acpi_rsdp_t *rsdp = (acpi_rsdp_t *)rsdp_response->address;
log_early("RSDP found at %p", rsdp);
if (strncmp(rsdp->signature, "RSD PTR ", 8) != 0)
{
kpanic(NULL, "Invalid RSDP signature");
}
if (rsdp->revision >= 2)
{
acpi_xsdp_t *xsdp = (acpi_xsdp_t *)rsdp;
if (!acpi_validate_xsdp(xsdp))
{
kpanic(NULL, "XSDP checksum validation failed");
}
acpi_uses_xsdt = 1;
acpi_rsdt_ptr = (void *)(uintptr_t)xsdp->xsdt_address;
}
else
{
if (!acpi_validate_rsdp(rsdp))
{
kpanic(NULL, "RSDP checksum validation failed");
}
acpi_uses_xsdt = 0;
acpi_rsdt_ptr = (void *)(uintptr_t)rsdp->rsdt_address;
}
/* Validate RSDT/XSDT header */
acpi_sdt_header_t *sdt = (acpi_sdt_header_t *)acpi_rsdt_ptr;
if (acpi_checksum(sdt, sdt->length) != 0)
{
kpanic(NULL, "RSDT/XSDT checksum validation failed");
}
log_early("ACPI initialized, using %s at %p",
acpi_uses_xsdt ? "XSDT" : "RSDT", acpi_rsdt_ptr);
}
void *acpi_find_table(const char *name)
{
if (!acpi_rsdt_ptr || !name)
return NULL;
acpi_sdt_header_t *sdt = (acpi_sdt_header_t *)acpi_rsdt_ptr;
uint32_t entries;
if (acpi_uses_xsdt)
{
entries = (sdt->length - sizeof(acpi_sdt_header_t)) / sizeof(uint64_t);
}
else
{
entries = (sdt->length - sizeof(acpi_sdt_header_t)) / sizeof(uint32_t);
}
for (uint32_t i = 0; i < entries; i++)
{
acpi_sdt_header_t *table;
if (acpi_uses_xsdt)
{
uint64_t *xsdt_entries = (uint64_t *)(sdt + 1);
table = (acpi_sdt_header_t *)(uintptr_t)xsdt_entries[i];
}
else
{
uint32_t *rsdt_entries = (uint32_t *)(sdt + 1);
table = (acpi_sdt_header_t *)(uintptr_t)rsdt_entries[i];
}
if (strncmp(table->signature, name, 4) == 0)
{
if (acpi_checksum(table, table->length) == 0)
{
return table;
}
}
}
return NULL;
}

47
kernel/src/sys/acpi.h Normal file
View file

@ -0,0 +1,47 @@
/* EMK 1.0 Copyright (c) 2025 Piraterna */
#ifndef EMK_ACPI_H
#define EMK_ACPI_H
#include <stdint.h>
#include <stddef.h>
#include <lib/string.h>
typedef struct acpi_rsdp
{
char signature[8];
uint8_t checksum;
char oem_id[6];
uint8_t revision;
uint32_t rsdt_address;
} __attribute__((packed)) acpi_rsdp_t;
typedef struct acpi_xsdp
{
char signature[8];
uint8_t checksum;
char oem_id[6];
uint8_t revision;
uint32_t rsdt_address;
uint32_t length;
uint64_t xsdt_address;
uint8_t full_checksum;
uint8_t reserved[3];
} __attribute__((packed)) acpi_xsdp_t;
typedef struct acpi_sdt_header
{
char signature[4];
uint32_t length;
uint8_t revision;
uint8_t checksum;
char oem_id[6];
char oem_table_id[8];
uint32_t oem_revision;
uint32_t creator_id;
uint32_t creator_revision;
} __attribute__((packed)) acpi_sdt_header_t;
void *acpi_find_table(const char *name);
void acpi_init(void);
#endif /* EMK_ACPI_H */