How to Edit AppleGraphicsPowerManagement.kext for Hackintosh GPU Power Management

Step-by-step guide to patching AGPM plist for Kepler and GCN GPUs on Sierra/High Sierra Hackintosh. Fix clock issues, sleep/wake crashes, and thermal throttling.

AppleGraphicsPowerManagement.kext (AGPM) contains the plist definitions that govern GPU voltage and frequency transitions under macOS. For a legacy Hackintosh—especially systems running macOS Sierra 10.12.x or High Sierra 10.13.x—the default AGPM profiles rarely match the installed graphics card. Injecting a custom AGPM entry is often the only way to prevent sudden frame drops, wake-from-sleep crashes, or thermal throttling during sustained loads.

What AGPM Actually Controls

AGPM is a kernel extension that talks to the GPU’s on-chip power management hardware. It reads a set of predefined “states” from its Info.plist, each containing a frequency and voltage pair, and switches between them based on GPU load. On genuine Mac hardware, each GPU model gets its own VendorID-DeviceID key. A Hackintosh lacking this key defaults to a generic profile that may either lock the GPU at its highest clock rate (causing heat) or never reach the boost clock (killing performance).

The plist is structured as a dictionary of board-IDs (e.g., Mac-F60DEB81FF30ACF6 for an iMac14,2). Each board-ID entry contains an array called logControl and another called ControlLoops. The ControlLoops array holds the actual power state tables for each GPU. Editing these requires locating the correct board-ID and either modifying an existing GPU entry or adding a new one for your exact graphics card.

When Editing Becomes Necessary

Most Kepler-based NVIDIA cards (GeForce GTX 600/700 series) and GCN 1.0/1.1 AMD cards (Radeon HD 7000, R9 200 series) lack native AGPM support in Sierra and High Sierra. These GPUs work out of the box for basic display but exhibit erratic clocking under OpenGL/Metal applications. Symptoms include:

  • GPU clock stuck at idle frequency (324 MHz for Kepler) during 3D workloads.
  • Instant kernel panic on sleep/wake cycle due to missing low-power state.
  • Unstable boost behavior, bouncing between maximum and minimum frequencies every few seconds.

A properly patched AGPM entry forces the GPU to use the exact state table designed for a similar Mac GPU, bringing predictable power delivery.

Locating the Right AGPM Kext Version

Every macOS build ships its own AGPM kext. The kext version inside /System/Library/Extensions/AppleGraphicsPowerManagement.kext/Contents/Info.plist differs between 10.12.6 and 10.13.6. You must edit the kext that actually runs on your target system; copying a plist from a different macOS version can cause a boot loop because the kernel extension’s binary validates the plist schema at load time. Always work on the installed kext, not a cached copy from another machine.

Before editing, back up the original: sudo cp -R /System/Library/Extensions/AppleGraphicsPowerManagement.kext ~/Desktop/AGPM_backup/. Then mount the system volume as read-write with sudo mount -uw / on Sierra, or disable SIP on High Sierra to allow kext modification.

Editing the Info.plist

Open the kext’s Info.plist with Xcode or a property list editor (PlistEdit Pro is more reliable for hex-style entries). Navigate to IOKitPersonalities | AppleGraphicsPowerManagement | Mach-O Kernel Extension. Below that you will see a dictionary named Mac-F60DEB81FF30ACF6 (the board-ID for an iMac14,2) or similar. For a build using a Haswell or Ivy Bridge platform, the board-ID in your Clover/OpenCore config may be set to Mac-F60DEB81FF30ACF6 anyway—common for desktop GPUs.

Inside that board-ID dictionary, find VendorID-DeviceID strings. For example, 0x10de1183 corresponds to a GeForce GTX 680 (Kepler). If your GPU’s device ID does not appear, you must create a new entry. The simplest method is to duplicate an existing entry for a similar GPU family and change the key to your device ID.

For a GeForce GTX 780 (GK110), device ID 0x10de1184 is not present in the default High Sierra AGPM. Duplicate the GTX 780 Ti entry (0x10de1004) and replace the key. The ControlLoops array contains entries like Mac-F60DEB81FF30ACF6_NVIDIA_NVDA_1_0_0_0. Inside those dictionaries the Power and Performance values define the state table. Keep the same structure; only change the GPU clock if you have verified it through tools like nvclock or radeon-profile.

Step-by-Step for NVIDIA Kepler Example

  1. Identify your GPU’s vendor and device ID using IORegistryExplorer: look under IOService:/IOResources/IOGraphics for your display controller, then find vendor-id and device-id as decimal numbers; convert to hex.
  2. Open AppleGraphicsPowerManagement.kext/Contents/Info.plist.
  3. Search for an existing Kepler entry (e.g., 0x10de1183 for GTX 680).
  4. Add a new key 0x10de1184 (GTX 780) by copying the whole dictionary from 0x10de1004 (GTX 780 Ti) if present, or from a GK104-based entry.
  5. Replace any hardcoded frequency values only if you have datasheet values; otherwise leave them untouched.
  6. Save the plist, rebuild kext cache with sudo kextcache -i /, and reboot.

Verifying the Injection

After reboot, open IORegistryExplorer again and search for AGPM. Under your GPU’s IOService you should see a AGPM key with a dictionary that matches the board-ID and device ID you entered. Use sysctl machdep.xcpm.vectors_loaded_count or Intel Power Gadget to verify GPU frequency switching. A correctly patched AGPM will show the GPU stepping between multiple P-states during a stress test like Unigine Valley.

Common Pitfalls and Risks

An incorrect device ID entry will be ignored silently and the GPU falls back to a generic profile—no crash, but no change. More dangerous is copying a state table from a completely different GPU architecture (e.g., using a Maxwell table on a Kepler card). This can request voltage levels the hardware cannot deliver, resulting in immediate kernel panic or, in rare cases, physical damage due to undervolt/overvoltage. Always match the architecture: GK104/GK110 for Kepler, GM107/GM204 for Maxwell, Tonga/Hawaii for AMD GCN.

For AMD GPUs, AGPM editing is trickier because the ControlLoops often reference an AMDSupport kext that expects specific ROM tables. Many users prefer injecting AGPM via a dedicated SSDT or using AMDRadeonCrusher utilities instead of direct plist edits. If you encounter boot failures after editing, boot with -x (safe mode) and restore the backup.

Additional pitfalls are covered in the April Q&A Session 3: ACPI Errors, Ethernet Drops, and GPU Patches for Old macOS, which details how a misconfigured AGPM interacts with other kernel extensions and can mask itself as a sleep/wake issue.

Advanced: Creating an AGPM Injector Kext

Rather than modifying the system kext in place (which gets overwritten by macOS updates), advanced users create a small injector kext that loads after AppleGraphicsPowerManagement and supplies the corrected Info.plist. Tools like PlistInjector or manual kext creation with a Info.plist containing only the IOKitPersonalities dictionary can work. The injector must have a higher load order than AGPM, typically achieved by placing it in /Library/Extensions/ and assigning a bundle identifier that sorts after com.apple.iokit.IOGraphicsFamily. This method survives minor updates and makes reverting as simple as removing the kext.

One final, narrow tip: after every AGPM modification, check GPU temperature under idle and load using sudo powermetrics --samplers gpu_power (on Intel iGPU) or stats from iStat Menus. If the idle temperature rises more than 5°C compared to before the patch, the card is likely stuck in a high-performance state—review your logControl entries and ensure the low-power state index is correctly referenced.