From 15aacddd2316a122084303fccb60336d0481163e Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk <48863253+khronokernel@users.noreply.github.com> Date: Mon, 17 May 2021 20:40:09 -0600 Subject: [PATCH] Add XHCI UEFI Driver --- CHANGELOG.md | 2 ++ Resources/Build.py | 15 +++++++++++++++ Resources/Constants.py | 3 +++ Resources/DeviceProbe.py | 1 + Resources/ModelArray.py | 33 +++++++++++++++++++++++++++++++++ payloads/Drivers/XhciDxe.efi | Bin 0 -> 40964 bytes 6 files changed, 54 insertions(+) create mode 100644 payloads/Drivers/XhciDxe.efi diff --git a/CHANGELOG.md b/CHANGELOG.md index a8537ce2c..3cebdb4fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # OpenCore Legacy Patcher changelog ## 0.1.6 +- Add XHCI UEFI Driver for 3rd Party USB 3.0 Controllers + - Allows for Boot Support from OpenCore' Picker ## 0.1.5 - Fix crashing when Wireless module not present diff --git a/Resources/Build.py b/Resources/Build.py index de6843a11..76fb303f7 100644 --- a/Resources/Build.py +++ b/Resources/Build.py @@ -476,6 +476,21 @@ class BuildOpenCore: print("- Adding Mac Pro, Xserve DRM patches") self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " shikigva=128 unfairgva=1 -wegtree" + # Add XhciDxe if firmware doesn't have XHCI controller support and XCHI controller detected + if self.model not in ModelArray.XhciSupport and not self.constants.custom_model: + devices = plistlib.loads(subprocess.run("ioreg -c IOPCIDevice -r -d2 -a".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode()) + try: + devices = [i for i in devices if i["class-code"] == binascii.unhexlify(self.constants.classcode_xhci)] + vendor_id = self.hexswap(binascii.hexlify(devices[0]["vendor-id"]).decode()[:4]) + device_id = self.hexswap(binascii.hexlify(devices[0]["device-id"]).decode()[:4]) + print("- Found XHCI Controller, adding Boot Support") + shutil.copy(self.constants.xhci_driver_path, self.constants.drivers_path) + self.config["UEFI"]["Drivers"] += ["XhciDxe.efi"] + except ValueError: + print("- No XHCI Controller Found (V)") + except IndexError: + print("- No XHCI Controller Found (I)") + # Add OpenCanopy print("- Adding OpenCanopy GUI") shutil.rmtree(self.constants.resources_path, onerror=rmtree_handler) diff --git a/Resources/Constants.py b/Resources/Constants.py index cb4db447b..8f7370e03 100644 --- a/Resources/Constants.py +++ b/Resources/Constants.py @@ -111,6 +111,7 @@ class Constants: self.classcode_wifi = "00800200" self.classcode_gpu = "00000300" self.classcode_gpu_variant = "00800300" + self.classcode_xhci = "30030C00" # Nvidia GPU Architecture self.arch_tesla = "NV50" @@ -138,6 +139,8 @@ class Constants: def nvme_driver_path(self): return self.payload_path / Path("Drivers/NvmExpressDxe.efi") @property def exfat_legacy_driver_path(self): return self.payload_path / Path("Drivers/ExFatDxeLegacy.efi") + @property + def xhci_driver_path(self): return self.payload_path / Path("Drivers/XhciDxe.efi") # Kexts @property diff --git a/Resources/DeviceProbe.py b/Resources/DeviceProbe.py index f401d81ee..fab8d4b7b 100644 --- a/Resources/DeviceProbe.py +++ b/Resources/DeviceProbe.py @@ -47,6 +47,7 @@ class pci_probe: # IOACPIPlane:/_SB/PCI0@0/P0P2@10000 -> /PCI0@0/P0P2@1 acpi_path = acpi_path_full.replace("IOACPIPlane:/_SB", "") acpi_path = acpi_path.replace("0000", "") + acpi_path = acpi_path.replace("0001", "") acpi_path = acpi_path.replace("ffff", "0") acpi_path = acpi_path.upper() return acpi_path diff --git a/Resources/ModelArray.py b/Resources/ModelArray.py index 37c5a6064..481c8f7da 100644 --- a/Resources/ModelArray.py +++ b/Resources/ModelArray.py @@ -442,6 +442,39 @@ NVMePatch = [ "Dortania1,1" ] +XhciSupport = [ + "MacBookAir5,1", + "MacBookAir5,2", + "MacBookAir6,1", + "MacBookAir6,2", + "MacBookAir7,1", + "MacBookAir7,2", + "MacBookPro9,1", + "MacBookPro9,2", + "MacBookPro10,1", + "MacBookPro10,2", + "MacBookPro11,1", + "MacBookPro11,2", + "MacBookPro11,3", + "MacBookPro11,4", + "MacBookPro11,5", + "MacBookPro12,1", + "Macmini6,1", + "Macmini6,2", + "Macmini7,1", + "iMac13,1", + "iMac13,2", + "iMac13,3", + "iMac14,1", + "iMac14,2", + "iMac14,3", + "iMac15,1", + "iMac16,1", + "iMac16,2", + "MacPro6,1", + "Dortania1,1" +] + SidecarPatch = [ "MacBook8,1", "MacBookAir5,1", diff --git a/payloads/Drivers/XhciDxe.efi b/payloads/Drivers/XhciDxe.efi new file mode 100644 index 0000000000000000000000000000000000000000..802838f9b44e390d8fb87f1282322cab1832aaf4 GIT binary patch literal 40964 zcmeHweP9&T)%WaXlWZU`LBK{tSR`mbYm?e)A}Bkso7{!n5JWx|h#y4A(^|w`!78$G z6Ox;8k+!zdK7DFxt)jMytqlPccN0tkDhBW)fUN<)Ca%>03JGB5{hd3r`2cLK?fd-k zzFA9V=6;@g?m6e4bMCpfz6H`Z{sq5r&7O*dZb`ajZGw?dZ9Lkg!3hJc)|{SFk~IBJ ze5LhDq4(b3@vQ2e^nvlTfATzAGhbO{y(IMk>?;fYYZ;gMm#p$rmF4(H0L7n_X8s(K zRCL)bH~Md+Zz>b)^~7uZ=ai(#Wh<8a;72!`u&zfAm8WN~Uy&r;)a$eVwI2ih80g19 zKL+|S(2s$B4D@559|Qdu=*K`m2L2z$z+A>(_woqiyN|GESUA6f$?oXl`d-PDdg_eS zVoL7nNk#)`=E&1X)s56SXk!=SZ+m(4=wnQ-$wPY0T%C*;9P?(I@BibY8I&X^c1bNjW2-*h~?lc%7lrlcEmw{}#F^2z!%smfOX6#~q2D z+|E1F0FfuunoJ!ZWxtQ5c=@hr;d_$xFA3B~PZ4;1K?AHu*)xH`fcEIqf#k)t7Ena} zVkFo1kjA-#i#7TxE|H3VeL~(SS0{}sE-KziX~*iUetWGYoFH-z56@s4xLDGfGW!;{2``6X2 zJGAa&v#ATIwfDQ^EcwC@*1c8C-!aFu@K*h~jH^&PoF^B)LcK5AQ+(s-Wcj!96UG07 z5!{ktD}H7D`fd+{uA}gOKOl+c&*IP5rP;IQ%)S4>to!R{-M@F1TrF<|k+|f|c~_|S zrryfJYql%@6-nbKO9opS=O6ujc$%L#hYrcn*3{zglmSo47FR}*SKfRb{)T_~3cB!w z-fJ&*@tOB~`TTWE^=I7Vso2T%sHfuO(MP>Rl<&$GZ$_c)h;Su+T$iq|ksTlKWv4

lWib~njS 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 Y^kbkO1N|82$3Q;@{#^{