mirror of
https://github.com/dortania/OpenCore-Legacy-Patcher.git
synced 2026-04-13 20:28:21 +10:00
WIP device probe refactor part 2
This commit is contained in:
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
|
||||
|
||||
def cls():
|
||||
if check_recovery() == False:
|
||||
os.system('cls' if os.name == 'nt' else 'clear')
|
||||
if not check_recovery():
|
||||
os.system("cls" if os.name == "nt" else "clear")
|
||||
else:
|
||||
print("\u001Bc")
|
||||
|
||||
|
||||
@@ -1,35 +1,11 @@
|
||||
import binascii
|
||||
import enum
|
||||
import itertools
|
||||
from dataclasses import dataclass, field
|
||||
import plistlib
|
||||
import subprocess
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Any, ClassVar, Optional, Type
|
||||
|
||||
from Resources import Utilities, ioreg, PCIIDArray
|
||||
|
||||
|
||||
@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
|
||||
from Resources import PCIIDArray, Utilities, ioreg
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -41,7 +17,8 @@ class PCIDevice:
|
||||
class_code: int # The class code of this PCI device
|
||||
|
||||
# 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
|
||||
|
||||
# def __getstate__(self):
|
||||
@@ -50,14 +27,15 @@ class PCIDevice:
|
||||
# return state
|
||||
|
||||
@classmethod
|
||||
def from_ioregistry(cls, entry: ioreg.IORegistryEntry):
|
||||
device = cls(
|
||||
int.from_bytes(entry.properties["vendor-id"][:4], byteorder="little"),
|
||||
int.from_bytes(entry.properties["device-id"][:4], byteorder="little"),
|
||||
int.from_bytes(entry.properties["class-code"][:6], byteorder="little"),
|
||||
)
|
||||
def from_ioregistry(cls, entry: ioreg.IORegistryEntry, anti_spoof=False):
|
||||
if anti_spoof and "IOName" in entry.properties:
|
||||
vendor_id, device_id = (int(i, 16) for i in entry.properties["IOName"][3:].split(","))
|
||||
else:
|
||||
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:
|
||||
device.name = entry.properties["model"].strip(b"\0").decode()
|
||||
device.model = entry.properties["model"].strip(b"\0").decode()
|
||||
device.populate_pci_path(entry)
|
||||
return device
|
||||
|
||||
@@ -69,7 +47,7 @@ class PCIDevice:
|
||||
# return 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):
|
||||
return i
|
||||
return None
|
||||
@@ -83,8 +61,7 @@ class PCIDevice:
|
||||
# raise NotImplementedError
|
||||
|
||||
def populate_pci_path(self, entry: ioreg.IORegistryEntry):
|
||||
# Eventually
|
||||
# Trash, but who really cares?
|
||||
# Based off gfxutil logic, seems to work.
|
||||
paths = []
|
||||
while entry:
|
||||
if entry.entry_class == "IOPCIDevice":
|
||||
@@ -98,7 +75,30 @@ class PCIDevice:
|
||||
|
||||
|
||||
@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
|
||||
|
||||
class Archs(enum.Enum):
|
||||
@@ -123,7 +123,7 @@ class NVIDIA(GPU, PCIDevice):
|
||||
|
||||
|
||||
@dataclass
|
||||
class AMD(GPU, PCIDevice):
|
||||
class AMD(GPU):
|
||||
VENDOR_ID: ClassVar[int] = 0x1002
|
||||
|
||||
class Archs(enum.Enum):
|
||||
@@ -156,7 +156,7 @@ class AMD(GPU, PCIDevice):
|
||||
|
||||
|
||||
@dataclass
|
||||
class Intel(GPU, PCIDevice):
|
||||
class Intel(GPU):
|
||||
VENDOR_ID: ClassVar[int] = 0x8086
|
||||
|
||||
class Archs(enum.Enum):
|
||||
@@ -180,10 +180,10 @@ class Intel(GPU, PCIDevice):
|
||||
|
||||
|
||||
@dataclass
|
||||
class Broadcom(WirelessCard, PCIDevice):
|
||||
class Broadcom(WirelessCard):
|
||||
VENDOR_ID: ClassVar[int] = 0x14E4
|
||||
|
||||
class Models(enum.Enum):
|
||||
class Chipsets(enum.Enum):
|
||||
# pylint: disable=invalid-name
|
||||
AirportBrcmNIC = "AirportBrcmNIC supported"
|
||||
AirPortBrcm4360 = "AirPortBrcm4360 supported"
|
||||
@@ -191,38 +191,38 @@ class Broadcom(WirelessCard, PCIDevice):
|
||||
AirPortBrcm43224 = "AppleAirPortBrcm43224 supported"
|
||||
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:
|
||||
self.model = Broadcom.Models.AirportBrcmNIC
|
||||
self.chipset = Broadcom.Chipsets.AirportBrcmNIC
|
||||
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:
|
||||
self.model = Broadcom.Models.AirPortBrcm4331
|
||||
self.chipset = Broadcom.Chipsets.AirPortBrcm4331
|
||||
elif self.device_id in PCIIDArray.broadcom_ids.AppleAirPortBrcm43224:
|
||||
self.model = Broadcom.Models.AirPortBrcm43224
|
||||
self.chipset = Broadcom.Chipsets.AirPortBrcm43224
|
||||
else:
|
||||
self.model = Broadcom.Models.Unknown
|
||||
self.chipset = Broadcom.Chipsets.Unknown
|
||||
|
||||
|
||||
@dataclass
|
||||
class Atheros(WirelessCard, PCIDevice):
|
||||
class Atheros(WirelessCard):
|
||||
VENDOR_ID: ClassVar[int] = 0x168C
|
||||
|
||||
class Models(enum.Enum):
|
||||
class Chipsets(enum.Enum):
|
||||
# pylint: disable=invalid-name
|
||||
# Well there's only one model but
|
||||
AirPortAtheros40 = "AirPortAtheros40 supported"
|
||||
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:
|
||||
self.model = Atheros.Models.AirPortAtheros40
|
||||
self.chipset = Atheros.Chipsets.AirPortAtheros40
|
||||
else:
|
||||
self.model = Atheros.Models.Unknown
|
||||
self.chipset = Atheros.Chipsets.Unknown
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -233,16 +233,16 @@ class CPU:
|
||||
|
||||
@dataclass
|
||||
class Computer:
|
||||
opencore_model: Optional[str] = None
|
||||
opencore_board_id: Optional[str] = None
|
||||
real_model: Optional[str] = None
|
||||
real_board_id: Optional[str] = None
|
||||
reported_model: Optional[str] = None
|
||||
reported_board_id: Optional[str] = None
|
||||
gpus: list[GPU] = field(default_factory=list)
|
||||
igpu: Optional[GPU] = None
|
||||
dgpu: Optional[GPU] = None
|
||||
wifi: Optional[PCIDevice] = None
|
||||
igpu: Optional[GPU] = None # Shortcut for IGPU
|
||||
dgpu: Optional[GPU] = None # Shortcut for GFX0
|
||||
wifi: Optional[WirelessCard] = None
|
||||
cpu: Optional[CPU] = None
|
||||
oclp: Optional[str] = None
|
||||
oclp_version: Optional[str] = None
|
||||
ioregistry: Optional[ioreg.IOReg] = None
|
||||
|
||||
@staticmethod
|
||||
@@ -258,6 +258,7 @@ class Computer:
|
||||
return computer
|
||||
|
||||
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"))))
|
||||
|
||||
for device in devices:
|
||||
@@ -266,28 +267,21 @@ class Computer:
|
||||
self.gpus.append(vendor.from_ioregistry(device)) # type: ignore
|
||||
|
||||
def dgpu_probe(self):
|
||||
# result = subprocess.run("ioreg -r -n GFX0 -a".split(), stdout=subprocess.PIPE).stdout.strip()
|
||||
result = list(self.ioregistry.find(name="GFX0"))
|
||||
|
||||
if not result:
|
||||
device = next(self.ioregistry.find(name="GFX0"), None)
|
||||
if not device:
|
||||
# No devices
|
||||
return
|
||||
|
||||
# device = plistlib.loads(result)[0]
|
||||
device = result[0]
|
||||
vendor: Type[GPU] = PCIDevice.from_ioregistry(device).vendor_detect(inherits=GPU) # type: ignore
|
||||
if vendor:
|
||||
self.dgpu = vendor.from_ioregistry(device) # type: ignore
|
||||
|
||||
def igpu_probe(self):
|
||||
# result = subprocess.run("ioreg -r -n IGPU -a".split(), stdout=subprocess.PIPE).stdout.strip()
|
||||
result = list(self.ioregistry.find(name="IGPU"))
|
||||
if not result:
|
||||
device = next(self.ioregistry.find(name="IGPU"), None)
|
||||
if not device:
|
||||
# No devices
|
||||
return
|
||||
|
||||
# device = plistlib.loads(result)[0]
|
||||
device = result[0]
|
||||
vendor: Type[GPU] = PCIDevice.from_ioregistry(device).vendor_detect(inherits=GPU) # type: ignore
|
||||
if vendor:
|
||||
self.igpu = vendor.from_ioregistry(device) # type: ignore
|
||||
@@ -311,24 +305,22 @@ class Computer:
|
||||
for device in devices:
|
||||
vendor: Type[WirelessCard] = PCIDevice.from_ioregistry(device).vendor_detect(inherits=WirelessCard) # type: ignore
|
||||
if vendor:
|
||||
self.wifi = vendor.from_ioregistry(device) # type: ignore
|
||||
self.wifi = vendor.from_ioregistry(device, anti_spoof=True) # type: ignore
|
||||
break
|
||||
|
||||
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()
|
||||
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()
|
||||
# Reported model
|
||||
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()
|
||||
|
||||
oclp_version = subprocess.run("nvram -x 4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:OCLP-Version".split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.strip()
|
||||
if oclp_version:
|
||||
self.oclp = plistlib.loads(oclp_version)["4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:OCLP-Version"].strip(b"\0").decode()
|
||||
# Real model
|
||||
# TODO: We previously had logic for OC users using iMacPro1,1 with incorrect ExposeSensitiveData. Add logic?
|
||||
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):
|
||||
self.cpu = CPU(
|
||||
|
||||
Reference in New Issue
Block a user