diff --git a/CHANGELOG.md b/CHANGELOG.md
index b61de996e..c4879af5f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -42,6 +42,9 @@
- Add EFICheckDisabler
- Based off stripped RestrictEvents.kext
- Add SimpleMSR to disable missing battery throttling on Nehalem+ MacBooks
+- Implement software demux patch set for 2011 15/17" MacBook Pros
+ - Alternative to hardware demux
+ - Adds [AMDGPUWakeHandler](https://github.com/blackgate/AMDGPUWakeHandler)
## 0.2.5
diff --git a/payloads/ACPI/SSDT-DGPU.aml b/payloads/ACPI/SSDT-DGPU.aml
new file mode 100644
index 000000000..17290002e
Binary files /dev/null and b/payloads/ACPI/SSDT-DGPU.aml differ
diff --git a/payloads/ACPI/Source/SSDT-DGPU.dsl b/payloads/ACPI/Source/SSDT-DGPU.dsl
new file mode 100644
index 000000000..38e6b9403
--- /dev/null
+++ b/payloads/ACPI/Source/SSDT-DGPU.dsl
@@ -0,0 +1,103 @@
+/* Requests power off of dGPU in MacBookPro8,2/3 (TS2 hardware failure)
+ * Main goal is to ensure power draw from the dGPU is reduced as
+ * much as possible to simulate a hardware demux without actual
+ * hardware modifications.
+ *
+ * Notes:
+ * - SSDT must be used in conjuction with '_INI' to 'XINI' patch
+ * to reroute PCI0 initialization.
+ *
+ * - AMD drivers in macOS may still attempt to attach and kernel
+ * panic. Disable the dGPU with class-code/device-id spoof or
+ * with '-wegnoegpu'.
+ *
+ * - dGPU will reactivate with sleep-wake, additional process
+ * is needed to disable the dGPU.
+ * - ie. AMDGPUWakeHandler.kext for macOS
+ *
+ * Ref:
+ * - https://www.tonymacx86.com/threads/help-macbook-pro-disable-radeon-gpu-via-dsdt.164458/
+ * - https://github.com/blackgate/AMDGPUWakeHandler
+ * - https://help.ubuntu.com/community/MacBookPro8-2/Raring
+ */
+DefinitionBlock ("", "SSDT", 2, "DRTNIA", "dGPU_OFF", 0x00001000)
+{
+ External (_SB_.PCI0, DeviceObj)
+ External (OSYS)
+
+ Scope (_SB.PCI0)
+ {
+ OperationRegion (IOGP, SystemIO, 0x0700, 0x51)
+ Field (IOGP, ByteAcc, NoLock, Preserve)
+ {
+ Offset (0x10),
+ P710, 8,
+ Offset (0x28),
+ P728, 8,
+ Offset (0x40),
+ P740, 8,
+ Offset (0x50),
+ P750, 8
+ }
+
+ Method (_INI, 0, NotSerialized) // _INI: Initialize
+ {
+ Store (0x07D0, OSYS)
+ If (CondRefOf (\_OSI, Local0))
+ {
+ If (_OSI ("Darwin"))
+ {
+ Store (0x2710, OSYS)
+ }
+
+ If (\_OSI ("Linux"))
+ {
+ Store (0x03E8, OSYS)
+ }
+
+ If (\_OSI ("Windows 2001"))
+ {
+ Store (0x07D1, OSYS)
+ }
+
+ If (\_OSI ("Windows 2001 SP1"))
+ {
+ Store (0x07D1, OSYS)
+ }
+
+ If (\_OSI ("Windows 2001 SP2"))
+ {
+ Store (0x07D2, OSYS)
+ }
+
+ If (\_OSI ("Windows 2006"))
+ {
+ Store (0x07D6, OSYS)
+ }
+
+ If (\_OSI ("Windows 2007"))
+ {
+ Store (0x07D7, OSYS)
+ }
+
+ If (\_OSI ("Windows 2008"))
+ {
+ Store (0x07D8, OSYS)
+ }
+
+ If (\_OSI ("Windows 2009"))
+ {
+ Store (0x07D9, OSYS)
+ }
+ }
+
+ // Disables dGPU
+ Store ("Requesting dGPU power off", Debug)
+ P728 = One // Switch select
+ P710 = 0x02 // Switch display
+ P740 = 0x02 // Switch DDC
+ P750 = Zero // Power down discrete graphics
+ }
+ }
+}
+
diff --git a/payloads/Config/config.plist b/payloads/Config/config.plist
index ec772ce17..c24566a68 100644
--- a/payloads/Config/config.plist
+++ b/payloads/Config/config.plist
@@ -31,6 +31,14 @@
Path
SSDT-PCI.aml
+
+ Enabled
+
+ Comment
+ Requests power off of dGPU for Sandy Bridge MacBook Pros
+ Path
+ SSDT-DGPU.aml
+
Delete
@@ -156,6 +164,36 @@
TableSignature
RFNEVA==
+
+ Base
+ \_SB.PCI0
+ BaseSkip
+ 0
+ Comment
+ _INI to XINI
+ Count
+ 1
+ Enabled
+
+ Find
+ X0lOSQ==
+ Limit
+ 0
+ Mask
+
+ OemTableId
+
+ Replace
+ WElOSQ==
+ ReplaceMask
+
+ Skip
+ 0
+ TableLength
+ 0
+ TableSignature
+ RFNEVA==
+
Quirks
@@ -1055,6 +1093,24 @@
PlistPath
Contents/Info.plist
+
+ Arch
+ x86_64
+ BundlePath
+ AMDGPUWakeHandler.kext
+ Comment
+ Force disable dGPU on wake
+ Enabled
+
+ ExecutablePath
+ Contents/MacOS/AMDGPUWakeHandler
+ MaxKernel
+
+ MinKernel
+
+ PlistPath
+ Contents/Info.plist
+
Block
diff --git a/payloads/Kexts/Misc/AMDGPUWakeHandler-v1.0.0.zip b/payloads/Kexts/Misc/AMDGPUWakeHandler-v1.0.0.zip
new file mode 100644
index 000000000..7cad8c581
Binary files /dev/null and b/payloads/Kexts/Misc/AMDGPUWakeHandler-v1.0.0.zip differ
diff --git a/resources/build.py b/resources/build.py
index e2310f9ce..dbb029d06 100644
--- a/resources/build.py
+++ b/resources/build.py
@@ -634,6 +634,19 @@ class BuildOpenCore:
self.config["DeviceProperties"]["Add"][tb_device_path] = {"class-code": binascii.unhexlify("FFFFFFFF"), "device-id": binascii.unhexlify("FFFF0000")}
+ if self.constants.software_demux is True and self.model in ["MacBookPro8,2", "MacBookPro8,3"]:
+ print("- Enabling software demux")
+ # Add ACPI patches
+ self.get_item_by_kv(self.config["ACPI"]["Add"], "Path", "SSDT-DGPU.aml")["Enabled"] = True
+ self.get_item_by_kv(self.config["ACPI"]["Patch"], "Comment", "_INI to XINI")["Enabled"] = True
+ shutil.copy(self.constants.demux_ssdt_path, self.constants.acpi_path)
+ # Disable dGPU
+ # IOACPIPlane:/_SB/PCI0@0/P0P2@10000/GFX0@0
+ self.config["DeviceProperties"]["Add"]["PciRoot(0x0)/Pci(0x1,0x0)/Pci(0x0,0x0)"] = {"class-code": binascii.unhexlify("FFFFFFFF"), "device-id": binascii.unhexlify("FFFF0000"), "IOName": "Dortania Disabled Card", "name": "Dortania Disabled Card"}
+ self.config["DeviceProperties"]["Delete"]["PciRoot(0x0)/Pci(0x1,0x0)/Pci(0x0,0x0)"] = ["class-code", "device-id", "IOName", "name"]
+ # Add AMDGPUWakeHandler
+ self.enable_kext("AMDGPUWakeHandler.kext", self.constants.gpu_wake_version, self.constants.gpu_wake_path)
+
# Bluetooth Detection
if not self.constants.custom_model and self.computer.bluetooth_chipset:
if self.computer.bluetooth_chipset in ["BRCM2070 Hub", "BRCM2046 Hub"]:
diff --git a/resources/cli_menu.py b/resources/cli_menu.py
index 405d8f65b..6e1aae6dc 100644
--- a/resources/cli_menu.py
+++ b/resources/cli_menu.py
@@ -681,6 +681,34 @@ for Windows may prefer to only work with the dGPU and eGPU active.
else:
self.dGPU_switch_support()
+ def set_software_demux(self):
+ utilities.cls()
+ utilities.header(["Set Software Demux"])
+ print(
+ """
+For MacBookPro8,2/3 users, it's very common for the dGPU to fail and
+thus require the user to disable them via the 'gpu-power-prefs'
+nvram argument.
+
+However this solution still allows the dGPU to pull power (6-7w). Enabling
+this option will simulate a demuxed enviroment allowing the dGPU to pull nearly
+no power and have the iGPU handle all tasks including brightness control.
+
+Note: this option requires dGPU to be disabled via NVRAM:
+https://dortania.github.io/OpenCore-Legacy-Patcher/ACCEL.html#unable-to-switch-gpus-on-2011-15-and-17-macbook-pros
+ """
+ )
+
+ change_menu = input("Set Software Demux?(y/n/q): ")
+ if change_menu in {"y", "Y", "yes", "Yes"}:
+ self.constants.software_demux = True
+ elif change_menu in {"n", "N", "no", "No"}:
+ self.constants.software_demux = False
+ elif change_menu in {"q", "Q", "Quit", "quit"}:
+ print("Returning to previous menu")
+ else:
+ self.set_software_demux()
+
def set_battery_throttle(self):
utilities.cls()
utilities.header(["Disable Firmware Throttling"])
@@ -951,6 +979,7 @@ system_profiler SPHardwareDataType | grep 'Model Identifier'
f"Set Windows GMUX support:\tCurrently {self.constants.dGPU_switch}",
MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).dGPU_switch_support,
],
+ [f"Set Software Demux:\t\tCurrently {self.constants.software_demux}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).set_software_demux],
[f"Disable Battery Throttling:\tCurrently {self.constants.disable_msr_power_ctl}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).set_battery_throttle],
]
diff --git a/resources/constants.py b/resources/constants.py
index a29748d33..c80b8fc5f 100644
--- a/resources/constants.py
+++ b/resources/constants.py
@@ -76,6 +76,10 @@ class Constants:
## https://github.com/arter97/SimpleMSR/
self.simplemsr_version = "1.0.0" # SimpleMSR
+ ## blackgate
+ ## https://github.com/blackgate/AMDGPUWakeHandler
+ self.gpu_wake_version = "1.0.0"
+
# Get resource path
self.current_path = Path(__file__).parent.parent.resolve()
self.payload_path = self.current_path / Path("payloads")
@@ -152,6 +156,7 @@ class Constants:
self.force_surplus = False # Force SurPlus patch in newer OSes
self.force_latest_psp = False # Force latest PatcherSupportPkg
self.disable_msr_power_ctl = False # Disable MSR Power Control (missing battery throttling)
+ self.software_demux = False # Enable Software Demux patch set
# OS Versions
## Based off Major Kernel Version
@@ -200,6 +205,10 @@ class Constants:
@property
def windows_ssdt_path(self):
return self.payload_path / Path("ACPI/SSDT-PCI.aml")
+
+ @property
+ def demux_ssdt_path(self):
+ return self.payload_path / Path("ACPI/SSDT-DGPU.aml")
# Drivers
@property
@@ -334,6 +343,10 @@ class Constants:
@property
def simplemsr_path(self):
return self.payload_kexts_path / Path(f"Misc/SimpleMSR-v{self.simplemsr_version}.zip")
+
+ @property
+ def gpu_wake_path(self):
+ return self.payload_kexts_path / Path(f"Misc/AMDGPUWakeHandler-v{self.gpu_wake_version}.zip")
@property
def latebloom_path(self):
diff --git a/resources/sys_patch.py b/resources/sys_patch.py
index bacd74d9a..ce825f1cd 100644
--- a/resources/sys_patch.py
+++ b/resources/sys_patch.py
@@ -721,13 +721,22 @@ set million colour before rebooting"""
self.amd_ts2 = False
self.iron_gpu = False
self.sandy_gpu = False
+
+ def check_dgpu_status(self):
+ dgpu = self.constants.computer.dgpu
+ if dgpu:
+ if dgpu.class_code and dgpu.class_code == 0xFFFFFFFF:
+ # If dGPU is disabled via class-codes, assume demuxed
+ return False
+ return True
+ return False
def detect_demux(self):
# If GFX0 is missing, assume machine was demuxed
# -wegnoegpu would also trigger this, so ensure arg is not present
if not "-wegnoegpu" in (utilities.get_nvram("boot-args") or ""):
igpu = self.constants.computer.igpu
- dgpu = self.constants.computer.dgpu
+ dgpu = self.check_dgpu_status()
if igpu and not dgpu:
return True
return False
diff --git a/resources/validation.py b/resources/validation.py
index 4f91d4145..33fe9ba54 100644
--- a/resources/validation.py
+++ b/resources/validation.py
@@ -67,5 +67,6 @@ def validate(settings):
settings.enable_wake_on_wlan = True
settings.disable_tb = True
settings.force_surplus = True
+ settings.software_demux = True
build_prebuilt()
build_dumps()