From 06350355ffcb4df41930e3996980f57f78164435 Mon Sep 17 00:00:00 2001 From: Mykola Grymalyuk Date: Tue, 28 Mar 2023 20:57:17 -0600 Subject: [PATCH] build: Add docstrings to functions --- resources/build/firmware.py | 21 ++++- resources/build/graphics_audio.py | 45 +++++++-- resources/build/misc.py | 122 ++++++++++++++++++------- resources/build/networking/wireless.py | 18 +++- resources/build/storage.py | 20 ++++ resources/build/support.py | 74 ++++++++++++--- 6 files changed, 241 insertions(+), 59 deletions(-) diff --git a/resources/build/firmware.py b/resources/build/firmware.py index 45221ba29..55ab81eb0 100644 --- a/resources/build/firmware.py +++ b/resources/build/firmware.py @@ -36,6 +36,10 @@ class BuildFirmware: def _power_management_handling(self) -> None: + """ + Power Management Handling + """ + if not self.model in smbios_data.smbios_dictionary: return if not "CPU Generation" in smbios_data.smbios_dictionary[self.model]: @@ -83,6 +87,10 @@ class BuildFirmware: def _acpi_handling(self) -> None: + """ + ACPI Table Handling + """ + if not self.model in smbios_data.smbios_dictionary: return if not "CPU Generation" in smbios_data.smbios_dictionary[self.model]: @@ -106,6 +114,10 @@ class BuildFirmware: def _cpu_compatibility_handling(self) -> None: + """ + CPU Compatibility Handling + """ + if not self.model in smbios_data.smbios_dictionary: return if not "CPU Generation" in smbios_data.smbios_dictionary[self.model]: @@ -158,7 +170,10 @@ class BuildFirmware: def _firmware_driver_handling(self) -> None: - # Firmware Drivers (Drivers/*.efi) + """ + Firmware Driver Handling (Drivers/*.efi) + """ + if not self.model in smbios_data.smbios_dictionary: return if not "CPU Generation" in smbios_data.smbios_dictionary[self.model]: @@ -194,6 +209,10 @@ class BuildFirmware: def _firmware_compatibility_handling(self) -> None: + """ + Firmware Compatibility Handling (Firmware and Kernel) + """ + self._dual_dp_handling() # Force VMM as a temporary solution to getting the MacPro6,1 booting in Ventura diff --git a/resources/build/graphics_audio.py b/resources/build/graphics_audio.py index cf73dfb22..a7c7e6b02 100644 --- a/resources/build/graphics_audio.py +++ b/resources/build/graphics_audio.py @@ -39,6 +39,12 @@ class BuildGraphicsAudio: def _graphics_handling(self) -> None: + """ + Graphics Handling + + Primarily for Mac Pros and systems with Nvidia Maxwell/Pascal GPUs + """ + if self.constants.allow_oc_everywhere is False and self.constants.serial_settings != "None": if not support.BuildSupport(self.model, self.constants, self.config).get_kext_by_bundle_path("WhateverGreen.kext")["Enabled"] is True: support.BuildSupport(self.model, self.constants, self.config).enable_kext("WhateverGreen.kext", self.constants.whatevergreen_version, self.constants.whatevergreen_path) @@ -115,10 +121,10 @@ class BuildGraphicsAudio: self.config["NVRAM"]["Delete"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"] += ["nvda_drv"] def _backlight_path_detection(self) -> None: + """ + iMac MXM dGPU Backlight DevicePath Detection + """ - # self.constants.custom_model: iMac has been modded with new dGPU - # self.computer.dgpu: dGPU has been found using the GFX0 path - # self.computer.dgpu.pci_path: if not self.constants.custom_model and self.computer.dgpu and self.computer.dgpu.pci_path: for i, device in enumerate(self.computer.gpus): logging.info(f"- Found dGPU ({i + 1}): {utilities.friendly_hex(device.vendor_id)}:{utilities.friendly_hex(device.device_id)}") @@ -153,6 +159,10 @@ class BuildGraphicsAudio: def _nvidia_mxm_patch(self, backlight_path) -> None: + """ + iMac Nvidia Kepler MXM Handler + """ + if not support.BuildSupport(self.model, self.constants, self.config).get_kext_by_bundle_path("WhateverGreen.kext")["Enabled"] is True: # Ensure WEG is enabled as we need if for Backlight patching support.BuildSupport(self.model, self.constants, self.config).enable_kext("WhateverGreen.kext", self.constants.whatevergreen_navi_version, self.constants.whatevergreen_navi_path) @@ -196,6 +206,10 @@ class BuildGraphicsAudio: def _amd_mxm_patch(self, backlight_path) -> None: + """ + iMac AMD GCN and Navi MXM Handler + """ + logging.info("- Adding AMD DRM patches") if not support.BuildSupport(self.model, self.constants, self.config).get_kext_by_bundle_path("WhateverGreen.kext")["Enabled"] is True: # Ensure WEG is enabled as we need if for Backlight patching @@ -278,6 +292,10 @@ class BuildGraphicsAudio: } def _audio_handling(self) -> None: + """ + Audio Handler + """ + if (self.model in model_array.LegacyAudio or self.model in model_array.MacPro) and self.constants.set_alc_usage is True: support.BuildSupport(self.model, self.constants, self.config).enable_kext("AppleALC.kext", self.constants.applealc_version, self.constants.applealc_path) @@ -315,6 +333,10 @@ class BuildGraphicsAudio: self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += " -lilubetaall" def _firmware_handling(self) -> None: + """ + Firmware Handler + """ + # Add UGA to GOP layer if "UGA Graphics" in smbios_data.smbios_dictionary[self.model]: logging.info("- Adding UGA to GOP Patch") @@ -363,6 +385,10 @@ class BuildGraphicsAudio: def _spoof_handling(self) -> None: + """ + SMBIOS Spoofing Handler + """ + if self.constants.serial_settings == "None": return @@ -421,6 +447,10 @@ class BuildGraphicsAudio: def _imac_mxm_patching(self) -> None: + """ + General iMac MXM Handler + """ + self._backlight_path_detection() # Check GPU Vendor if self.constants.metal_build is True: @@ -447,10 +477,13 @@ class BuildGraphicsAudio: self._nvidia_mxm_patch(self.gfx0_path) def _ioaccel_workaround(self) -> None: - # Handle misc IOAccelerator issues + """ + Miscellaneous IOAccelerator Handler + + When MTL bundles are missing from disk, WindowServer will repeatedly crash + This primarily occurs when installing an RSR update, where root is cleaned but AuxKC is not + """ - # When MTL bundles are missing from disk, WindowServer will repeatedly crash - # This primarily occurs when installing an RSR update, where root is cleaned but AuxKC is not gpu_dict = [] if not self.constants.custom_model: gpu_dict = self.constants.computer.gpus diff --git a/resources/build/misc.py b/resources/build/misc.py index 8939ceb38..a7abe5c66 100644 --- a/resources/build/misc.py +++ b/resources/build/misc.py @@ -22,12 +22,18 @@ class BuildMiscellaneous: self._build() + def rmtree_handler(func, path, exc_info) -> None: if exc_info[0] == FileNotFoundError: return raise # pylint: disable=misplaced-bare-raise + def _build(self) -> None: + """ + Kick off Misc Build Process + """ + self._feature_unlock_handling() self._restrict_events_handling() self._firewire_handling() @@ -39,17 +45,26 @@ class BuildMiscellaneous: self._cpu_friend_handling() self._general_oc_handling() + def _feature_unlock_handling(self) -> None: - if self.constants.fu_status is True: - support.BuildSupport(self.model, self.constants, self.config).enable_kext("FeatureUnlock.kext", self.constants.featureunlock_version, self.constants.featureunlock_path) - if self.constants.fu_arguments is not None: - logging.info(f"- Adding additional FeatureUnlock args: {self.constants.fu_arguments}") - self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += self.constants.fu_arguments + """ + FeatureUnlock Handler + """ + + if self.constants.fu_status is False: + return + + support.BuildSupport(self.model, self.constants, self.config).enable_kext("FeatureUnlock.kext", self.constants.featureunlock_version, self.constants.featureunlock_path) + if self.constants.fu_arguments is not None: + logging.info(f"- Adding additional FeatureUnlock args: {self.constants.fu_arguments}") + self.config["NVRAM"]["Add"]["7C436110-AB2A-4BBB-A880-FE41995C9F82"]["boot-args"] += self.constants.fu_arguments + def _restrict_events_handling(self) -> None: - # RestrictEvents handling - # - revpatch: Process patching - # - revblock: Process blocking + """ + RestrictEvents Handler + """ + block_args = "" if self.model in ["MacBookPro6,1", "MacBookPro6,2", "MacBookPro9,1", "MacBookPro10,1"]: block_args += "gmux," @@ -114,29 +129,53 @@ class BuildMiscellaneous: def _cpu_friend_handling(self) -> None: - if self.model not in ["iMac7,1", "Xserve2,1", "Dortania1,1"] and self.constants.disallow_cpufriend is False and self.constants.serial_settings != "None": - support.BuildSupport(self.model, self.constants, self.config).enable_kext("CPUFriend.kext", self.constants.cpufriend_version, self.constants.cpufriend_path) + """ + CPUFriend Handler + """ + + if self.constants.disallow_cpufriend is True: + return + if self.model not in ["iMac7,1", "Xserve2,1", "Dortania1,1"]: + return + if self.constants.serial_settings == "None": + return + + support.BuildSupport(self.model, self.constants, self.config).enable_kext("CPUFriend.kext", self.constants.cpufriend_version, self.constants.cpufriend_path) + + # CPUFriendDataProvider handling + pp_map_path = Path(self.constants.platform_plugin_plist_path) / Path(f"{self.model}/Info.plist") + if not pp_map_path.exists(): + raise Exception(f"{pp_map_path} does not exist!!! Please file an issue stating file is missing for {self.model}.") + Path(self.constants.pp_kext_folder).mkdir() + Path(self.constants.pp_contents_folder).mkdir() + shutil.copy(pp_map_path, self.constants.pp_contents_folder) + support.BuildSupport(self.model, self.constants, self.config).get_kext_by_bundle_path("CPUFriendDataProvider.kext")["Enabled"] = True - # CPUFriendDataProvider handling - pp_map_path = Path(self.constants.platform_plugin_plist_path) / Path(f"{self.model}/Info.plist") - if not pp_map_path.exists(): - raise Exception(f"{pp_map_path} does not exist!!! Please file an issue stating file is missing for {self.model}.") - Path(self.constants.pp_kext_folder).mkdir() - Path(self.constants.pp_contents_folder).mkdir() - shutil.copy(pp_map_path, self.constants.pp_contents_folder) - support.BuildSupport(self.model, self.constants, self.config).get_kext_by_bundle_path("CPUFriendDataProvider.kext")["Enabled"] = True def _firewire_handling(self) -> None: - if self.constants.firewire_boot is True and generate_smbios.check_firewire(self.model) is True: - # Enable FireWire Boot Support - # Applicable for both native FireWire and Thunderbolt to FireWire adapters - logging.info("- Enabling FireWire Boot Support") - support.BuildSupport(self.model, self.constants, self.config).enable_kext("IOFireWireFamily.kext", self.constants.fw_kext, self.constants.fw_family_path) - support.BuildSupport(self.model, self.constants, self.config).enable_kext("IOFireWireSBP2.kext", self.constants.fw_kext, self.constants.fw_sbp2_path) - support.BuildSupport(self.model, self.constants, self.config).enable_kext("IOFireWireSerialBusProtocolTransport.kext", self.constants.fw_kext, self.constants.fw_bus_path) - support.BuildSupport(self.model, self.constants, self.config).get_kext_by_bundle_path("IOFireWireFamily.kext/Contents/PlugIns/AppleFWOHCI.kext")["Enabled"] = True + """ + FireWire Handler + """ + + if self.constants.firewire_boot is False: + return + if generate_smbios.check_firewire(self.model) is False: + return + + # Enable FireWire Boot Support + # Applicable for both native FireWire and Thunderbolt to FireWire adapters + logging.info("- Enabling FireWire Boot Support") + support.BuildSupport(self.model, self.constants, self.config).enable_kext("IOFireWireFamily.kext", self.constants.fw_kext, self.constants.fw_family_path) + support.BuildSupport(self.model, self.constants, self.config).enable_kext("IOFireWireSBP2.kext", self.constants.fw_kext, self.constants.fw_sbp2_path) + support.BuildSupport(self.model, self.constants, self.config).enable_kext("IOFireWireSerialBusProtocolTransport.kext", self.constants.fw_kext, self.constants.fw_bus_path) + support.BuildSupport(self.model, self.constants, self.config).get_kext_by_bundle_path("IOFireWireFamily.kext/Contents/PlugIns/AppleFWOHCI.kext")["Enabled"] = True + def _trackpad_handling(self) -> None: + """ + Trackpad Handler + """ + # Pre-Force Touch trackpad support for macOS Ventura if smbios_data.smbios_dictionary[self.model]["CPU Generation"] < cpu_data.cpu_data.skylake.value: if self.model.startswith("MacBook"): @@ -151,7 +190,12 @@ class BuildMiscellaneous: if self.model in ["MacBook4,1", "MacBook5,2"]: support.BuildSupport(self.model, self.constants, self.config).enable_kext("AppleUSBTrackpad.kext", self.constants.apple_trackpad, self.constants.apple_trackpad_path) + def _thunderbolt_handling(self) -> None: + """ + Thunderbolt Handler + """ + if self.constants.disable_tb is True and self.model in ["MacBookPro11,1", "MacBookPro11,2", "MacBookPro11,3", "MacBookPro11,4", "MacBookPro11,5"]: logging.info("- Disabling 2013-2014 laptop Thunderbolt Controller") if self.model in ["MacBookPro11,3", "MacBookPro11,5"]: @@ -163,13 +207,22 @@ class BuildMiscellaneous: self.config["DeviceProperties"]["Add"][tb_device_path] = {"class-code": binascii.unhexlify("FFFFFFFF"), "device-id": binascii.unhexlify("FFFF0000")} + def _webcam_handling(self) -> None: - # Legacy iSight patches + """ + iSight Handler + """ + if "Legacy iSight" in smbios_data.smbios_dictionary[self.model]: if smbios_data.smbios_dictionary[self.model]["Legacy iSight"] is True: support.BuildSupport(self.model, self.constants, self.config).enable_kext("LegacyUSBVideoSupport.kext", self.constants.apple_isight_version, self.constants.apple_isight_path) + def _usb_handling(self) -> None: + """ + USB Handler + """ + # USB Map usb_map_path = Path(self.constants.plist_folder_path) / Path("AppleUSBMaps/Info.plist") if ( @@ -193,10 +246,7 @@ class BuildMiscellaneous: # And MacPro4,1 and MacPro5,1 are the only post-Penryn Macs that lack an internal USB hub # - Ref: https://techcommunity.microsoft.com/t5/microsoft-usb-blog/reasons-to-avoid-companion-controllers/ba-p/270710 # - # Required downgrades: - # - IOUSBHostFamily.kext (only kext itself, not plugins) - # - AppleUSBHub.kext - # - AppleUSBEHCI.kext + # To be paired for sys_patch_dict.py's 'Legacy USB 1.1' patchset if ( smbios_data.smbios_dictionary[self.model]["CPU Generation"] <= cpu_data.cpu_data.penryn.value or \ self.model in ["MacPro4,1", "MacPro5,1"] @@ -208,8 +258,11 @@ class BuildMiscellaneous: support.BuildSupport(self.model, self.constants, self.config).get_kext_by_bundle_path("USB1.1-Injector.kext/Contents/PlugIns/AppleUSBUHCI.kext")["Enabled"] = True support.BuildSupport(self.model, self.constants, self.config).get_kext_by_bundle_path("USB1.1-Injector.kext/Contents/PlugIns/AppleUSBUHCIPCI.kext")["Enabled"] = True + def _debug_handling(self) -> None: - # DEBUG Settings (OpenCorePkg and Kernel Space) + """ + Debug Handler for OpenCorePkg and Kernel Space + """ if self.constants.verbose_debug is True: logging.info("- Enabling Verbose boot") @@ -228,13 +281,12 @@ class BuildMiscellaneous: self.config["Misc"]["Debug"]["Target"] = 0x43 self.config["Misc"]["Debug"]["DisplayLevel"] = 0x80000042 + def _general_oc_handling(self) -> None: """ - + General OpenCorePkg Handler """ - # OpenCorePkg Settings - # OpenCanopy Settings (GUI) logging.info("- Adding OpenCanopy GUI") shutil.rmtree(self.constants.resources_path, onerror=self.rmtree_handler) shutil.copy(self.constants.gui_path, self.constants.oc_folder) diff --git a/resources/build/networking/wireless.py b/resources/build/networking/wireless.py index 90bd80fd9..cc2ba8c5a 100644 --- a/resources/build/networking/wireless.py +++ b/resources/build/networking/wireless.py @@ -101,8 +101,13 @@ class BuildWirelessNetworking: def _wowl_handling(self) -> None: - # To avoid reduced networking performance from wake, AirPortBrcmFixup is used to disable wake on WLAN by default. - # However some users may want to enable wake on WLAN, so enable if requested. + """ + Wake on WLAN handling + + To avoid reduced networking performance from wake, AirPortBrcmFixup is used to disable wake on WLAN by default. + However some users may want to enable wake on WLAN, so enable if requested. + """ + if self.constants.enable_wake_on_wlan is False: return if support.BuildSupport(self.model, self.constants, self.config).get_kext_by_bundle_path("AirportBrcmFixup.kext")["Enabled"] is False: @@ -113,8 +118,13 @@ class BuildWirelessNetworking: def _wifi_fake_id(self) -> None: - # BCM94331 and BCM943224 are both partially supported within Big Sur's native AirPortBrcmNIC stack - # Simply adding the Device IDs and usage of AirPortBrcmFixup will restore full functionality + """ + Fake Device ID Handler for BCM943224 and BCM94331 chipsets + + BCM94331 and BCM943224 are both partially supported within Big Sur's native AirPortBrcmNIC stack + Simply adding the Device IDs and usage of AirPortBrcmFixup will restore full functionality + """ + support.BuildSupport(self.model, self.constants, self.config).enable_kext("AirportBrcmFixup.kext", self.constants.airportbcrmfixup_version, self.constants.airportbcrmfixup_path) support.BuildSupport(self.model, self.constants, self.config).get_kext_by_bundle_path("AirportBrcmFixup.kext/Contents/PlugIns/AirPortBrcmNIC_Injector.kext")["Enabled"] = True if not self.constants.custom_model and self.computer.wifi and self.computer.wifi.pci_path: diff --git a/resources/build/storage.py b/resources/build/storage.py index f40012d18..093f1f1d2 100644 --- a/resources/build/storage.py +++ b/resources/build/storage.py @@ -32,6 +32,10 @@ class BuildStorage: def _ahci_handling(self) -> None: + """ + AHCI (SATA) Handler + """ + # MacBookAir6,x ship with an AHCI over PCIe SSD model 'APPLE SSD TS0128F' and 'APPLE SSD TS0256F' # This controller is not supported properly in macOS Ventura, instead populating itself as 'Media' with no partitions # To work-around this, use Monterey's AppleAHCI driver to force support @@ -67,6 +71,10 @@ class BuildStorage: def _pata_handling(self) -> None: + """ + ATA (PATA) Handler + """ + if not self.model in smbios_data.smbios_dictionary: return if not "Stock Storage" in smbios_data.smbios_dictionary[self.model]: @@ -78,6 +86,10 @@ class BuildStorage: def _pcie_handling(self) -> None: + """ + PCIe/NVMe Handler + """ + if not self.constants.custom_model and (self.constants.allow_oc_everywhere is True or self.model in model_array.MacPro): # Use Innie's same logic: # https://github.com/cdf/Innie/blob/v1.3.0/Innie/Innie.cpp#L90-L97 @@ -127,6 +139,10 @@ class BuildStorage: def _misc_handling(self) -> None: + """ + SDXC Handler + """ + if not self.model in smbios_data.smbios_dictionary: return if not "CPU Generation" in smbios_data.smbios_dictionary[self.model]: @@ -140,6 +156,10 @@ class BuildStorage: def _trim_handling(self) -> None: + """ + TRIM Handler + """ + if self.constants.apfs_trim_timeout is False: logging.info(f"- Disabling APFS TRIM timeout") self.config["Kernel"]["Quirks"]["SetApfsTrimTimeout"] = 0 \ No newline at end of file diff --git a/resources/build/support.py b/resources/build/support.py index 2d473edbc..b70a63e95 100644 --- a/resources/build/support.py +++ b/resources/build/support.py @@ -2,6 +2,7 @@ # Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk import shutil +import typing import logging import plistlib import zipfile @@ -21,7 +22,17 @@ class BuildSupport: @staticmethod - def get_item_by_kv(iterable, key, value): + def get_item_by_kv(iterable: dict, key: str, value: typing.Any) -> dict: + """ + Gets an item from a list of dicts by key and value + + Parameters: + iterable (list): List of dicts + key (str): Key to search for + value (any): Value to search for + + """ + item = None for i in iterable: if i[key] == value: @@ -30,24 +41,49 @@ class BuildSupport: return item - def get_kext_by_bundle_path(self, bundle_path): - kext = self.get_item_by_kv(self.config["Kernel"]["Add"], "BundlePath", bundle_path) + def get_kext_by_bundle_path(self, bundle_path: str) -> dict: + """ + Gets a kext by bundle path + + Parameters: + bundle_path (str): Relative bundle path of the kext in the EFI folder + """ + + kext: dict = self.get_item_by_kv(self.config["Kernel"]["Add"], "BundlePath", bundle_path) if not kext: logging.info(f"- Could not find kext {bundle_path}!") raise IndexError return kext - def get_efi_binary_by_path(self, bundle_path, entry_location, efi_type): - efi_binary = self.get_item_by_kv(self.config[entry_location][efi_type], "Path", bundle_path) + def get_efi_binary_by_path(self, bundle_name: str, entry_type: str, efi_type: str) -> dict: + """ + Gets an EFI binary by name + + Parameters: + bundle_name (str): Name of the EFI binary + entry_type (str): Type of EFI binary (UEFI, Misc) + efi_type (str): Type of EFI binary (Drivers, Tools) + """ + + efi_binary: dict = self.get_item_by_kv(self.config[entry_type][efi_type], "Path", bundle_name) if not efi_binary: - logging.info(f"- Could not find {efi_type}: {bundle_path}!") + logging.info(f"- Could not find {efi_type}: {bundle_name}!") raise IndexError return efi_binary - def enable_kext(self, kext_name, kext_version, kext_path, check=False): - kext = self.get_kext_by_bundle_path(kext_name) + def enable_kext(self, kext_name: str, kext_version: str, kext_path: Path, check: bool = False) -> None: + """ + Enables a kext in the config.plist + + Parameters: + kext_name (str): Name of the kext + kext_version (str): Version of the kext + kext_path (Path): Path to the kext + """ + + kext: dict = self.get_kext_by_bundle_path(kext_name) if callable(check) and not check(): # Check failed @@ -61,7 +97,11 @@ class BuildSupport: kext["Enabled"] = True - def sign_files(self): + def sign_files(self) -> None: + """ + Signs files for on OpenCorePkg's Vault system + """ + if self.constants.vault is False: return @@ -77,9 +117,13 @@ class BuildSupport: subprocess.run([str(self.constants.vault_path), f"{self.constants.oc_folder}/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) - def validate_pathing(self): - # Verify whether all files are accounted for on-disk - # This ensures that OpenCore won't hit a critical error and fail to boot + def validate_pathing(self) -> None: + """ + Validate whether all files are accounted for on-disk + + This ensures that OpenCore won't hit a critical error and fail to boot + """ + logging.info("- Validating generated config") if not Path(self.constants.opencore_release_folder / Path("EFI/OC/config.plist")): logging.info("- OpenCore config file missing!!!") @@ -129,7 +173,11 @@ class BuildSupport: raise Exception(f"Found extra driver: {driver_file.name}") - def cleanup(self): + def cleanup(self) -> None: + """ + Clean up files and entries + """ + logging.info("- Cleaning up files") # Remove unused entries entries_to_clean = {