11#include <kernel.h>
22#include <uacpi/uacpi.h>
3+ #include <uacpi/acpi.h>
4+ #include <uacpi/helpers.h>
35#include <uacpi/namespace.h>
46#include <uacpi/resources.h>
57#include <stdatomic.h>
68#include "uacpi/context.h"
9+ #include "uacpi/tables.h"
710
811volatile struct limine_rsdp_request rsdp_request = {
912 .id = LIMINE_RSDP_REQUEST ,
@@ -84,6 +87,32 @@ void init_uacpi(void) {
8487 preboot_fail ("uACPI namespace init failed" );
8588 }
8689
90+ struct acpi_fadt * fadt = NULL ;
91+ st = uacpi_table_fadt (& fadt );
92+ if (!uacpi_unlikely_error (st ) && fadt ) {
93+ struct acpi_gas * gas = & fadt -> x_pm_tmr_blk ;
94+
95+ if (gas -> address_space_id == 1 ) {
96+ // System I/O
97+ pm_timer_port = (uint16_t )gas -> address ;
98+ pm_timer_is_io = true;
99+ dprintf ("Using PM timer IO port 0x%04lx\n" , pm_timer_port );
100+ } else if (gas -> address_space_id == 0 ) {
101+ // System memory (MMIO)
102+ pm_timer_port = (uintptr_t )gas -> address ;
103+ pm_timer_is_io = false;
104+ dprintf ("Using PM timer MMIO 0x%lx\n" , pm_timer_port );
105+ } else {
106+ dprintf ("Unsupported PM timer space_id %u\n" , gas -> address_space_id );
107+ pm_timer_port = 0 ;
108+ }
109+
110+ pm_timer_32bit = (gas -> register_bit_width == 32 );
111+ } else {
112+ dprintf ("FADT not found, no PM timer available\n" );
113+ pm_timer_port = 0 ;
114+ }
115+
87116 dprintf ("init_uacpi done. Peak allocation: %lu Current allocation: %lu\n" , acpi_pool .peak_bytes , acpi_pool .current_bytes );
88117}
89118
@@ -114,10 +143,6 @@ uint16_t get_cpu_count() {
114143 return numcore ;
115144}
116145
117- uint64_t get_local_apic () {
118- return (uint64_t ) lapic_ptr ;
119- }
120-
121146uint16_t get_ioapic_count () {
122147 return numioapic ;
123148}
@@ -214,48 +239,6 @@ void init_acpi() {
214239 }
215240 }
216241 break ;
217- } else if (memcmp (acpi_table , "FACP" , 4 ) == 0 ) {
218-
219- uint32_t pm_tmr_blk = * ((uint32_t * )(acpi_table + 0x40 ));
220- uint32_t flags = * ((uint32_t * )(acpi_table + 112 ));
221- bool timer_is_32bit = (flags & (1 << 8 )) != 0 ;
222-
223- dprintf ("PM timer block at 0x%x (%s)\n" ,
224- pm_tmr_blk ,
225- timer_is_32bit ? "32-bit" : "24-bit" );
226-
227- struct acpi_gas {
228- uint8_t space_id ;
229- uint8_t bit_width ;
230- uint8_t bit_offset ;
231- uint8_t access_size ;
232- uint64_t address ;
233- } __attribute__((packed ));
234-
235- struct acpi_gas * xpm = (struct acpi_gas * )(acpi_table + 208 );
236-
237- if (xpm -> address != 0 ) {
238- if (xpm -> space_id == 1 ) {
239- // I/O space
240- pm_timer_port = (uint16_t )xpm -> address ;
241- pm_timer_is_io = true;
242- dprintf ("Using X_PM_TMR_BLK IO port 0x%04lx\n" , pm_timer_port );
243- } else if (xpm -> space_id == 0 ) {
244- // System memory (MMIO)
245- pm_timer_port = (uintptr_t )xpm -> address ;
246- pm_timer_is_io = false;
247- dprintf ("Using X_PM_TMR_BLK MMIO 0x%lx\n" , pm_timer_port );
248- } else {
249- dprintf ("Unsupported X_PM_TMR_BLK space_id %d\n" , xpm -> space_id );
250- pm_timer_port = pm_tmr_blk ;
251- pm_timer_is_io = true;
252- }
253- } else {
254- // fallback to legacy PM_TMR_BLK
255- pm_timer_port = pm_tmr_blk ;
256- pm_timer_is_io = true;
257- }
258- pm_timer_32bit = timer_is_32bit ;
259242 }
260243 }
261244 enumerate_all_gsis ();
@@ -294,7 +277,7 @@ uint32_t pm_timer_read(void) {
294277 uint32_t mask = pm_timer_32bit ? 0xFFFFFFFF : 0xFFFFFF ;
295278
296279 if (pm_timer_is_io ) {
297- // I/O port read
280+ // Always use a 32-bit port read
298281 return inl ((uint16_t )pm_timer_port ) & mask ;
299282 } else {
300283 // MMIO read
@@ -303,6 +286,7 @@ uint32_t pm_timer_read(void) {
303286 }
304287}
305288
289+
306290bool pm_timer_available (void ) {
307291 return pm_timer_port != 0 ;
308292}
0 commit comments