mirror of
https://github.com/dortania/OpenCore-Legacy-Patcher.git
synced 2026-06-20 14:10:51 +10:00
WIP device probe refactor part 2
This commit is contained in:
+672
-672
File diff suppressed because it is too large
Load Diff
@@ -83,8 +83,8 @@ def patching_status():
|
|||||||
return sip_enabled, sbm_enabled, amfi_enabled, fv_enabled
|
return sip_enabled, sbm_enabled, amfi_enabled, fv_enabled
|
||||||
|
|
||||||
def cls():
|
def cls():
|
||||||
if check_recovery() == False:
|
if not check_recovery():
|
||||||
os.system('cls' if os.name == 'nt' else 'clear')
|
os.system("cls" if os.name == "nt" else "clear")
|
||||||
else:
|
else:
|
||||||
print("\u001Bc")
|
print("\u001Bc")
|
||||||
|
|
||||||
|
|||||||
+76
-84
@@ -1,35 +1,11 @@
|
|||||||
import binascii
|
import binascii
|
||||||
import enum
|
import enum
|
||||||
import itertools
|
import itertools
|
||||||
from dataclasses import dataclass, field
|
|
||||||
import plistlib
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from dataclasses import dataclass, field
|
||||||
from typing import Any, ClassVar, Optional, Type
|
from typing import Any, ClassVar, Optional, Type
|
||||||
|
|
||||||
from Resources import Utilities, ioreg, PCIIDArray
|
from Resources import PCIIDArray, Utilities, ioreg
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class GPU:
|
|
||||||
arch: enum.Enum = field(init=False) # The architecture, see subclasses.
|
|
||||||
|
|
||||||
def __post_init__(self):
|
|
||||||
self.detect_arch()
|
|
||||||
|
|
||||||
def detect_arch(self):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class WirelessCard:
|
|
||||||
CLASS_CODE: ClassVar[int] = 0x028000 # 00800200 hexswapped
|
|
||||||
model: enum.Enum = field(init=False)
|
|
||||||
|
|
||||||
def __post_init__(self):
|
|
||||||
self.detect_model()
|
|
||||||
|
|
||||||
def detect_model(self):
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -41,7 +17,8 @@ class PCIDevice:
|
|||||||
class_code: int # The class code of this PCI device
|
class_code: int # The class code of this PCI device
|
||||||
|
|
||||||
# ioregistryentry: Optional[ioreg.IORegistryEntry] = None
|
# ioregistryentry: Optional[ioreg.IORegistryEntry] = None
|
||||||
name: Optional[str] = None
|
name: Optional[str] = None # Name of IORegistryEntry
|
||||||
|
model: Optional[str] = None # model property
|
||||||
pci_path: Optional[str] = None
|
pci_path: Optional[str] = None
|
||||||
|
|
||||||
# def __getstate__(self):
|
# def __getstate__(self):
|
||||||
@@ -50,14 +27,15 @@ class PCIDevice:
|
|||||||
# return state
|
# return state
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_ioregistry(cls, entry: ioreg.IORegistryEntry):
|
def from_ioregistry(cls, entry: ioreg.IORegistryEntry, anti_spoof=False):
|
||||||
device = cls(
|
if anti_spoof and "IOName" in entry.properties:
|
||||||
int.from_bytes(entry.properties["vendor-id"][:4], byteorder="little"),
|
vendor_id, device_id = (int(i, 16) for i in entry.properties["IOName"][3:].split(","))
|
||||||
int.from_bytes(entry.properties["device-id"][:4], byteorder="little"),
|
else:
|
||||||
int.from_bytes(entry.properties["class-code"][:6], byteorder="little"),
|
vendor_id, device_id = [int.from_bytes(entry.properties[i][:4], byteorder="little") for i in ["vendor-id", "device-id"]]
|
||||||
)
|
|
||||||
|
device = cls(vendor_id, device_id, int.from_bytes(entry.properties["class-code"][:6], byteorder="little"), name=entry.name)
|
||||||
if "model" in entry.properties:
|
if "model" in entry.properties:
|
||||||
device.name = entry.properties["model"].strip(b"\0").decode()
|
device.model = entry.properties["model"].strip(b"\0").decode()
|
||||||
device.populate_pci_path(entry)
|
device.populate_pci_path(entry)
|
||||||
return device
|
return device
|
||||||
|
|
||||||
@@ -69,7 +47,7 @@ class PCIDevice:
|
|||||||
# return None
|
# return None
|
||||||
|
|
||||||
def vendor_detect(self, *, inherits: ClassVar[Any] = None, classes: list = None):
|
def vendor_detect(self, *, inherits: ClassVar[Any] = None, classes: list = None):
|
||||||
for i in classes or PCIDevice.__subclasses__():
|
for i in classes or itertools.chain.from_iterable([subclass.__subclasses__() for subclass in PCIDevice.__subclasses__()]):
|
||||||
if issubclass(i, inherits or object) and i.detect(self):
|
if issubclass(i, inherits or object) and i.detect(self):
|
||||||
return i
|
return i
|
||||||
return None
|
return None
|
||||||
@@ -83,8 +61,7 @@ class PCIDevice:
|
|||||||
# raise NotImplementedError
|
# raise NotImplementedError
|
||||||
|
|
||||||
def populate_pci_path(self, entry: ioreg.IORegistryEntry):
|
def populate_pci_path(self, entry: ioreg.IORegistryEntry):
|
||||||
# Eventually
|
# Based off gfxutil logic, seems to work.
|
||||||
# Trash, but who really cares?
|
|
||||||
paths = []
|
paths = []
|
||||||
while entry:
|
while entry:
|
||||||
if entry.entry_class == "IOPCIDevice":
|
if entry.entry_class == "IOPCIDevice":
|
||||||
@@ -98,7 +75,30 @@ class PCIDevice:
|
|||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class NVIDIA(GPU, PCIDevice):
|
class GPU(PCIDevice):
|
||||||
|
arch: enum.Enum = field(init=False) # The architecture, see subclasses.
|
||||||
|
|
||||||
|
def __post_init__(self):
|
||||||
|
self.detect_arch()
|
||||||
|
|
||||||
|
def detect_arch(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class WirelessCard(PCIDevice):
|
||||||
|
CLASS_CODE: ClassVar[int] = 0x028000 # 00800200 hexswapped
|
||||||
|
chipset: enum.Enum = field(init=False)
|
||||||
|
|
||||||
|
def __post_init__(self):
|
||||||
|
self.detect_chipset()
|
||||||
|
|
||||||
|
def detect_chipset(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class NVIDIA(GPU):
|
||||||
VENDOR_ID: ClassVar[int] = 0x10DE
|
VENDOR_ID: ClassVar[int] = 0x10DE
|
||||||
|
|
||||||
class Archs(enum.Enum):
|
class Archs(enum.Enum):
|
||||||
@@ -123,7 +123,7 @@ class NVIDIA(GPU, PCIDevice):
|
|||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class AMD(GPU, PCIDevice):
|
class AMD(GPU):
|
||||||
VENDOR_ID: ClassVar[int] = 0x1002
|
VENDOR_ID: ClassVar[int] = 0x1002
|
||||||
|
|
||||||
class Archs(enum.Enum):
|
class Archs(enum.Enum):
|
||||||
@@ -156,7 +156,7 @@ class AMD(GPU, PCIDevice):
|
|||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Intel(GPU, PCIDevice):
|
class Intel(GPU):
|
||||||
VENDOR_ID: ClassVar[int] = 0x8086
|
VENDOR_ID: ClassVar[int] = 0x8086
|
||||||
|
|
||||||
class Archs(enum.Enum):
|
class Archs(enum.Enum):
|
||||||
@@ -180,10 +180,10 @@ class Intel(GPU, PCIDevice):
|
|||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Broadcom(WirelessCard, PCIDevice):
|
class Broadcom(WirelessCard):
|
||||||
VENDOR_ID: ClassVar[int] = 0x14E4
|
VENDOR_ID: ClassVar[int] = 0x14E4
|
||||||
|
|
||||||
class Models(enum.Enum):
|
class Chipsets(enum.Enum):
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
AirportBrcmNIC = "AirportBrcmNIC supported"
|
AirportBrcmNIC = "AirportBrcmNIC supported"
|
||||||
AirPortBrcm4360 = "AirPortBrcm4360 supported"
|
AirPortBrcm4360 = "AirPortBrcm4360 supported"
|
||||||
@@ -191,38 +191,38 @@ class Broadcom(WirelessCard, PCIDevice):
|
|||||||
AirPortBrcm43224 = "AppleAirPortBrcm43224 supported"
|
AirPortBrcm43224 = "AppleAirPortBrcm43224 supported"
|
||||||
Unknown = "Unknown"
|
Unknown = "Unknown"
|
||||||
|
|
||||||
model: Models = field(init=False)
|
chipset: Chipsets = field(init=False)
|
||||||
|
|
||||||
def detect_model(self):
|
def detect_chipset(self):
|
||||||
if self.device_id in PCIIDArray.broadcom_ids.AirPortBrcmNIC:
|
if self.device_id in PCIIDArray.broadcom_ids.AirPortBrcmNIC:
|
||||||
self.model = Broadcom.Models.AirportBrcmNIC
|
self.chipset = Broadcom.Chipsets.AirportBrcmNIC
|
||||||
elif self.device_id in PCIIDArray.broadcom_ids.AirPortBrcm4360:
|
elif self.device_id in PCIIDArray.broadcom_ids.AirPortBrcm4360:
|
||||||
self.model = Broadcom.Models.AirPortBrcm4360
|
self.chipset = Broadcom.Chipsets.AirPortBrcm4360
|
||||||
elif self.device_id in PCIIDArray.broadcom_ids.AirPortBrcm4331:
|
elif self.device_id in PCIIDArray.broadcom_ids.AirPortBrcm4331:
|
||||||
self.model = Broadcom.Models.AirPortBrcm4331
|
self.chipset = Broadcom.Chipsets.AirPortBrcm4331
|
||||||
elif self.device_id in PCIIDArray.broadcom_ids.AppleAirPortBrcm43224:
|
elif self.device_id in PCIIDArray.broadcom_ids.AppleAirPortBrcm43224:
|
||||||
self.model = Broadcom.Models.AirPortBrcm43224
|
self.chipset = Broadcom.Chipsets.AirPortBrcm43224
|
||||||
else:
|
else:
|
||||||
self.model = Broadcom.Models.Unknown
|
self.chipset = Broadcom.Chipsets.Unknown
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Atheros(WirelessCard, PCIDevice):
|
class Atheros(WirelessCard):
|
||||||
VENDOR_ID: ClassVar[int] = 0x168C
|
VENDOR_ID: ClassVar[int] = 0x168C
|
||||||
|
|
||||||
class Models(enum.Enum):
|
class Chipsets(enum.Enum):
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
# Well there's only one model but
|
# Well there's only one model but
|
||||||
AirPortAtheros40 = "AirPortAtheros40 supported"
|
AirPortAtheros40 = "AirPortAtheros40 supported"
|
||||||
Unknown = "Unknown"
|
Unknown = "Unknown"
|
||||||
|
|
||||||
model: Models = field(init=False)
|
chipset: Chipsets = field(init=False)
|
||||||
|
|
||||||
def detect_model(self):
|
def detect_chipset(self):
|
||||||
if self.device_id in PCIIDArray.atheros_ids.AtherosWifi:
|
if self.device_id in PCIIDArray.atheros_ids.AtherosWifi:
|
||||||
self.model = Atheros.Models.AirPortAtheros40
|
self.chipset = Atheros.Chipsets.AirPortAtheros40
|
||||||
else:
|
else:
|
||||||
self.model = Atheros.Models.Unknown
|
self.chipset = Atheros.Chipsets.Unknown
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -233,16 +233,16 @@ class CPU:
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Computer:
|
class Computer:
|
||||||
opencore_model: Optional[str] = None
|
real_model: Optional[str] = None
|
||||||
opencore_board_id: Optional[str] = None
|
real_board_id: Optional[str] = None
|
||||||
reported_model: Optional[str] = None
|
reported_model: Optional[str] = None
|
||||||
reported_board_id: Optional[str] = None
|
reported_board_id: Optional[str] = None
|
||||||
gpus: list[GPU] = field(default_factory=list)
|
gpus: list[GPU] = field(default_factory=list)
|
||||||
igpu: Optional[GPU] = None
|
igpu: Optional[GPU] = None # Shortcut for IGPU
|
||||||
dgpu: Optional[GPU] = None
|
dgpu: Optional[GPU] = None # Shortcut for GFX0
|
||||||
wifi: Optional[PCIDevice] = None
|
wifi: Optional[WirelessCard] = None
|
||||||
cpu: Optional[CPU] = None
|
cpu: Optional[CPU] = None
|
||||||
oclp: Optional[str] = None
|
oclp_version: Optional[str] = None
|
||||||
ioregistry: Optional[ioreg.IOReg] = None
|
ioregistry: Optional[ioreg.IOReg] = None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -258,6 +258,7 @@ class Computer:
|
|||||||
return computer
|
return computer
|
||||||
|
|
||||||
def gpu_probe(self):
|
def gpu_probe(self):
|
||||||
|
# Chain together two iterators: one for class code 00000300, the other for class code 00800300
|
||||||
devices = itertools.chain(self.ioregistry.find(property=("class-code", binascii.a2b_hex("00000300"))), self.ioregistry.find(property=("class-code", binascii.a2b_hex("00800300"))))
|
devices = itertools.chain(self.ioregistry.find(property=("class-code", binascii.a2b_hex("00000300"))), self.ioregistry.find(property=("class-code", binascii.a2b_hex("00800300"))))
|
||||||
|
|
||||||
for device in devices:
|
for device in devices:
|
||||||
@@ -266,28 +267,21 @@ class Computer:
|
|||||||
self.gpus.append(vendor.from_ioregistry(device)) # type: ignore
|
self.gpus.append(vendor.from_ioregistry(device)) # type: ignore
|
||||||
|
|
||||||
def dgpu_probe(self):
|
def dgpu_probe(self):
|
||||||
# result = subprocess.run("ioreg -r -n GFX0 -a".split(), stdout=subprocess.PIPE).stdout.strip()
|
device = next(self.ioregistry.find(name="GFX0"), None)
|
||||||
result = list(self.ioregistry.find(name="GFX0"))
|
if not device:
|
||||||
|
|
||||||
if not result:
|
|
||||||
# No devices
|
# No devices
|
||||||
return
|
return
|
||||||
|
|
||||||
# device = plistlib.loads(result)[0]
|
|
||||||
device = result[0]
|
|
||||||
vendor: Type[GPU] = PCIDevice.from_ioregistry(device).vendor_detect(inherits=GPU) # type: ignore
|
vendor: Type[GPU] = PCIDevice.from_ioregistry(device).vendor_detect(inherits=GPU) # type: ignore
|
||||||
if vendor:
|
if vendor:
|
||||||
self.dgpu = vendor.from_ioregistry(device) # type: ignore
|
self.dgpu = vendor.from_ioregistry(device) # type: ignore
|
||||||
|
|
||||||
def igpu_probe(self):
|
def igpu_probe(self):
|
||||||
# result = subprocess.run("ioreg -r -n IGPU -a".split(), stdout=subprocess.PIPE).stdout.strip()
|
device = next(self.ioregistry.find(name="IGPU"), None)
|
||||||
result = list(self.ioregistry.find(name="IGPU"))
|
if not device:
|
||||||
if not result:
|
|
||||||
# No devices
|
# No devices
|
||||||
return
|
return
|
||||||
|
|
||||||
# device = plistlib.loads(result)[0]
|
|
||||||
device = result[0]
|
|
||||||
vendor: Type[GPU] = PCIDevice.from_ioregistry(device).vendor_detect(inherits=GPU) # type: ignore
|
vendor: Type[GPU] = PCIDevice.from_ioregistry(device).vendor_detect(inherits=GPU) # type: ignore
|
||||||
if vendor:
|
if vendor:
|
||||||
self.igpu = vendor.from_ioregistry(device) # type: ignore
|
self.igpu = vendor.from_ioregistry(device) # type: ignore
|
||||||
@@ -311,24 +305,22 @@ class Computer:
|
|||||||
for device in devices:
|
for device in devices:
|
||||||
vendor: Type[WirelessCard] = PCIDevice.from_ioregistry(device).vendor_detect(inherits=WirelessCard) # type: ignore
|
vendor: Type[WirelessCard] = PCIDevice.from_ioregistry(device).vendor_detect(inherits=WirelessCard) # type: ignore
|
||||||
if vendor:
|
if vendor:
|
||||||
self.wifi = vendor.from_ioregistry(device) # type: ignore
|
self.wifi = vendor.from_ioregistry(device, anti_spoof=True) # type: ignore
|
||||||
break
|
break
|
||||||
|
|
||||||
def smbios_probe(self):
|
def smbios_probe(self):
|
||||||
opencore_model = subprocess.run("nvram -x 4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:oem-product".split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.strip()
|
# Reported model
|
||||||
if opencore_model:
|
|
||||||
self.opencore_model = plistlib.loads(opencore_model)["4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:oem-product"].decode()
|
|
||||||
self.reported_model = next(self.ioregistry.find(entry_class="IOPlatformExpertDevice")).properties["model"].strip(b"\0").decode()
|
|
||||||
|
|
||||||
opencore_board = subprocess.run("nvram -x 4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:oem-board".split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.strip()
|
|
||||||
if opencore_board:
|
|
||||||
self.opencore_board_id = plistlib.loads(opencore_board)["4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:oem-board"].decode()
|
|
||||||
entry = next(self.ioregistry.find(entry_class="IOPlatformExpertDevice"))
|
entry = next(self.ioregistry.find(entry_class="IOPlatformExpertDevice"))
|
||||||
|
self.reported_model = entry.properties["model"].strip(b"\0").decode()
|
||||||
self.reported_board_id = entry.properties.get("board-id", entry.properties.get("target-type", b"")).strip(b"\0").decode()
|
self.reported_board_id = entry.properties.get("board-id", entry.properties.get("target-type", b"")).strip(b"\0").decode()
|
||||||
|
|
||||||
oclp_version = subprocess.run("nvram -x 4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:OCLP-Version".split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.strip()
|
# Real model
|
||||||
if oclp_version:
|
# TODO: We previously had logic for OC users using iMacPro1,1 with incorrect ExposeSensitiveData. Add logic?
|
||||||
self.oclp = plistlib.loads(oclp_version)["4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:OCLP-Version"].strip(b"\0").decode()
|
self.real_model = Utilities.get_nvram("oem-product", "4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102", decode=True) or self.reported_model
|
||||||
|
self.real_board_id = Utilities.get_nvram("oem-board", "4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102", decode=True) or self.reported_board_id
|
||||||
|
|
||||||
|
# OCLP version
|
||||||
|
self.oclp_version = Utilities.get_nvram("OCLP-Version", "4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102", decode=True)
|
||||||
|
|
||||||
def cpu_probe(self):
|
def cpu_probe(self):
|
||||||
self.cpu = CPU(
|
self.cpu = CPU(
|
||||||
|
|||||||
Reference in New Issue
Block a user