feat: expanded ACPI support, initial support for S3 sleep

This commit is contained in:
2026-03-15 00:55:19 +01:00
parent 261b536041
commit 64c26f4288
39 changed files with 4403 additions and 59 deletions
+54
View File
@@ -640,4 +640,58 @@ namespace Drivers::Graphics::IntelGPU {
return g_fbPitch;
}
void Reinitialize() {
if (!g_initialized || !g_mmioBase) return;
KernelLogStream(INFO, "IntelGPU") << "Reinitializing display after S3 resume";
// 1. Re-enable PCI memory space and bus mastering. S3 resets the PCI
// command register, so MMIO writes to the GPU are silently dropped
// until we re-enable these bits.
Pci::EnableBusMaster(g_gpuInfo.pciBus, g_gpuInfo.pciDevice, g_gpuInfo.pciFunction);
KernelLogStream(DEBUG, "IntelGPU") << "PCI memory space and bus mastering re-enabled";
// 2. Disable VGA plane (firmware may have re-enabled it during POST)
DisableVga();
// 3. Reprogram GTT entries (hardware lost all GTT state during S3)
uint64_t pageCount = (g_fbSize + 0xFFF) / 0x1000;
if (g_gpuGen >= 8) {
volatile uint64_t* gtt64 = (volatile uint64_t*)g_gttBase;
for (uint64_t i = 0; i < pageCount; i++) {
gtt64[i] = MakeGttPte64(g_fbPhysBase + i * 0x1000);
}
// Flush GTT writes by reading back the last entry
(void)gtt64[pageCount - 1];
} else {
volatile uint32_t* gtt32 = (volatile uint32_t*)g_gttBase;
for (uint64_t i = 0; i < pageCount; i++) {
gtt32[i] = MakeGttPte32(g_fbPhysBase + i * 0x1000);
}
// Flush GTT writes by reading back the last entry
(void)gtt32[pageCount - 1];
}
// 4. Re-enable the display pipe. After S3, the pipe may be off even
// though the firmware lit the backlight. Wait for it to become
// active before programming the display plane.
uint32_t pipeConf = ReadReg(PIPEACONF);
if (!(pipeConf & PIPECONF_ENABLE)) {
WriteReg(PIPEACONF, pipeConf | PIPECONF_ENABLE);
// Wait for pipe to become active (PIPECONF_STATE bit 30)
for (int i = 0; i < 100000; i++) {
if (ReadReg(PIPEACONF) & PIPECONF_STATE)
break;
asm volatile("pause");
}
}
// 5. Reprogram display plane to point at our GTT-mapped framebuffer
ProgramDisplayPlane();
KernelLogStream(OK, "IntelGPU") << "Display restored after S3 resume";
}
};
+3
View File
@@ -401,6 +401,9 @@ namespace Drivers::Graphics::IntelGPU {
// Check if an Intel GPU was found and initialized
bool IsInitialized();
// Restore display state after S3 resume (GTT entries, pipe, display plane)
void Reinitialize();
// Get detected GPU information
const GpuInfo* GetGpuInfo();
+25
View File
@@ -63,6 +63,31 @@ namespace Drivers::PS2 {
return g_DualChannel;
}
void Reinitialize() {
// Flush any stale data from the output buffer
FlushOutputBuffer();
// Re-enable both ports
SendCommand(CmdEnablePort1);
if (g_DualChannel) {
SendCommand(CmdEnablePort2);
}
// Re-enable interrupts and translation in the config byte
SendCommand(CmdReadConfig);
uint8_t config = ReadData();
config |= ConfigPort1Interrupt | ConfigPort1Translation;
if (g_DualChannel) {
config |= ConfigPort2Interrupt;
}
SendCommand(CmdWriteConfig);
SendData(config);
Kt::KernelLogStream(Kt::OK, "PS2") << "Controller re-enabled after S3 resume";
}
void Initialize() {
Kt::KernelLogStream(Kt::INFO, "PS2") << "Initializing PS/2 controller";
+5
View File
@@ -43,6 +43,11 @@ namespace Drivers::PS2 {
void Initialize();
// Lightweight re-enable after S3 resume. Skips the full self-test
// and port-test sequence (which can reset attached devices); just
// re-enables ports and interrupts so keyboard/mouse work again.
void Reinitialize();
void SendCommand(uint8_t command);
void SendData(uint8_t data);
uint8_t ReadData();