feat: power down dGPUs on hybrid graphics laptops

This commit is contained in:
daniel committed 2026-10-01 13:09:26 +02:00
1 parent 7f12e1a150
commit 24f88ec4c6
23 files changed
+4325 -1130

No files matched your search

+29
View File
@@ -365,6 +365,35 @@ namespace Timekeeping {
Hal::HaltWithInterruptsDisabled();
}
void BusyWaitUs(uint64_t us) {
// An I/O write to port 0x80 is an ISA-bus cycle of roughly a
// microsecond on every chipset since the 486, and never shorter.
for (uint64_t i = 0; i < us; i++)
Io::IoPortWait();
}
void BusyWaitMs(uint64_t ms) {
if (ms == 0) return;
uint64_t flags;
asm volatile("pushfq; pop %0" : "=r"(flags));
bool ticking = g_ticksPerMs != 0 && (flags & (1 << 9));
// Either clock alone is long enough, so stop at whichever says so
// first. The tick is the accurate one; the port writes bound the wait
// when the tick is not running yet (or is masked), so this can never
// hang on a timer that does not fire. One extra tick of slack because
// the first may already be nearly over.
uint64_t start = g_tickCount.load(std::memory_order_relaxed);
uint64_t portBudget = (ms + 1) * 1000;
for (uint64_t spins = 0; spins < portBudget; spins++) {
if (ticking &&
g_tickCount.load(std::memory_order_relaxed) - start >= ms + 1)
return;
Io::IoPortWait();
}
}
void Sleep(uint64_t ms) {
if (ms == 0) return;
// Use BlockForSleep to properly deschedule the process instead