diff --git a/Resources/Build.py b/Resources/Build.py index 53548ea571..06446da71d 100644 --- a/Resources/Build.py +++ b/Resources/Build.py @@ -586,6 +586,25 @@ def amd_patch(self, backlight_path): self.config["DeviceProperties"]["Add"][tb_device_path] = {"class-code": binascii.unhexlify("FFFFFFFF"), "device-id": binascii.unhexlify("FFFF0000")} + # Bluetooth Detection + if not self.constants.custom_model and self.computer.bluetooth_chipset: + if self.computer.bluetooth_chipset == "BRCM2070 Hub": + print("- Enabling Bluetooth BRCM2070 for macOS Monterey") + self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -brcm2070_patch" + self.enable_kext("BlueToolFixup.kext", self.constants.bluetool_version, self.constants.bluetool_path) + elif self.computer.bluetooth_chipset == "BRCM2046 Hub": + print("- Enabling Bluetooth BRCM2046 for macOS Monterey") + self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -brcm2046_patch" + self.enable_kext("BlueToolFixup.kext", self.constants.bluetool_version, self.constants.bluetool_path) + elif self.model in ModelArray.Bluetooth_BRCM2070: + print("- Enabling Bluetooth BRCM2070 for macOS Monterey") + self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -brcm2070_patch" + self.enable_kext("BlueToolFixup.kext", self.constants.bluetool_version, self.constants.bluetool_path) + elif self.model in ModelArray.Bluetooth_BRCM2046: + print("- Enabling Bluetooth BRCM2046 for macOS Monterey") + self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -brcm2046_patch" + self.enable_kext("BlueToolFixup.kext", self.constants.bluetool_version, self.constants.bluetool_path) + # Add XhciDxe if firmware doesn't have XHCI controller support and XCHI controller detected # TODO: Fix XhciDxe to work on pre UEFI 2.0 Macs # Ref: https://github.com/acidanthera/bugtracker/issues/1663 @@ -697,7 +716,6 @@ def amd_patch(self, backlight_path): print("- Allowing FileVault on Root Patched systems") self.get_item_by_kv(self.config["Kernel"]["Patch"], "Identifier", "com.apple.filesystems.apfs")["Enabled"] = True - def set_smbios(self): spoofed_model = self.model if self.constants.override_smbios == "Default": @@ -847,7 +865,6 @@ def get_efi_binary_by_path(self, bundle_path, entry_location, efi_type): print(f"- Could not find {efi_type}: {bundle_path}!") raise IndexError return efi_binary - def enable_kext(self, kext_name, kext_version, kext_path, check=False): kext = self.get_kext_by_bundle_path(kext_name) diff --git a/Resources/Constants.py b/Resources/Constants.py index 179e8a46da..0415325e6e 100644 --- a/Resources/Constants.py +++ b/Resources/Constants.py @@ -34,6 +34,7 @@ def __init__(self): self.featureunlock_version = "1.0.3" # FeatureUnlock self.debugenhancer_version = "1.0.4" # DebugEnhancer self.cpufriend_version = "1.2.4" # CPUFriend + self.bluetool_version = "2.6.1" # BlueToolFixup ## Apple ## https://www.apple.com @@ -325,6 +326,10 @@ def featureunlock_path(self): def debugenhancer_path(self): return self.payload_kexts_path / Path(f"Acidanthera/DebugEnhancer-v{self.debugenhancer_version}.zip") + @property + def bluetool_path(self): + return self.payload_kexts_path / Path(f"Acidanthera/BlueToolFixup-v{self.bluetool_version}.zip") + @property def innie_path(self): return self.payload_kexts_path / Path(f"Misc/Innie-v{self.innie_version}.zip") @@ -653,7 +658,7 @@ def legacy_wifi_libexec(self): "j215ap", # MacBookPro16,4 "j185ap", # iMac20,1 "j185fap", # iMac20,2 - #"x86legacy", # non-T2 Macs/VMs, Monterey's boot.efi enforces this on all Macs + # "x86legacy", # non-T2 Macs/VMs, Monterey's boot.efi enforces this on all Macs ] sandy_board_id = [ diff --git a/Resources/ModelArray.py b/Resources/ModelArray.py index 688990bd1d..32e4de0bec 100644 --- a/Resources/ModelArray.py +++ b/Resources/ModelArray.py @@ -1146,8 +1146,8 @@ "iMac12,2", "MacPro3,1", "MacPro4,1", - "XServer2,1", - "XServer3,1", + "XServe2,1", + "XServe3,1", ] dGPU_switch = [ @@ -1165,3 +1165,46 @@ "MacBookPro16,1", "MacBookPro16,4", ] + +Bluetooth_BRCM2046 = [ + "MacBook4,1", + "MacBook5,1", + "MacBook5,2", + "MacBookAir2,1", + "MacBookAir3,1", + "MacBookAir3,2", + "MacBookPro4,1", + "MacBookPro5,1", + "MacBookPro5,2", + "MacBookPro5,3", + "MacBookPro5,4", + "MacBookPro5,5", + "MacBookPro7,1", + "Macmini3,1", + "iMac8,1", + "iMac9,1", + "iMac10,1", + "iMac11,1", + "iMac11,2", + "iMac11,3", + "iMac12,1", + "iMac12,2", + "MacPro4,1", + "MacPro5,1", +] + +Bluetooth_BRCM2070 = [ + "MacBook6,1", + "MacBook7,1", + "MacBookAir4,1", + "MacBookAir4,2", + "MacBookPro6,1", + "MacBookPro6,2", + "MacBookPro8,1", + "MacBookPro8,2", + "MacBookPro8,3", + "Macmini4,1", + "Macmini5,1", + "Macmini5,2", + "Macmini5,3", +] diff --git a/Resources/Utilities.py b/Resources/Utilities.py index cbefeb792f..f4e359616e 100644 --- a/Resources/Utilities.py +++ b/Resources/Utilities.py @@ -259,7 +259,7 @@ def download_file(link, location): def enable_apfs(fw_feature, fw_mask): fw_feature |= 2 ** 19 fw_mask |= 2 ** 19 - + return fw_feature, fw_mask # def menu(title, prompt, menu_options, add_quit=True, auto_number=False, in_between=[], top_level=False): # return_option = ["Q", "Quit", None] if top_level else ["B", "Back", None] diff --git a/Resources/device_probe.py b/Resources/device_probe.py index 54f98dcf2f..aff61baa8d 100644 --- a/Resources/device_probe.py +++ b/Resources/device_probe.py @@ -313,6 +313,7 @@ class Computer: cpu: Optional[CPU] = None oclp_version: Optional[str] = None opencore_version: Optional[str] = None + bluetooth_chipset: Optional[str] = None @staticmethod def probe(): @@ -324,6 +325,7 @@ def probe(): computer.storage_probe() computer.smbios_probe() computer.cpu_probe() + computer.bluetooth_probe() return computer def gpu_probe(self): @@ -437,3 +439,12 @@ def cpu_probe(self): subprocess.run("sysctl machdep.cpu.brand_string".split(), stdout=subprocess.PIPE).stdout.decode().partition(": ")[2].strip(), subprocess.run("sysctl machdep.cpu.features".split(), stdout=subprocess.PIPE).stdout.decode().partition(": ")[2].strip().split(" "), ) + + def bluetooth_probe(self): + usb_data: str = subprocess.run("system_profiler SPUSBDataType".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode() + if "BRCM2070 Hub" in usb_data: + self.bluetooth_chipset = "BRCM2070 Hub" + elif "BRCM2046 Hub" in usb_data: + self.bluetooth_chipset = "BRCM2046 Hub" + elif "Bluetooth": + self.bluetooth_chipset = "Generic" diff --git a/payloads/Config/config.plist b/payloads/Config/config.plist index 633c05a40c..d7ffcdb343 100644 --- a/payloads/Config/config.plist +++ b/payloads/Config/config.plist @@ -912,7 +912,25 @@ MaxKernel MinKernel - 20.4.0 + 16.0.0 + PlistPath + Contents/Info.plist + + + Arch + x86_64 + BundlePath + BlueToolFixup.kext + Comment + Fix Monterey Bluetooth + Enabled + + ExecutablePath + Contents/MacOS/BlueToolFixup + MaxKernel + + MinKernel + 21.0.0 PlistPath Contents/Info.plist diff --git a/payloads/Kexts/Acidanthera/BlueToolFixup-v2.6.1.zip b/payloads/Kexts/Acidanthera/BlueToolFixup-v2.6.1.zip new file mode 100644 index 0000000000..efd4f88421 Binary files /dev/null and b/payloads/Kexts/Acidanthera/BlueToolFixup-v2.6.1.zip differ diff --git a/payloads/Kexts/Acidanthera/BlueToolFixup.patch b/payloads/Kexts/Acidanthera/BlueToolFixup.patch new file mode 100644 index 0000000000..28c807cadd --- /dev/null +++ b/payloads/Kexts/Acidanthera/BlueToolFixup.patch @@ -0,0 +1,42 @@ +diff --git a/BrcmPatchRAM/BlueToolFixup.cpp b/BrcmPatchRAM/BlueToolFixup.cpp +index 0fa891a..819eb3f 100644 +--- a/BrcmPatchRAM/BlueToolFixup.cpp ++++ b/BrcmPatchRAM/BlueToolFixup.cpp +@@ -50,7 +50,15 @@ bool BlueToolFixup::start(IOService *provider) { + static const uint8_t kSkipUpdateFilePathOriginal[] = "/etc/bluetool/SkipBluetoothAutomaticFirmwareUpdate"; + static const uint8_t kSkipUpdateFilePathPatched[] = "/System/Library/CoreServices/boot.efi"; + ++static const uint8_t kBluetoothUSBNameOriginal[] = "Bluetooth USB Host Controller"; ++static const uint8_t kBluetoothUSBNamePatched2070[] = "BRCM2070 Hub Host Controller"; ++static const uint8_t kBluetoothUSBNamePatched2046[] = "BRCM2046 Hub Host Controller"; ++ + static const char *blueToolPath = "/usr/sbin/BlueTool"; ++static const char *bluetoothdPath = "/usr/sbin/bluetoothd"; ++ ++static const char brcm2046_patch = checkKernelArgument("-brcm2046_patch"); ++static const char brcm2070_patch = checkKernelArgument("-brcm2070_patch"); + + static mach_vm_address_t orig_cs_validate {}; + +@@ -71,8 +79,19 @@ static void patched_cs_validate_page(vnode_t vp, memory_object_t pager, memory_o + char path[PATH_MAX]; + int pathlen = PATH_MAX; + FunctionCast(patched_cs_validate_page, orig_cs_validate)(vp, pager, page_offset, data, validated_p, tainted_p, nx_p); +- if (vn_getpath(vp, path, &pathlen) == 0 && UNLIKELY(strcmp(path, blueToolPath) == 0)) { +- searchAndPatch(data, PAGE_SIZE, path, kSkipUpdateFilePathOriginal, kSkipUpdateFilePathPatched); ++ if (vn_getpath(vp, path, &pathlen) == 0) { ++ if (UNLIKELY(strcmp(path, blueToolPath) == 0)) { ++ searchAndPatch(data, PAGE_SIZE, path, kSkipUpdateFilePathOriginal, kSkipUpdateFilePathPatched); ++ } ++ if (UNLIKELY(strcmp(path, bluetoothdPath) == 0)) { ++ if (brcm2046_patch) { ++ DBGLOG(MODULE_SHORT, "Patching BRCM2046 Hub into bluetoothd"); ++ searchAndPatch(data, PAGE_SIZE, path, kBluetoothUSBNameOriginal, kBluetoothUSBNamePatched2046); ++ } else if (brcm2070_patch) { ++ DBGLOG(MODULE_SHORT, "Patching BRCM2070 Hub into bluetoothd"); ++ searchAndPatch(data, PAGE_SIZE, path, kBluetoothUSBNameOriginal, kBluetoothUSBNamePatched2070); ++ } ++ } + } + } +