diff --git a/Changelog.md b/Changelog.md new file mode 100644 index 0000000..356dbe8 --- /dev/null +++ b/Changelog.md @@ -0,0 +1,22 @@ +NvidiaGraphicsFixup Changelog +============================= +#### v1.2.1 +- All patches can be turned off by boot-args (and some of them can be also turned off by using ioreg properties) + +#### v1.2.0 +- Lilu 1.2.0 compatibility fixes +- NVidiaAudio device to add connector-type, layout-id and other properties for HDMI audio (allows audio for HDMI, DP, Digital DVI ports) +- A new hook for nvAcceleratorParent::SetAccelProperties to add properties "IOVARendererID" and "IOVARendererSubID" +- NVWebDriverLibValFix fix is implemented (csfg_get_platform_binary) + +#### v1.1.3 +- High Sierra compatibility + +#### v1.1.2 +- Added OSBundleCompatibleVersion + +#### v1.1 +- Patch has been improved (vit9696) + +#### v1.0.0 +- Initial release diff --git a/FAQ.md b/FAQ.md new file mode 100644 index 0000000..407905d --- /dev/null +++ b/FAQ.md @@ -0,0 +1,49 @@ +- _What are the system requirements?_ +while there are no particular limitations, this FAQ does not include the specific information regarding GPUs before Kepler (i.e. older than 6xx series). +In general it appears to be less convenient to use CPUs newer than Ivy and Haswell with NVIDIA GPUs. +For GPUs newer than Kepler (e.g. Maxwell or Pascal) you need [NVIDIA Web Driver](http://www.nvidia.com/download/driverResults.aspx/125379/en-us). Use `nv_disable=1` boot argument to install it. + +- _What is the general idea?_ +If you have builtin Intel GPU, make sure to rename it to IGPU and enable with connector-less frame first. Then choose a most suitable mac model and install NvidiaGraphicsFixup. To get hardware video decoding you are likely to need [Shiki](https://github.com/vit9696/Shiki), please read its [FAQ](https://github.com/vit9696/Shiki/blob/master/Manual/FAQ.en.md) carefully to get a good understanding. + +- _How to properly choose a mac model?_ +If you have Ivy Bridge or Haswell CPU you should go with iMac13,2 or iMac14,2. Otherwise choose the model you prefer, but keep this in mind: + * If you have Intel GPU, especially if Ivy Bridge or newer, choose the model (by `board-id`) that has `forceOfflineRenderer` set to YES (true) in /System/Library/PrivateFrameworks/AppleGVA.framework/Versions/A/Info.plist. + * Models other than iMac13,2 and iMac14,2 require patches, which are though normally automated in NvidiaGraphicsFixup (see below) + * CPUs newer than Haswell require Shiki patches for hardware video decoding (see below). + +- _Why should I use Intel GPU with a connector-less frame?_ +Nvidia GPUs newer than 2xx do not implement hardware video decoder in macOS, also starting with 10.13 dual-GPU setups often cause a bootloop. If you absolutely need your IGPU with connector-full frame you will have to use [IntelGraphicsFixup](https://sourceforge.net/projects/intelgraphicsfixup) and most likely [Shiki](https://github.com/vit9696/Shiki) with `shikigva=1` OR a model without `forceOfflineRenderer`. + +- _How to use Intel GPU with a connector-less frame?_ +Please refer to [Shiki FAQ](https://github.com/vit9696/Shiki/blob/master/Manual/FAQ.en.md) for full details. You could use SSDT to rename GFX0 to IGPU by creating a proper IGPU device and setting STA of the existing one to Zero: +``` +Scope (GFX0) { + Name (_STA, Zero) // _STA: Status +} +``` + +- _What patches do I need for mac models other than iMac13,2 and iMac14,2?_ +AppleGraphicsDisplayPolicy.kext contains a check against its Info.plist and determines which mode should be used for a specific board-id. It is dependent on the GPU which mode is suitable and is normally determined experimentally. NvidiaGraphicsFixup contains several ways to configure to set power management modes: + - kext patch enforcing `none` into ConfigMap dictionary for system board-id (ngfxpatch=cfgmap) + - kext patch disabling string comparison `` (ngfxpatch=vit9696, enabled by default) + - kext patch replacing `board-id` with `board-ix` (ngfxpatch=pikera) + +- _What patches do I need for Maxwell or Pascal GPUs?_ +Maxwell GPUs (normally 9xx and some 7xx) no longer supply a correct IOVARendererID to enable hardware video decoder. See more details: [here](https://github.com/vit9696/Shiki/issues/5). You no longer need any changes (e.g. iMac.kext) but NvidiaGraphicsFixup. This fix was added in 1.2.0 branch. Can be switched off by using boot-arg "-ngfxnovarenderer". + +- _What patches do processors newer than Haswell need?_ +Apple limits hardware video decoder with NVIDIA to only Haswell and earlier. To get hardware accelerated video decoding you need to patch AppleGVA.framework. To do so you could use [Shiki](https://github.com/vit9696/Shiki) with `shikigva=4` boot argument. On 10.13 you may currently use a temporary workaround that enables hardware video decoding only for a subset of processes via `shikigva=12` boot argument. + +- _What patches do Pascal GPUs need on 10.12?_ +On 10.12 and possibly on 10.13 Pascal GPUs need a team id unlock to avoid glitches like empty transparent windows and so on. This patch is already present in NvidiaGraphicsFixup, and the use of any other kext (e.g. NVWebDriverLibValFix.kext) is not needed. +Can be switched off by using boot-arg "-ngfxlibvalfix". + +- _How can I enable digital (HDMI audio)?_ +NvidiaGraphicsFixup will do it itself but you must esnure that you do not have any conflicting "fixes" from Clover, SSDT patches, Arbitrary and so on (e.g. FixDisplay, AddHDMI, etc.). NvidiaGraphicsFixup also renames GPU devices to GFX0 and HDAU and injects audio connectors @0,connector-type - @5,connector-type. Injection can be switched off by using boot-arg "-ngfxnoaudio" or more specific "-ngfxnoaudiocon". You can also use ioreg properties in GPU to disable respective injections: "no-audio-autofix" or "no-audio-fixconn". + +- _How can I partially fix Apple Logo during boot?_ +Inject `@X,AAPL,boot-display` GFX0 property with the main screen index instead of X, the value does not matter. + +- _Does NvidiaGraphicsFixup fix visual issues on wakeup with Pascal GPUs?_ +Not at the moment. It is also known that HDMI audio may not always work with Pascal GPUs. diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..59e861b --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,13 @@ +Copyright (c) 2017, lvs1974 + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/NvidiaGraphicsFixup.xcodeproj/project.pbxproj b/NvidiaGraphicsFixup.xcodeproj/project.pbxproj new file mode 100644 index 0000000..7cccd66 --- /dev/null +++ b/NvidiaGraphicsFixup.xcodeproj/project.pbxproj @@ -0,0 +1,412 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1C748C2D1C21952C0024EED2 /* kern_start.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C748C2C1C21952C0024EED2 /* kern_start.cpp */; }; + 1C9CB7B01C789FF500231E41 /* kern_ngfx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C9CB7AE1C789FF500231E41 /* kern_ngfx.cpp */; }; + 1C9CB7B11C789FF500231E41 /* kern_ngfx.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 1C9CB7AF1C789FF500231E41 /* kern_ngfx.hpp */; }; + 3BED6D991FD7026400B0577F /* Headers in Resources */ = {isa = PBXBuildFile; fileRef = 3BED6D981FD7026300B0577F /* Headers */; }; + 3BED6D9D1FD7028100B0577F /* LegacyIOService.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BED6D9A1FD7028100B0577F /* LegacyIOService.h */; }; + 3BED6D9E1FD7028100B0577F /* libkmod.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3BED6D9B1FD7028100B0577F /* libkmod.a */; }; + 3BED6D9F1FD7028100B0577F /* plugin_start.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3BED6D9C1FD7028100B0577F /* plugin_start.cpp */; }; + F65909931F7E8A4F005C96D1 /* kern_audio.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F65909911F7E8A4F005C96D1 /* kern_audio.hpp */; }; + F65909941F7E8A4F005C96D1 /* kern_audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F65909921F7E8A4F005C96D1 /* kern_audio.cpp */; }; + F69B33D91F9BCECD00F26009 /* FAQ.md in Resources */ = {isa = PBXBuildFile; fileRef = F69B33D81F9BCECC00F26009 /* FAQ.md */; }; + F6AA9BFB1F927574004D869C /* kern_config.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F6AA9BFA1F927574004D869C /* kern_config.hpp */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 1C642F521C8F157A006B4C51 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1C748C271C21952C0024EED2 /* NvidiaGraphicsFixup.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NvidiaGraphicsFixup.kext; sourceTree = BUILT_PRODUCTS_DIR; }; + 1C748C2C1C21952C0024EED2 /* kern_start.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = kern_start.cpp; sourceTree = ""; }; + 1C748C2E1C21952C0024EED2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1C9CB7AE1C789FF500231E41 /* kern_ngfx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kern_ngfx.cpp; sourceTree = ""; }; + 1C9CB7AF1C789FF500231E41 /* kern_ngfx.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = kern_ngfx.hpp; sourceTree = ""; }; + 1CF01C901C8CF97F002DCEA3 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + 1CF01C921C8CF997002DCEA3 /* Changelog.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = Changelog.md; sourceTree = ""; }; + 1CF01C931C8DF02E002DCEA3 /* LICENSE.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE.txt; sourceTree = ""; }; + 3BED6D981FD7026300B0577F /* Headers */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Headers; path = ../../Lilu/Lilu/Headers; sourceTree = ""; }; + 3BED6D9A1FD7028100B0577F /* LegacyIOService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LegacyIOService.h; path = ../../Lilu/Lilu/Library/LegacyIOService.h; sourceTree = ""; }; + 3BED6D9B1FD7028100B0577F /* libkmod.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libkmod.a; path = ../../Lilu/Lilu/Library/libkmod.a; sourceTree = ""; }; + 3BED6D9C1FD7028100B0577F /* plugin_start.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = plugin_start.cpp; path = ../../Lilu/Lilu/Library/plugin_start.cpp; sourceTree = ""; }; + F65909911F7E8A4F005C96D1 /* kern_audio.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = kern_audio.hpp; sourceTree = ""; }; + F65909921F7E8A4F005C96D1 /* kern_audio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = kern_audio.cpp; sourceTree = ""; }; + F69B33D81F9BCECC00F26009 /* FAQ.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = FAQ.md; sourceTree = ""; }; + F6AA9BFA1F927574004D869C /* kern_config.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = kern_config.hpp; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1C748C231C21952C0024EED2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3BED6D9E1FD7028100B0577F /* libkmod.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1C748C1D1C21952C0024EED2 = { + isa = PBXGroup; + children = ( + 1CF01C911C8CF982002DCEA3 /* Docs */, + 1C748C291C21952C0024EED2 /* NvidiaGraphicsFixup */, + CE405EC81E49DD7B00AA0B3D /* SDK */, + 1C748C281C21952C0024EED2 /* Products */, + ); + sourceTree = ""; + }; + 1C748C281C21952C0024EED2 /* Products */ = { + isa = PBXGroup; + children = ( + 1C748C271C21952C0024EED2 /* NvidiaGraphicsFixup.kext */, + ); + name = Products; + sourceTree = ""; + }; + 1C748C291C21952C0024EED2 /* NvidiaGraphicsFixup */ = { + isa = PBXGroup; + children = ( + F6AA9BFA1F927574004D869C /* kern_config.hpp */, + F65909921F7E8A4F005C96D1 /* kern_audio.cpp */, + F65909911F7E8A4F005C96D1 /* kern_audio.hpp */, + 1C748C2C1C21952C0024EED2 /* kern_start.cpp */, + 1C9CB7AE1C789FF500231E41 /* kern_ngfx.cpp */, + 1C9CB7AF1C789FF500231E41 /* kern_ngfx.hpp */, + 1C748C2E1C21952C0024EED2 /* Info.plist */, + ); + path = NvidiaGraphicsFixup; + sourceTree = ""; + }; + 1CF01C911C8CF982002DCEA3 /* Docs */ = { + isa = PBXGroup; + children = ( + F69B33D81F9BCECC00F26009 /* FAQ.md */, + 1CF01C901C8CF97F002DCEA3 /* README.md */, + 1CF01C931C8DF02E002DCEA3 /* LICENSE.txt */, + 1CF01C921C8CF997002DCEA3 /* Changelog.md */, + ); + name = Docs; + sourceTree = ""; + }; + CE405EC81E49DD7B00AA0B3D /* SDK */ = { + isa = PBXGroup; + children = ( + 3BED6D9A1FD7028100B0577F /* LegacyIOService.h */, + 3BED6D9B1FD7028100B0577F /* libkmod.a */, + 3BED6D9C1FD7028100B0577F /* plugin_start.cpp */, + 3BED6D981FD7026300B0577F /* Headers */, + ); + name = SDK; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 1C748C241C21952C0024EED2 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 1C9CB7B11C789FF500231E41 /* kern_ngfx.hpp in Headers */, + 3BED6D9D1FD7028100B0577F /* LegacyIOService.h in Headers */, + F65909931F7E8A4F005C96D1 /* kern_audio.hpp in Headers */, + F6AA9BFB1F927574004D869C /* kern_config.hpp in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 1C748C261C21952C0024EED2 /* NvidiaGraphicsFixup */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1C748C311C21952C0024EED2 /* Build configuration list for PBXNativeTarget "NvidiaGraphicsFixup" */; + buildPhases = ( + 1C748C221C21952C0024EED2 /* Sources */, + 1C748C231C21952C0024EED2 /* Frameworks */, + 1C748C241C21952C0024EED2 /* Headers */, + 1C748C251C21952C0024EED2 /* Resources */, + 1C642F521C8F157A006B4C51 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = NvidiaGraphicsFixup; + productName = NvidiaGraphicsFixup; + productReference = 1C748C271C21952C0024EED2 /* NvidiaGraphicsFixup.kext */; + productType = "com.apple.product-type.kernel-extension"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 1C748C1E1C21952C0024EED2 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0900; + ORGANIZATIONNAME = vit9696; + TargetAttributes = { + 1C748C261C21952C0024EED2 = { + CreatedOnToolsVersion = 7.2; + }; + }; + }; + buildConfigurationList = 1C748C211C21952C0024EED2 /* Build configuration list for PBXProject "NvidiaGraphicsFixup" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 1C748C1D1C21952C0024EED2; + productRefGroup = 1C748C281C21952C0024EED2 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1C748C261C21952C0024EED2 /* NvidiaGraphicsFixup */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1C748C251C21952C0024EED2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F69B33D91F9BCECD00F26009 /* FAQ.md in Resources */, + 3BED6D991FD7026400B0577F /* Headers in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1C748C221C21952C0024EED2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F65909941F7E8A4F005C96D1 /* kern_audio.cpp in Sources */, + 3BED6D9F1FD7028100B0577F /* plugin_start.cpp in Sources */, + 1C9CB7B01C789FF500231E41 /* kern_ngfx.cpp in Sources */, + 1C748C2D1C21952C0024EED2 /* kern_start.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1C748C2F1C21952C0024EED2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "c++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = c11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + 1C748C301C21952C0024EED2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "c++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = c11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 3; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_UNROLL_LOOPS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + SDKROOT = macosx; + }; + name = Release; + }; + 1C748C321C21952C0024EED2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = "$(MODULE_VERSION)"; + DEPLOYMENT_POSTPROCESSING = YES; + GCC_ENABLE_FLOATING_POINT_LIBRARY_CALLS = NO; + GCC_ENABLE_KERNEL_DEVELOPMENT = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "MODULE_VERSION=$(MODULE_VERSION)", + "PRODUCT_NAME=$(PRODUCT_NAME)", + "$(inherited)", + ); + HEADER_SEARCH_PATHS = /Volumes/evo/crack/Lilu/Lilu/; + INFOPLIST_FILE = NvidiaGraphicsFixup/Info.plist; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + /Volumes/evo/crack/Lilu/Lilu/Library, + ); + MACOSX_DEPLOYMENT_TARGET = 10.8; + MODULE_NAME = as.lvs1974.NvidiaGraphicsFixup; + MODULE_START = "$(PRODUCT_NAME)_kern_start"; + MODULE_STOP = "$(PRODUCT_NAME)_kern_stop"; + MODULE_VERSION = 1.2.1; + OTHER_CFLAGS = ( + "-mmmx", + "-msse", + "-msse2", + "-msse3", + "-mfpmath=sse", + "-mssse3", + "-ftree-vectorize", + "-fno-non-call-exceptions", + "-fno-builtin", + "-fno-asynchronous-unwind-tables", + ); + OTHER_LDFLAGS = "-static"; + PRODUCT_BUNDLE_IDENTIFIER = as.lvs1974.NvidiaGraphicsFixup; + PRODUCT_NAME = "$(TARGET_NAME)"; + WRAPPER_EXTENSION = kext; + }; + name = Debug; + }; + 1C748C331C21952C0024EED2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CURRENT_PROJECT_VERSION = "$(MODULE_VERSION)"; + DEAD_CODE_STRIPPING = YES; + DEPLOYMENT_POSTPROCESSING = YES; + GCC_ENABLE_FLOATING_POINT_LIBRARY_CALLS = NO; + GCC_ENABLE_KERNEL_DEVELOPMENT = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "MODULE_VERSION=$(MODULE_VERSION)", + "PRODUCT_NAME=$(PRODUCT_NAME)", + ); + HEADER_SEARCH_PATHS = /Volumes/evo/crack/Lilu/Lilu/; + INFOPLIST_FILE = NvidiaGraphicsFixup/Info.plist; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + /Volumes/evo/crack/Lilu/Lilu/Library, + ); + LLVM_LTO = YES; + MACOSX_DEPLOYMENT_TARGET = 10.8; + MODULE_NAME = as.lvs1974.NvidiaGraphicsFixup; + MODULE_START = "$(PRODUCT_NAME)_kern_start"; + MODULE_STOP = "$(PRODUCT_NAME)_kern_stop"; + MODULE_VERSION = 1.2.1; + OTHER_CFLAGS = ( + "-mmmx", + "-msse", + "-msse2", + "-msse3", + "-mfpmath=sse", + "-mssse3", + "-ftree-vectorize", + "-fno-non-call-exceptions", + "-fno-builtin", + "-fno-asynchronous-unwind-tables", + ); + OTHER_LDFLAGS = "-static"; + PRODUCT_BUNDLE_IDENTIFIER = as.lvs1974.NvidiaGraphicsFixup; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_STYLE = "non-global"; + WRAPPER_EXTENSION = kext; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1C748C211C21952C0024EED2 /* Build configuration list for PBXProject "NvidiaGraphicsFixup" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1C748C2F1C21952C0024EED2 /* Debug */, + 1C748C301C21952C0024EED2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1C748C311C21952C0024EED2 /* Build configuration list for PBXNativeTarget "NvidiaGraphicsFixup" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1C748C321C21952C0024EED2 /* Debug */, + 1C748C331C21952C0024EED2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 1C748C1E1C21952C0024EED2 /* Project object */; +} diff --git a/NvidiaGraphicsFixup.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/NvidiaGraphicsFixup.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..883aea0 --- /dev/null +++ b/NvidiaGraphicsFixup.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/NvidiaGraphicsFixup.xcodeproj/project.xcworkspace/xcuserdata/dany.xcuserdatad/UserInterfaceState.xcuserstate b/NvidiaGraphicsFixup.xcodeproj/project.xcworkspace/xcuserdata/dany.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..0847a3f Binary files /dev/null and b/NvidiaGraphicsFixup.xcodeproj/project.xcworkspace/xcuserdata/dany.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/NvidiaGraphicsFixup.xcodeproj/xcuserdata/dany.xcuserdatad/xcschemes/xcschememanagement.plist b/NvidiaGraphicsFixup.xcodeproj/xcuserdata/dany.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..aaac2cd --- /dev/null +++ b/NvidiaGraphicsFixup.xcodeproj/xcuserdata/dany.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + NvidiaGraphicsFixup.xcscheme + + orderHint + 0 + + + + diff --git a/NvidiaGraphicsFixup/Info.plist b/NvidiaGraphicsFixup/Info.plist new file mode 100644 index 0000000..dcd8ea5 --- /dev/null +++ b/NvidiaGraphicsFixup/Info.plist @@ -0,0 +1,80 @@ + + + + + OSBundleCompatibleVersion + 1.0 + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + KEXT + CFBundleShortVersionString + $(MODULE_VERSION) + CFBundleSignature + ???? + CFBundleVersion + $(MODULE_VERSION) + IOKitPersonalities + + as.lvs1974.NvidiaAudio + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + IOClass + NVidiaAudio + IOMatchCategory + IOService + IOPCIClassMatch + 0x04030000&0xffff0000 + IOPCIMatch + 0x000010de&0x0000ffff + IOProbeScore + 60000 + IOProviderClass + IOPCIDevice + + as.lvs1974.NvidiaGraphicsFixup + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + IOClass + $(PRODUCT_NAME:rfc1034identifier) + IOMatchCategory + $(PRODUCT_NAME:rfc1034identifier) + IOProviderClass + IOResources + IOResourceMatch + IOKit + + + NSHumanReadableCopyright + Copyright © 2017 lvs1974. All rights reserved. + OSBundleLibraries + + as.vit9696.Lilu + 1.2.0 + com.apple.kpi.bsd + 12.0.0 + com.apple.kpi.dsep + 12.0.0 + com.apple.kpi.iokit + 12.0.0 + com.apple.kpi.libkern + 12.0.0 + com.apple.kpi.mach + 12.0.0 + com.apple.kpi.unsupported + 12.0.0 + + OSBundleRequired + Root + + diff --git a/NvidiaGraphicsFixup/kern_audio.cpp b/NvidiaGraphicsFixup/kern_audio.cpp new file mode 100644 index 0000000..fbe92f8 --- /dev/null +++ b/NvidiaGraphicsFixup/kern_audio.cpp @@ -0,0 +1,249 @@ +// +// kern_audio.cpp +// NvidiaGraphicsFixup +// +// Copyright © 2017 lvs1974. All rights reserved. +// + +#include +#include + +#include "kern_config.hpp" +#include "kern_audio.hpp" + +OSDefineMetaClassAndStructors(NVidiaAudio, IOService) + +uint32_t NVidiaAudio::getAnalogLayout() { + // For some DP monitors layout-id value should match HDEF layout-id + // If we have HDEF properly configured, get the value + static uint32_t layout = 0; + + if (!layout) { + const char *tree[] {"AppleACPIPCI", "HDEF"}; + auto sect = WIOKit::findEntryByPrefix("/AppleACPIPlatformExpert", "PCI", gIOServicePlane); + for (size_t i = 0; sect && i < arrsize(tree); i++) { + sect = WIOKit::findEntryByPrefix(sect, tree[i], gIOServicePlane); + if (sect && i+1 == arrsize(tree)) { + if (WIOKit::getOSDataValue(sect, "layout-id", layout)) { + DBGLOG("audio", "found HDEF with layout-id %u", layout); + return layout; + } else { + SYSLOG("audio", "found HDEF with missing layout-id"); + } + } + } + + DBGLOG("audio", "failed to find HDEF layout-id, falling back to 1"); + layout = 0x1; + } + + return layout; +} + +IOService *NVidiaAudio::probe(IOService *hdaService, SInt32 *score) { + if (!ADDPR(startSuccess)) { + return nullptr; + } + + if (config.noaudiofixes) { + DBGLOG("audio", "all audio fixes are disabled"); + return nullptr; + } + + if (!hdaService) { + DBGLOG("audio", "received null digitial audio device"); + return nullptr; + } + + uint32_t hdaVen, hdaDev; + if (!WIOKit::getOSDataValue(hdaService, "vendor-id", hdaVen) || + !WIOKit::getOSDataValue(hdaService, "device-id", hdaDev)) { + SYSLOG("audio", "found an unknown device"); + return nullptr; + } + + auto hdaPlaneName = hdaService->getName(); + DBGLOG("audio", "corrects digital audio for hdau at %s with %04X:%04X", + hdaPlaneName ? hdaPlaneName : "(null)", hdaVen, hdaDev); + + if (hdaVen != VendorID::NVIDIA) { + DBGLOG("audio", "unsupported hdau vendor"); + return nullptr; + } + + IORegistryEntry *gpuService {nullptr}; + + // Cannot iterate over siblings, so firstly get to IOPP + auto controller = hdaService->getParentEntry(gIOServicePlane); + if (controller) { + // Then iterate over IOPP children (GFX0 and HDAU) + auto iterator = controller->getChildIterator(gIOServicePlane); + if (iterator) { + while ((gpuService = OSDynamicCast(IORegistryEntry, iterator->getNextObject())) != nullptr) { + uint32_t classCode; + if (WIOKit::getOSDataValue(gpuService, "class-code", classCode)) { + // https://pci-ids.ucw.cz/read/PD/03/00 PCI CLASS VGA COMPATIBLE CONTROLLER + if ((classCode & 0xFFFF00) == 0x030000) + break; + else + DBGLOG("audio", "found incompatible class-code %04X", classCode); + } else { + auto name = gpuService->getName(); + if (!name) name = "null"; + DBGLOG("audio", "failed to find class-code in %s", name); + } + + gpuService = nullptr; + } + + iterator->release(); + } else { + DBGLOG("audio", "hdau parent iterator error"); + } + } else { + DBGLOG("audio", "hdau parent error"); + } + + if (!gpuService) { + DBGLOG("audio", "failed to find gpu service"); + return nullptr; + } + + uint32_t gpuVen, gpuDev; + if (!WIOKit::getOSDataValue(gpuService, "vendor-id", gpuVen) || + !WIOKit::getOSDataValue(gpuService, "device-id", gpuDev)) { + SYSLOG("audio", "found an unknown gpu device"); + return nullptr; + } + + if (gpuService->getProperty("no-audio-autofix")) { + DBGLOG("audio", "asked to avoid messing with digital audio"); + return nullptr; + } + + auto gpuPlaneName = gpuService->getName(); + if (!gpuPlaneName) gpuPlaneName = "(null)"; + DBGLOG("audio", "corrects digital audio for gpu at %s with %04X:%04X", gpuPlaneName, gpuVen, gpuDev); + + if (gpuVen != VendorID::NVIDIA) { + DBGLOG("audio", "unsupported GPU vendor"); + return nullptr; + } + + // Power management may cause issues for non GFXx + if (!gpuPlaneName || strncmp(gpuPlaneName, "GFX", strlen("GFX"))) { + DBGLOG("audio", "fixing gpu plane name to GFX0"); + gpuService->setName("GFX0"); + } + + // AppleHDAController only recognises HDEF and HDAU + + if (!hdaPlaneName || strcmp(hdaPlaneName, "HDAU")) { + DBGLOG("audio", "fixing audio plane name to HDAU"); + hdaService->setName("HDAU"); + } + + // hda-gfx allows to separate the devices, must be unique + + auto hdaHdaGfx = hdaService->getProperty("hda-gfx"); + auto gpuHdaGfx = gpuService->getProperty("hda-gfx"); + if (!hdaHdaGfx && !gpuHdaGfx) { + static uint32_t hdaCounter {0}; + static const char *hdaNames[] { + "onboard-2", + "onboard-3", + "onboard-4" + }; + + if (hdaCounter < arrsize(hdaNames)) { + DBGLOG("audio", "fixing hda-gfx to %s", hdaNames[hdaCounter]); + auto hda = OSData::withBytes(hdaNames[hdaCounter], sizeof("onboard-2")); + hdaService->setProperty("hda-gfx", hda); + gpuService->setProperty("hda-gfx", hda); + hdaCounter++; + } else { + SYSLOG("audio", "out of hda-gfx indexes"); + } + } else { + DBGLOG("audio", "existing hda-gfx in gpu (%d) or hdau (%d), assuming complete inject", + gpuHdaGfx != nullptr, hdaHdaGfx != nullptr); + } + + // layout-id is heard to be required in rare cases + + if (!hdaService->getProperty("layout-id")) { + DBGLOG("audio", "fixing layout-id in hdau"); + uint32_t layout = getAnalogLayout(); + hdaService->setProperty("layout-id", OSData::withBytes(&layout, sizeof(layout))); + } else { + DBGLOG("audio", "found existing layout-id in hdau"); + } + + if (!config.noaudioconnectors && !gpuService->getProperty("no-audio-fixconn")) { + uint8_t builtBytes[] { 0x00, 0x08, 0x00, 0x00 }; + char connector_type[] { "@0,connector-type" }; + for (int i=0; igetProperty(connector_type)) { + DBGLOG("audio", "fixing %s in gpu", connector_type); + gpuService->setProperty(connector_type, OSData::withBytes(builtBytes, sizeof(builtBytes))); + } else { + DBGLOG("audio", "found existing %s in gpu", connector_type); + } + } + } + + // built-in is required for non-renamed devices + + if (!hdaService->getProperty("built-in")) { + DBGLOG("audio", "fixing built-in in hdau"); + uint8_t builtBytes[] { 0x01, 0x00, 0x00, 0x00 }; + hdaService->setProperty("built-in", OSData::withBytes(builtBytes, sizeof(builtBytes))); + } else { + DBGLOG("audio", "found existing built-in in hdau"); + } + + if (!gpuService->getProperty("built-in")) { + DBGLOG("audio", "fixing built-in in gpu"); + uint8_t builtBytes[] { 0x01, 0x00, 0x00, 0x00 }; + gpuService->setProperty("built-in", OSData::withBytes(builtBytes, sizeof(builtBytes))); + } else { + DBGLOG("audio", "found existing built-in in gpu"); + } + + // This may be required for device matching + + auto compatibleProp = OSDynamicCast(OSData, hdaService->getProperty("compatible")); + if (compatibleProp) { + uint32_t compatibleSz = compatibleProp->getLength(); + auto compatibleStr = static_cast(compatibleProp->getBytesNoCopy()); + DBGLOG("audio", "compatible property starts with %s and is %u bytes", compatibleStr ? compatibleStr : "(null)", compatibleSz); + + if (compatibleStr) { + for (uint32_t i = 0; i < compatibleSz; i++) { + if (!strcmp(&compatibleStr[i], "HDAU")) { + DBGLOG("audio", "found HDAU in compatible, ignoring"); + return nullptr; + } + + i += strlen(&compatibleStr[i]); + } + + uint32_t compatibleBufSz = compatibleSz + sizeof("HDAU"); + uint8_t *compatibleBuf = Buffer::create(compatibleBufSz); + if (compatibleBuf) { + DBGLOG("audio", "fixing compatible to have HDAU"); + lilu_os_memcpy(&compatibleBuf[0], compatibleStr, compatibleSz); + lilu_os_memcpy(&compatibleBuf[compatibleSz], "HDAU", sizeof("HDAU")); + hdaService->setProperty("compatible", OSData::withBytes(compatibleBuf, compatibleBufSz)); + } else { + SYSLOG("audio", "compatible property memory alloc failure %u", compatibleBufSz); + } + } + } else { + SYSLOG("audio", "compatible property is missing"); + } + + return nullptr; +} diff --git a/NvidiaGraphicsFixup/kern_audio.hpp b/NvidiaGraphicsFixup/kern_audio.hpp new file mode 100644 index 0000000..9da8814 --- /dev/null +++ b/NvidiaGraphicsFixup/kern_audio.hpp @@ -0,0 +1,35 @@ +// +// kern_audio.hpp +// NvidiaGraphicsFixup +// +// Copyright © 2017 lvs1974. All rights reserved. +// + +#ifndef kern_audio_hpp +#define kern_audio_hpp + +#include + +#include +#include + + + +class EXPORT NVidiaAudio : public IOService { + OSDeclareDefaultStructors(NVidiaAudio) + uint32_t getAnalogLayout(); +public: + IOService *probe(IOService *provider, SInt32 *score) override; + + struct VendorID { + enum : uint16_t { + ATIAMD = 0x1002, + NVIDIA = 0x10de, + Intel = 0x8086 + }; + }; + + static constexpr int MaxConnectorCount = 6; +}; + +#endif /* kern_audio_hpp */ diff --git a/NvidiaGraphicsFixup/kern_config.hpp b/NvidiaGraphicsFixup/kern_config.hpp new file mode 100644 index 0000000..53c26bb --- /dev/null +++ b/NvidiaGraphicsFixup/kern_config.hpp @@ -0,0 +1,63 @@ +// +// kern_config.hpp +// NvidiaGraphicFixup +// +// Copyright © 2016-2017 lvs1974. All rights reserved. +// + +#ifndef kern_config_private_h +#define kern_config_private_h + + +class Configuration { +public: + /** + * Possible boot arguments + */ + static const char *bootargOff[]; + static const char *bootargDebug[]; + static const char *bootargBeta[]; + static constexpr const char *bootargNoAudio {"-ngfxnoaudio"}; // disable all audio fixes + static constexpr const char *bootargNoAudioCon {"-ngfxnoaudiocon"}; // disable adding of @0,connector-type - @5,connector-type + static constexpr const char *bootargNoVARenderer {"-ngfxnovarenderer"}; // disable IOVARenderer injection + static constexpr const char *bootargNoLibValFix {"-ngfxlibvalfix"}; // disable NVWebDriverLibValFix fix + static constexpr const char *bootargPatchList {"ngfxpatch"}; // comma separated patches: cfgmap,pikera,vit9696 (by default) + + +public: + /** + * Retrieve boot arguments + */ + void readArguments(); + + /** + * disable all audio fixes + */ + bool noaudiofixes {false}; + + /** + * disable adding of @0,connector-type - @5,connector-type + */ + bool noaudioconnectors {false}; + + /** + * disable IOVARenderer injection + */ + bool novarenderer {false}; + + /** + * disable NVWebDriverLibValFix fix + */ + bool nolibvalfix {false}; + + /** + * patch list (can be separated by comma, space or something like that) + */ + char patch_list[64] = {"pikera"}; + + Configuration() = default; +}; + +extern Configuration config; + +#endif /* kern_config_private_h */ diff --git a/NvidiaGraphicsFixup/kern_ngfx.cpp b/NvidiaGraphicsFixup/kern_ngfx.cpp new file mode 100644 index 0000000..cd63d9b --- /dev/null +++ b/NvidiaGraphicsFixup/kern_ngfx.cpp @@ -0,0 +1,993 @@ +// +// kern_ngfx.cpp +// NvidiaGraphicsFixup +// +// Copyright © 2017 lvs1974. All rights reserved. +// + +#include +#include +#include + +#include "kern_config.hpp" +#include "kern_ngfx.hpp" + + +static const char *kextAGDPolicy[] { "/System/Library/Extensions/AppleGraphicsControl.kext/Contents/PlugIns/AppleGraphicsDevicePolicy.kext/Contents/MacOS/AppleGraphicsDevicePolicy" }; +static const char *kextAGDPolicyId { "com.apple.driver.AppleGraphicsDevicePolicy" }; + +static const char *kextGeForce[] { "/System/Library/Extensions/GeForce.kext/Contents/MacOS/GeForce" }; +static const char *kextGeForceId { "com.apple.GeForce" }; + +static const char *kextGeForceWeb[] { "/Library/Extensions/GeForceWeb.kext/Contents/MacOS/GeForceWeb", "/System/Library/Extensions/GeForceWeb.kext/Contents/MacOS/GeForceWeb" }; +static const char *kextGeForceWebId { "com.nvidia.web.GeForceWeb" }; + + +static const char *kextNVDAResmanWeb[] { "/Library/Extensions/NVDAResmanWeb.kext/Contents/MacOS/NVDAResmanWeb" }; +static const char *kextNVDAResmanId { "com.nvidia.web.NVDAResmanWeb" }; + +static const char *kextIOGraphicsFamily[] { "/System/Library/Extensions/IOGraphicsFamily.kext/IOGraphicsFamily" }; +static const char *kextIOGraphicsFamilyId { "com.apple.iokit.IOGraphicsFamily" }; + + +static const char *kextIONDRVSupport[] { "/System/Library/Extensions/IONDRVSupport.kext/IONDRVSupport" }; +static const char *kextIONDRVSupportId { "com.apple.iokit.IONDRVSupport" }; + +static KernelPatcher::KextInfo kextList[] { + { kextAGDPolicyId, kextAGDPolicy, arrsize(kextAGDPolicy), {true}, {}, KernelPatcher::KextInfo::Unloaded }, + { kextGeForceId, kextGeForce, arrsize(kextGeForce), {}, {}, KernelPatcher::KextInfo::Unloaded }, + { kextGeForceWebId, kextGeForceWeb, arrsize(kextGeForceWeb), {}, {}, KernelPatcher::KextInfo::Unloaded }, + { kextNVDAResmanId, kextNVDAResmanWeb, arrsize(kextNVDAResmanWeb), {}, {}, KernelPatcher::KextInfo::Unloaded }, + { kextIOGraphicsFamilyId, kextIOGraphicsFamily, arrsize(kextIOGraphicsFamily), {}, {}, KernelPatcher::KextInfo::Unloaded }, + { kextIONDRVSupportId, kextIONDRVSupport, arrsize(kextIONDRVSupport), {}, {}, KernelPatcher::KextInfo::Unloaded }, + +}; + +static size_t kextListSize {arrsize(kextList)}; + +// Only used in apple-driven callbacks +static NGFX *callbackNGFX = nullptr; + + +bool NGFX::init() { + if (getKernelVersion() > KernelVersion::Mavericks) + { + LiluAPI::Error error = lilu.onPatcherLoad( + [](void *user, KernelPatcher &patcher) { + callbackNGFX = static_cast(user); + callbackNGFX->processKernel(patcher); + }, this); + + if (error != LiluAPI::Error::NoError) { + SYSLOG("ngfx", "failed to register onPatcherLoad method %d", error); + return false; + } + } else { + progressState |= ProcessingState::KernelRouted; + } + + LiluAPI::Error error = lilu.onKextLoad(kextList, kextListSize, + [](void *user, KernelPatcher &patcher, size_t index, mach_vm_address_t address, size_t size) { + callbackNGFX = static_cast(user); + callbackNGFX->processKext(patcher, index, address, size); + }, this); + + if (error != LiluAPI::Error::NoError) { + SYSLOG("ngfx", "failed to register onKextLoad method %d", error); + return false; + } + + return true; +} + +void NGFX::deinit() { +} + +void NGFX::processKernel(KernelPatcher &patcher) { + if (!(progressState & ProcessingState::KernelRouted)) + { + if (!config.nolibvalfix) { + auto method_address = patcher.solveSymbol(KernelPatcher::KernelID, "_csfg_get_teamid"); + if (method_address) { + DBGLOG("ngfx", "obtained _csfg_get_teamid"); + csfg_get_teamid = reinterpret_cast(method_address); + + method_address = patcher.solveSymbol(KernelPatcher::KernelID, "_csfg_get_platform_binary"); + if (method_address ) { + DBGLOG("ngfx", "obtained _csfg_get_platform_binary"); + patcher.clearError(); + org_csfg_get_platform_binary = reinterpret_cast(patcher.routeFunction(method_address, reinterpret_cast(csfg_get_platform_binary), true)); + if (patcher.getError() == KernelPatcher::Error::NoError) { + DBGLOG("ngfx", "routed _csfg_get_platform_binary"); + } else { + SYSLOG("ngfx", "failed to route _csfg_get_platform_binary"); + } + } else { + SYSLOG("ngfx", "failed to resolve _csfg_get_platform_binary"); + } + + } else { + SYSLOG("ngfx", "failed to resolve _csfg_get_teamid"); + } + } + + progressState |= ProcessingState::KernelRouted; + } + + // Ignore all the errors for other processors + patcher.clearError(); +} + +void NGFX::processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t address, size_t size) { + if (progressState != ProcessingState::EverythingDone) { + for (size_t i = 0; i < kextListSize; i++) { + if (kextList[i].loadIndex == index) { + if (!(progressState & ProcessingState::GraphicsDevicePolicyPatched) && !strcmp(kextList[i].id, kextAGDPolicyId)) + { + DBGLOG("ngfx", "found %s", kextAGDPolicyId); + + const bool patch_vit9696 = (strstr(config.patch_list, "vit9696") != nullptr); + const bool patch_pikera = (strstr(config.patch_list, "pikera") != nullptr); + const bool patch_cfgmap = (strstr(config.patch_list, "cfgmap") != nullptr); + + if (patch_vit9696) + { + const uint8_t find[] = {0xBA, 0x05, 0x00, 0x00, 0x00}; + const uint8_t replace[] = {0xBA, 0x00, 0x00, 0x00, 0x00}; + KextPatch kext_patch { + {&kextList[i], find, replace, sizeof(find), 1}, + KernelVersion::MountainLion, KernelPatcher::KernelAny + }; + applyPatches(patcher, index, &kext_patch, 1, "vit9696"); + } + + if (patch_pikera) + { + const uint8_t find[] = "board-id"; + const uint8_t replace[] = "board-ix"; + KextPatch kext_patch { + {&kextList[i], find, replace, strlen((const char*)find), 1}, + KernelVersion::MountainLion, KernelPatcher::KernelAny + }; + applyPatches(patcher, index, &kext_patch, 1, "pikera"); + } + + if (patch_cfgmap) + { + auto method_address = patcher.solveSymbol(index, "__ZN25AppleGraphicsDevicePolicy5startEP9IOService"); + if (method_address) { + DBGLOG("ngfx", "obtained __ZN25AppleGraphicsDevicePolicy5startEP9IOService"); + patcher.clearError(); + orgAgdpStart = reinterpret_cast(patcher.routeFunction(method_address, reinterpret_cast(AppleGraphicsDevicePolicy_start), true)); + if (patcher.getError() == KernelPatcher::Error::NoError) { + DBGLOG("ngfx", "routed __ZN25AppleGraphicsDevicePolicy5startEP9IOService"); + } else { + SYSLOG("ngfx", "failed to route __ZN25AppleGraphicsDevicePolicy5startEP9IOService"); + } + } else { + SYSLOG("ngfx", "failed to resolve __ZN25AppleGraphicsDevicePolicy5startEP9IOService"); + } + } + progressState |= ProcessingState::GraphicsDevicePolicyPatched; + } + else if (!(progressState & ProcessingState::GeForceRouted) && !strcmp(kextList[i].id, kextGeForceId)) + { + if (!config.novarenderer) { + DBGLOG("ngfx", "found %s", kextGeForceId); + auto method_address = patcher.solveSymbol(index, "__ZN13nvAccelerator18SetAccelPropertiesEv"); + if (method_address) { + DBGLOG("ngfx", "obtained __ZN13nvAccelerator18SetAccelPropertiesEv"); + patcher.clearError(); + orgSetAccelProperties = reinterpret_cast(patcher.routeFunction(method_address, reinterpret_cast(nvAccelerator_SetAccelProperties), true)); + if (patcher.getError() == KernelPatcher::Error::NoError) { + DBGLOG("ngfx", "routed __ZN13nvAccelerator18SetAccelPropertiesEv"); + } else { + SYSLOG("ngfx", "failed to route __ZN13nvAccelerator18SetAccelPropertiesEv"); + } + } else { + SYSLOG("ngfx", "failed to resolve __ZN13nvAccelerator18SetAccelPropertiesEv"); + } + } + + progressState |= ProcessingState::GeForceRouted; + } + else if (!(progressState & ProcessingState::GeForceWebRouted) && !strcmp(kextList[i].id, kextGeForceWebId)) + { + if (!config.novarenderer) { + DBGLOG("ngfx", "found %s", kextGeForceWebId); + auto method_address = patcher.solveSymbol(index, "__ZN19nvAcceleratorParent18SetAccelPropertiesEv"); + if (method_address) { + DBGLOG("ngfx", "obtained __ZN19nvAcceleratorParent18SetAccelPropertiesEv"); + patcher.clearError(); + orgSetAccelProperties = reinterpret_cast(patcher.routeFunction(method_address, reinterpret_cast(nvAccelerator_SetAccelProperties), true)); + if (patcher.getError() == KernelPatcher::Error::NoError) { + DBGLOG("ngfx", "routed __ZN19nvAcceleratorParent18SetAccelPropertiesEv"); + } else { + SYSLOG("ngfx", "failed to route __ZN19nvAcceleratorParent18SetAccelPropertiesEv"); + } + } else { + SYSLOG("ngfx", "failed to resolve __ZN19nvAcceleratorParent18SetAccelPropertiesEv"); + } + } + + progressState |= ProcessingState::GeForceWebRouted; + } + else if (!(progressState & ProcessingState::NVDAResmanRouted) && !strcmp(kextList[i].id, kextNVDAResmanId)) + { + DBGLOG("ngfx", "found %s", kextNVDAResmanId); + + auto method_address = patcher.solveSymbol(index, "__ZN4NVDA22validateDetailedTimingEPvy"); + if (method_address) { + DBGLOG("ngfx", "obtained __ZN4NVDA22validateDetailedTimingEPvy"); + patcher.clearError(); + org_nda_validateDetailedTiming = reinterpret_cast(patcher.routeFunction(method_address, reinterpret_cast(nvda_validateDetailedTiming_patch), true)); + } + else + { + SYSLOG("ngfx", "failed to resolve __ZN4NVDA22validateDetailedTimingEPvy"); + + } + + + method_address = patcher.solveSymbol(index, "__ZN4NVDA25setAttributeForConnectionEijm"); + if (method_address) { + DBGLOG("ngfx", "obtained __ZN4NVDA25setAttributeForConnectionEijm"); + patcher.clearError(); + org_NVDA_setAttributeForConnection = reinterpret_cast(patcher.routeFunction(method_address, reinterpret_cast(NVDA_setAttributeForConnection), true)); + } + else + { + SYSLOG("ngfx", "failed to resolve __ZN4NVDA25setAttributeForConnectionEijm"); + } + method_address = patcher.solveSymbol(index, "__ZN4NVDA25getAttributeForConnectionEijPm"); + if (method_address) { + DBGLOG("ngfx", "obtained __ZN4NVDA25getAttributeForConnectionEijPm"); + patcher.clearError(); + org_NVDA_getAttributeForConnection = reinterpret_cast(patcher.routeFunction(method_address, reinterpret_cast(NVDA_getAttributeForConnection), true)); + } + else + { + SYSLOG("ngfx", "failed to resolve __ZN4NVDA25getAttributeForConnectionEijPm"); + + } + + + //__ZN4NVDA16enableControllerEv + +// method_address = patcher.solveSymbol(index, "__ZN4NVDA16enableControllerEv"); +// if (method_address) { +// DBGLOG("ngfx", "obtained __ZN4NVDA16enableControllerEv"); +// patcher.clearError(); +// org_enablecontroller = reinterpret_cast(patcher.routeFunction(method_address, reinterpret_cast(nvenablecontroller), true)); +// } +// else +// { +// SYSLOG("ngfx", "failed to resolve __ZN4NVDA16enableControllerEv"); +// +// } + + + + //__ZN4NVDA28getInformationForDisplayModeEiP24IODisplayModeInformation: // NVDA::getInformationForDisplayMode(int, IODisplayModeInformation*) + + // using t_getInformationForDisplayMode = IOReturn (*)(IONDRVFramebuffer *that, IODisplayModeID mode, IODisplayModeInformation * info ); + // t_getInformationForDisplayMode org_getInformationForDisplayMode{nullptr}; + +// method_address = patcher.solveSymbol(index, "__ZN4NVDA28getInformationForDisplayModeEiP24IODisplayModeInformation"); +// if (method_address) { +// DBGLOG("ngfx", "obtained __ZN4NVDA28getInformationForDisplayModeEiP24IODisplayModeInformation"); +// patcher.clearError(); +// org_getInformationForDisplayMode = reinterpret_cast(patcher.routeFunction(method_address, reinterpret_cast(getInformationForDisplayMode), true)); +// } +// else +// { +// SYSLOG("ngfx", "failed to resolve __ZN4NVDA28getInformationForDisplayModeEiP24IODisplayModeInformation"); +// +// } + + progressState |= ProcessingState::NVDAResmanRouted; + + } + + else if (!(progressState & ProcessingState::NVDAIOGraphicsRouted) && !strcmp(kextList[i].id, kextIOGraphicsFamilyId)) + { + DBGLOG("ngfx", "found %s", kextIOGraphicsFamilyId); + +// auto method_address = patcher.solveSymbol(index, "__ZN13IOFramebuffer24extSetStartupDisplayModeEP8OSObjectPvP25IOExternalMethodArguments"); +// if (method_address) { +// DBGLOG("ngfx", "obtained __ZN13IOFramebuffer24extSetStartupDisplayModeEP8OSObjectPvP25IOExternalMethodArguments"); +// patcher.clearError(); +// orgExtSetStartupDisplayMode = reinterpret_cast(patcher.routeFunction(method_address, reinterpret_cast(extSetStartupDisplayModePatch), true)); +// +// } +// else +// { +// SYSLOG("ngfx", "failed to resolve __ZN13IOFramebuffer24extSetStartupDisplayModeEP8OSObjectPvP25IOExternalMethodArguments"); +// +// } +// + + // __ZN13IOFramebuffer16extSetPropertiesEP12OSDictionary: // IOFramebuffer::extSetProperties(OSDictionary*) + // using t_extSetProperties = IOReturn (*) (IOFramebuffer * that, OSDictionary * dict ); + +// method_address = patcher.solveSymbol(index, "__ZN13IOFramebuffer16extSetPropertiesEP12OSDictionary"); +// if (method_address) { +// DBGLOG("ngfx", "obtained __ZN13IOFramebuffer16extSetPropertiesEP12OSDictionary"); +// patcher.clearError(); +// org_extSetProperties = reinterpret_cast(patcher.routeFunction(method_address, reinterpret_cast(extSetProperties), true)); +// } +// else +// { +// SYSLOG("ngfx", "failed to resolve __ZN13IOFramebuffer16extSetPropertiesEP12OSDictionary"); +// } + + + // __ZN13IOFramebuffer16matchFramebufferEv: // IOFramebuffer::matchFramebuffer() + //using t_matchFramebuffer = IOReturn (*) (IOFramebuffer * that); +// method_address = patcher.solveSymbol(index, "__ZN13IOFramebuffer16matchFramebufferEv"); +// if (method_address) { +// DBGLOG("ngfx", "obtained __ZN13IOFramebuffer16matchFramebufferEv"); +// patcher.clearError(); +// org_matchFramebuffer = reinterpret_cast(patcher.routeFunction(method_address, reinterpret_cast(matchFramebuffer), true)); +// } +// else +// { +// SYSLOG("ngfx", "failed to resolve __ZN13IOFramebuffer16matchFramebufferEv"); +// } + + + + + // IOReturn IOFramebuffer::extGetInformationForDisplayMode( + // OSObject * target, void * reference, IOExternalMethodArguments * args) + //__ZN13IOFramebuffer31extGetInformationForDisplayModeEP8OSObjectPvP25IOExternalMethodArguments: // IOFramebuffer::extGetInformationForDisplayMode(OSObject*, void*, IOExternalMethodArguments*) + +// using t_extGetInformationForDisplayMode = IOReturn (*)( OSObject * target, void * reference, IOExternalMethodArguments * args ); +// t_extGetInformationForDisplayMode org_extGetInformationForDisplayMode{nullptr}; + +// method_address = patcher.solveSymbol(index, "__ZN13IOFramebuffer31extGetInformationForDisplayModeEP8OSObjectPvP25IOExternalMethodArguments"); +// if (method_address) { +// DBGLOG("ngfx", "obtained __ZN13IOFramebuffer31extGetInformationForDisplayModeEP8OSObjectPvP25IOExternalMethodArguments"); +// patcher.clearError(); +// org_extGetInformationForDisplayMode = reinterpret_cast(patcher.routeFunction(method_address, reinterpret_cast(extGetInformationForDisplayMode), true)); +// } +// else +// { +// SYSLOG("ngfx", "failed to resolve __ZN13IOFramebuffer31extGetInformationForDisplayModeEP8OSObjectPvP25IOExternalMethodArguments"); +// } +// + + + // __ZN13IOFramebuffer7doSetupEb: // IOFramebuffer::doSetup(bool) + // using t_doSetup = IOReturn (*)( IONDRVFramebuffer *that, bool full); + +// method_address = patcher.solveSymbol(index, "__ZN13IOFramebuffer7doSetupEb"); +// if (method_address) { +// DBGLOG("ngfx", "obtained __ZN13IOFramebuffer7doSetupEb"); +// patcher.clearError(); +// org_doSetup = reinterpret_cast(patcher.routeFunction(method_address, reinterpret_cast(doSetup), true)); +// } +// else +// { +// SYSLOG("ngfx", "failed to resolve __ZN13IOFramebuffer7doSetupEb"); +// } + + + + progressState |= ProcessingState::NVDAIOGraphicsRouted; + + } + + else if (!(progressState & ProcessingState::NVDASupportRouted) && !strcmp(kextList[i].id, kextIONDRVSupportId)) + { + DBGLOG("ngfx", "found %s", kextIONDRVSupportId); + +// auto method_address = patcher.solveSymbol(index, "__ZN17IONDRVFramebuffer17setDetailedTimingEijPvy"); +// if (method_address) { +// DBGLOG("ngfx", "obtained __ZN17IONDRVFramebuffer17setDetailedTimingEijPvy"); +// patcher.clearError(); +// org_setDetailedTiming = reinterpret_cast(patcher.routeFunction(method_address, reinterpret_cast(nvda_setDetailedTiming_patch), true)); +// +// } +// else +// { +// SYSLOG("ngfx", "failed to resolve __ZN17IONDRVFramebuffer17setDetailedTimingEijPvy"); +// +// } +// + + + // __ZN17IONDRVFramebuffer21getStartupDisplayModeEPiS0_ + +// method_address = patcher.solveSymbol(index, "__ZN17IONDRVFramebuffer21getStartupDisplayModeEPiS0_"); +// if (method_address) { +// DBGLOG("ngfx", "obtained __ZN17IONDRVFramebuffer21getStartupDisplayModeEPiS0_"); +// patcher.clearError(); +// org_getStartupDisplayMode = reinterpret_cast(patcher.routeFunction(method_address, reinterpret_cast(getStartupDisplayMode), true)); +// +// } +// else +// { +// SYSLOG("ngfx", "failed to resolve __ZN17IONDRVFramebuffer21getStartupDisplayModeEPiS0_"); +// +// } + + + //__ZN17IONDRVFramebuffer21setStartupDisplayModeEii + + + auto method_address = patcher.solveSymbol(index, "__ZN17IONDRVFramebuffer21setStartupDisplayModeEii"); + if (method_address) { + DBGLOG("ngfx", "obtained __ZN17IONDRVFramebuffer21setStartupDisplayModeEii"); + patcher.clearError(); + org_setStartupDisplayMode = reinterpret_cast(patcher.routeFunction(method_address, reinterpret_cast(setStartupDisplayMode), true)); + + } + else + { + SYSLOG("ngfx", "failed to resolve __ZN17IONDRVFramebuffer21setStartupDisplayModeEii"); + + } + + //__ZN17IONDRVFramebuffer18setDetailedTimingsEP7OSArray + +// method_address = patcher.solveSymbol(index, "__ZN17IONDRVFramebuffer18setDetailedTimingsEP7OSArray"); +// if (method_address) { +// DBGLOG("ngfx", "obtained __ZN17IONDRVFramebuffer18setDetailedTimingsEP7OSArray"); +// patcher.clearError(); +// org_setDetailedTimings = reinterpret_cast(patcher.routeFunction(method_address, +// reinterpret_cast(setDetailedTimings), true)); +// +// } +// else +// { +// SYSLOG("ngfx", "failed to resolve __ZN17IONDRVFramebuffer18setDetailedTimingsEP7OSArray"); +// +// } +// + + // __ZN17IONDRVFramebuffer14setDisplayModeEii: // IONDRVFramebuffer::setDisplayMode(int, int) + +// method_address = patcher.solveSymbol(index, "__ZN17IONDRVFramebuffer14setDisplayModeEii"); +// if (method_address) { +// DBGLOG("ngfx", "obtained __ZN17IONDRVFramebuffer14setDisplayModeEii"); +// patcher.clearError(); +// org_setDisplayMode = reinterpret_cast(patcher.routeFunction(method_address, +// reinterpret_cast(setDisplayMode), true)); +// } +// else +// { +// SYSLOG("ngfx", "failed to resolve __ZN17IONDRVFramebuffer14setDisplayModeEii"); +// +// } + + // __ZN17IONDRVFramebuffer20processConnectChangeEPm: // IONDRVFramebuffer::processConnectChange(unsigned long*) + //using t_processConnectChange= IOReturn (*)(IONDRVFramebuffer *that, uintptr_t * value ); + +// method_address = patcher.solveSymbol(index, "__ZN17IONDRVFramebuffer20processConnectChangeEPm"); +// if (method_address) { +// DBGLOG("ngfx", "obtained __ZN17IONDRVFramebuffer20processConnectChangeEPm"); +// patcher.clearError(); +// org_processConnectChange = reinterpret_cast(patcher.routeFunction(method_address, +// reinterpret_cast(processConnectChange), true)); +// } +// else +// { +// SYSLOG("ngfx", "failed to resolve __ZN17IONDRVFramebuffer20processConnectChangeEPm"); +// +// } +// + + + //IOReturn IONDRVFramebuffer::validateDisplayMode( IODisplayModeID _mode, IOOptionBits flags, VDDetailedTimingRec ** detailed ) + // __ZN17IONDRVFramebuffer19validateDisplayModeEijPP19VDDetailedTimingRec: // IONDRVFramebuffer::validateDisplayMode(int, unsigned int, VDDetailedTimingRec**) +// using t_validateDisplayMode = IOReturn (*)(IONDRVFramebuffer *that, IODisplayModeID _mode, IOOptionBits flags, VDDetailedTimingRec ** detailed ); +// t_validateDisplayMode org_validateDisplayMode; + +// method_address = patcher.solveSymbol(index, "__ZN17IONDRVFramebuffer19validateDisplayModeEijPP19VDDetailedTimingRec"); +// if (method_address) { +// DBGLOG("ngfx", "obtained __ZN17IONDRVFramebuffer19validateDisplayModeEijPP19VDDetailedTimingRec"); +// patcher.clearError(); +// org_validateDisplayMode = reinterpret_cast(patcher.routeFunction(method_address, +// reinterpret_cast(validateDisplayMode), true)); +// } +// else +// { +// SYSLOG("ngfx", "failed to resolve __ZN17IONDRVFramebuffer19validateDisplayModeEijPP19VDDetailedTimingRec"); +// +// } +// + // __ZN17IONDRVFramebuffer20getResInfoForArbModeEiP24IODisplayModeInformation: // IONDRVFramebuffer::getResInfoForArbMode(int, IODisplayModeInformation*) +// using t_getResInfoForArbMode = IOReturn (*)(IONDRVFramebuffer *that, IODisplayModeID mode, IODisplayModeInformation* info); +// t_getResInfoForArbMode org_getResInfoForArbMode{nullptr}; + +// method_address = patcher.solveSymbol(index, "__ZN17IONDRVFramebuffer20getResInfoForArbModeEiP24IODisplayModeInformation"); +// if (method_address) { +// DBGLOG("ngfx", "obtained __ZN17IONDRVFramebuffer20getResInfoForArbModeEiP24IODisplayModeInformation"); +// patcher.clearError(); +// org_getResInfoForArbMode = reinterpret_cast(patcher.routeFunction(method_address, +// reinterpret_cast(getResInfoForArbMode), true)); +// } +// else +// { +// SYSLOG("ngfx", "failed to resolve __ZN17IONDRVFramebuffer20getResInfoForArbModeEiP24IODisplayModeInformation"); +// +// } +// //__ZN17IONDRVFramebuffer17getResInfoForModeEiP24IODisplayModeInformation: // IONDRVFramebuffer::getResInfoForMode(int, IODisplayModeInformation*) +// +// // IOReturn IONDRVFramebuffer::getResInfoForMode( IODisplayModeID modeID, +// // IODisplayModeInformation * info ) +//// using t_getResInfoForMode = IOReturn (*)(IONDRVFramebuffer *that, IODisplayModeID mode, IODisplayModeInformation * info ); +//// t_getResInfoForMode org_getResInfoForMode{nullptr}; +// +// method_address = patcher.solveSymbol(index, "__ZN17IONDRVFramebuffer17getResInfoForModeEiP24IODisplayModeInformation"); +// if (method_address) { +// DBGLOG("ngfx", "obtained __ZN17IONDRVFramebuffer17getResInfoForModeEiP24IODisplayModeInformation"); +// patcher.clearError(); +// org_getResInfoForMode = reinterpret_cast(patcher.routeFunction(method_address, +// reinterpret_cast(getResInfoForMode), true)); +// } +// else +// { +// SYSLOG("ngfx", "failed to resolve __ZN17IONDRVFramebuffer17getResInfoForModeEiP24IODisplayModeInformation"); +// +// } +// +// +// //__ZN17IONDRVFramebuffer19getPixelInformationEiiiP18IOPixelInformation: // IONDRVFramebuffer::getPixelInformation(int, int, int, IOPixelInformation*) +//// using t_getPixelInformation = IOReturn (*)( IONDRVFramebuffer *that, IODisplayModeID displayMode, IOIndex depth, +//// IOPixelAperture aperture, IOPixelInformation * pixelInfo); +//// t_getPixelInformation org_getPixelInformation{nullptr}; +// +// method_address = patcher.solveSymbol(index, "__ZN17IONDRVFramebuffer19getPixelInformationEiiiP18IOPixelInformation"); +// if (method_address) { +// DBGLOG("ngfx", "obtained __ZN17IONDRVFramebuffer19getPixelInformationEiiiP18IOPixelInformation"); +// patcher.clearError(); +// org_getPixelInformation = reinterpret_cast(patcher.routeFunction(method_address, +// reinterpret_cast(getPixelInformation), true)); +// } +// else +// { +// SYSLOG("ngfx", "failed to resolve __ZN17IONDRVFramebuffer19getPixelInformationEiiiP18IOPixelInformation"); +// +// } + + progressState |= ProcessingState::NVDASupportRouted; + + } + } + } + } + + // Ignore all the errors for other processors + patcher.clearError(); +} + +void NGFX::nvAccelerator_SetAccelProperties(IOService* that) +{ + DBGLOG("ngfx", "SetAccelProperties is called"); + + if (callbackNGFX && callbackNGFX->orgSetAccelProperties) + { + callbackNGFX->orgSetAccelProperties(that); + + if (!that->getProperty("IOVARendererID")) + { + uint8_t rendererId[] {0x08, 0x00, 0x04, 0x01}; + that->setProperty("IOVARendererID", rendererId, sizeof(rendererId)); + DBGLOG("ngfx", "set IOVARendererID to 08 00 04 01"); + } + + if (!that->getProperty("IOVARendererSubID")) + { + uint8_t rendererSubId[] {0x03, 0x00, 0x00, 0x00}; + that->setProperty("IOVARendererSubID", rendererSubId, sizeof(rendererSubId)); + DBGLOG("ngfx", "set IOVARendererSubID to value 03 00 00 00"); + } + } +} + + + + + +bool NGFX::AppleGraphicsDevicePolicy_start(IOService *that, IOService *provider) +{ + bool result = false; + + DBGLOG("ngfx", "AppleGraphicsDevicePolicy::start is calledv %s", that->getName()); + if (callbackNGFX && callbackNGFX->orgAgdpStart) + { + char board_id[32]; + if (WIOKit::getComputerInfo(nullptr, 0, board_id, sizeof(board_id))) + { + DBGLOG("ngfx", "got board-id '%s'", board_id); + auto dict = that->getPropertyTable(); + auto newProps = OSDynamicCast(OSDictionary, dict->copyCollection()); + OSDictionary *configMap = OSDynamicCast(OSDictionary, newProps->getObject("ConfigMap")); + if (configMap != nullptr) + { + OSString *value = OSDynamicCast(OSString, configMap->getObject(board_id)); + if (value != nullptr) + DBGLOG("ngfx", "Current value for board-id '%s' is %s", board_id, value->getCStringNoCopy()); + if (!configMap->setObject(board_id, OSString::withCString("none"))) + SYSLOG("ngfx", "Configuration for board-id '%s' can't be set, setObject was failed.", board_id); + else + DBGLOG("ngfx", "Configuration for board-id '%s' has been set to none", board_id); + that->setPropertyTable(newProps); + } + else + { + SYSLOG("ngfx", "ConfigMap key was not found in personalities"); + OSSafeReleaseNULL(newProps); + } + } + + result = callbackNGFX->orgAgdpStart(that, provider); + DBGLOG("ngfx", "AppleGraphicsDevicePolicy::start returned %d", result); + } + + return result; +} + +int NGFX::csfg_get_platform_binary(void *fg) +{ + //DBGLOG("ngfx", "csfg_get_platform_binary is called"); // is called quite often + + if (callbackNGFX && callbackNGFX->org_csfg_get_platform_binary && callbackNGFX->csfg_get_teamid) + { + int result = callbackNGFX->org_csfg_get_platform_binary(fg); + if (!result) + { + // Special case NVIDIA drivers + const char *teamId = callbackNGFX->csfg_get_teamid(fg); + if (teamId != nullptr && strcmp(teamId, kNvidiaTeamId) == 0) + { + DBGLOG("ngfx", "platform binary override for %s", kNvidiaTeamId); + return 1; + } + } + + return result; + } + + // Default to error + return 0; +} + + +void NGFX::applyPatches(KernelPatcher &patcher, size_t index, const KextPatch *patches, size_t patchNum, const char* name) { + DBGLOG("ngfx", "applying patch '%s' for %zu kext", name, index); + for (size_t p = 0; p < patchNum; p++) { + auto &patch = patches[p]; + if (patch.patch.kext->loadIndex == index) { + if (patcher.compatibleKernel(patch.minKernel, patch.maxKernel)) { + DBGLOG("ngfx", "applying %zu patch for %zu kext", p, index); + patcher.applyLookupPatch(&patch.patch); + // Do not really care for the errors for now + patcher.clearError(); + } + } + } +} + + +void logTimingInfoV2(IOService * that, const char *szPrefix, IODetailedTimingInformationV2 & v2) +{ + DBGLOG("ngfx", "%s %s:%s timing: %u x %u @ %llu hz numLinks: %u signalLevels: %u signalConfig: %x", + szPrefix, + that->getName(), + that->getProvider()->getName(), + v2.horizontalActive, + v2.verticalActive, + v2.pixelClock, + v2.numLinks, + v2.signalLevels, + v2.signalConfig + ); +} + +bool isValidTimev2(IODetailedTimingInformationV2 &v2) + +{ + if ( + (v2.horizontalActive == 1920 && v2.verticalActive == 1080) + || + (v2.horizontalActive == 3840 && v2.verticalActive == 2160) + || + (v2.horizontalActive == 1080 && v2.verticalActive == 1920) + // || +// (v2.horizontalActive == 2160 && v2.verticalActive == 3840) + || + (v2.horizontalActive == 5120 && v2.verticalActive == 2880) +// || + // (v2.horizontalActive == 2560 && v2.verticalActive == 1440) + // || + // (v2.horizontalActive == 2560 && v2.verticalActive == 2880) + ) + { + return true; + } + + return false; +} +bool isValidTime(IOTimingInformation &timingInfo) +{ + if ( + isValidTimev2(timingInfo.detailedInfo.v2) + ) + { + return true; + } + + return false; +} + + + +IOReturn NGFX::nvda_validateDetailedTiming_patch(IONDRVFramebuffer *that, void* _desc, IOByteCount descripSize) +{ + if(callbackNGFX && callbackNGFX->org_nda_validateDetailedTiming) + { + + //kIOReturnSuccess + if (descripSize == sizeof(IOFBDisplayModeDescription)) + { + IOFBDisplayModeDescription * fbdesc = (IOFBDisplayModeDescription *) _desc; + + + + // IOFixed1616 xf = fbdesc->info.refreshRate; + // float hz = 0.0f; + // hz = *((float *)&xf); + // + DBGLOG("ngfx", "validateDetailedTiming %s:%s %u info %u x %u @ %u.%u hz, maxDepthIndex: %u",that->getName(), that->getProvider()->getName(), + fbdesc->timingInfo.appleTimingID, + fbdesc->info.nominalWidth, + fbdesc->info.nominalHeight, + (fbdesc->info.refreshRate>>16)&0xffff, + fbdesc->info.refreshRate&0xffff, + fbdesc->info.maxDepthIndex + + ); + // if (strcmp(that->getProvider()->getName(), "NVDA,Display-C")==0) + { + //4096 x 2304 + if(isValidTime(fbdesc->timingInfo) + ) + { +// fbdesc->timingInfo.detailedInfo.v2.signalConfig = 0; +// fbdesc->timingInfo.detailedInfo.v2.signalLevels = 0; +// fbdesc->timingInfo.detailedInfo.v2.numLinks = 1; + + logTimingInfoV2(that, "validateDetailedTiming isValidTiming", fbdesc->timingInfo.detailedInfo.v2); + } + else + { + logTimingInfoV2(that, "validateDetailedTiming notvalidTiming", fbdesc->timingInfo.detailedInfo.v2); + return kIOReturnUnsupported; + } + } + + + } + else if(sizeof(IODetailedTimingInformationV2)==descripSize) + { + IODetailedTimingInformationV2 *pifov2 =(IODetailedTimingInformationV2 *) _desc; + + if( + isValidTimev2(*pifov2) + ) + { + logTimingInfoV2(that, "validateDetailedTiming V2 isValidTiming", *pifov2); + } + else + { + logTimingInfoV2(that, "validateDetailedTiming V2 notvalidTiming", *pifov2); + return kIOReturnUnsupported; + } + + } + else + { + DBGLOG("ngfx", "validateDetailedTiming %s:%s called size %llu unknown ", that->getName(), that->getProvider()->getName(), descripSize); + + } + + + + IOReturn ret= callbackNGFX->org_nda_validateDetailedTiming(that,_desc, descripSize); + DBGLOG("ngfx", "validateDetailedTiming %s:%s org_nda_validateDetailedTiming return %x",that->getName(), that->getProvider()->getName(), ret); + return ret; + + + } + + DBGLOG("ngfx", "validateDetailedTimin not install "); + + return kIOReturnUnsupported; +} + + +IOReturn NGFX::setStartupDisplayMode (IONDRVFramebuffer *that, IODisplayModeID displayMode, IOIndex depth ) +{ + if (callbackNGFX && callbackNGFX->org_setStartupDisplayMode) + { + + DBGLOG("ngfx", "setStartupDisplayMode %s:%s displayMode %u depth %u called",that->getName(), that->getProvider()->getName(), displayMode, depth); + + IODisplayModeID curdisplayMode; + IOIndex curdepth; + that->getCurrentDisplayMode( &curdisplayMode, &curdepth); + + DBGLOG("ngfx", "setStartupDisplayMode %s:%s mode %u current mode %u",that->getName(), that->getProvider()->getName(),displayMode,curdisplayMode); + IOReturn ret =callbackNGFX->org_setStartupDisplayMode(that,displayMode,depth); + DBGLOG("ngfx", "org_setStartupDisplayMode %s:%s ret %x displayMode %u depth %u",that->getName(), that->getProvider()->getName(), ret, displayMode, depth); + // IOSleep(10000); + //return that->setDisplayMode(displayMode, depth); + return ret; + } +// + return kIOReturnSuccess; +} + + +IOReturn NGFX::NVDA_setAttributeForConnection(IONDRVFramebuffer *that , IOIndex connectIndex, + IOSelect attribute, uintptr_t value ) +{ + if (callbackNGFX && callbackNGFX->org_NVDA_setAttributeForConnection) + { +// DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:%s begin ",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,(const char *)&attribute); + + switch(attribute) + { + + + case kConnectionFlags: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionFlags",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionSyncEnable: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionSyncEnable",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionSyncFlags: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionSyncFlags",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionSupportsAppleSense: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionSupportsAppleSense",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionSupportsLLDDCSense: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionSupportsLLDDCSense",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionSupportsHLDDCSense: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionSupportsHLDDCSense",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionEnable: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionEnable",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionCheckEnable: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionCheckEnable",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionProbe: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionProbe",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionChanged: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionChanged",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionPower: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionPower",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionPostWake: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionPostWake",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionDisplayParameterCount: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionDisplayParameterCount",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionDisplayParameters: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionDisplayParameters",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionOverscan: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionOverscan",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionVideoBest: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionVideoBest",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionRedGammaScale: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionRedGammaScale",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionGreenGammaScale: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionGreenGammaScale",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionBlueGammaScale: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionBlueGammaScale",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionGammaScale: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionGammaScale",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionFlushParameters: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionFlushParameters",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionVBLMultiplier: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionVBLMultiplier",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionHandleDisplayPortEvent: + { + uintptr_t evt= value!=0?(*((uintptr_t *)value)):0; + const char *eventname=(value==0)?"notset":"unknown"; + switch (evt) { + case kIODPEventStart: + eventname ="kIODPEventStart"; + break; + case kIODPEventIdle: + eventname ="kIODPEventIdle"; + break; + case kIODPEventForceRetrain: + eventname ="kIODPEventForceRetrain"; + break; + + case kIODPEventRemoteControlCommandPending: + eventname ="kIODPEventRemoteControlCommandPending"; + break; + case kIODPEventAutomatedTestRequest: + eventname ="kIODPEventAutomatedTestRequest"; + break; + case kIODPEventContentProtection: + eventname ="kIODPEventContentProtection"; + + break; + case kIODPEventMCCS: + eventname ="kIODPEventMCCS"; + break; + case kIODPEventSinkSpecific: + eventname ="kIODPEventSinkSpecific"; + break; + default: + break; + } + DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionHandleDisplayPortEvent value:%s",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex, eventname); + + if(kIODPEventIdle==evt) + { + return kIOReturnSuccess; + } +// if(that->getProvider()!=NULL&&strcmp("NVDA,Display-B",that->getProvider()->getName())==0) +// { +// return kIOReturnSuccess; +// } + } + break; + case kConnectionPanelTimingDisable: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionPanelTimingDisable",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionColorMode: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionColorMode",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionColorModesSupported: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionColorModesSupported",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionColorDepthsSupported: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionColorDepthsSupported",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionControllerDepthsSupported: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionControllerDepthsSupported",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionControllerColorDepth: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionControllerColorDepth",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionControllerDitherControl: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionControllerDitherControl",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionDisplayFlags: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionDisplayFlags",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionEnableAudio: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionEnableAudio",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + case kConnectionAudioStreaming: DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s index:%u attribute:kConnectionAudioStreaming",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex);break; + + } + + IOReturn ret = callbackNGFX->org_NVDA_setAttributeForConnection(that, connectIndex,attribute,value); + DBGLOG("ngfx", "NVDA_setAttributeForConnection %s:%s ret %x ",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",ret); + return ret; + } + return kIOReturnSuccess; +} +IOReturn NGFX::NVDA_getAttributeForConnection(IONDRVFramebuffer *that,IOIndex connectIndex, + IOSelect attribute, uintptr_t * value) +{ + if (callbackNGFX && callbackNGFX->org_NVDA_getAttributeForConnection) + { + DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s attribute:%s begin ",that->getName(), + that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",(const char*)&attribute); + + + IOReturn ret = callbackNGFX->org_NVDA_getAttributeForConnection(that,connectIndex,attribute,value); + + switch ( attribute) + { + case kConnectionFlags: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionFlags value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionSyncEnable: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionSyncEnable value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionSyncFlags: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionSyncFlags value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionSupportsAppleSense: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionSupportsAppleSense value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionSupportsLLDDCSense: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionSupportsLLDDCSense value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionSupportsHLDDCSense: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionSupportsHLDDCSense value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionEnable: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionEnable value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionCheckEnable: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionCheckEnable value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionProbe: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionProbe value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionChanged: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionChanged value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionPower: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionPower value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionPostWake: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionPostWake value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionDisplayParameterCount: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionDisplayParameterCount value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionDisplayParameters: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionDisplayParameters value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionOverscan: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionOverscan value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionVideoBest: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionVideoBest value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionRedGammaScale: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionRedGammaScale value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionGreenGammaScale: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionGreenGammaScale value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionBlueGammaScale: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionBlueGammaScale value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionGammaScale: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionGammaScale value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionFlushParameters: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionFlushParameters value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionVBLMultiplier: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionVBLMultiplier value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionHandleDisplayPortEvent: + + DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionHandleDisplayPortEvent value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret); + break; + case kConnectionPanelTimingDisable: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionPanelTimingDisable value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionColorMode: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionColorMode value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionColorModesSupported: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionColorModesSupported value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionColorDepthsSupported: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionColorDepthsSupported value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionControllerDepthsSupported: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionControllerDepthsSupported value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionControllerColorDepth: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionControllerColorDepth value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionControllerDitherControl: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionControllerDitherControl value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionDisplayFlags: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionDisplayFlags value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionEnableAudio: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionEnableAudio value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + case kConnectionAudioStreaming: DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s index:%u attribute:kConnectionAudioStreaming value:%lu ret:%x",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",connectIndex,value!=NULL?*value:0, ret);break; + default: + + DBGLOG("ngfx", "NVDA_getAttributeForConnection %s:%s ret %x index:%u attribute:%s value:%lu",that->getName(), that->getProvider()!=NULL?that->getProvider()->getName():"nopriver",ret, connectIndex,(const char*)&attribute,value!=NULL?*value:0); + break; + } + + return ret; + } + return kIOReturnSuccess; +} + + diff --git a/NvidiaGraphicsFixup/kern_ngfx.hpp b/NvidiaGraphicsFixup/kern_ngfx.hpp new file mode 100644 index 0000000..9bf8cb9 --- /dev/null +++ b/NvidiaGraphicsFixup/kern_ngfx.hpp @@ -0,0 +1,260 @@ +// +// kern_ngfx.hpp +// NvidiaGraphicsFixup +// +// Copyright © 2017 lvs1974. All rights reserved. +// + +#ifndef kern_ngfx_hpp +#define kern_ngfx_hpp + +#include +#include +#define IOFRAMEBUFFER_PRIVATE +#include +#include +#include +#include + +struct KextPatch { + KernelPatcher::LookupPatch patch; + uint32_t minKernel; + uint32_t maxKernel; +}; + +class NGFX { +public: + bool init(); + void deinit(); + +private: + /** + * Patch kernel + * + * @param patcher KernelPatcher instance + */ + void processKernel(KernelPatcher &patcher); + + /** + * Patch kext if needed and prepare other patches + * + * @param patcher KernelPatcher instance + * @param index kinfo handle + * @param address kinfo load address + * @param size kinfo memory size + */ + void processKext(KernelPatcher &patcher, size_t index, mach_vm_address_t address, size_t size); + + /** + * SetAccelProperties callback type + */ + using t_set_accel_properties = void (*) (IOService * that); + + /** + * AppleGraphicsDevicePolicy::start callback type + */ + using t_agdp_start = bool (*) (IOService *that, IOService *); + + /** + * csfg_get_platform_binary callback type + */ + using t_csfg_get_platform_binary = int (*) (void * fg); + + /** + * csfg_get_teamid callback type + */ + using t_csfg_get_teamid = const char* (*) (void *fg); + + + + + /** + * Hooked methods / callbacks + */ + static void nvAccelerator_SetAccelProperties(IOService* that); + + static bool AppleGraphicsDevicePolicy_start(IOService *that, IOService *provider); + + static int csfg_get_platform_binary(void *fg); + + + /** + * Trampolines for original method invocations + */ + t_set_accel_properties orgSetAccelProperties {nullptr}; + + t_agdp_start orgAgdpStart {nullptr}; + + t_csfg_get_platform_binary org_csfg_get_platform_binary {nullptr}; + + t_csfg_get_teamid csfg_get_teamid {nullptr}; + + + + // static IOReturn extSetStartupDisplayModePatch(OSObject * target, void * reference, IOExternalMethodArguments * args); + // static IOReturn nvda_setDetailedTiming_patch(IONDRVFramebuffer *that,IODisplayModeID mode, IOOptionBits options, void * _desc, IOByteCount descripSize); + // + // t_extSetStartupDisplayMode orgExtSetStartupDisplayMode{nullptr}; + +// t_getStartupDisplayMode org_getStartupDisplayMode{nullptr}; +// t_doDriverIO org_doDriverIO{nullptr}; +// +// +// +// using t_enablecontroller = IOReturn (*)(IONDRVFramebuffer *that); +// using t_setDisplayMode = IOReturn (*)(IONDRVFramebuffer *that, IODisplayModeID displayMode, IOIndex depth ); +// using t_setDetailedTimings = IOReturn (*)(IONDRVFramebuffer *that, OSArray *timings); +// +// t_enablecontroller org_enablecontroller{nullptr}; +// t_setDisplayMode org_setDisplayMode{nullptr}; +// t_setDetailedTimings org_setDetailedTimings{nullptr}; +// +// static IOReturn nvenablecontroller(IONDRVFramebuffer *that); +// static IOReturn setDisplayMode(IONDRVFramebuffer *that, IODisplayModeID displayMode, IOIndex depth ); +// static IOReturn setDetailedTimings(IONDRVFramebuffer *that, OSArray *timings); +// +// // __ZN13IOFramebuffer16extSetPropertiesEP12OSDictionary: // IOFramebuffer::extSetProperties(OSDictionary*) +// using t_extSetProperties = IOReturn (*) (IOFramebuffer * that, OSDictionary * dict ); +// // __ZN13IOFramebuffer16matchFramebufferEv: // IOFramebuffer::matchFramebuffer() +// using t_matchFramebuffer = IOReturn (*) (IOFramebuffer * that); +// // __ZN17IONDRVFramebuffer20processConnectChangeEPm: // IONDRVFramebuffer::processConnectChange(unsigned long*) +// using t_processConnectChange= IOReturn (*)(IONDRVFramebuffer *that, uintptr_t * value ); +// +// t_extSetProperties org_extSetProperties{nullptr}; +// t_matchFramebuffer org_matchFramebuffer{nullptr}; +// t_processConnectChange org_processConnectChange{nullptr}; +// + + + + + + using t_nvda_validateDetailedTiming = IOReturn (*) (IONDRVFramebuffer *that, void * _desc, IOByteCount descripSize); + t_nvda_validateDetailedTiming org_nda_validateDetailedTiming{nullptr}; + static IOReturn nvda_validateDetailedTiming_patch(IONDRVFramebuffer *that, void*, unsigned long long); + + using t_setStartupDisplayMode = IOReturn (*)(IONDRVFramebuffer *that, IODisplayModeID displayMode, IOIndex depth ); + t_setStartupDisplayMode org_setStartupDisplayMode{nullptr}; + static IOReturn setStartupDisplayMode (IONDRVFramebuffer *that, IODisplayModeID displayMode, IOIndex depth ); + + //__ZN4NVDA25getAttributeForConnectionEijPm: + + using t_NVDA_getAttributeForConnection=IOReturn (*) (IONDRVFramebuffer *that, IOIndex connectIndex, IOSelect attribute, uintptr_t * value) ; + t_NVDA_getAttributeForConnection org_NVDA_getAttributeForConnection={nullptr}; + static IOReturn NVDA_getAttributeForConnection(IONDRVFramebuffer *that, IOIndex connectIndex, IOSelect attribute, uintptr_t * value) ; + + + // __ZN4NVDA25setAttributeForConnectionEijm: // NVDA::setAttributeForConnection(int, unsigned int, unsigned long) + using t_NVDA_setAttributeForConnection=IOReturn (*) (IONDRVFramebuffer *that, IOIndex connectIndex,IOSelect attribute, uintptr_t value) ; + t_NVDA_setAttributeForConnection org_NVDA_setAttributeForConnection={nullptr}; + static IOReturn NVDA_setAttributeForConnection(IONDRVFramebuffer *that, IOIndex connectIndex,IOSelect attribute, uintptr_t value) ; + + +// using t_extSetStartupDisplayMode = IOReturn (*) (OSObject * target, void * reference, IOExternalMethodArguments * args); +// + + //IOReturn IONDRVFramebuffer::setDetailedTiming(IODisplayModeID mode, IOOptionBits options, void * _desc, IOByteCount descripSize ) + +// using t_setDetailedTiming = IOReturn (*)(IONDRVFramebuffer *that,IODisplayModeID mode, IOOptionBits options, void * _desc, IOByteCount descripSize); +// +// using t_getStartupDisplayMode = IOReturn (*)(IONDRVFramebuffer *that, IODisplayModeID * displayMode, IOIndex * depth ); +// using t_doDriverIO = IOReturn (*)(IONDRVFramebuffer *that, UInt32 commandID, void * contents, UInt32 commandCode, UInt32 commandKind ); +// +// + + + + +// static IOReturn getStartupDisplayMode(IONDRVFramebuffer *that, IODisplayModeID * displayMode, IOIndex * depth ); + +// static IOReturn doDriverIO(IONDRVFramebuffer *that, UInt32 commandID, void * contents, UInt32 commandCode, UInt32 commandKind ); +// + + + + +// static IOReturn extSetProperties(IOFramebuffer * that, OSDictionary * dict ); +// static IOReturn matchFramebuffer(IOFramebuffer * that); + // static IOReturn processConnectChange(IONDRVFramebuffer *that, uintptr_t * value); + +// //IOReturn IONDRVFramebuffer::validateDisplayMode( IODisplayModeID _mode, IOOptionBits flags, VDDetailedTimingRec ** detailed ) +// // __ZN17IONDRVFramebuffer19validateDisplayModeEijPP19VDDetailedTimingRec: // IONDRVFramebuffer::validateDisplayMode(int, unsigned int, VDDetailedTimingRec**) +// using t_validateDisplayMode = IOReturn (*)(IONDRVFramebuffer *that, IODisplayModeID _mode, IOOptionBits flags, VDDetailedTimingRec ** detailed ); +// t_validateDisplayMode org_validateDisplayMode; +// +// // __ZN17IONDRVFramebuffer20getResInfoForArbModeEiP24IODisplayModeInformation: // IONDRVFramebuffer::getResInfoForArbMode(int, IODisplayModeInformation*) +// using t_getResInfoForArbMode = IOReturn (*)(IONDRVFramebuffer *that, IODisplayModeID mode, IODisplayModeInformation* info); +// t_getResInfoForArbMode org_getResInfoForArbMode{nullptr}; +// +// +//// IOReturn IONDRVFramebuffer::getResInfoForMode( IODisplayModeID modeID, +//// IODisplayModeInformation * info ) +// using t_getResInfoForMode = IOReturn (*)(IONDRVFramebuffer *that, IODisplayModeID mode, IODisplayModeInformation * info ); +// t_getResInfoForMode org_getResInfoForMode{nullptr}; +// +// +// //__ZN4NVDA28getInformationForDisplayModeEiP24IODisplayModeInformation: // NVDA::getInformationForDisplayMode(int, IODisplayModeInformation*) +// +// using t_getInformationForDisplayMode = IOReturn (*)(IONDRVFramebuffer *that, IODisplayModeID mode, IODisplayModeInformation * info ); +// t_getInformationForDisplayMode org_getInformationForDisplayMode{nullptr}; +// +// +// // IOReturn IOFramebuffer::extGetInformationForDisplayMode( +// // OSObject * target, void * reference, IOExternalMethodArguments * args) +// //__ZN13IOFramebuffer31extGetInformationForDisplayModeEP8OSObjectPvP25IOExternalMethodArguments: // IOFramebuffer::extGetInformationForDisplayMode(OSObject*, void*, IOExternalMethodArguments*) +// +// using t_extGetInformationForDisplayMode = IOReturn (*)( OSObject * target, void * reference, IOExternalMethodArguments * args ); +// t_extGetInformationForDisplayMode org_extGetInformationForDisplayMode{nullptr}; +// +// +// static IOReturn validateDisplayMode (IONDRVFramebuffer *that, IODisplayModeID _mode, IOOptionBits flags, VDDetailedTimingRec ** detailed ); +// static IOReturn getResInfoForArbMode (IONDRVFramebuffer *that, IODisplayModeID mode, IODisplayModeInformation* info ); +// static IOReturn getResInfoForMode (IONDRVFramebuffer *that, IODisplayModeID mode, IODisplayModeInformation * info ); +// static IOReturn getInformationForDisplayMode (IONDRVFramebuffer *that, IODisplayModeID mode, IODisplayModeInformation * info ); +// static IOReturn extGetInformationForDisplayMode (OSObject * target, void * reference, IOExternalMethodArguments * args); +// +// +// //__ZN17IONDRVFramebuffer19getPixelInformationEiiiP18IOPixelInformation: // IONDRVFramebuffer::getPixelInformation(int, int, int, IOPixelInformation*) +// using t_getPixelInformation = IOReturn (*)( IONDRVFramebuffer *that, IODisplayModeID displayMode, IOIndex depth, +// IOPixelAperture aperture, IOPixelInformation * pixelInfo); +// t_getPixelInformation org_getPixelInformation{nullptr}; +// static IOReturn getPixelInformation ( IONDRVFramebuffer *that, IODisplayModeID displayMode, IOIndex depth, +// IOPixelAperture aperture, IOPixelInformation * pixelInfo); +// +// // __ZN13IOFramebuffer7doSetupEb: // IOFramebuffer::doSetup(bool) +// using t_doSetup = IOReturn (*)( IONDRVFramebuffer *that, bool full); +// t_doSetup org_doSetup{nullptr}; +// static IOReturn doSetup ( IONDRVFramebuffer *that, bool full); + /** + * Apply kext patches for loaded kext index + * + * @param patcher KernelPatcher instance + * @param index kinfo index + * @param patches patch list + * @param patchesNum patch number + */ + void applyPatches(KernelPatcher &patcher, size_t index, const KextPatch *patches, size_t patchesNum, const char *name); + + /** + * Current progress mask + */ + struct ProcessingState { + enum { + NothingReady = 0, + GraphicsDevicePolicyPatched = 2, + GeForceRouted = 4, + GeForceWebRouted = 8, + KernelRouted = 16, + NVDAResmanRouted = 32, + NVDAIOGraphicsRouted = 64, + NVDASupportRouted = 128, + + EverythingDone = GraphicsDevicePolicyPatched | GeForceRouted | GeForceWebRouted | KernelRouted | NVDAResmanRouted, + }; + }; + int progressState {ProcessingState::NothingReady}; + + static constexpr const char* kNvidiaTeamId { "6KR3T733EC" }; +}; + +#endif /* kern_ngfx */ diff --git a/NvidiaGraphicsFixup/kern_start.cpp b/NvidiaGraphicsFixup/kern_start.cpp new file mode 100644 index 0000000..3863bd6 --- /dev/null +++ b/NvidiaGraphicsFixup/kern_start.cpp @@ -0,0 +1,77 @@ +// +// kern_start.cpp +// NvidiaGraphicsFixup +// +// Copyright © 2017 lvs1974. All rights reserved. +// + +#include +#include + +#include "kern_config.hpp" +#include "kern_ngfx.hpp" + +static NGFX ngfx; + +const char *Configuration::bootargOff[] { + "-ngfxoff" +}; + +const char *Configuration::bootargDebug[] { + "-ngfxdbg" +}; + +const char *Configuration::bootargBeta[] { + "-ngfxbeta" +}; + +Configuration config; + +void Configuration::readArguments() { + char tmp[20]; + if (PE_parse_boot_argn(bootargNoAudioCon, tmp, sizeof(tmp))) + noaudioconnectors = true; + + if (PE_parse_boot_argn(bootargNoAudio, tmp, sizeof(tmp))) + noaudiofixes = true; + + if (PE_parse_boot_argn(bootargNoVARenderer, tmp, sizeof(tmp))) + novarenderer = true; + + if (PE_parse_boot_argn(bootargNoVARenderer, tmp, sizeof(tmp))) + novarenderer = true; + + if (PE_parse_boot_argn(bootargNoLibValFix, tmp, sizeof(tmp))) + nolibvalfix = true; + + if (PE_parse_boot_argn(bootargPatchList, patch_list, sizeof(patch_list))) + { + DBGLOG("ngfx", "boot-arg %s specified, value = %s", bootargPatchList, patch_list); + } + else + DBGLOG("ngfx", "use default value = %s for patch list", patch_list); +} + + +PluginConfiguration ADDPR(config) { + xStringify(PRODUCT_NAME), + parseModuleVersion(xStringify(MODULE_VERSION)), + LiluAPI::AllowNormal | LiluAPI::AllowInstallerRecovery, + config.bootargOff, + arrsize(config.bootargOff), + config.bootargDebug, + arrsize(config.bootargDebug), + config.bootargBeta, + arrsize(config.bootargBeta), + KernelVersion::MountainLion, + KernelVersion::HighSierra, + []() { + config.readArguments(); + ngfx.init(); + } +}; + + + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..e602a04 --- /dev/null +++ b/README.md @@ -0,0 +1,26 @@ +NvidiaGraphicsFixup +=================== + +An open source kernel extension providing patches for NVidia GPUs. + +#### Features +-Fixes LG Ultrafine 5K + gtx1080(TI) blackscreen problem-- by aerror 2017-12-17 + +- Fixes an issue in AppleGraphicsDevicePolicy.kext so that we could use a MacPro6,1 board-id/model combination, + without the usual hang with a black screen. + [Patching AppleGraphicsDevicePolicy.kext](https://pikeralpha.wordpress.com/2015/11/23/patching-applegraphicsdevicepolicy-kext) +- Modifies macOS to recognize NVIDIA's web drivers as platform binaries. This resolves the issue with transparent windows without content, + which appear for applications that use Metal and have Library Validation enabled. Common affected applications are iBooks and Little Snitch Network Monitor, + though this patch is universal and fixes them all. + [NVWebDriverLibValFix](https://github.com/mologie/NVWebDriverLibValFix) +- Injects IOVARendererID into GPU properties (required for Shiki-based solution for non-freezing Intel and/or any discrete GPU) +- Allows to use ports HDMI, DP, Digital DVI with audio (Injects @0connector-type - @5connector-type properties into GPU) + +#### Credits +- [Apple](https://www.apple.com) for macOS +- [vit9696](https://github.com/vit9696) for [Lilu.kext](https://github.com/vit9696/Lilu) & for zero-length string comparison patch (AppleGraphicsDevicePolicy.kext ) +- [Pike R. Alpha](https://github.com/Piker-Alpha) for board-id patch (AppleGraphicsDevicePolicy.kext) +- [FredWst](http://www.insanelymac.com/forum/user/509660-fredwst/) +- [igork](https://applelife.ru/members/igork.564) for adding properties IOVARendererID & IOVARendererSubID in nvAcceleratorParent::SetAccelProperties +- [mologie](https://github.com/mologie/NVWebDriverLibValFix) for creating NVWebDriverLibValFix.kext which forces macOS to recognize NVIDIA's web drivers as platform binaries +- [lvs1974](https://applelife.ru/members/lvs1974.53809) for writing the software and maintaining it