build.py: Add XHCI Boot Support

This commit is contained in:
Mykola Grymalyuk
2022-01-21 11:40:43 -07:00
parent 158dac6ab4
commit 92324ede72
10 changed files with 123 additions and 1 deletions

View File

@@ -1,6 +1,10 @@
# OpenCore Legacy Patcher changelog
## 0.4.1
- Add XHCI Boot Support to pre-UEFI 2.0 Macs
- Applicable to pre-Ivy Macs with upgraded USB 3.0 controllers, allows USB 3.0 boot
- Credit to Jazzzny for research and testing
- Drivers stripped from MacPro6,1 firmware
## 0.4.0
- Resolves Install USB Creation using incorrect installer

View File

@@ -1867,6 +1867,14 @@ class wx_python_gui:
print("NVMe Disabled")
self.constants.nvme_boot = False
def xhci_click(self, event=None):
if self.xhci_boot_checkbox.GetValue():
print("XHCI Enabled")
self.constants.xhci_boot = True
else:
print("XHCI Disabled")
self.constants.xhci_boot = False
def wake_on_wlan_click(self, event=None):
if self.wake_on_wlan_checkbox.GetValue():
print("Wake on WLAN Enabled")
@@ -2354,11 +2362,18 @@ OpenCore Legacy Patcher by default knows the most ideal
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.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"))
# 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.nvme_boot_checkbox.GetPosition().x, self.nvme_boot_checkbox.GetPosition().y + self.nvme_boot_checkbox.GetSize().height))
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.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"))
# Button: return to main menu

View File

@@ -1946,6 +1946,16 @@
<key>Arguments</key>
<string></string>
</dict>
<dict>
<key>Comment</key>
<string></string>
<key>Path</key>
<string>UsbBusDxe.efi</string>
<key>Enabled</key>
<false/>
<key>Arguments</key>
<string></string>
</dict>
<dict>
<key>Comment</key>
<string></string>

Binary file not shown.

Binary file not shown.

View File

@@ -761,6 +761,14 @@ class BuildOpenCore:
except KeyError:
pass
if self.constants.xhci_boot is True:
print("- Adding USB 3.0 Controller Patch")
print("- Adding XhciDxe.efi and UsbBusDxe.efi")
shutil.copy(self.constants.xhci_driver_path, self.constants.drivers_path)
shutil.copy(self.constants.usb_bus_driver_path, self.constants.drivers_path)
self.get_efi_binary_by_path("XhciDxe.efi", "UEFI", "Drivers")["Enabled"] = True
self.get_efi_binary_by_path("UsbBusDxe.efi", "UEFI", "Drivers")["Enabled"] = True
# ThirdPartDrives Check
if self.constants.allow_3rd_party_drives is True:
for drive in ["SATA 2.5", "SATA 3.5", "mSATA"]:

View File

@@ -466,6 +466,33 @@ OpenCore will enable NVMe support in it's picker
print("Returning to previous menu")
else:
self.allow_nvme()
def allow_xhci(self):
utilities.cls()
utilities.header(["Allow NVMe UEFI Support"])
print(
"""
For machines not natively supporting XHCI/USB 3.o,
this option allows you to see and boot XHCI
drive in OpenCore's picker
Not required if your machine natively supports USB 3.0
Note: You must have OpenCore on a bootable volume
first, ie. USB 2.0 or SATA drive. Once loaded,
OpenCore will enable XHCI support in it's picker
"""
)
change_menu = input("Enable XHCI Boot support?(y/n/q): ")
if change_menu in {"y", "Y", "yes", "Yes"}:
self.constants.xhci_boot = True
elif change_menu in {"n", "N", "no", "No"}:
self.constants.xhci_boot = False
elif change_menu in {"q", "Q", "Quit", "quit"}:
print("Returning to previous menu")
else:
self.allow_xhci()
def allow_wowl(self):
utilities.cls()
@@ -1129,6 +1156,7 @@ system_profiler SPHardwareDataType | grep 'Model Identifier'
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],
]
for option in options:

View File

@@ -155,6 +155,7 @@ class Constants:
## Boot Volume Settings
self.firewire_boot = False # Allow macOS FireWire Boot
self.nvme_boot = False # Allow UEFI NVMe Boot
self.xhci_boot = False
## Graphics Settings
self.metal_build = False # Set MXM Build support
@@ -228,6 +229,10 @@ class Constants:
@property
def xhci_driver_path(self):
return self.payload_path / Path("Drivers/XhciDxe.efi")
@property
def usb_bus_driver_path(self):
return self.payload_path / Path("Drivers/UsbBusDxe.efi")
@property
def diags_launcher_path(self):

View File

@@ -12,6 +12,12 @@ class generate_defaults:
settings.amfi_status = True
if host_is_target:
if settings.computer.usb_controllers and smbios_data.smbios_dictionary[model]["CPU Generation"] < cpu_data.cpu_data.ivy_bridge.value:
# Pre-Ivy do not natively support XHCI boot support
# If we detect XHCI on older model, enable
for controller in settings.computer.usb_controllers:
if isinstance(controller, device_probe.XHCIController):
settings.xhci_boot = True
if utilities.check_metal_support(device_probe, settings.computer) is False:
settings.disable_cs_lv = True
if settings.computer.gpus:

View File

@@ -158,6 +158,17 @@ class SATAController(PCIDevice):
class SASController(PCIDevice):
CLASS_CODE: ClassVar[int] = 0x010400
@dataclass
class XHCIController(PCIDevice):
CLASS_CODE: ClassVar[int] = 0x0c0330
@dataclass
class EHCIController(PCIDevice):
CLASS_CODE: ClassVar[int] = 0x0c0320
@dataclass
class OHCIController(PCIDevice):
CLASS_CODE: ClassVar[int] = 0x0c0310
@dataclass
class NVIDIA(GPU):
@@ -339,6 +350,7 @@ class Computer:
igpu: Optional[GPU] = None # Shortcut for IGPU
dgpu: Optional[GPU] = None # Shortcut for GFX0
storage: list[PCIDevice] = field(default_factory=list)
usb_controllers: list[PCIDevice] = field(default_factory=list)
wifi: Optional[WirelessCard] = None
cpu: Optional[CPU] = None
oclp_version: Optional[str] = None
@@ -354,6 +366,7 @@ class Computer:
computer.igpu_probe()
computer.wifi_probe()
computer.storage_probe()
computer.usb_controller_probe()
computer.smbios_probe()
computer.cpu_probe()
computer.bluetooth_probe()
@@ -412,6 +425,39 @@ class Computer:
self.wifi = vendor.from_ioregistry(device, anti_spoof=True) # type: ignore
break
ioreg.IOObjectRelease(device)
def usb_controller_probe(self):
xhci_controllers = ioreg.ioiterator_to_list(
ioreg.IOServiceGetMatchingServices(
ioreg.kIOMasterPortDefault,
{"IOProviderClass": "IOPCIDevice", "IOPropertyMatch": [{"class-code": binascii.a2b_hex(utilities.hexswap(hex(XHCIController.CLASS_CODE)[2:].zfill(8)))}]},
None,
)[1]
)
ehci_controllers = ioreg.ioiterator_to_list(
ioreg.IOServiceGetMatchingServices(
ioreg.kIOMasterPortDefault,
{"IOProviderClass": "IOPCIDevice", "IOPropertyMatch": [{"class-code": binascii.a2b_hex(utilities.hexswap(hex(EHCIController.CLASS_CODE)[2:].zfill(8)))}]},
None,
)[1]
)
ohci_controllers = ioreg.ioiterator_to_list(
ioreg.IOServiceGetMatchingServices(
ioreg.kIOMasterPortDefault,
{"IOProviderClass": "IOPCIDevice", "IOPropertyMatch": [{"class-code": binascii.a2b_hex(utilities.hexswap(hex(OHCIController.CLASS_CODE)[2:].zfill(8)))}]},
None,
)[1]
)
for device in xhci_controllers:
self.usb_controllers.append(XHCIController.from_ioregistry(device))
ioreg.IOObjectRelease(device)
for device in ehci_controllers:
self.usb_controllers.append(EHCIController.from_ioregistry(device))
ioreg.IOObjectRelease(device)
for device in ohci_controllers:
self.usb_controllers.append(OHCIController.from_ioregistry(device))
ioreg.IOObjectRelease(device)
def storage_probe(self):
sata_controllers = ioreg.ioiterator_to_list(