22#include "Console.h"
33#include "Io.h"
44#include "MemOps.h"
5+ #include "Scheduler.h"
56#include "StringOps.h"
67#include "VMem.h"
78#include "TSC.h"
9+ #include "VFS.h"
810
911static ACPIFADT * g_fadt = NULL ;
1012static bool g_acpi_initialized = false;
@@ -47,128 +49,126 @@ static bool ValidateChecksum(void* table, uint32_t length) {
4749
4850// Map ACPI table to virtual memory
4951static void * MapACPITable (uint32_t phys_addr , uint32_t size ) {
50- // Align to page boundaries
51- uint32_t aligned_addr = phys_addr & ~0xFFF ;
52- uint32_t offset = phys_addr - aligned_addr ;
53- uint32_t aligned_size = ((size + offset + 0xFFF ) & ~0xFFF );
54-
52+ uint64_t aligned_addr = phys_addr & ~0xFFF ;
53+ uint64_t offset = phys_addr - aligned_addr ;
54+ uint64_t aligned_size = ((size + offset + 0xFFF ) & ~0xFFF );
55+
5556 void * virt_addr = VMemAlloc (aligned_size );
56- if (!virt_addr ) return NULL ;
57-
57+ if (!virt_addr ) {
58+ PrintKernelError ("ACPI: Failed to allocate virtual memory for ACPI table\n" );
59+ return NULL ;
60+ }
61+
5862 if (VMemUnmap ((uint64_t )virt_addr , aligned_size ) != VMEM_SUCCESS ) {
5963 VMemFree (virt_addr , aligned_size );
64+ PrintKernelError ("ACPI: Failed to unmap virtual memory for ACPI table\n" );
6065 return NULL ;
6166 }
62-
67+
6368 if (VMemMapMMIO ((uint64_t )virt_addr , aligned_addr , aligned_size , PAGE_WRITABLE | PAGE_NOCACHE ) != VMEM_SUCCESS ) {
64- VMemFree (virt_addr , aligned_size );
69+ // No need to free here as VMemMapMMIO should handle cleanup on failure
70+ PrintKernelError ("ACPI: Failed to map MMIO for ACPI table\n" );
6571 return NULL ;
6672 }
67-
73+
6874 return (uint8_t * )virt_addr + offset ;
6975}
7076
77+ static ACPIRSDT * g_rsdt = NULL ;
78+
79+ void * AcpiFindTable (const char * signature ) {
80+ if (!g_rsdt ) {
81+ return NULL ;
82+ }
83+
84+ uint32_t entries = (g_rsdt -> header .length - sizeof (ACPISDTHeader )) / 4 ;
85+ for (uint32_t i = 0 ; i < entries ; i ++ ) {
86+ ACPISDTHeader * header = (ACPISDTHeader * )MapACPITable (g_rsdt -> table_pointers [i ], sizeof (ACPISDTHeader ));
87+ if (!header ) {
88+ continue ;
89+ }
90+
91+ if (FastMemcmp (header -> signature , signature , 4 ) == 0 ) {
92+ void * table = MapACPITable (g_rsdt -> table_pointers [i ], header -> length );
93+ VMemUnmap ((uint64_t )header - (g_rsdt -> table_pointers [i ] & 0xFFF ), ((sizeof (ACPISDTHeader ) + (g_rsdt -> table_pointers [i ] & 0xFFF ) + 0xFFF ) & ~0xFFF ));
94+ return table ;
95+ }
96+
97+ VMemUnmap ((uint64_t )header - (g_rsdt -> table_pointers [i ] & 0xFFF ), ((sizeof (ACPISDTHeader ) + (g_rsdt -> table_pointers [i ] & 0xFFF ) + 0xFFF ) & ~0xFFF ));
98+ }
99+
100+ return NULL ;
101+ }
102+
71103bool ACPIInit (void ) {
72104 PrintKernel ("ACPI: Initializing ACPI subsystem...\n" );
73-
74- // Find RSDP
105+
75106 ACPIRSDPv1 * rsdp = FindRSDP ();
76107 if (!rsdp ) {
77108 PrintKernelError ("ACPI: RSDP not found\n" );
78109 return false;
79110 }
80-
81- PrintKernel ("ACPI: Found RSDP at 0x" );
82- PrintKernelHex ((uint64_t )rsdp );
83- PrintKernel ("\n" );
84-
85- // Validate RSDP checksum
111+
86112 if (!ValidateChecksum (rsdp , sizeof (ACPIRSDPv1 ))) {
87113 PrintKernelError ("ACPI: Invalid RSDP checksum\n" );
88114 return false;
89115 }
90116
91- ACPIRSDT * rsdt = (ACPIRSDT * )MapACPITable (rsdp -> rsdt_address ,
92- sizeof (ACPISDTHeader ));
93- if (!rsdt ) {
94- PrintKernelError ("ACPI: Failed to map RSDT\n" );
117+ g_rsdt = (ACPIRSDT * )MapACPITable (rsdp -> rsdt_address , sizeof (ACPISDTHeader ));
118+ if (!g_rsdt ) {
119+ PrintKernelError ("ACPI: Failed to map RSDT header\n" );
95120 return false;
96121 }
97- // Validate RSDT signature
98- if (FastMemcmp (rsdt -> header .signature , ACPI_RSDT_SIG , 4 ) != 0 ) {
122+
123+ if (FastMemcmp (g_rsdt -> header .signature , ACPI_RSDT_SIG , 4 ) != 0 ) {
99124 PrintKernelError ("ACPI: Invalid RSDT signature\n" );
100- // Clean up the initial header‐only mapping
101- VMemUnmap ((uint64_t )rsdt - (rsdp -> rsdt_address & 0xFFF ),
102- ((sizeof (ACPISDTHeader ) + (rsdp -> rsdt_address & 0xFFF ) + 0xFFF )
103- & ~0xFFF ));
125+ VMemUnmap ((uint64_t )g_rsdt - (rsdp -> rsdt_address & 0xFFF ), ((sizeof (ACPISDTHeader ) + (rsdp -> rsdt_address & 0xFFF ) + 0xFFF ) & ~0xFFF ));
104126 return false;
105127 }
106- // Remap with the full table length
107- uint32_t rsdt_size = rsdt -> header .length ;
108- // Remember the old header mapping so we can free it afterward
109- void * old_rsdt = rsdt ;
110- uint32_t old_offset = rsdp -> rsdt_address & 0xFFF ;
111- rsdt = (ACPIRSDT * )MapACPITable (rsdp -> rsdt_address , rsdt_size );
112- // Now unmap the temporary header‐only region
113- VMemUnmap ((uint64_t )old_rsdt - old_offset ,
114- ((sizeof (ACPISDTHeader ) + old_offset + 0xFFF ) & ~0xFFF ));
115-
116- PrintKernel ("ACPI: RSDT mapped, length=" );
117- PrintKernelInt (rsdt_size );
118- PrintKernel ("\n" );
119-
120- // Find FADT
121- uint32_t entries = (rsdt_size - sizeof (ACPISDTHeader )) / 4 ;
122- for (uint32_t i = 0 ; i < entries ; i ++ ) {
123- ACPISDTHeader * header = (ACPISDTHeader * )MapACPITable (
124- rsdt -> table_pointers [i ],
125- sizeof (ACPISDTHeader )
126- );
127- if (!header ) continue ;
128-
129- bool is_fadt = FastMemcmp (header -> signature , ACPI_FADT_SIG , 4 ) == 0 ;
130- uint32_t table_length = header -> length ;
131- uint32_t header_offset = rsdt -> table_pointers [i ] & 0xFFF ;
132-
133- // Unmap the header mapping now that we've inspected it
134- VMemUnmap (
135- (uint64_t )header - header_offset ,
136- ( (sizeof (ACPISDTHeader ) + header_offset + 0xFFF ) & ~0xFFF )
137- );
138-
139- if (is_fadt ) {
140- PrintKernel ("ACPI: Found FADT\n" );
141- g_fadt = (ACPIFADT * )MapACPITable (
142- rsdt -> table_pointers [i ],
143- table_length
144- );
145- break ;
146- }
128+
129+ uint32_t rsdt_size = g_rsdt -> header .length ;
130+ VMemUnmap ((uint64_t )g_rsdt - (rsdp -> rsdt_address & 0xFFF ), ((sizeof (ACPISDTHeader ) + (rsdp -> rsdt_address & 0xFFF ) + 0xFFF ) & ~0xFFF ));
131+ g_rsdt = (ACPIRSDT * )MapACPITable (rsdp -> rsdt_address , rsdt_size );
132+ if (!g_rsdt ) {
133+ PrintKernelError ("ACPI: Failed to map full RSDT\n" );
134+ return false;
147135 }
148-
149- PrintKernelError ("ACPI: FADT not found or invalid\n" );
150- return false;
136+
137+ g_fadt = (ACPIFADT * )AcpiFindTable (ACPI_FADT_SIG );
138+ if (!g_fadt ) {
139+ PrintKernelError ("ACPI: FADT not found or invalid\n" );
140+ return false;
141+ }
142+
143+ g_acpi_initialized = true;
144+ PrintKernelSuccess ("ACPI: Subsystem initialized\n" );
145+ return true;
146+ }
147+
148+ void ACPIResetProcedure () {
149+ PrintKernel ("ACPI: Unmounting Filesystems...\n" );
150+ VfsUnmountAll ();
151+ PrintKernelSuccess ("ACPI: Filesystems unmounted\n" );
152+
153+ PrintKernel ("ACPI: Stopping all processes and services...\n" );
154+ KillAllProcess ("SHUTDOWN" );
155+ PrintKernelSuccess ("ACPI: All processes and services stopped\n" );
151156}
152157
153158void ACPIShutdown (void ) {
154- if (!g_acpi_initialized || !g_fadt ) {
155- PrintKernel ("ACPI: Shutdown not available, using fallback\n" );
156- outw (0x604 , 0x2000 );
157- return ;
158- }
159-
160159 PrintKernel ("ACPI: Initiating shutdown...\n" );
161160
162161 // Enable ACPI mode if needed
163162 if (g_fadt -> smi_command_port && g_fadt -> acpi_enable ) {
164163 PrintKernel ("ACPI: Enabling ACPI mode via SMI\n" );
165164 outb (g_fadt -> smi_command_port , g_fadt -> acpi_enable );
166165 }
167-
166+
167+ ACPIResetProcedure ();
168+
168169 // Try multiple shutdown methods
169- uint16_t shutdown_values [] = {0x2000 , 0x3C00 , 0x1400 , 0x0000 };
170-
171170 for (int i = 0 ; i < 4 ; i ++ ) {
171+ const uint16_t shutdown_values [] = {0x2000 , 0x3C00 , 0x1400 , 0x0000 };
172172 PrintKernel ("ACPI: Trying shutdown value 0x" );
173173 PrintKernelHex (shutdown_values [i ]);
174174 PrintKernel (" on port 0x" );
@@ -180,18 +180,17 @@ void ACPIShutdown(void) {
180180 // Wait a bit
181181 delay (10 );
182182 }
183-
184- // Fallback methods
185- PrintKernel ("ACPI: Trying QEMU shutdown\n" );
186- outw (0x604 , 0x2000 );
187-
183+
188184 PrintKernel ("ACPI: Trying Bochs shutdown\n" );
189185 outw (0xB004 , 0x2000 );
190186
191187 PrintKernelError ("ACPI: All shutdown methods failed\n" );
192188}
193189
194190void ACPIReboot (void ) {
191+
192+ ACPIResetProcedure ();
193+
195194 PrintKernel ("ACPI: Initiating reboot...\n" );
196195
197196 // Try keyboard controller reset
0 commit comments