From df958a2b1c054ec17462c3ff19dcafcaf79c9e28 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Tue, 1 Feb 2022 11:30:44 -0700 Subject: [PATCH] Add NVMe Enhanced Power Management configuration Closes https://github.com/dortania/OpenCore-Legacy-Patcher/issues/921 --- CHANGELOG.md | 2 ++ gui/gui_main.py | 31 +++++++++++++++++++++++-------- resources/build.py | 7 ++----- resources/cli_menu.py | 34 +++++++++++++++++++++++++++++++--- resources/constants.py | 1 + resources/defaults.py | 9 +++++++++ 6 files changed, 68 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3499d45f3..70850af0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ - Fix Power Management Support in macOS 12.3 Beta 1 - Applicable for Sandy Bridge and older - Enforces ACPI_SMC_PlatformPlugin matching +- Add NVMe Enhanced Power Management configuration + - Disables NVMe adjustments on Skylake and newer Macs by default ## 0.4.1 - Add XHCI Boot Support to pre-UEFI 2.0 Macs diff --git a/gui/gui_main.py b/gui/gui_main.py index 3dfbf880b..f35476ce4 100644 --- a/gui/gui_main.py +++ b/gui/gui_main.py @@ -1871,6 +1871,14 @@ class wx_python_gui: print("NVMe Disabled") self.constants.nvme_boot = False + def nvme_power_management_click(self, event=None): + if self.nvme_power_management_checkbox.GetValue(): + print("NVMe Power Management Enabled") + self.constants.allow_nvme_fixing = True + else: + print("NVMe Power Management Disabled") + self.constants.allow_nvme_fixing = False + def xhci_click(self, event=None): if self.xhci_boot_checkbox.GetValue(): print("XHCI Enabled") @@ -2366,26 +2374,33 @@ OpenCore Legacy Patcher by default knows the most ideal self.firewire_boot_checkbox.SetToolTip(wx.ToolTip("Enable FireWire Boot support in macOS 10.15 and newer.\nMainly applicable for Macs with FireWire or Thunderbolt to FireWire adapters")) if generate_smbios.check_firewire(self.computer.real_model) is False and not self.constants.custom_model: self.firewire_boot_checkbox.Disable() + + # XHCI Boot + self.xhci_boot_checkbox = wx.CheckBox(self.frame, label="XHCI Boot") + self.xhci_boot_checkbox.SetValue(self.constants.xhci_boot) + self.xhci_boot_checkbox.Bind(wx.EVT_CHECKBOX, self.xhci_click) + self.xhci_boot_checkbox.SetPosition(wx.Point(self.firewire_boot_checkbox.GetPosition().x, self.firewire_boot_checkbox.GetPosition().y + self.firewire_boot_checkbox.GetSize().height)) + self.xhci_boot_checkbox.SetToolTip(wx.ToolTip("Enables XHCI/USB3.o support in UEFI for non-native systems (ie. pre-Ivy Bridge)\nRequires OpenCore to be stored on a natively bootable volume however")) # NVMe Boot self.nvme_boot_checkbox = wx.CheckBox(self.frame, label="NVMe Boot") self.nvme_boot_checkbox.SetValue(self.constants.nvme_boot) self.nvme_boot_checkbox.Bind(wx.EVT_CHECKBOX, self.nvme_click) - self.nvme_boot_checkbox.SetPosition(wx.Point(self.firewire_boot_checkbox.GetPosition().x, self.firewire_boot_checkbox.GetPosition().y + self.firewire_boot_checkbox.GetSize().height)) + self.nvme_boot_checkbox.SetPosition(wx.Point(self.xhci_boot_checkbox.GetPosition().x, self.xhci_boot_checkbox.GetPosition().y + self.xhci_boot_checkbox.GetSize().height)) self.nvme_boot_checkbox.SetToolTip(wx.ToolTip("Enables NVMe support in UEFI for non-native systems (ie. MacPro3,1)\nRequires OpenCore to be stored on a natively bootable volume however")) - # XHCI Boot - self.xhci_boot_checkbox = wx.CheckBox(self.frame, label="XHCI Boot") - self.xhci_boot_checkbox.SetValue(self.constants.xhci_boot) - self.xhci_boot_checkbox.Bind(wx.EVT_CHECKBOX, self.xhci_click) - self.xhci_boot_checkbox.SetPosition(wx.Point(self.nvme_boot_checkbox.GetPosition().x, self.nvme_boot_checkbox.GetPosition().y + self.nvme_boot_checkbox.GetSize().height)) - self.xhci_boot_checkbox.SetToolTip(wx.ToolTip("Enables XHCI/USB3.o support in UEFI for non-native systems (ie. pre-Ivy Bridge)\nRequires OpenCore to be stored on a natively bootable volume however")) + # NVMe Power Management + self.nvme_power_management_checkbox = wx.CheckBox(self.frame, label="NVMe Power Management") + self.nvme_power_management_checkbox.SetValue(self.constants.allow_nvme_fixing) + self.nvme_power_management_checkbox.Bind(wx.EVT_CHECKBOX, self.nvme_power_management_click) + self.nvme_power_management_checkbox.SetPosition(wx.Point(self.nvme_boot_checkbox.GetPosition().x, self.nvme_boot_checkbox.GetPosition().y + self.nvme_boot_checkbox.GetSize().height)) + self.nvme_power_management_checkbox.SetToolTip(wx.ToolTip("For machines with upgraded NVMe drives, this option allows for better power management support within macOS.\nNote that some NVMe drives don't support macOS's power management settings, and can result in boot issues. Disable this option if you experience IONVMeFamily kernel panics. Mainly applicable for Skylake and newer Macs.")) # Wake on WLAN self.wake_on_wlan_checkbox = wx.CheckBox(self.frame, label="Wake on WLAN") self.wake_on_wlan_checkbox.SetValue(self.constants.enable_wake_on_wlan) self.wake_on_wlan_checkbox.Bind(wx.EVT_CHECKBOX, self.wake_on_wlan_click) - self.wake_on_wlan_checkbox.SetPosition(wx.Point(self.xhci_boot_checkbox.GetPosition().x, self.xhci_boot_checkbox.GetPosition().y + self.xhci_boot_checkbox.GetSize().height)) + self.wake_on_wlan_checkbox.SetPosition(wx.Point(self.nvme_power_management_checkbox.GetPosition().x, self.nvme_power_management_checkbox.GetPosition().y + self.nvme_power_management_checkbox.GetSize().height)) self.wake_on_wlan_checkbox.SetToolTip(wx.ToolTip("Enables Wake on WLAN for Broadcom Wifi.\nBy default, Wake on WLAN is disabled to work around Apple's wake from sleep bug causing heavily degraded networking performance.\nNote: This option is only applicable for BCM943224, BCM94331, BCM94360 and BCM943602 chipsets")) # Content Caching diff --git a/resources/build.py b/resources/build.py index 2e7579d81..45c134d1e 100644 --- a/resources/build.py +++ b/resources/build.py @@ -227,7 +227,7 @@ class BuildOpenCore: if not self.computer.storage: print("- No PCIe Storage Controllers found to fix") - if not self.constants.custom_model: + if not self.constants.custom_model and self.constants.allow_nvme_fixing is True: nvme_devices = [i for i in self.computer.storage if isinstance(i, device_probe.NVMeController)] for i, controller in enumerate(nvme_devices): print(f"- Found 3rd Party NVMe SSD ({i + 1}): {utilities.friendly_hex(controller.vendor_id)}:{utilities.friendly_hex(controller.device_id)}") @@ -245,11 +245,8 @@ class BuildOpenCore: print("- Falling back to -nvmefaspm") self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -nvmefaspm" - if (controller.vendor_id != 0x144D and controller.device_id != 0xA804 and self.model not in ["MacBookPro13,3", "MacBookPro14,3"]): + if (controller.vendor_id != 0x144D and controller.device_id != 0xA804): # Avoid injecting NVMeFix when a native Apple NVMe drive is present - # Note on 2016-2017 MacBook Pros, 15" devices used a stock Samsung SSD with IONVMeController - # Technically this should be patched based on NVMeFix.kext logic, - # however Apple deemed the SSD unsupported for enhanced performance # https://github.com/acidanthera/NVMeFix/blob/1.0.9/NVMeFix/NVMeFix.cpp#L220-L225 if self.get_kext_by_bundle_path("NVMeFix.kext")["Enabled"] is False: self.enable_kext("NVMeFix.kext", self.constants.nvmefix_version, self.constants.nvmefix_path) diff --git a/resources/cli_menu.py b/resources/cli_menu.py index 5a7003b3e..24f37a1c1 100644 --- a/resources/cli_menu.py +++ b/resources/cli_menu.py @@ -467,6 +467,33 @@ OpenCore will enable NVMe support in it's picker else: self.allow_nvme() + def allow_nvme_pwr_mgmt(self): + utilities.cls() + utilities.header(["Allow NVMe Power Management Adjustments"]) + print( + """ +For machines with upgraded NVMe drives, this +option allows for better power management support +within macOS. + +Note that some NVMe drives don't support macOS's +power management settings, and can result in boot +issues. Disable this option if you experience +IONVMeFamily kernel panics. Mainly applicable for +Skylake and newer Macs. + """ + ) + + change_menu = input("Enable NVMe Power Management?(y/n/q): ") + if change_menu in {"y", "Y", "yes", "Yes"}: + self.constants.allow_nvme_fixing = True + elif change_menu in {"n", "N", "no", "No"}: + self.constants.allow_nvme_fixing = False + elif change_menu in {"q", "Q", "Quit", "quit"}: + print("Returning to previous menu") + else: + self.allow_nvme() + def allow_xhci(self): utilities.cls() utilities.header(["Allow NVMe UEFI Support"]) @@ -1174,9 +1201,10 @@ system_profiler SPHardwareDataType | grep 'Model Identifier' title = ["Adjust Bootable Volume Settings"] menu = utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True) options = [ - [f"Set FireWire Boot:\tCurrently {self.constants.firewire_boot}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).allow_firewire], - [f"Set NVMe Boot:\tCurrently {self.constants.nvme_boot}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).allow_nvme], - [f"Set XHCI Boot:\tCurrently {self.constants.xhci_boot}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).allow_xhci], + [f"Set FireWire Boot:\t\tCurrently {self.constants.firewire_boot}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).allow_firewire], + [f"Set XHCI Boot:\t\tCurrently {self.constants.xhci_boot}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).allow_xhci], + [f"Set NVMe Boot:\t\tCurrently {self.constants.nvme_boot}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).allow_nvme], + [f"Set NVMe Power Management:\tCurrently {self.constants.allow_nvme_fixing}", MenuOptions(self.constants.custom_model or self.constants.computer.real_model, self.constants).allow_nvme_pwr_mgmt], ] for option in options: diff --git a/resources/constants.py b/resources/constants.py index aa7fc24fb..cc057241a 100644 --- a/resources/constants.py +++ b/resources/constants.py @@ -184,6 +184,7 @@ class Constants: self.disable_connectdrivers = False # Disable ConnectDrivers (hibernation) self.allow_3rd_party_drives = True # Allow ThridPartyDrives quirk self.set_content_caching = False # Set Content Caching + self.allow_nvme_fixing = True # Allow NVMe Kernel Space Patches self.legacy_accel_support = [ os_data.os_data.mojave, diff --git a/resources/defaults.py b/resources/defaults.py index 2a2d4e0b1..cd12313f6 100644 --- a/resources/defaults.py +++ b/resources/defaults.py @@ -116,6 +116,15 @@ class generate_defaults: settings.fu_arguments = " -disable_sidecar_mac" else: settings.fu_arguments = None + if smbios_data.smbios_dictionary[model]["CPU Generation"] >= cpu_data.cpu_data.skylake.value: + # On 2016-2017 MacBook Pros, 15" devices used a stock Samsung SSD with IONVMeController + # Technically this should be patched based on NVMeFix.kext logic, + # however Apple deemed the SSD unsupported for enhanced performance + # In addition, some upgraded NVMe drives still have issues with enhanced power management + # Safest to disable by default, allow user to configure afterwards + settings.allow_nvme_fixing = False + else: + settings.allow_nvme_fixing = True except KeyError: pass