Add compatibility information and improve multi hardware management

This commit is contained in:
Hoang Hong Quan
2025-03-20 20:15:01 +07:00
parent 6626e0cd88
commit 623bcbfbb8
4 changed files with 342 additions and 141 deletions

View File

@@ -1,4 +1,3 @@
from Scripts.datasets import chipset_data
from Scripts.datasets import gpu_data
from Scripts.datasets import os_data
from Scripts.datasets import pci_data
@@ -22,16 +21,16 @@ class CompatibilityChecker:
max_version = self.utils.parse_darwin_version(os_data.get_latest_darwin_version())[0]
min_version = self.utils.parse_darwin_version(os_data.get_lowest_darwin_version())[0]
if min_version < min_compatibility and max_compatibility < max_version:
return "\033[1;32m{} - {}\033[0m".format(
os_data.get_macos_name_by_darwin(device_compatibility[0]),
os_data.get_macos_name_by_darwin(device_compatibility[-1])
)
if max_compatibility == min_version:
return "\033[1;36mMaximum support up to {}\033[0m".format(
os_data.get_macos_name_by_darwin(device_compatibility[-1])
)
if min_version < min_compatibility or max_compatibility < max_version:
return "\033[1;32m{} to {}\033[0m".format(
os_data.get_macos_name_by_darwin(device_compatibility[-1]),
os_data.get_macos_name_by_darwin(device_compatibility[0])
)
return "\033[1;36mUp to {}\033[0m".format(
os_data.get_macos_name_by_darwin(device_compatibility[0])
@@ -53,19 +52,31 @@ class CompatibilityChecker:
max_version = "21.99.99"
self.hardware_report["CPU"]["Compatibility"] = (max_version, min_version)
print("{}- {}: {}".format(" "*3, self.hardware_report.get("CPU").get("Processor Name"), self.show_macos_compatibility(self.hardware_report["CPU"].get("Compatibility"))))
if max_version == min_version and max_version == None:
self.utils.request_input("\n\nThe CPU is not compatible with macOS!")
print("")
print("Missing required SSE4.x instruction set.")
print("Your CPU is not supported by macOS versions newer than Sierra (10.12).")
print("")
self.utils.request_input()
self.utils.exit_program()
self.max_native_macos_version = max_version
self.min_native_macos_version = min_version
def check_gpu_compatibility(self):
gpu_compatibility = []
if not self.hardware_report.get("GPU"):
print("")
print("No GPU found!")
print("Please make sure to export the hardware report with the GPU information")
print("and try again.")
print("")
self.utils.request_input()
self.utils.exit_program()
for gpu_name, gpu_props in self.hardware_report.get("GPU").items():
for gpu_name, gpu_props in self.hardware_report["GPU"].items():
gpu_manufacturer = gpu_props.get("Manufacturer")
gpu_codename = gpu_props.get("Codename")
device_id = gpu_props.get("Device ID")[5:]
@@ -84,14 +95,14 @@ class CompatibilityChecker:
max_version = "20.99.99"
elif device_id.startswith(("04", "0A", "0C", "0D", "0B", "16")):
max_version = "21.99.99"
elif device_id.startswith(("09", "19", "59", "59", "3E", "87", "9B")) and not device_id in ("3E90", "3E93", "3E99", "3E9C", "3EA1", "3EA4", "9B21", "9BA0", "9BA2", "9BA4", "9BA5", "9BA8", "9BAA", "9BAB", "9BAC"):
elif device_id.startswith(("09", "19", "59", "3E", "87", "9B")) and not device_id in ("3E90", "3E93", "3E99", "3E9C", "3EA1", "3EA4", "9B21", "9BA0", "9BA2", "9BA4", "9BA5", "9BA8", "9BAA", "9BAB", "9BAC"):
pass
elif device_id.startswith("8A"):
min_version = "19.4.0"
else:
max_version = min_version = None
if self.is_low_end_intel_cpu(self.hardware_report.get("CPU").get("Processor Name")) or self.hardware_report.get("Motherboard").get("Chipset") in chipset_data.IntelChipsets[127:141]:
if self.is_low_end_intel_cpu(self.hardware_report.get("CPU").get("Processor Name")):
max_version = min_version = None
elif "AMD" in gpu_manufacturer:
if "Navi 2" in gpu_codename:
@@ -144,15 +155,11 @@ class CompatibilityChecker:
if max_version != ocl_patched_max_version:
gpu_props["OCLP Compatibility"] = (ocl_patched_max_version, ocl_patched_min_version if self.utils.parse_darwin_version(ocl_patched_min_version) > self.utils.parse_darwin_version("{}.{}.{}".format(int(max_version[:2]) + 1, 0, 0)) else "{}.{}.{}".format(int(max_version[:2]) + 1, 0, 0))
print("{}- {}: {}{}".format(
" "*3,
gpu_name,
self.show_macos_compatibility(gpu_props.get("Compatibility")),
" \033[1;36m(requires monitor)\033[0m"
if max_version and \
not "Intel" in gpu_manufacturer and \
not any(monitor_info.get("Connected GPU", gpu_name) == gpu_name for monitor_name, monitor_info in self.hardware_report.get("Monitor", {}).items()) else ""
))
print("{}- {}: {}".format(" "*3, gpu_name, self.show_macos_compatibility(gpu_props.get("Compatibility"))))
if "OCLP Compatibility" in gpu_props:
print("{}- OCLP Compatibility: {}".format(" "*6, self.show_macos_compatibility(gpu_props.get("OCLP Compatibility"))))
connected_monitors = []
for monitor_name, monitor_info in self.hardware_report.get("Monitor", {}).items():
if monitor_info.get("Connected GPU") == gpu_name:
@@ -182,50 +189,46 @@ class CompatibilityChecker:
self.ocl_patched_macos_version = (gpu_props.get("OCLP Compatibility")[0], self.ocl_patched_macos_version[-1] if self.ocl_patched_macos_version and self.utils.parse_darwin_version(self.ocl_patched_macos_version[-1]) < self.utils.parse_darwin_version(gpu_props.get("OCLP Compatibility")[-1]) else gpu_props.get("OCLP Compatibility")[-1])
if max_supported_gpu_version == min_supported_gpu_version and max_supported_gpu_version == None:
self.utils.request_input("\n\nNo compatible GPU card for macOS was found!")
print("")
print("No compatible GPU for macOS was found!")
if self.hardware_report.get("Motherboard").get("Platform") == "Desktop":
print("Consider purchasing a compatible GPU for your system.")
print("")
self.utils.request_input()
self.utils.exit_program()
self.max_native_macos_version = max_supported_gpu_version if self.utils.parse_darwin_version(max_supported_gpu_version) < self.utils.parse_darwin_version(self.max_native_macos_version) else self.max_native_macos_version
self.min_native_macos_version = min_supported_gpu_version if self.utils.parse_darwin_version(min_supported_gpu_version) > self.utils.parse_darwin_version(self.min_native_macos_version) else self.min_native_macos_version
return gpu_compatibility
def check_sound_compatibility(self):
sound_info = {}
for audio_device, audio_props in self.hardware_report.get("Sound", {}).items():
codec_id = audio_props.get("Device ID")
max_version = min_version = None
if "USB" in audio_props.get("Bus Type") or \
codec_id.startswith("1002") or \
codec_id.startswith("8086") and not codec_id in pci_data.IntelSSTIDs or \
codec_id in codec_layouts.data:
audio_props["Compatibility"] = (os_data.get_latest_darwin_version(), os_data.get_lowest_darwin_version())
if codec_id in codec_layouts.data:
sound_info = {**{audio_device: audio_props}, **sound_info}
else:
sound_info[audio_device] = audio_props
else:
audio_props["Compatibility"] = (None, None)
sound_info[audio_device] = audio_props
max_version, min_version = os_data.get_latest_darwin_version(), os_data.get_lowest_darwin_version()
audio_props["Compatibility"] = (max_version, min_version)
print("{}- {}: {}".format(" "*3, audio_device, self.show_macos_compatibility(audio_props.get("Compatibility"))))
audio_endpoints = audio_props.get("Audio Endpoints")
if audio_endpoints:
print("{}- Audio Endpoint{}: {}".format(" "*6, "s" if len(audio_endpoints) > 1 else "", ", ".join(audio_endpoints)))
self.hardware_report["Sound"] = sound_info
def check_biometric_compatibility(self):
print(" \033[93mNote:\033[0m Biometric authentication in macOS requires Apple T2 Chip,")
print(" which is not available for Hackintosh systems.")
print("")
for biometric_device, biometric_props in self.hardware_report.get("Biometric", {}).items():
biometric_props["Compatibility"] = (None, None)
print("{}- {}: {}".format(" "*3, biometric_device, self.show_macos_compatibility(biometric_props.get("Compatibility"))))
def check_network_compatibility(self):
primary_wifi_device = next((device_props.get("Device ID") for device_name, device_props in self.hardware_report.get("Network", {}).items() if device_props.get("Device ID") in pci_data.BroadcomWiFiIDs), None)
if not primary_wifi_device:
primary_wifi_device = next((device_props.get("Device ID") for device_name, device_props in self.hardware_report.get("Network", {}).items() if device_props.get("Device ID") in pci_data.IntelWiFiIDs), None)
if not primary_wifi_device:
primary_wifi_device = next((device_props.get("Device ID") for device_name, device_props in self.hardware_report.get("Network", {}).items() if device_props.get("Device ID") in pci_data.AtherosWiFiIDs), None)
for device_name, device_props in self.hardware_report.get("Network", {}).items():
bus_type = device_props.get("Bus Type")
device_id = device_props.get("Device ID")
@@ -253,12 +256,10 @@ class CompatibilityChecker:
min_version = "21.0.0"
if device_id in pci_data.WirelessCardIDs:
if device_id == primary_wifi_device:
if not device_id in pci_data.IntelWiFiIDs and not device_id in pci_data.AtherosWiFiIDs[8:]:
device_props["OCLP Compatibility"] = (ocl_patched_max_version, ocl_patched_min_version)
self.ocl_patched_macos_version = (ocl_patched_max_version, self.ocl_patched_macos_version[-1] if self.ocl_patched_macos_version and self.utils.parse_darwin_version(self.ocl_patched_macos_version[-1]) < self.utils.parse_darwin_version(device_props.get("OCLP Compatibility")[-1]) else device_props.get("OCLP Compatibility")[-1])
device_props["Compatibility"] = (max_version, min_version)
primary_wifi_device = None
if not device_id in pci_data.IntelWiFiIDs and not device_id in pci_data.AtherosWiFiIDs[8:]:
device_props["OCLP Compatibility"] = (ocl_patched_max_version, ocl_patched_min_version)
self.ocl_patched_macos_version = (ocl_patched_max_version, self.ocl_patched_macos_version[-1] if self.ocl_patched_macos_version and self.utils.parse_darwin_version(self.ocl_patched_macos_version[-1]) < self.utils.parse_darwin_version(device_props.get("OCLP Compatibility")[-1]) else device_props.get("OCLP Compatibility")[-1])
device_props["Compatibility"] = (max_version, min_version)
elif device_id in pci_data.EthernetIDs + pci_data.WirelessUSBIDs:
device_props["Compatibility"] = (max_version, min_version)
@@ -267,9 +268,31 @@ class CompatibilityChecker:
print("{}- {}: {}".format(" "*3, device_name, self.show_macos_compatibility(device_props.get("Compatibility"))))
if device_id in pci_data.WirelessCardIDs:
if device_id in pci_data.BroadcomWiFiIDs:
print("{}- Continuity Support: \033[1;32mFull\033[0m (AirDrop, Handoff, Universal Clipboard, Instant Hotspot,...)".format(" "*6))
elif device_id in pci_data.IntelWiFiIDs:
print("{}- Continuity Support: \033[1;33mPartial\033[0m (Handoff and Universal Clipboard with AirportItlwm)".format(" "*6))
print("{}\033[93mNote:\033[0m AirDrop, Universal Clipboard, Instant Hotspot,... not available".format(" "*6))
elif device_id in pci_data.AtherosWiFiIDs:
print("{}- Continuity Support: \033[1;31mLimited\033[0m (No Continuity features available)".format(" "*6))
print("{}\033[93mNote:\033[0m Atheros cards are not recommended for macOS".format(" "*6))
if "OCLP Compatibility" in device_props:
print("{}- OCLP Compatibility: {}".format(" "*6, self.show_macos_compatibility(device_props.get("OCLP Compatibility"))))
def check_storage_compatibility(self):
for controller_name, controller_props in self.hardware_report.get("Storage Controllers", {}).items():
if "PCI" not in controller_props.get("Bus Type"):
if not self.hardware_report.get("Storage Controllers"):
print("")
print("No storage controller found!")
print("Please make sure to export the hardware report with the storage controller information")
print("and try again.")
print("")
self.utils.request_input()
self.utils.exit_program()
for controller_name, controller_props in self.hardware_report["Storage Controllers"].items():
if controller_props.get("Bus Type") != "PCI":
continue
device_id = controller_props.get("Device ID")
@@ -279,18 +302,27 @@ class CompatibilityChecker:
min_version = os_data.get_lowest_darwin_version()
if device_id in pci_data.IntelVMDIDs:
self.utils.request_input("\n\nDisable Intel RST VMD in the BIOS before exporting the hardware report and try again with the new report")
print("")
print("Intel VMD controllers are not supported in macOS.")
print("Please disable Intel VMD in the BIOS settings and try again with new hardware report.")
print("")
self.utils.request_input()
self.utils.exit_program()
controller_props["Compatibility"] = (max_version, min_version)
if next((device for device in pci_data.UnsupportedNVMeSSDIDs if device_id == device[0] and subsystem_id in device[1]), None):
controller_props["Compatibility"] = (None, None)
max_version = min_version = None
controller_props["Compatibility"] = (max_version, min_version)
print("{}- {}: {}".format(" "*3, controller_name, self.show_macos_compatibility(controller_props.get("Compatibility"))))
if all(controller_props.get("Compatibility") == (None, None) for controller_name, controller_props in self.hardware_report.get("Storage Controllers", {}).items()):
self.utils.request_input("\n\nNo compatible storage for macOS was found!")
if all(controller_props.get("Compatibility") == (None, None) for controller_name, controller_props in self.hardware_report["Storage Controllers"].items()):
print("")
print("No compatible storage controller for macOS was found!")
print("Consider purchasing a compatible SSD NVMe for your system.")
print("Western Digital NVMe SSDs are generally recommended for good macOS compatibility.")
print("")
self.utils.request_input()
self.utils.exit_program()
def check_bluetooth_compatibility(self):
@@ -308,59 +340,34 @@ class CompatibilityChecker:
max_version = min_version = None
bluetooth_props["Compatibility"] = (max_version, min_version)
print("{}- {}: {}".format(" "*3, bluetooth_name, self.show_macos_compatibility(bluetooth_props.get("Compatibility"))))
def check_sd_controller_compatibility(self):
for controller_name, controller_props in self.hardware_report.get("SD Controller", {}).items():
if controller_props.get("Device ID") not in pci_data.RealtekCardReaderIDs:
controller_props["Compatibility"] = (None, None)
device_id = controller_props.get("Device ID")
max_version = os_data.get_latest_darwin_version()
min_version = os_data.get_lowest_darwin_version()
if device_id in pci_data.RealtekCardReaderIDs:
if device_id in pci_data.RealtekCardReaderIDs[:5]:
max_version = "23.99.99"
else:
controller_props["Compatibility"] = (os_data.get_latest_darwin_version() if controller_props.get("Device ID") in pci_data.RealtekCardReaderIDs[5:] else "23.99.99", os_data.get_lowest_darwin_version())
max_version = min_version = None
controller_props["Compatibility"] = (max_version, min_version)
print("{}- {}: {}".format(" "*3, controller_name, self.show_macos_compatibility(controller_props.get("Compatibility"))))
def get_unsupported_devices(self, macos_verison):
new_hardware_report = {}
unsupported_device = {}
needs_oclp = False
for device_type, devices in self.hardware_report.items():
if device_type in ("Motherboard", "BIOS", "CPU", "USB Controllers", "Input", "System Devices"):
new_hardware_report[device_type] = devices
continue
new_hardware_report[device_type] = {}
for device_name in devices:
device_props = devices[device_name].copy()
if device_props.get("OCLP Compatibility") and self.utils.parse_darwin_version(device_props.get("OCLP Compatibility")[0]) >= self.utils.parse_darwin_version(macos_verison) >= self.utils.parse_darwin_version(device_props.get("OCLP Compatibility")[-1]):
new_hardware_report[device_type][device_name] = device_props
needs_oclp = True
continue
device_compatibility = device_props.get("Compatibility")
if device_compatibility:
if device_compatibility[0] is None or not self.utils.parse_darwin_version(device_compatibility[0]) >= self.utils.parse_darwin_version(macos_verison) >= self.utils.parse_darwin_version(device_compatibility[-1]):
unsupported_device["{}: {}{}".format(device_props.get("Device Type") or device_type, device_name, "" if not device_props.get("Audio Endpoints") else " ({})".format(", ".join(device_props.get("Audio Endpoints"))))] = device_props
else:
new_hardware_report[device_type][device_name] = device_props
else:
new_hardware_report[device_type][device_name] = device_props
if new_hardware_report[device_type].get(device_name) and new_hardware_report[device_type][device_name].get("OCLP Compatibility"):
del new_hardware_report[device_type][device_name]["OCLP Compatibility"]
if not new_hardware_report[device_type]:
del new_hardware_report[device_type]
return new_hardware_report, unsupported_device, needs_oclp
def check_compatibility(self, hardware_report):
self.hardware_report = hardware_report
self.ocl_patched_macos_version = None
self.utils.head("Compatibility Checker")
print()
print("")
print("Checking compatibility with macOS for the following devices:")
print("")
steps = [
('CPU', self.check_cpu_compatibility),
@@ -378,10 +385,10 @@ class CompatibilityChecker:
if self.hardware_report.get(device_type):
index += 1
print("{}. {}:".format(index, device_type))
time.sleep(0.5)
time.sleep(0.25)
function()
print("")
self.utils.request_input()
return (self.min_native_macos_version, self.max_native_macos_version), *self.get_unsupported_devices(self.max_native_macos_version), self.ocl_patched_macos_version
return hardware_report, (self.min_native_macos_version, self.max_native_macos_version), self.ocl_patched_macos_version

View File

@@ -304,7 +304,7 @@ class ConfigProdigy:
except:
continue
def deviceproperties(self, hardware_report, unsupported_devices, macos_version, kexts):
def deviceproperties(self, hardware_report, disabled_devices, macos_version, kexts):
deviceproperties_add = {}
def add_device_property(pci_path, properties):
@@ -325,7 +325,6 @@ class ConfigProdigy:
if device_id in pci_data.IntelWiFiIDs and network_props.get("PCI Path"):
add_device_property(network_props.get("PCI Path"), {"IOName": "pci14e4,43a0"})
elif kext.name == "WhateverGreen":
discrete_gpu = None
for gpu_name, gpu_info in hardware_report.get("GPU", {}).items():
if gpu_info.get("Device Type") == "Integrated GPU":
if "Intel" in gpu_info.get("Manufacturer"):
@@ -348,8 +347,6 @@ class ConfigProdigy:
elif "Ivy Bridge" in gpu_info.get("Codename") and device_id in "8086-1C3A":
add_device_property(device_info.get("PCI Path", "PciRoot(0x0)/Pci(0x16,0x0)"), {"device-id": "3A1E0000"})
elif gpu_info.get("Device Type") == "Discrete GPU":
discrete_gpu = gpu_info
if not gpu_info.get("Device ID") in pci_data.SpoofGPUIDs:
continue
@@ -393,7 +390,7 @@ class ConfigProdigy:
if not device_props.get("ACPI Path"):
add_device_property(device_props.get("PCI Path"), {"built-in": "01"})
for device_name, device_props in unsupported_devices.items():
for device_name, device_props in disabled_devices.items():
if "GPU" in device_name and not device_props.get("Disabled", False):
add_device_property(device_props.get("PCI Path"), {"disable-gpu": True})
@@ -601,7 +598,7 @@ class ConfigProdigy:
return uefi_drivers
def genarate(self, hardware_report, unsupported_devices, smbios_model, macos_version, needs_oclp, kexts, config):
def genarate(self, hardware_report, disabled_devices, smbios_model, macos_version, needs_oclp, kexts, config):
del config["#WARNING - 1"]
del config["#WARNING - 2"]
del config["#WARNING - 3"]
@@ -626,7 +623,7 @@ class ConfigProdigy:
config["Booter"]["Quirks"]["SetupVirtualMap"] = hardware_report.get("BIOS").get("Firmware Type") == "UEFI" and not hardware_report.get("Motherboard").get("Chipset") in chipset_data.AMDChipsets[11:17] + chipset_data.IntelChipsets[90:100]
config["Booter"]["Quirks"]["SyncRuntimePermissions"] = "AMD" in hardware_report.get("CPU").get("Manufacturer") or hardware_report.get("Motherboard").get("Chipset") in chipset_data.IntelChipsets[90:100] + chipset_data.IntelChipsets[104:]
config["DeviceProperties"]["Add"] = self.deviceproperties(hardware_report, unsupported_devices, macos_version, kexts)
config["DeviceProperties"]["Add"] = self.deviceproperties(hardware_report, disabled_devices, macos_version, kexts)
config["Kernel"]["Block"] = self.block_kext_bundle(kexts)
spoof_cpuid = self.spoof_cpuid(

View File

@@ -0,0 +1,176 @@
from Scripts.datasets import os_data
from Scripts.datasets import pci_data
from Scripts import compatibility_checker
from Scripts import utils
class HardwareCustomizer:
def __init__(self):
self.compatibility_checker = compatibility_checker.CompatibilityChecker()
self.utils = utils.Utils()
def hardware_customization(self, hardware_report, macos_version):
self.hardware_report = hardware_report
self.macos_version = macos_version
self.customized_hardware = {}
self.disabled_devices = {}
self.selected_devices = {}
needs_oclp = False
self.utils.head("Hardware Customization")
for device_type, devices in self.hardware_report.items():
if not device_type in ("GPU", "Sound", "Biometric", "Network", "Storage Controllers", "Bluetooth", "SD Controller"):
self.customized_hardware[device_type] = devices
continue
self.customized_hardware[device_type] = {}
for device_name in devices:
device_props = devices[device_name].copy()
if device_props.get("OCLP Compatibility") and self.utils.parse_darwin_version(device_props.get("OCLP Compatibility")[0]) >= self.utils.parse_darwin_version(macos_version) >= self.utils.parse_darwin_version(device_props.get("OCLP Compatibility")[-1]):
self.customized_hardware[device_type][device_name] = device_props
needs_oclp = True
continue
device_compatibility = device_props.get("Compatibility", (os_data.get_latest_darwin_version(), os_data.get_lowest_darwin_version()))
try:
if self.utils.parse_darwin_version(device_compatibility[0]) >= self.utils.parse_darwin_version(macos_version) >= self.utils.parse_darwin_version(device_compatibility[-1]):
self.customized_hardware[device_type][device_name] = device_props
except:
self.disabled_devices["{}: {}{}".format(device_props["Device Type"] if not "Unknown" in device_props.get("Device Type", "Unknown") else device_type, device_name, "" if not device_props.get("Audio Endpoints") else " ({})".format(", ".join(device_props.get("Audio Endpoints"))))] = device_props
if self.customized_hardware[device_type].get(device_name) and self.customized_hardware[device_type][device_name].get("OCLP Compatibility"):
del self.customized_hardware[device_type][device_name]["OCLP Compatibility"]
if not self.customized_hardware[device_type]:
del self.customized_hardware[device_type]
else:
if device_type in ("GPU", "Network", "Bluetooth"):
self._handle_device_selection(device_type if device_type != "Network" else "WiFi")
if self.selected_devices:
self.utils.head("Device Selection Summary")
print("")
print("Selected devices:")
print("")
print("Type Device Device ID")
print("------------------------------------------------------------------")
for device_type, device_dict in self.selected_devices.items():
device_name = list(device_dict.keys())[0]
device_props = list(device_dict.values())[0]
device_id = device_props.get("Device ID", "Unknown")
print("{:<13} {:<42} {}".format(device_type, device_name[:38], device_id))
print("")
print("All other devices of the same type have been disabled.")
print("")
self.utils.request_input("Press Enter to continue...")
return self.customized_hardware, self.disabled_devices, needs_oclp
def _handle_device_selection(self, device_type):
devices = self._get_compatible_devices(device_type)
if len(devices) > 1:
print("\n*** Multiple {} Devices Detected".format(device_type))
if device_type == "WiFi" or device_type == "Bluetooth":
print(f"macOS works best with only one {device_type} device enabled.")
elif device_type == "GPU":
_has_multiple_compatible_devices = False
for gpu_name, gpu_props in devices.items():
gpu_manufacturer = gpu_props.get("Manufacturer")
gpu_codename = gpu_props.get("Codename")
if gpu_manufacturer == "AMD":
if gpu_props.get("Device Type") == "Integrated GPU":
_has_multiple_compatible_devices = True
elif gpu_props.get("Device Type") == "Discrete GPU" and gpu_codename == "Navi 22":
_has_multiple_compatible_devices = True
if _has_multiple_compatible_devices:
print("Multiple active GPUs can cause kext conflicts in macOS.")
print("It's recommended to use only one GPU at a time.")
else:
return
selected_device = self._select_device(device_type, devices)
if selected_device:
self.selected_devices[device_type] = {
selected_device: devices[selected_device]
}
def _get_compatible_devices(self, device_type):
compatible_devices = {}
if device_type == "WiFi":
hardware_category = "Network"
else:
hardware_category = device_type
for device_name, device_props in self.customized_hardware.get(hardware_category, {}).items():
if device_type == "WiFi":
device_id = device_props.get("Device ID")
if device_id not in pci_data.WirelessCardIDs:
continue
compatible_devices[device_name] = device_props
return compatible_devices
def _select_device(self, device_type, devices):
print("")
print("Please select which {} device you want to use:".format(device_type))
print("")
for index, device_name in enumerate(devices, start=1):
device_props = devices[device_name]
compatibility = device_props.get("Compatibility")
print("{}. {}".format(index, device_name))
print(" Device ID: {}".format(device_props.get("Device ID", "Unknown")))
print(" Compatibility: {}".format(self.compatibility_checker.show_macos_compatibility(compatibility)))
if device_props.get("OCLP Compatibility"):
oclp_compatibility = device_props.get("OCLP Compatibility")
if self.utils.parse_darwin_version(oclp_compatibility[0]) > self.utils.parse_darwin_version(compatibility[0]):
print(" OCLP Compatibility: {}".format(self.compatibility_checker.show_macos_compatibility((oclp_compatibility[0], os_data.get_lowest_darwin_version()))))
print()
while True:
choice = self.utils.request_input(f"Select a {device_type} device (1-{len(devices)}): ")
try:
choice_num = int(choice)
if 1 <= choice_num <= len(devices):
selected_device = list(devices)[choice_num - 1]
for device in devices:
if device != selected_device:
self._disable_device(device_type, device, devices[device])
return selected_device
else:
print("Invalid option. Please try again.")
except:
print("Please enter a number.")
def _disable_device(self, device_type, device_name, device_props):
if device_type == "WiFi":
device_id = device_props.get("Device ID")
if not device_id or device_id not in pci_data.WirelessCardIDs:
return
hardware_category = "Network"
else:
hardware_category = device_type
if (hardware_category in self.customized_hardware and device_name in self.customized_hardware[hardware_category]):
del self.customized_hardware[hardware_category][device_name]
if not self.customized_hardware[hardware_category]:
del self.customized_hardware[hardware_category]
self.disabled_devices["{}: {}".format(device_type, device_name)] = device_props