Fixing macOS Sleep/Wake on Legacy Hackintosh by Editing AGPM Kext
Step-by-step guide to edit AGPM kext for Hackintosh sleep/wake issues on Sierra through Mojave. Covers iGPU, AMD, NVIDIA, and dual-GPU setups.
Your Hackintosh goes to sleep but never wakes up? Chances are the AppleGraphicsPowerManagement (AGPM) kext is ignoring your GPU. This kext controls power states, and on non-Apple hardware its default plist rarely matches your exact graphics card. Editing AGPM can fix sleep/wake failures, graphical glitches, and kernel panics tied to GPU power transitions. Here's a step-by-step for Sierra through Mojave on Ivy Bridge, Haswell, and X79/X99 builds.
Understanding AGPM’s Role in GPU Power States
AGPM maps GPU models to specific power management profiles. Each profile defines voltage and frequency thresholds for idle, low-power, and high-performance states. macOS uses the IOKit personality AGPM to match your GPU’s device-id and vendor-id against entries in /System/Library/Extensions/AppleGraphicsPowerManagement.kext/Contents/Info.plist. If no match exists, the kext either applies a generic profile or disables power management entirely—resulting in a GPU that never sleeps or crashes when entering a low-power state.
The plist contains an array of Machines keys (e.g., Mac-F60DEB81FF30ACF6 for iMac14,2) and within each, a Vendor dictionary with sub-entries for hardware IDs like 0x01620007 (Ivy Bridge iGPU) or 0x100267b0 (AMD Radeon R9 280X). For a custom build, you must either add your board’s SMBIOS or override the GPU entry under an existing machine profile.
Identifying Your GPU’s IOKit Registry Entry
Before editing, locate the exact IOKit name and device ID. Open Terminal and run:
ioreg -l | grep -i "AGPM"
This returns a tree of GPU-related nodes. Look for entries like "IODeviceMemory" or "model" under @0 (display). For NVIDIA Kepler cards (e.g., GTX 660, GTX 770), the IOKit name is often GFX0; for AMD GCN cards (e.g., R9 280X, RX 560), it may be AMD Radeon XXXX. Note the device-id (e.g., 0x679a1002 for R9 280X) and vendor-id (0x1002 for AMD).
Cross-check that against the AGPM plist. Open the kext’s Info.plist in a plist editor (PlistEdit Pro or Xcode) and search for your device-id. If absent, you must add it.
Backing Up and Preparing the Kext
Always work on a copy. Use Terminal:
sudo cp -R /System/Library/Extensions/AppleGraphicsPowerManagement.kext ~/Desktop/AGPM_Backup
Then edit the live kext or, better, inject a modified plist via Clover’s KextsToPatch or a custom SSDT-AGPM.aml. Directly modifying /S/L/E is risky because SIP and system integrity verification can revert changes after updates. For Sierra and High Sierra, I recommend the Clover injection method: place a copy of the edited Info.plist inside a folder named AppleGraphicsPowerManagement.kext in /EFI/CLOVER/kexts/Other/, or use a config.plist patch.
Editing the Plist: Adding or Overriding a GPU Profile
Open the plist and navigate to IOKitPersonalities > AGPM > Machines. Choose a machine profile that matches your SMBIOS (e.g., Mac-F60DEB81FF30ACF6 for iMac14,2). Under Vendor, you’ll see entries like:
<key>0x01620007</key>
<dict>
<key>Heuristic</key>
<dict>...</dict>
<key>control-id</key>
<integer>18</integer>
</dict>
To plug in your GPU, create a new key with your device-id in the format 0x{device_id}{vendor_id} (e.g., 0x679a1002). Inside the dictionary, include:
- Heuristic: a dictionary containing
LogControl(integer, usually 0),MinPower(integer, often 0),ThresholdHigh(integer, e.g., 90),ThresholdLow(integer, e.g., 60). These values control when the GPU transitions between states; start with values from a similar GPU in the same plist. - control-id: integer, typically 18 for desktop GPUs. This links to the AppleMuxControl kext’s power management.
- Vendor (optional): a string like
0x8086for Intel or0x1002for AMD. Usually inferred from device-id, but explicit inclusion avoids ambiguity.
Example for an AMD R9 280X (device-id 0x679a, vendor 0x1002):
<key>0x679a1002</key>
<dict>
<key>Heuristic</key>
<dict>
<key>LogControl</key>
<integer>0</integer>
<key>MinPower</key>
<integer>0</integer>
<key>ThresholdHigh</key>
<integer>90</integer>
<key>ThresholdLow</key>
<integer>60</integer>
</dict>
<key>control-id</key>
<integer>18</integer>
</dict>
For iGPU users (e.g., HD 4000 on Ivy Bridge), the process is similar but the device-id format uses Intel’s vendor ID (0x8086). For HD 4000, the key would be 0x01628086. Copy the Heuristic values from an existing HD 4000 entry under a different machine profile, or use defaults: ThresholdHigh 80, ThresholdLow 60, MinPower 0.
Testing Without Reboot: Kernel Cache and Permissions
After editing, rebuild the kernel cache and repair permissions:
sudo touch /System/Library/Extensions
sudo kextcache -i /
Reboot. If the system fails to boot or the GPU exhibits artifacts, boot with -x (safe mode) and restore the backup. Common pitfalls include incorrect device-id byte order (big-endian vs little-endian) and missing control-id. Use the ioreg -l | grep -i agpm command again post-boot to verify your entry is loaded—look for "AGPM" under the GPU’s IOKit node.
For those on X79 or X99 dual-CPU builds, AGPM can interact with ACPI power states in unexpected ways. If sleep still fails after editing AGPM, the issue may lie in ACPI tables rather than GPU power management. Refer to the Guide 226: ACPI Fixes for Sandy Bridge and Haswell Hackintosh for debugging ACPI-related sleep problems. Additionally, Dropbox kernel panics on legacy systems sometimes mimic AGPM failures—see the Dropbox Kernel Panics on Legacy Hackintosh: Fixes for Sierra to Mojave guide if your crashes occur only when Dropbox syncs during sleep transitions.
Case Study: Fixing Sleep on an Ivy Bridge Hackintosh with HD 4000
On a Gigabyte GA-Z77-DS3H with an i5-3570K and HD 4000 iGPU, sleep worked under Mavericks but broke after upgrading to High Sierra. The console log showed AppleGraphicsPowerManagement: GPU 0 (0x0162) not found in list. The AGPM plist for SMBIOS iMac13,2 lacked an entry for HD 4000 (0x01628086). Adding the entry with control-id 18 and Heuristic values copied from the Mac-00BE6ED71E35EB86 (iMac13,1) profile resolved the issue. After the edit, sleep/wake cycles completed without a black screen or panic.
For discrete GPUs (NVIDIA Kepler, AMD GCN), the same principle applies but the device-id differs. A GTX 660 (device-id 0x0fc0, vendor 0x10de) requires key 0x0fc010de. Always verify the exact device-id from ioreg -l | grep "device-id" rather than relying on online lists, as OEM cards sometimes report alternative IDs.
If you're running dual GPUs (iGPU + dGPU), AGPM must manage both. Add separate entries for each GPU under the same machine profile. The iGPU entry typically uses control-id 18, while the dGPU may need control-id 17 or 19 depending on the framebuffer configuration. Experiment with these values if sleep remains broken—start with 18 for both, then test 17 for the dGPU if panics occur.
One quick test: before editing, capture a full ioreg -l dump to a file. After applying your changes, diff the new dump against the old one to confirm the AGPM node appears under your GPU. This removes guesswork and gives you a clean before/after comparison for troubleshooting.
