Hackintosh Power Management: CPU, GPU, and Sleep for Legacy macOS

Fix Hackintosh sleep, CPU idle frequency, and GPU power draw on legacy macOS (10.6–10.15). Step-by-step guide to XCPM, SSDT-PM, AGPM injection, and sleep troubleshooting.

A Hackintosh that boots macOS without issues but drains battery while sleeping, runs the CPU at idle frequencies higher than expected, or fails to wake from sleep is almost always suffering from incomplete power management configuration. On real Macs, the firmware and macOS collaborate to control processor P-states and C-states, GPU voltage transitions, and device sleep states. On a custom PC, these mechanisms must be replicated through ACPI patches, SSDT injections, and correct bootloader settings. This article walks through the essential layers of power management for legacy macOS versions (10.6 through 10.15), focusing on CPU, GPU, and system sleep.

CPU Power Management: XCPM vs. Legacy ACPI

Starting with Ivy Bridge (3rd‑gen Core), macOS uses XCPM (XNU’s CPU Power Management) instead of the older ACPI-based speedstep. For Sandy Bridge and older, you must inject P-state and C-state tables via SSDT. The tool ssdtPRGen.sh (by Pike R. Alpha) remains the standard method to generate a custom SSDT for your processor. Run it on your target system with the -cpus 1 flag if you have an odd core count, and place the resulting SSDT.aml into EFI/OC/ACPI (OpenCore) or /EFI/Clover/ACPI/patched (Clover).

For Haswell and newer, XCPM is enabled automatically when the bootloader sets xcpm=1 (or equivalent). However, missing or incorrect _PSS tables can cause macOS to fall back to a single P-state, resulting in constant high frequency and excessive heat. Verify XCPM is active by running sysctl -n machdep.xcpm.mode in Terminal. A return of 1 confirms XCPM is managing the CPU. If you see 0, check your ACPI tables and ensure the plugin-type property is injected for the CPU object (typically _SB.PR00).

Generating SSDT-PM for Sandy Bridge and Ivy Bridge

For CPUs older than Haswell, the ssdtPRGen.sh script reads your processor’s frequency tables and outputs a custom SSDT. Run it as root and ignore warnings about unsupported board IDs — those affect only Mac model matching, not power management. After placing the SSDT, add the following to your bootloader configuration:

  • Clover: set GeneratePStates and GenerateCStates to Yes under ACPI/SSDT.
  • OpenCore: enable AppleCpuPmCfgLock (if your BIOS locks MSR 0xE2) and AppleXcpmCfgLock for Haswell+.

Be aware that generating C-states from a generic script can produce too many states, causing instability. Manually pruning the SSDT to retain only the deepest C-states (C3, C6, C7) is a safer approach for older motherboards.

GPU Power Management and Sleep

Graphics cards require AGPM (Apple Graphics Power Management) injection to transition between performance states and to properly enter sleep. Without it, the GPU may stay at full clock, increasing power draw and preventing the system from reaching S3 sleep. For Intel HD Graphics (Ivy Bridge, Haswell, Broadwell), the framebuffer injection must include the correct ig-platform-id and device-id to match a real Mac’s power profile. A detailed walkthrough for these iGPUs is available in the Intel HD Graphics on Legacy Hackintosh: A Practical Guide for Ivy Bridge, Haswell, and Broadwell.

For NVIDIA Kepler cards (GTX 6xx/7xx), AGPM injection is handled via the NVIDIA kernel extension or a custom SSDT that populates AGPM keys. Common symptoms of missing GPU power management include a black screen after wake, a fan that never idles down, or a system that reboots instead of sleeping. The AppleGraphicsControl.kext must be patched to accept the GPU’s device ID if it is not natively supported. For Maxwell and Pascal, Web Drivers handle power management, but only up to macOS High Sierra; Mojave and later drop NVIDIA support entirely.

System Sleep and Wake Troubleshooting

Sleep (S3) requires all devices to report readiness. Use pmset -g assertions to see what is preventing sleep. Common culprits:

  • USB devices — disable “Allow wake from USB” in BIOS or inject SSDT-USBW.aml to limit wake sources.
  • Ethernet — some Realtek and Intel NICs keep the system awake if Wake-on-LAN is enabled in macOS. Disable it with pmset -a womp 0.
  • Audio codecs — AppleHDA can hold a power assertion. Use log show --predicate 'eventMessage contains "power"' --last 1h to inspect sleep failures.

ACPI patches for _PTS (Prepare To Sleep) and _WAK (Wake) are often required on boards with custom DSDTs. A typical fix involves renaming _PTS to XPTS and providing a custom method that calls Notify(_SB.PCI0.LPC, 0x80) to ensure the LPC controller enters the correct state. This is especially common on H67 and Z68 chipsets.

Debugging with IORegistryExplorer

After applying CPU and GPU patches, verify that the system’s power plane is populated. Open IORegistryExplorer and look for IOPlatformPlugin (for CPU) and AppleGraphicsPowerManagement (for GPU). If these entries are missing, the kernel is not loading the respective power management kexts. Check your bootloader’s Kernel and AddProperties sections for any blacklisted kexts or incorrect device properties.

For legacy macOS versions (10.9–10.11), the NullCPUPowerManagement.kext is sometimes used as a temporary workaround when ACPI tables are incomplete. This kext disables all CPU power management, which is acceptable only for testing. Long-term use leads to high power draw and thermal throttling. Remove it once a proper SSDT is in place.

Tools and Final Verification

Beyond pmset and IORegistryExplorer, the following utilities help confirm power management:

  • Intel Power Gadget — shows real-time CPU frequency and package power. Idle frequency should drop below 1 GHz on modern CPUs.
  • MSRDumper — dumps MSR register values to confirm P-state transitions.
  • log stream –predicate 'process contains "kernel"' — captures kernel messages during sleep/wake cycles.

One concrete step to validate your setup: after a clean boot, run sysctl -n machdep.xcpm.mode and verify it returns 1. Then open IORegistryExplorer and search for IOPlatformPlugin. If both checks pass, your CPU power management is correctly configured. For sleep, execute pmset sleepnow from Terminal and wait 10 seconds before waking with a keyboard press. If the system resumes without errors, your ACPI patches are sufficient. If it reboots or hangs, examine the log for a specific device that failed to power down.