Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
df5aa1d
Add limine request for RSDP
ryuukumar Apr 8, 2026
66e8db1
Add initialisation for RSDP reading
ryuukumar Apr 8, 2026
5989566
Add init_and_return and some extra verification/fixes
ryuukumar Apr 8, 2026
782125e
Add init for rsdp and getters
ryuukumar Apr 9, 2026
c62b2b1
Merge remote-tracking branch 'origin/main' into acpi/rsdp
ryuukumar Apr 10, 2026
b7c3629
Merge branch 'acpi/rsdp' of github.com:ryuukumar/cos into acpi/rsdp
ryuukumar Apr 10, 2026
3b638ed
Merge remote-tracking branch 'origin/main' into acpi/rsdp
ryuukumar Apr 10, 2026
5679f52
Stop errors on BSD
ryuukumar Apr 11, 2026
37fc507
Add SDT header definition
ryuukumar Apr 11, 2026
01ff351
Move sdt header to common location and add rsdt definition
ryuukumar Apr 11, 2026
6e328b7
Add get_vaddr_from_phys_addr
ryuukumar Apr 11, 2026
fa80549
Format + fix
ryuukumar Apr 11, 2026
f21deca
sdt_header -> acpi_common, add acpi_allocate_table declaration
ryuukumar Apr 13, 2026
8afbdbf
Add a get_hhdm_offset util
ryuukumar Apr 13, 2026
38d702d
Implement acpi_allocate_table
ryuukumar Apr 13, 2026
472d2b3
Fix header for RSDT
ryuukumar Apr 13, 2026
54b9dca
Add utils acpi_validate_checksum and acpi_data_length
ryuukumar Apr 13, 2026
a7e00ee
Fix checksum calculation
ryuukumar Apr 13, 2026
cfe2906
Add init_rsdt and implement it
ryuukumar Apr 13, 2026
c2e0955
Remove unused stuff
ryuukumar Apr 13, 2026
780fdaa
Also verify checksum for RSDT
ryuukumar Apr 13, 2026
521d22d
Initialise the rsdt
ryuukumar Apr 13, 2026
1b2e75d
Group init script
ryuukumar Apr 13, 2026
a64f98f
Add FADT definition
ryuukumar Apr 13, 2026
dad9416
Initialise FADT and allow getting a copy
ryuukumar Apr 13, 2026
e0b938e
Check if FADT is null before copying it over
ryuukumar Apr 13, 2026
f3a3ea3
Switch to pragma once consistently
ryuukumar Apr 13, 2026
029a447
Spaces -> tabs on one line
ryuukumar Apr 13, 2026
cc3fc79
Fix imports
ryuukumar Apr 13, 2026
a037753
Reduce a line
ryuukumar Apr 13, 2026
db708a3
Revert because it was used
ryuukumar Apr 13, 2026
4c9bb62
Return the actual fadt instead of copy
ryuukumar Apr 14, 2026
a08129a
Add defintions for a basic MADT
ryuukumar Apr 14, 2026
5c928e1
Implement some MADT parsing and wire it up
ryuukumar Apr 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions kernel/include/kernel/acpi/acpi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once

#include <stdint.h>

void init_acpi (uintptr_t rsdp_ptr);
31 changes: 31 additions & 0 deletions kernel/include/kernel/acpi/acpi_common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include <stdint.h>

#define FADT_IDENTIFIER "FACP"
#define MADT_IDENTIFIER "APIC"

typedef struct __attribute__ ((packed)) {
char signature[4];
uint32_t length;
uint8_t revision;
uint8_t checksum;
char oemid[6];
char oemTableId[8];
uint32_t oemRevision;
uint32_t creatorId;
uint32_t creatorRevision;
} SDT_header_t;

typedef struct __attribute__ ((packed)) {
uint8_t address_space;
uint8_t bit_width;
uint8_t bit_offset;
uint8_t access_size;
uint64_t address;
} ACPI_GAS_t;

SDT_header_t* acpi_allocate_table (uint32_t phys_address);

bool acpi_validate_checksum (SDT_header_t* header);
uint64_t acpi_data_length (SDT_header_t* header);
62 changes: 62 additions & 0 deletions kernel/include/kernel/acpi/fadt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#pragma once

#include <kernel/acpi/acpi_common.h>
#include <stdint.h>

typedef struct __attribute__ ((packed)) {
SDT_header_t header;
uint32_t firmware_ctrl;
uint32_t dsdt;
uint8_t reserved;
uint8_t preferred_power_management_profile;
uint16_t sci_interrupt;
uint32_t smi_command_port;
uint8_t acpi_enable;
uint8_t acpi_disable;
uint8_t s4bios_req;
uint8_t pstate_control;
uint32_t pm1a_event_block;
uint32_t pm1b_event_block;
uint32_t pm1a_control_block;
uint32_t pm1b_control_block;
uint32_t pm2_control_block;
uint32_t pm_timer_block;
uint32_t gpe0_block;
uint32_t gpe1_block;
uint8_t pm1_event_length;
uint8_t pm1_control_length;
uint8_t pm2_control_length;
uint8_t pm_timer_length;
uint8_t gpe0_length;
uint8_t gpe1_length;
uint8_t gpe1_base;
uint8_t c_state_control;
uint16_t worst_c2_latency;
uint16_t worst_c3_latency;
uint16_t flush_size;
uint16_t flush_stride;
uint8_t duty_offset;
uint8_t duty_width;
uint8_t day_alarm;
uint8_t month_alarm;
uint8_t century;
uint16_t boot_architecture_flags;
uint8_t reserved2;
uint32_t flags;
ACPI_GAS_t reset_reg;
uint8_t reset_value;
uint8_t reserved3[3];
uint64_t x_firmware_control;
uint64_t x_dsdt;
ACPI_GAS_t x_pm1a_event_block;
ACPI_GAS_t x_pm1b_event_block;
ACPI_GAS_t x_pm1a_control_block;
ACPI_GAS_t x_pm1b_control_block;
ACPI_GAS_t x_pm2_control_block;
ACPI_GAS_t x_pm_timer_block;
ACPI_GAS_t x_gpe0_block;
ACPI_GAS_t x_gpe1_block;
} FADT;

void init_fadt (SDT_header_t* header);
FADT* get_fadt (void);
91 changes: 91 additions & 0 deletions kernel/include/kernel/acpi/madt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#pragma once

#include <kernel/acpi/acpi_common.h>
#include <stdint.h>

typedef struct __attribute__ ((packed)) {
uint8_t entry_type;
uint8_t record_length;
} MADT_entry_header_t;

typedef struct __attribute__ ((packed)) {
MADT_entry_header_t entry_header;
uint8_t acpi_proc_id;
uint8_t acpi_id;
uint32_t flags;
} MADT_PL_APIC_t;

typedef struct __attribute__ ((packed)) {
MADT_entry_header_t entry_header;
uint8_t apic_id;
uint8_t reserved;
uint32_t apic_address;
uint32_t flags;
} MADT_IO_APIC_t;

typedef struct __attribute__ ((packed)) {
MADT_entry_header_t entry_header;
uint8_t bus_source;
uint8_t irq_source;
uint32_t global_sys_int;
uint16_t flags;
} MADT_IO_APIC_ISO_t;

typedef struct __attribute__ ((packed)) {
MADT_entry_header_t entry_header;
uint8_t nmi_source;
uint8_t reserved;
uint16_t flags;
uint32_t global_sys_int;
} MADT_IO_APIC_NM_t;

typedef struct __attribute__ ((packed)) {
MADT_entry_header_t entry_header;
uint8_t acpi_proc_id;
uint16_t flags;
uint8_t lint;
} MADT_PL_APIC_NM_t;

typedef struct __attribute__ ((packed)) {
MADT_entry_header_t entry_header;
uint16_t reserved;
uint64_t apic_addr_64;
} MADT_PL_APIC_AO_t;

typedef struct __attribute__ ((packed)) {
MADT_entry_header_t entry_header;
uint16_t reserved;
uint32_t acpi_proc_id;
uint32_t flags;
uint32_t acpi_id;
} MADT_PL_APIC_x2_t;

typedef union {
MADT_entry_header_t header_only;
MADT_IO_APIC_ISO_t io_apic_iso;
MADT_IO_APIC_NM_t io_apic_nm;
MADT_IO_APIC_t io_apic;
MADT_PL_APIC_AO_t pl_apic_ao;
MADT_PL_APIC_NM_t pl_apic_nm;
MADT_PL_APIC_t pl_apic;
MADT_PL_APIC_x2_t pl_apic_x2;
} MADT_entry_t;

constexpr uint8_t MADT_PL_APIC_ENTRY = 0;
constexpr uint8_t MADT_IO_APIC_ENTRY = 1;
constexpr uint8_t MADT_IO_APIC_ISO_ENTRY = 2;
constexpr uint8_t MADT_IO_APIC_NM_ENTRY = 3;
constexpr uint8_t MADT_PL_APIC_NM_ENTRY = 4;
constexpr uint8_t MADT_PL_APIC_AO_ENTRY = 5;
constexpr uint8_t MADT_PL_APIC_X2_ENTRY = 9;

typedef struct __attribute__ ((packed)) {
SDT_header_t header;
uint32_t local_apic_addr;
uint32_t flags;
} MADT_header_t;

void init_madt (SDT_header_t* header);

MADT_header_t* get_madt_header (void);
MADT_entry_t* get_nth_entry (size_t n);
33 changes: 33 additions & 0 deletions kernel/include/kernel/acpi/rsdp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once

#include <stdint.h>

typedef struct __attribute__ ((packed)) {
char signature[8];
uint8_t checksum;
char oemid[6];
uint8_t revision;
uint32_t rsdt_address;
} RSDP_t;

typedef struct __attribute__ ((packed)) {
char signature[8];
uint8_t checksum;
char oemid[6];
uint8_t revision;
uint32_t rsdt_address;
uint32_t length;
uint64_t xsdt_address;
uint8_t extended_checksum;
uint8_t reserved[3];
} XSDP_t;

void* init_rsdp (uintptr_t rsdp_base_ptr, uint64_t hhdm_offset);

bool is_init (void);
bool is_rsdp (void);
bool is_xsdp (void);

uint8_t get_rsdp_revision ();
RSDP_t* get_rsdp ();
XSDP_t* get_xsdp ();
3 changes: 3 additions & 0 deletions kernel/include/kernel/acpi/rsdt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once

void init_rsdt (uint32_t rsdt_base_ptr);
7 changes: 5 additions & 2 deletions kernel/include/kernel/memmgt.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
#include <stddef.h>
#include <stdint.h>

#define PAGE_SIZE 4096ull
#define PAGE_SIZE 4096ull
#define ALIGN_PAGE_DOWN(x) ((x) & ~(PAGE_SIZE - 1))

typedef struct {
uint64_t present : 1; // Page present in memory
Expand Down Expand Up @@ -91,7 +92,8 @@ uint64_t read_cr3 (void);
void write_cr3 (uint64_t new_value);

vaddr_t get_vaddr_t_from_ptr (void* ptr);
void* get_vaddr_from_frame (uint64_t phys_address);
void* get_vaddr_from_frame (uint64_t phys_frame);
void* get_vaddr_from_phys_addr (uint64_t phys_address);
void* vaddr_t_to_ptr (vaddr_t* virtual_addr);

void* alloc_vpages (size_t req_count, bool user);
Expand All @@ -108,6 +110,7 @@ void init_memmgt (uint64_t, struct limine_memmap_response*);
void walk_pagetable (void);
void* get_paddr (void* vaddr);
uintptr_t get_kernel_cr3 (void);
uint64_t get_hhdm_offset (void);

int clone_user_memory (uint64_t cr3_src, uint64_t* cr3_dest);

Expand Down
28 changes: 28 additions & 0 deletions kernel/src/kernel/acpi/acpi_allocate_table.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include <kernel/acpi/acpi_common.h>
#include <kernel/memmgt.h>

/*!
* Allocate all the memory occupied by the ACPI table at the given physical address.
* @param phys_address the physical address of the ACPI table
* @return pointer to the first byte of the ACPI table in virtual memory as SDT_header_t
*/
SDT_header_t* acpi_allocate_table (uint32_t phys_address) {
// stage 1: allocate just enough to read the header
uint64_t table_base_ptr_64 = (uint64_t)phys_address;
uint64_t hhdm_offset = get_hhdm_offset ();
paddr_t table_base_frame = (paddr_t)ALIGN_PAGE_DOWN (table_base_ptr_64);
table_base_ptr_64 += hhdm_offset;

vaddr_t table_vaddr_start = get_vaddr_t_from_ptr ((void*)ALIGN_PAGE_DOWN (table_base_ptr_64));
vaddr_t table_vaddr_end =
get_vaddr_t_from_ptr ((void*)ALIGN_PAGE_DOWN (table_base_ptr_64 + sizeof (SDT_header_t)));
alloc_all_vpages_in_range (table_vaddr_start, table_vaddr_end, table_base_frame);

// stage 2: allocate enough to read the entire table
SDT_header_t* table_ptr = (SDT_header_t*)table_base_ptr_64;
table_vaddr_end =
get_vaddr_t_from_ptr ((void*)ALIGN_PAGE_DOWN (table_base_ptr_64 + table_ptr->length));
alloc_all_vpages_in_range (table_vaddr_start, table_vaddr_end, table_base_frame);

return table_ptr;
}
9 changes: 9 additions & 0 deletions kernel/src/kernel/acpi/acpi_data_length.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include <kernel/acpi/acpi_common.h>

/*!
* Returns the number of bytes occupied by the ACPI table, excepting the bytes occupied by its
* common header. Behavior undefined if header points to unallocated memory.
* @param header the allocated SDT_header_t (typically returned from acpi_allocate_table)
* @return size of ACPI data in bytes
*/
uint64_t acpi_data_length (SDT_header_t* header) { return header->length - sizeof (SDT_header_t); }
14 changes: 14 additions & 0 deletions kernel/src/kernel/acpi/acpi_validate_checksum.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include <kernel/acpi/acpi_common.h>

/*!
* Validates the ACPI table with the present checksum. Behavior undefined if header points to
* unallocated memory.
* @param header the allocated SDT_header_t (typically returned from acpi_allocate_table)
* @return true if ACPI table checksum is valid, false otherwise
*/
bool acpi_validate_checksum (SDT_header_t* header) {
uint8_t checksum = 0;
for (uint64_t i = 0; i < header->length; i++)
checksum += ((uint8_t*)header)[i];
return checksum == 0;
}
15 changes: 15 additions & 0 deletions kernel/src/kernel/acpi/fadt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include <kclib/string.h>
#include <kernel/acpi/acpi_common.h>
#include <kernel/acpi/fadt.h>
#include <liballoc/liballoc.h>

static FADT* cp_fadt = nullptr;

void init_fadt (SDT_header_t* header) {
cp_fadt = kmalloc (sizeof (FADT));
if (!cp_fadt) return;

kmemcpy ((void*)cp_fadt, (void*)header, sizeof (FADT));
}

FADT* get_fadt (void) { return cp_fadt; }
9 changes: 9 additions & 0 deletions kernel/src/kernel/acpi/init_acpi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include <kernel/acpi/acpi.h>
#include <kernel/acpi/rsdp.h>
#include <kernel/acpi/rsdt.h>
#include <kernel/memmgt.h>

void init_acpi (uintptr_t rsdp_ptr) {
RSDP_t* rsdp_ptr_vmm = (RSDP_t*)init_rsdp (rsdp_ptr, get_hhdm_offset ());
init_rsdt (rsdp_ptr_vmm->rsdt_address);
}
28 changes: 28 additions & 0 deletions kernel/src/kernel/acpi/madt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include <kclib/string.h>
#include <kernel/acpi/madt.h>
#include <liballoc/liballoc.h>

static MADT_header_t* cp_madt = nullptr;

void init_madt (SDT_header_t* header) {
uint64_t madt_len = header->length;
cp_madt = kmalloc (madt_len);
if (!cp_madt) return;

kmemcpy ((void*)cp_madt, (void*)header, madt_len);
}

MADT_header_t* get_madt_header (void) { return cp_madt; }

MADT_entry_t* get_nth_entry (size_t n) {
if (!cp_madt) return nullptr;
MADT_entry_t* entry = (MADT_entry_t*)&cp_madt[1];

for (size_t i = 0; (char*)entry - (char*)cp_madt < cp_madt->header.length; i++) {
if (i == n) return entry;
if (entry->header_only.record_length == 0) return nullptr;
entry = (MADT_entry_t*)(((char*)entry) + entry->header_only.record_length);
}

return nullptr;
}
Loading
Loading