diff --git a/Resources/Build.py b/Resources/Build.py
index f61a45564..d8daed90b 100644
--- a/Resources/Build.py
+++ b/Resources/Build.py
@@ -692,6 +692,14 @@ class BuildOpenCore:
# Note this function was added in 11.3 (20E232, 20.4), older builds do not support this (ie. 11.2.3)
print("- Allowing FileVault on Root Patched systems")
self.get_item_by_kv(self.config["Kernel"]["Patch"], "Identifier", "com.apple.filesystems.apfs")["Enabled"] = True
+
+ if self.model in ModelArray.Bluetooth_BRCM2070:
+ print("- Enabling Bluetooth BRCM2070 for macOS Monterey")
+ self.enable_kext("BlueToolFixup.kext", self.constants.bluetool_version, self.constants.brcm2070_path)
+ elif self.model in ModelArray.Bluetooth_BRCM2046:
+ print("- Enabling Bluetooth BRCM2046 for macOS Monterey")
+ self.enable_kext("BlueToolFixup.kext", self.constants.bluetool_version, self.constants.brcm2046_path)
+
def set_smbios(self):
diff --git a/Resources/Constants.py b/Resources/Constants.py
index a45f8f6a2..4a21e5cea 100644
--- a/Resources/Constants.py
+++ b/Resources/Constants.py
@@ -34,6 +34,7 @@ class Constants:
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
@@ -341,6 +342,18 @@ class Constants:
def plist_folder_path(self):
return self.payload_kexts_path / Path("Plists")
+ @property
+ def bluetooth_folder_path(self):
+ return self.payload_kexts_path / Path("Bluetooth")
+
+ @property
+ def brcm2046_path(self):
+ return self.bluetooth_folder_path / Path(f"BlueToolFixup-2046-v{self.bluetool_version}.zip")
+
+ @property
+ def brcm2070_path(self):
+ return self.bluetooth_folder_path / Path(f"BlueToolFixup-2070-v{self.bluetool_version}.zip")
+
@property
def platform_plugin_plist_path(self):
return self.plist_folder_path / Path("PlatformPlugin")
@@ -633,7 +646,7 @@ class Constants:
"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 688990bd1..4c1c0be42 100644
--- a/Resources/ModelArray.py
+++ b/Resources/ModelArray.py
@@ -1165,3 +1165,50 @@ dGPU_switch = [
"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",
+ "iMac7,1",
+ "iMac8,1",
+ "iMac9,1",
+ "iMac10,1",
+ "iMac11,1",
+ "iMac11,2",
+ "iMac11,3",
+ "iMac12,1",
+ "iMac12,2",
+ "MacPro3,1",
+ "MacPro4,1",
+ "MacPro5,1",
+ "XServer2,1",
+ "XServer3,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 ab5776fe1..6b15e0b9d 100644
--- a/Resources/Utilities.py
+++ b/Resources/Utilities.py
@@ -135,6 +135,7 @@ def amfi_status():
return False
return True
+
def check_oclp_boot():
if get_nvram("OCLP-Version", "4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102", decode=False):
return True
@@ -244,10 +245,11 @@ def download_file(link, location):
chunk = file.read(1024 * 1024 * 16)
return checksum
-def enable_apfs(fw_feature, fw_mask):
- fw_feature |= 2**19
- fw_mask |= 2**19
+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):
diff --git a/payloads/Config/config.plist b/payloads/Config/config.plist
index 3c03d2685..1a29c5a78 100644
--- a/payloads/Config/config.plist
+++ b/payloads/Config/config.plist
@@ -948,7 +948,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/Bluetooth/BlueToolFixup-2046-v2.6.1.zip b/payloads/Kexts/Bluetooth/BlueToolFixup-2046-v2.6.1.zip
new file mode 100644
index 000000000..355f0c70a
Binary files /dev/null and b/payloads/Kexts/Bluetooth/BlueToolFixup-2046-v2.6.1.zip differ
diff --git a/payloads/Kexts/Bluetooth/BlueToolFixup-2046.patch b/payloads/Kexts/Bluetooth/BlueToolFixup-2046.patch
new file mode 100644
index 000000000..36c38df92
--- /dev/null
+++ b/payloads/Kexts/Bluetooth/BlueToolFixup-2046.patch
@@ -0,0 +1,26 @@
+diff --git a/BrcmPatchRAM/BlueToolFixup.cpp b/BrcmPatchRAM/BlueToolFixup.cpp
+index 0fa891a..e68f28e 100644
+--- a/BrcmPatchRAM/BlueToolFixup.cpp
++++ b/BrcmPatchRAM/BlueToolFixup.cpp
+@@ -50,7 +50,11 @@ 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 kBluetoothUSBNamePatched[] = "BRCM2046 Hub Host Controller";
++
+ static const char *blueToolPath = "/usr/sbin/BlueTool";
++static const char *bluetoothdPath = "/usr/sbin/bluetoothd";
+
+ static mach_vm_address_t orig_cs_validate {};
+
+@@ -74,6 +78,9 @@ static void patched_cs_validate_page(vnode_t vp, memory_object_t pager, memory_o
+ 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 && UNLIKELY(strcmp(path, bluetoothdPath) == 0)) {
++ searchAndPatch(data, PAGE_SIZE, path, kBluetoothUSBNameOriginal, kBluetoothUSBNamePatched);
++ }
+ }
+
+
diff --git a/payloads/Kexts/Bluetooth/BlueToolFixup-2070-v2.6.1.zip b/payloads/Kexts/Bluetooth/BlueToolFixup-2070-v2.6.1.zip
new file mode 100644
index 000000000..fd0215ae1
Binary files /dev/null and b/payloads/Kexts/Bluetooth/BlueToolFixup-2070-v2.6.1.zip differ
diff --git a/payloads/Kexts/Bluetooth/BlueToolFixup-2070.patch b/payloads/Kexts/Bluetooth/BlueToolFixup-2070.patch
new file mode 100644
index 000000000..cd0dd1970
--- /dev/null
+++ b/payloads/Kexts/Bluetooth/BlueToolFixup-2070.patch
@@ -0,0 +1,26 @@
+diff --git a/BrcmPatchRAM/BlueToolFixup.cpp b/BrcmPatchRAM/BlueToolFixup.cpp
+index 0fa891a..6a9d2f3 100644
+--- a/BrcmPatchRAM/BlueToolFixup.cpp
++++ b/BrcmPatchRAM/BlueToolFixup.cpp
+@@ -50,7 +50,11 @@ 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 kBluetoothUSBNamePatched[] = "BRCM2070 Hub Host Controller";
++
+ static const char *blueToolPath = "/usr/sbin/BlueTool";
++static const char *bluetoothdPath = "/usr/sbin/bluetoothd";
+
+ static mach_vm_address_t orig_cs_validate {};
+
+@@ -74,6 +78,9 @@ static void patched_cs_validate_page(vnode_t vp, memory_object_t pager, memory_o
+ 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 && UNLIKELY(strcmp(path, bluetoothdPath) == 0)) {
++ searchAndPatch(data, PAGE_SIZE, path, kBluetoothUSBNameOriginal, kBluetoothUSBNamePatched);
++ }
+ }
+
+