mirror of
https://github.com/dortania/OpenCore-Legacy-Patcher.git
synced 2026-04-24 20:10:14 +10:00
detect.py: Strip incompatible hardware combos
ie. Non-Metal with Metal, Metal 3802 with Metal 31001
This commit is contained in:
@@ -12,7 +12,7 @@ from enum import StrEnum
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from functools import cache
|
from functools import cache
|
||||||
|
|
||||||
from .hardware.base import BaseHardware
|
from .hardware.base import BaseHardware, HardwareVariantGraphicsSubclass
|
||||||
|
|
||||||
from .hardware.graphics import (
|
from .hardware.graphics import (
|
||||||
intel_iron_lake,
|
intel_iron_lake,
|
||||||
@@ -331,23 +331,109 @@ class HardwarePatchsetDetection:
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def _strip_incompatible_hardware(self, present_hardware: list[BaseHardware]) -> list[BaseHardware]:
|
||||||
|
"""
|
||||||
|
Strip out incompatible hardware. Priority is given to Metal GPUs (specifically 31001 when applicable)
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- Non-Metal GPUs are stripped out if any Metal GPUs are present
|
||||||
|
- Metal 3802 GPUs are stripped out if Metal 31001 GPUs are present on macOS Sequoia or newer
|
||||||
|
"""
|
||||||
|
non_metal_gpu_present = False
|
||||||
|
metal_gpu_present = False
|
||||||
|
metal_3802_gpu_present = False
|
||||||
|
metal_31001_gpu_present = False
|
||||||
|
|
||||||
|
for hardware in present_hardware:
|
||||||
|
hardware: BaseHardware
|
||||||
|
sub_variant = hardware.hardware_variant_graphics_subclass()
|
||||||
|
if sub_variant == HardwareVariantGraphicsSubclass.METAL_31001_GRAPHICS:
|
||||||
|
metal_31001_gpu_present = True
|
||||||
|
elif sub_variant == HardwareVariantGraphicsSubclass.METAL_3802_GRAPHICS:
|
||||||
|
metal_3802_gpu_present = True
|
||||||
|
elif sub_variant == HardwareVariantGraphicsSubclass.NON_METAL_GRAPHICS:
|
||||||
|
non_metal_gpu_present = True
|
||||||
|
|
||||||
|
metal_gpu_present = metal_31001_gpu_present or metal_3802_gpu_present
|
||||||
|
|
||||||
|
if metal_gpu_present and non_metal_gpu_present:
|
||||||
|
logging.error("Cannot mix Metal and Non-Metal GPUs")
|
||||||
|
logging.error("Stripping out Non-Metal GPUs")
|
||||||
|
for hardware in list(present_hardware):
|
||||||
|
if hardware.hardware_variant_graphics_subclass() == HardwareVariantGraphicsSubclass.NON_METAL_GRAPHICS:
|
||||||
|
print(f" Stripping out {hardware.name()}")
|
||||||
|
present_hardware.remove(hardware)
|
||||||
|
|
||||||
|
if metal_3802_gpu_present and metal_31001_gpu_present and self._xnu_major >= os_data.sequoia.value:
|
||||||
|
logging.error("Cannot mix Metal 3802 and Metal 31001 GPUs on macOS Sequoia or newer")
|
||||||
|
logging.error("Stripping out Metal 3802 GPUs")
|
||||||
|
for hardware in list(present_hardware):
|
||||||
|
if hardware.hardware_variant_graphics_subclass() == HardwareVariantGraphicsSubclass.METAL_3802_GRAPHICS:
|
||||||
|
logging.error(f" Stripping out {hardware.name()}")
|
||||||
|
present_hardware.remove(hardware)
|
||||||
|
|
||||||
|
return present_hardware
|
||||||
|
|
||||||
|
|
||||||
|
def _handle_missing_network_connection(self, requirements: dict, device_properties: dict) -> tuple[dict, dict]:
|
||||||
|
"""
|
||||||
|
Sync network connection requirements
|
||||||
|
"""
|
||||||
|
if self._can_patch(requirements, ignore_keys=[HardwarePatchsetValidation.MISSING_NETWORK_CONNECTION]) is False:
|
||||||
|
return requirements, device_properties
|
||||||
|
logging.info("Network connection missing, checking whether network patches are applicable")
|
||||||
|
if self._already_has_networking_patches() is True:
|
||||||
|
logging.info("Network patches are already applied, requiring network connection")
|
||||||
|
return requirements, device_properties
|
||||||
|
|
||||||
|
if not any([key.startswith("Networking:") for key in device_properties.keys()]):
|
||||||
|
logging.info("Network patches are not applicable, requiring network connection")
|
||||||
|
return requirements, device_properties
|
||||||
|
|
||||||
|
logging.info("Network patches are applicable, removing other patches")
|
||||||
|
for key in list(device_properties.keys()):
|
||||||
|
if key.startswith("Networking:"):
|
||||||
|
continue
|
||||||
|
device_properties.pop(key, None)
|
||||||
|
|
||||||
|
requirements[HardwarePatchsetValidation.MISSING_NETWORK_CONNECTION] = False
|
||||||
|
requirements[HardwarePatchsetSettings.KERNEL_DEBUG_KIT_REQUIRED] = False
|
||||||
|
requirements[HardwarePatchsetSettings.KERNEL_DEBUG_KIT_MISSING] = False
|
||||||
|
requirements[HardwarePatchsetSettings.METALLIB_SUPPORT_PKG_REQUIRED] = False
|
||||||
|
requirements[HardwarePatchsetSettings.METALLIB_SUPPORT_PKG_MISSING] = False
|
||||||
|
|
||||||
|
return requirements, device_properties
|
||||||
|
|
||||||
|
|
||||||
|
def _handle_sip_breakdown(self, requirements: dict, required_sip_configs: list[str]) -> dict:
|
||||||
|
"""
|
||||||
|
Handle SIP breakdown
|
||||||
|
"""
|
||||||
|
current_sip_status = hex(py_sip_xnu.SipXnu().get_sip_status().value)
|
||||||
|
expected_sip_status = hex(self._convert_required_sip_config_to_int(required_sip_configs))
|
||||||
|
sip_string = f"Validation: Booted SIP: {current_sip_status} vs expected: {expected_sip_status}"
|
||||||
|
index = list(requirements.keys()).index(HardwarePatchsetValidation.SIP_ENABLED)
|
||||||
|
return dict(list(requirements.items())[:index+1] + [(sip_string, True)] + list(requirements.items())[index+1:])
|
||||||
|
|
||||||
|
|
||||||
def _detect(self) -> None:
|
def _detect(self) -> None:
|
||||||
"""
|
"""
|
||||||
Detect patches for a given system
|
Detect patches for a given system
|
||||||
"""
|
"""
|
||||||
|
present_hardware = []
|
||||||
device_properties = {}
|
device_properties = {}
|
||||||
patches = {}
|
patches = {}
|
||||||
|
|
||||||
requires_metallib_support_pkg = False
|
requires_metallib_support_pkg = False
|
||||||
missing_metallib_support_pkg = False
|
missing_metallib_support_pkg = False
|
||||||
requires_kernel_debug_kit = False
|
requires_kernel_debug_kit = False
|
||||||
missing_kernel_debug_kit = False
|
missing_kernel_debug_kit = False
|
||||||
has_nvidia_web_drivers = False
|
has_nvidia_web_drivers = False
|
||||||
has_3802_gpu = False
|
has_metal_3802_gpu = False
|
||||||
highest_amfi_level = amfi_detect.AmfiConfigDetectLevel.NO_CHECK
|
highest_amfi_level = amfi_detect.AmfiConfigDetectLevel.NO_CHECK
|
||||||
required_sip_configs = []
|
required_sip_configs = []
|
||||||
|
|
||||||
|
# First pass to find all present hardware
|
||||||
for hardware in self._hardware_variants:
|
for hardware in self._hardware_variants:
|
||||||
item: BaseHardware = hardware(
|
item: BaseHardware = hardware(
|
||||||
xnu_major = self._xnu_major,
|
xnu_major = self._xnu_major,
|
||||||
@@ -362,13 +448,19 @@ class HardwarePatchsetDetection:
|
|||||||
continue
|
continue
|
||||||
if item.native_os() is True: # Skip if native OS
|
if item.native_os() is True: # Skip if native OS
|
||||||
continue
|
continue
|
||||||
|
present_hardware.append(item)
|
||||||
|
|
||||||
|
present_hardware = self._strip_incompatible_hardware(present_hardware)
|
||||||
|
|
||||||
|
# Second pass to gather all properties
|
||||||
|
for item in present_hardware:
|
||||||
|
item: BaseHardware
|
||||||
device_properties[item.name()] = True
|
device_properties[item.name()] = True
|
||||||
|
|
||||||
if item.name() == "Graphics: Nvidia Web Drivers":
|
if item.name() == "Graphics: Nvidia Web Drivers":
|
||||||
has_nvidia_web_drivers = True
|
has_nvidia_web_drivers = True
|
||||||
if item.name() in ["Graphics: Nvidia Kepler", "Graphics: Intel Ivy Bridge", "Graphics: Intel Haswell"]:
|
if item.hardware_variant_graphics_subclass() == HardwareVariantGraphicsSubclass.METAL_3802_GRAPHICS:
|
||||||
has_3802_gpu = True
|
has_metal_3802_gpu = True
|
||||||
|
|
||||||
for config in item.required_system_integrity_protection_configurations():
|
for config in item.required_system_integrity_protection_configurations():
|
||||||
if config not in required_sip_configs:
|
if config not in required_sip_configs:
|
||||||
@@ -383,13 +475,11 @@ class HardwarePatchsetDetection:
|
|||||||
|
|
||||||
patches.update(item.patches())
|
patches.update(item.patches())
|
||||||
|
|
||||||
|
|
||||||
if requires_metallib_support_pkg is True:
|
if requires_metallib_support_pkg is True:
|
||||||
missing_metallib_support_pkg = not self._is_cached_metallib_support_pkg_present()
|
missing_metallib_support_pkg = not self._is_cached_metallib_support_pkg_present()
|
||||||
if requires_kernel_debug_kit is True:
|
if requires_kernel_debug_kit is True:
|
||||||
missing_kernel_debug_kit = not self._is_cached_kernel_debug_kit_present()
|
missing_kernel_debug_kit = not self._is_cached_kernel_debug_kit_present()
|
||||||
|
|
||||||
|
|
||||||
requirements = {
|
requirements = {
|
||||||
HardwarePatchsetSettings.KERNEL_DEBUG_KIT_REQUIRED: requires_kernel_debug_kit,
|
HardwarePatchsetSettings.KERNEL_DEBUG_KIT_REQUIRED: requires_kernel_debug_kit,
|
||||||
HardwarePatchsetSettings.KERNEL_DEBUG_KIT_MISSING: missing_kernel_debug_kit,
|
HardwarePatchsetSettings.KERNEL_DEBUG_KIT_MISSING: missing_kernel_debug_kit,
|
||||||
@@ -406,38 +496,16 @@ class HardwarePatchsetDetection:
|
|||||||
HardwarePatchsetValidation.FORCE_OPENGL_MISSING: self._validation_check_force_opengl_missing() if has_nvidia_web_drivers is True else False,
|
HardwarePatchsetValidation.FORCE_OPENGL_MISSING: self._validation_check_force_opengl_missing() if has_nvidia_web_drivers is True else False,
|
||||||
HardwarePatchsetValidation.FORCE_COMPAT_MISSING: self._validation_check_force_compat_missing() if has_nvidia_web_drivers is True else False,
|
HardwarePatchsetValidation.FORCE_COMPAT_MISSING: self._validation_check_force_compat_missing() if has_nvidia_web_drivers is True else False,
|
||||||
HardwarePatchsetValidation.NVDA_DRV_MISSING: self._validation_check_nvda_drv_missing() if has_nvidia_web_drivers is True else False,
|
HardwarePatchsetValidation.NVDA_DRV_MISSING: self._validation_check_nvda_drv_missing() if has_nvidia_web_drivers is True else False,
|
||||||
HardwarePatchsetValidation.HELL_SPAWN_GPU_PRESENT: has_3802_gpu and not self._dortania_internal_check(),
|
HardwarePatchsetValidation.HELL_SPAWN_GPU_PRESENT: has_metal_3802_gpu and self._xnu_major >= os_data.sequoia.value and self._dortania_internal_check() is False,
|
||||||
}
|
}
|
||||||
|
|
||||||
_cant_patch = False
|
_cant_patch = False
|
||||||
_cant_unpatch = requirements[HardwarePatchsetValidation.SIP_ENABLED]
|
_cant_unpatch = requirements[HardwarePatchsetValidation.SIP_ENABLED]
|
||||||
|
|
||||||
if requirements[HardwarePatchsetValidation.SIP_ENABLED] is True:
|
if requirements[HardwarePatchsetValidation.SIP_ENABLED] is True:
|
||||||
current_sip_status = hex(py_sip_xnu.SipXnu().get_sip_status().value)
|
requirements = self._handle_sip_breakdown(requirements, required_sip_configs)
|
||||||
expected_sip_status = hex(self._convert_required_sip_config_to_int(required_sip_configs))
|
|
||||||
sip_string = f"Validation: Booted SIP: {current_sip_status} vs expected: {expected_sip_status}"
|
|
||||||
index = list(requirements.keys()).index(HardwarePatchsetValidation.SIP_ENABLED)
|
|
||||||
requirements = dict(list(requirements.items())[:index+1] + [(sip_string, True)] + list(requirements.items())[index+1:])
|
|
||||||
|
|
||||||
# If MISSING_NETWORK_CONNECTION is enabled, see whether 'Networking: Legacy Wireless' or 'Networking: Modern Wireless' is present
|
|
||||||
# If so, remove other patches and set PATCHING_NOT_POSSIBLE to True
|
|
||||||
if requirements[HardwarePatchsetValidation.MISSING_NETWORK_CONNECTION] is True:
|
if requirements[HardwarePatchsetValidation.MISSING_NETWORK_CONNECTION] is True:
|
||||||
if self._can_patch(requirements, ignore_keys=[HardwarePatchsetValidation.MISSING_NETWORK_CONNECTION]) is True:
|
requirements, device_properties = self._handle_missing_network_connection(requirements, device_properties)
|
||||||
logging.info("Network connection missing, checking whether network patches are applicable")
|
|
||||||
if self._already_has_networking_patches() is True:
|
|
||||||
logging.info("Network patches are already applied, requiring network connection")
|
|
||||||
else:
|
|
||||||
if "Networking: Legacy Wireless" in device_properties or "Networking: Modern Wireless" in device_properties:
|
|
||||||
logging.info("Network patches are applicable, removing other patches")
|
|
||||||
for key in list(device_properties.keys()):
|
|
||||||
if key.startswith("Networking:"):
|
|
||||||
continue
|
|
||||||
device_properties.pop(key, None)
|
|
||||||
requirements[HardwarePatchsetValidation.MISSING_NETWORK_CONNECTION] = False
|
|
||||||
requirements[HardwarePatchsetSettings.KERNEL_DEBUG_KIT_REQUIRED] = False
|
|
||||||
requirements[HardwarePatchsetSettings.KERNEL_DEBUG_KIT_MISSING] = False
|
|
||||||
requirements[HardwarePatchsetSettings.METALLIB_SUPPORT_PKG_REQUIRED] = False
|
|
||||||
requirements[HardwarePatchsetSettings.METALLIB_SUPPORT_PKG_MISSING] = False
|
|
||||||
|
|
||||||
_cant_patch = not self._can_patch(requirements)
|
_cant_patch = not self._can_patch(requirements)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user