mirror of
https://github.com/outbackdingo/OpCore-Simplify.git
synced 2026-01-27 10:19:49 +00:00
Add compatibility information and improve multi hardware management
This commit is contained in:
@@ -3,6 +3,7 @@ from Scripts import acpi_guru
|
||||
from Scripts import compatibility_checker
|
||||
from Scripts import config_prodigy
|
||||
from Scripts import gathering_files
|
||||
from Scripts import hardware_customizer
|
||||
from Scripts import kext_maestro
|
||||
from Scripts import run
|
||||
from Scripts import smbios
|
||||
@@ -18,10 +19,11 @@ import time
|
||||
class OCPE:
|
||||
def __init__(self):
|
||||
self.u = utils.Utils("OpCore Simplify")
|
||||
self.o = gathering_files.gatheringFiles()
|
||||
self.ac = acpi_guru.ACPIGuru()
|
||||
self.c = compatibility_checker.CompatibilityChecker()
|
||||
self.co = config_prodigy.ConfigProdigy()
|
||||
self.o = gathering_files.gatheringFiles()
|
||||
self.h = hardware_customizer.HardwareCustomizer()
|
||||
self.k = kext_maestro.KextMaestro()
|
||||
self.s = smbios.SMBIOS()
|
||||
self.r = run.Run()
|
||||
@@ -45,11 +47,10 @@ class OCPE:
|
||||
self.u.head("Select hardware report")
|
||||
print("")
|
||||
if os.name == "nt":
|
||||
print("\033[1;36m", end="")
|
||||
print("Note:")
|
||||
print("\033[93mNote:\033[0m")
|
||||
print("- Ensure you are using the latest version of Hardware Sniffer before generating the hardware report.")
|
||||
print("- Hardware Sniffer will not collect information related to Resizable BAR option of GPU (disabled by default) and monitor connections in Windows PE.")
|
||||
print("\033[0m", end="")
|
||||
print("")
|
||||
if self.hardware_sniffer:
|
||||
print("")
|
||||
print("E. Export hardware report (Recommended)")
|
||||
@@ -92,28 +93,50 @@ class OCPE:
|
||||
|
||||
return path, data
|
||||
|
||||
def select_macos_version(self, native_macos_version, ocl_patched_macos_version):
|
||||
def select_macos_version(self, hardware_report, native_macos_version, ocl_patched_macos_version):
|
||||
suggested_macos_version = native_macos_version[1]
|
||||
version_pattern = re.compile(r'^(\d+)(?:\.(\d+)(?:\.(\d+))?)?$')
|
||||
|
||||
for device_type in ("GPU", "Network", "Bluetooth", "SD Controller"):
|
||||
if device_type in hardware_report:
|
||||
for device_name, device_props in hardware_report[device_type].items():
|
||||
if device_props.get("Compatibility", (None, None)) != (None, None):
|
||||
if device_type == "GPU" and device_props.get("Device Type") == "Integrated GPU":
|
||||
device_id = device_props.get("Device ID", ""*8)[5:]
|
||||
|
||||
if device_props.get("Manufacturer") == "AMD" or device_id.startswith(("59", "87C0")):
|
||||
suggested_macos_version = "22.99.99"
|
||||
elif device_id.startswith(("09", "19")):
|
||||
suggested_macos_version = "21.99.99"
|
||||
|
||||
if self.u.parse_darwin_version(suggested_macos_version) > self.u.parse_darwin_version(device_props.get("Compatibility")[0]):
|
||||
suggested_macos_version = device_props.get("Compatibility")[0]
|
||||
|
||||
while True:
|
||||
self.u.head("Select macOS Version")
|
||||
if native_macos_version[1][:2] != suggested_macos_version[:2]:
|
||||
print("")
|
||||
print("\033[1;36mSuggested macOS version:\033[0m")
|
||||
print("- For better compatibility and stability, we suggest you to use only {} or older.".format(os_data.get_macos_name_by_darwin(suggested_macos_version)))
|
||||
print("")
|
||||
print("Available macOS versions:")
|
||||
print("")
|
||||
if ocl_patched_macos_version:
|
||||
print("* Native macOS versions: ")
|
||||
print(" * Native macOS versions: ")
|
||||
for darwin_version in range(int(native_macos_version[0][:2]), min(int(native_macos_version[-1][:2]), (int(ocl_patched_macos_version[-1][:2]) - 1) if ocl_patched_macos_version else 99) + 1):
|
||||
print("{}{}. {}".format(" "*3 if ocl_patched_macos_version else "", darwin_version, os_data.get_macos_name_by_darwin(str(darwin_version))))
|
||||
if ocl_patched_macos_version:
|
||||
print("* Requires OpenCore Legacy Patcher: ")
|
||||
print(" * Requires OpenCore Legacy Patcher: ")
|
||||
for darwin_version in range(int(ocl_patched_macos_version[-1][:2]), int(ocl_patched_macos_version[0][:2]) + 1):
|
||||
print(" {}. {}".format(darwin_version, os_data.get_macos_name_by_darwin(str(darwin_version))))
|
||||
print("")
|
||||
print("Please enter the macOS version you want to select:")
|
||||
print("\033[93mNote:\033[0m")
|
||||
print("- To select a major version, enter the number (e.g., 19).")
|
||||
print("- To specify a full version, use the Darwin version format (e.g., 22.4.6).")
|
||||
print("")
|
||||
print("Q. Quit")
|
||||
print("")
|
||||
option = self.u.request_input("Select macOS version: ")
|
||||
option = self.u.request_input("Please enter the macOS version you want to use (default: {}): ".format(os_data.get_macos_name_by_darwin(suggested_macos_version))) or suggested_macos_version
|
||||
if option.lower() == "q":
|
||||
self.u.exit_program()
|
||||
|
||||
@@ -125,7 +148,7 @@ class OCPE:
|
||||
(ocl_patched_macos_version and self.u.parse_darwin_version(ocl_patched_macos_version[-1]) <= self.u.parse_darwin_version(target_version) <= self.u.parse_darwin_version(ocl_patched_macos_version[0])):
|
||||
return target_version
|
||||
|
||||
def build_opencore_efi(self, hardware_report, unsupported_devices, smbios_model, macos_version, needs_oclp):
|
||||
def build_opencore_efi(self, hardware_report, disabled_devices, smbios_model, macos_version, needs_oclp):
|
||||
self.u.head("Building OpenCore EFI")
|
||||
print("")
|
||||
print("1. Copy EFI base to results folder...", end=" ")
|
||||
@@ -149,7 +172,7 @@ class OCPE:
|
||||
config_data["ACPI"]["Patch"] = []
|
||||
if self.ac.ensure_dsdt():
|
||||
self.ac.hardware_report = hardware_report
|
||||
self.ac.unsupported_devices = unsupported_devices
|
||||
self.ac.disabled_devices = disabled_devices
|
||||
self.ac.acpi_directory = os.path.join(self.result_dir, "EFI", "OC", "ACPI")
|
||||
self.ac.smbios_model = smbios_model
|
||||
self.ac.lpc_bus_device = self.ac.get_lpc_name()
|
||||
@@ -179,7 +202,7 @@ class OCPE:
|
||||
config_data["Kernel"]["Add"] = self.k.load_kexts(hardware_report, macos_version, kexts_directory)
|
||||
print("Done")
|
||||
print("4. Generate config.plist...", end=" ")
|
||||
self.co.genarate(hardware_report, unsupported_devices, smbios_model, macos_version, needs_oclp, self.k.kexts, config_data)
|
||||
self.co.genarate(hardware_report, disabled_devices, smbios_model, macos_version, needs_oclp, self.k.kexts, config_data)
|
||||
self.u.write_file(config_file, config_data)
|
||||
print("Done")
|
||||
print("5. Clean up unused drivers, resources, and tools...", end=" ")
|
||||
@@ -272,7 +295,7 @@ class OCPE:
|
||||
def main(self):
|
||||
hardware_report_path = None
|
||||
native_macos_version = None
|
||||
unsupported_devices = None
|
||||
disabled_devices = None
|
||||
macos_version = None
|
||||
ocl_patched_macos_version = None
|
||||
needs_oclp = False
|
||||
@@ -287,11 +310,10 @@ class OCPE:
|
||||
print("* Hardware Compatibility:")
|
||||
if native_macos_version:
|
||||
print(" - Native macOS Version: {}".format(self.c.show_macos_compatibility((native_macos_version[-1], native_macos_version[0]))))
|
||||
if unsupported_devices:
|
||||
print(" - Unsupported devices:")
|
||||
for index, device_name in enumerate(unsupported_devices, start=1):
|
||||
device_props = unsupported_devices.get(device_name)
|
||||
print("{}{}. {}{}".format(" "*6, index, device_name, "" if not device_props.get("Audio Endpoints") else " ({})".format(", ".join(device_props.get("Audio Endpoints")))))
|
||||
if disabled_devices:
|
||||
print(" - Disabled Devices:")
|
||||
for index, device_name in enumerate(disabled_devices, start=1):
|
||||
print("{}{}. {}".format(" "*6, index, device_name))
|
||||
print("* EFI Options:")
|
||||
print(" - macOS Version: {}{}{}".format("Unknown" if not macos_version else os_data.get_macos_name_by_darwin(macos_version), "" if not macos_version else " ({})".format(macos_version), ". \033[1;36mRequires OpenCore Legacy Patcher\033[0m" if needs_oclp else ""))
|
||||
print(" - SMBIOS: {}".format("Unknown" if not smbios_model else smbios_model))
|
||||
@@ -316,40 +338,39 @@ class OCPE:
|
||||
|
||||
if option == 1:
|
||||
hardware_report_path, hardware_report = self.select_hardware_report()
|
||||
native_macos_version, hardware_report, unsupported_devices, needs_oclp, ocl_patched_macos_version = self.c.check_compatibility(hardware_report)
|
||||
macos_version = native_macos_version[-1]
|
||||
if int(macos_version[:2]) == os_data.macos_versions[-1].darwin_version and os_data.macos_versions[-1].release_status == "beta":
|
||||
macos_version = str(int(macos_version[:2]) - 1) + macos_version[2:]
|
||||
smbios_model = self.s.select_smbios_model(hardware_report, macos_version)
|
||||
hardware_report, native_macos_version, ocl_patched_macos_version = self.c.check_compatibility(hardware_report)
|
||||
macos_version = self.select_macos_version(hardware_report, native_macos_version, ocl_patched_macos_version)
|
||||
customized_hardware, disabled_devices, needs_oclp = self.h.hardware_customization(hardware_report, macos_version)
|
||||
smbios_model = self.s.select_smbios_model(customized_hardware, macos_version)
|
||||
if not self.ac.ensure_dsdt():
|
||||
self.ac.select_acpi_tables()
|
||||
self.ac.select_acpi_patches(hardware_report, unsupported_devices)
|
||||
self.k.select_required_kexts(hardware_report, macos_version, needs_oclp, self.ac.patches)
|
||||
self.s.smbios_specific_options(hardware_report, smbios_model, macos_version, self.ac.patches, self.k)
|
||||
self.ac.select_acpi_patches(customized_hardware, disabled_devices)
|
||||
self.k.select_required_kexts(customized_hardware, macos_version, needs_oclp, self.ac.patches)
|
||||
self.s.smbios_specific_options(customized_hardware, smbios_model, macos_version, self.ac.patches, self.k)
|
||||
elif option < 7:
|
||||
try:
|
||||
hardware_report
|
||||
customized_hardware
|
||||
except:
|
||||
self.u.request_input("\nPlease select a hardware report to proceed")
|
||||
continue
|
||||
|
||||
if option == 2:
|
||||
macos_version = self.select_macos_version(native_macos_version, ocl_patched_macos_version)
|
||||
hardware_report, unsupported_devices, needs_oclp = self.c.get_unsupported_devices(macos_version)
|
||||
smbios_model = self.s.select_smbios_model(hardware_report, macos_version)
|
||||
self.k.select_required_kexts(hardware_report, macos_version, needs_oclp, self.ac.patches)
|
||||
self.s.smbios_specific_options(hardware_report, smbios_model, macos_version, self.ac.patches, self.k)
|
||||
customized_hardware, disabled_devices, needs_oclp = self.h.hardware_customization(macos_version)
|
||||
smbios_model = self.s.select_smbios_model(customized_hardware, macos_version)
|
||||
self.k.select_required_kexts(customized_hardware, macos_version, needs_oclp, self.ac.patches)
|
||||
self.s.smbios_specific_options(customized_hardware, smbios_model, macos_version, self.ac.patches, self.k)
|
||||
elif option == 3:
|
||||
self.ac.customize_patch_selection()
|
||||
elif option == 4:
|
||||
self.k.kext_configuration_menu(macos_version)
|
||||
elif option == 5:
|
||||
smbios_model = self.s.customize_smbios_model(hardware_report, smbios_model, macos_version)
|
||||
self.s.smbios_specific_options(hardware_report, smbios_model, macos_version, self.ac.patches, self.k)
|
||||
smbios_model = self.s.customize_smbios_model(customized_hardware, smbios_model, macos_version)
|
||||
self.s.smbios_specific_options(customized_hardware, smbios_model, macos_version, self.ac.patches, self.k)
|
||||
elif option == 6:
|
||||
self.gathering_files(macos_version)
|
||||
self.build_opencore_efi(hardware_report, unsupported_devices, smbios_model, macos_version, needs_oclp)
|
||||
self.results(hardware_report, smbios_model, self.k.kexts)
|
||||
self.build_opencore_efi(customized_hardware, disabled_devices, smbios_model, macos_version, needs_oclp)
|
||||
self.results(customized_hardware, smbios_model, self.k.kexts)
|
||||
|
||||
if __name__ == '__main__':
|
||||
update_flag = updater.Updater().run_update()
|
||||
|
||||
@@ -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
|
||||
@@ -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(
|
||||
|
||||
176
Scripts/hardware_customizer.py
Normal file
176
Scripts/hardware_customizer.py
Normal 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
|
||||
Reference in New Issue
Block a user