Skip to content

Commit

Permalink
Implemented unfairgva device property for MP5,1
Browse files Browse the repository at this point in the history
  • Loading branch information
vit9696 committed Jan 6, 2021
1 parent efd9895 commit e5543d8
Show file tree
Hide file tree
Showing 9 changed files with 257 additions and 42 deletions.
3 changes: 3 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
WhateverGreen Changelog
=======================
#### v1.4.7
- Implemented `unfairgva` device property (use `<01 00 00 00>` value for MP5,1 to enable streaming DRM)

#### v1.4.6
- Backlight registers fix replaces the previous Coffee Lake backlight fix and is now available on Intel Ice Lake platforms.
- Boot argument `igfxcflbklt=1` as well as device property `enable-cfl-backlight-fix` are deprecated and replaced by `-igfxblr` and `enable-backlight-registers-fix`.
Expand Down
1 change: 1 addition & 0 deletions Manual/FAQ.Chart.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Things to keep in mind:
- WhateverGreen Shiki functionality is not planned for inclusion for macOS 11
- AMD GPU video decoder preference can be chosen through preferences overrides for some types of DRM content (like Apple TV and iTunes movie streaming)
- Only IGPU-free Mac models allow for full DRM content access given a compatible AMD GPU video decoder
- For old CPUs (e.g. Xeons or Quad 2 Quad) and supported AMD GPUs injecting `unfairgva` with `<01 00 00 00>` value is required for streaming DRM

List of overrides:

Expand Down
10 changes: 9 additions & 1 deletion WhateverGreen.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
CE1970FF21C380DF00B02AB4 /* kern_nvhda.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE1970FD21C380DF00B02AB4 /* kern_nvhda.cpp */; };
CE19710021C380DF00B02AB4 /* kern_nvhda.hpp in Headers */ = {isa = PBXBuildFile; fileRef = CE1970FE21C380DF00B02AB4 /* kern_nvhda.hpp */; };
CE1F61B92432DEE800201DF4 /* kern_igfx_debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE1F61B82432DEE800201DF4 /* kern_igfx_debug.cpp */; };
CE3DADB025A425FC009991FB /* kern_unfair.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE3DADAE25A425FC009991FB /* kern_unfair.cpp */; };
CE3DADB125A425FC009991FB /* kern_unfair.hpp in Headers */ = {isa = PBXBuildFile; fileRef = CE3DADAF25A425FC009991FB /* kern_unfair.hpp */; };
CE405ED91E4A080700AA0B3D /* plugin_start.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE405ED81E4A080700AA0B3D /* plugin_start.cpp */; };
CE766ED6210763B200A84567 /* kern_guc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CE766ED4210763B200A84567 /* kern_guc.cpp */; };
CE766ED7210763B200A84567 /* kern_guc.hpp in Headers */ = {isa = PBXBuildFile; fileRef = CE766ED5210763B200A84567 /* kern_guc.hpp */; };
Expand Down Expand Up @@ -92,6 +94,8 @@
CE1F61B82432DEE800201DF4 /* kern_igfx_debug.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = kern_igfx_debug.cpp; sourceTree = "<group>"; };
CE271B4C1F319BD000D2BC1C /* reference.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = reference.cpp; sourceTree = "<group>"; };
CE363A7D20FE4EEC00ED7DC0 /* IntelFramebuffer.bt */ = {isa = PBXFileReference; lastKnownFileType = text; name = IntelFramebuffer.bt; path = Manual/IntelFramebuffer.bt; sourceTree = "<group>"; };
CE3DADAE25A425FC009991FB /* kern_unfair.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = kern_unfair.cpp; sourceTree = "<group>"; };
CE3DADAF25A425FC009991FB /* kern_unfair.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_unfair.hpp; sourceTree = "<group>"; };
CE405EBA1E49DD7100AA0B3D /* kern_compression.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_compression.hpp; sourceTree = "<group>"; };
CE405EBB1E49DD7100AA0B3D /* kern_disasm.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_disasm.hpp; sourceTree = "<group>"; };
CE405EBC1E49DD7100AA0B3D /* kern_file.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = kern_file.hpp; sourceTree = "<group>"; };
Expand Down Expand Up @@ -219,6 +223,8 @@
CEA03B5D20EE825A00BA842F /* kern_weg.hpp */,
CE7FC0B220F6809600138088 /* kern_shiki.cpp */,
CE7FC0B320F6809600138088 /* kern_shiki.hpp */,
CE3DADAE25A425FC009991FB /* kern_unfair.cpp */,
CE3DADAF25A425FC009991FB /* kern_unfair.hpp */,
CE8190A11F1E3ECE00DE95F4 /* kern_model.cpp */,
CE7FC0C920F682A200138088 /* kern_resources.cpp */,
CE7FC0C820F682A200138088 /* kern_resources.hpp */,
Expand Down Expand Up @@ -331,6 +337,7 @@
CEA03B5F20EE825A00BA842F /* kern_weg.hpp in Headers */,
E2BE6CE220FB209400ED2D55 /* kern_fb.hpp in Headers */,
CE7FC0AB20F55E7400138088 /* kern_ngfx.hpp in Headers */,
CE3DADB125A425FC009991FB /* kern_unfair.hpp in Headers */,
CE7FC0CA20F682A300138088 /* kern_resources.hpp in Headers */,
CE7FC0AF20F5622700138088 /* kern_igfx.hpp in Headers */,
CEC0863624331E9B00F5B701 /* kern_agdc.hpp in Headers */,
Expand Down Expand Up @@ -391,7 +398,7 @@
1C748C1E1C21952C0024EED2 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1220;
LastUpgradeCheck = 1230;
ORGANIZATIONNAME = vit9696;
TargetAttributes = {
1C748C261C21952C0024EED2 = {
Expand Down Expand Up @@ -472,6 +479,7 @@
CEA03B5E20EE825A00BA842F /* kern_weg.cpp in Sources */,
CE8190A21F1E3ECE00DE95F4 /* kern_model.cpp in Sources */,
CE1970FF21C380DF00B02AB4 /* kern_nvhda.cpp in Sources */,
CE3DADB025A425FC009991FB /* kern_unfair.cpp in Sources */,
D5C32F5624FC45D30078A824 /* kern_igfx_memory.cpp in Sources */,
CE405ED91E4A080700AA0B3D /* plugin_start.cpp in Sources */,
CE7FC0CB20F682A300138088 /* kern_resources.cpp in Sources */,
Expand Down
32 changes: 3 additions & 29 deletions WhateverGreen/kern_shiki.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <Headers/kern_iokit.hpp>
#include <IOKit/IODeviceTreeSupport.h>

#include "kern_weg.hpp"
#include "kern_resources.hpp"

void SHIKI::init() {
Expand All @@ -39,33 +40,6 @@ void SHIKI::deinit() {

}

bool SHIKI::getBootArgument(DeviceInfo *info, const char *name, void *bootarg, int size) {
if (PE_parse_boot_argn(name, bootarg, size))
return true;

for (size_t i = 0; i < info->videoExternal.size(); i++) {
auto prop = OSDynamicCast(OSData, info->videoExternal[i].video->getProperty(name));
auto propSize = prop ? prop->getLength() : 0;
if (propSize > 0 && propSize <= size) {
lilu_os_memcpy(bootarg, prop->getBytesNoCopy(), propSize);
memset(static_cast<uint8_t *>(bootarg) + propSize, 0, size - propSize);
return true;
}
}

if (info->videoBuiltin) {
auto prop = OSDynamicCast(OSData, info->videoBuiltin->getProperty(name));
auto propSize = prop ? prop->getLength() : 0;
if (propSize > 0 && propSize <= size) {
lilu_os_memcpy(bootarg, prop->getBytesNoCopy(), propSize);
memset(static_cast<uint8_t *>(bootarg) + propSize, 0, size - propSize);
return true;
}
}

return false;
}

UserPatcher::BinaryModPatch *SHIKI::getPatchSection(uint32_t section) {
for (size_t i = 0; i < ADDPR(binaryModSize); i++) {
auto patches = ADDPR(binaryMod)[i].patches;
Expand Down Expand Up @@ -97,7 +71,7 @@ void SHIKI::processKernel(KernelPatcher &patcher, DeviceInfo *info) {
lilu_os_strlcpy(reinterpret_cast<char *>(selfBoardId), bdi.boardIdentifier, sizeof(selfBoardId));

int bootarg {0};
if (getBootArgument(info, "shikigva", &bootarg, sizeof(bootarg))) {
if (WEG::getVideoArgument(info, "shikigva", &bootarg, sizeof(bootarg))) {
forceOnlineRenderer = bootarg & ForceOnlineRenderer;
allowNonBGRA = bootarg & AllowNonBGRA;
forceCompatibleRenderer = bootarg & ForceCompatibleRenderer;
Expand Down Expand Up @@ -187,7 +161,7 @@ void SHIKI::processKernel(KernelPatcher &patcher, DeviceInfo *info) {

// Custom board-id may be overridden by a boot-arg
if (replaceBoardID) {
if (getBootArgument(info, "shiki-id", customBoardID, sizeof(customBoardID)))
if (WEG::getVideoArgument(info, "shiki-id", customBoardID, sizeof(customBoardID)))
customBoardID[sizeof(customBoardID)-1] = '\0';
else
snprintf(customBoardID, sizeof(customBoardID), "Mac-27ADBB7B4CEE8E61"); // iMac14,2
Expand Down
5 changes: 0 additions & 5 deletions WhateverGreen/kern_shiki.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,6 @@ class SHIKI {
*/
bool setCompatibleRendererPatch();

/**
* Get overridable boot argument from kernel args (priority) and GPU properties
*/
bool getBootArgument(DeviceInfo *info, const char *name, void *bootarg, int size);

/**
* Get patch by section
*/
Expand Down
110 changes: 110 additions & 0 deletions WhateverGreen/kern_unfair.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
//
// kern_unfair.cpp
// WhateverGreen
//
// Copyright © 2021 vit9696. All rights reserved.
//

#include "kern_unfair.hpp"
#include "kern_weg.hpp"

#include <IOKit/IOService.h>
#include <Headers/plugin_start.hpp>
#include <Headers/kern_api.hpp>
#include <Headers/kern_cpu.hpp>
#include <Headers/kern_devinfo.hpp>
#include <Headers/kern_file.hpp>
#include <Headers/kern_iokit.hpp>
#include <Headers/kern_user.hpp>
#include <IOKit/IODeviceTreeSupport.h>

UNFAIR *UNFAIR::callbackUNFAIR;

void UNFAIR::init() {
callbackUNFAIR = this;

disableUnfair = !(lilu.getRunMode() & LiluAPI::RunningNormal);
disableUnfair |= checkKernelArgument("-unfairoff");

if (disableUnfair)
return;

sharedCachePath = UserPatcher::getSharedCachePath();
DBGLOG("unfair", "chosen shared cache path is %s", sharedCachePath);
}

void UNFAIR::deinit() {

}

void UNFAIR::csValidatePage(vnode *vp, memory_object_t pager, memory_object_offset_t page_offset, const void *data, int *validated_p, int *tainted_p, int *nx_p) {
FunctionCast(csValidatePage, callbackUNFAIR->orgCsValidatePage)(vp, pager, page_offset, data, validated_p, tainted_p, nx_p);

char path[PATH_MAX];
int pathlen = PATH_MAX;
if (vn_getpath(vp, path, &pathlen) == 0) {
//DBGLOG("unfair", "csValidatePage %s", path);

if ((callbackUNFAIR->unfairGva & UnfairDyldSharedCache) != 0 && UNLIKELY(strcmp(path, callbackUNFAIR->sharedCachePath) == 0)) {
if ((callbackUNFAIR->unfairGva & UnfairRelaxHdcpRequirements) != 0) {
static const uint8_t find[29] = {
0x4D, 0x61, 0x63, 0x50, 0x72, 0x6F, 0x35, 0x2C, 0x31, 0x00, 0x4D, 0x61, 0x63, 0x50, 0x72, 0x6F,
0x36, 0x2C, 0x31, 0x00, 0x49, 0x4F, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65
};
if (UNLIKELY(KernelPatcher::findAndReplace(const_cast<void *>(data), PAGE_SIZE, find, sizeof(find), BaseDeviceInfo::get().modelIdentifier, 20)))
DBGLOG("unfair", "patched relaxed drm model");
}

if ((callbackUNFAIR->unfairGva & UnfairCustomAppleGvaBoardId) != 0) {
static const uint8_t find[18] = {
0x62, 0x6F, 0x61, 0x72, 0x64, 0x2D, 0x69, 0x64, 0x00, 0x68, 0x77, 0x2E, 0x6D, 0x6F, 0x64, 0x65,
0x6C
};
static const uint8_t repl[5] = {
0x68, 0x77, 0x67, 0x76, 0x61
};
if (UNLIKELY(KernelPatcher::findAndReplace(const_cast<void *>(data), PAGE_SIZE, find, sizeof(find), repl, sizeof(repl))))
DBGLOG("unfair", "patched board-id -> hwgva-id");
}

} else if ((callbackUNFAIR->unfairGva & UnfairAllowHardwareDrmStreamDecoderOnOldCpuid) != 0 &&
(UNLIKELY(strcmp(path, "/System/Library/PrivateFrameworks/CoreLSKDMSE.framework/Versions/A/CoreLSKDMSE") == 0) ||
UNLIKELY(strcmp(path, "/System/Library/PrivateFrameworks/CoreLSKD.framework/Versions/A/CoreLSKD") == 0))) {
static const uint8_t find[] = {0xC7, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x0F, 0xA2};
static const uint8_t repl[] = {0xC7, 0xC0, 0xC3, 0x06, 0x03, 0x00, 0x90, 0x90};
if (UNLIKELY(KernelPatcher::findAndReplace(const_cast<void *>(data), PAGE_SIZE, find, sizeof(find), repl, sizeof(repl))))
DBGLOG("unfair", "patched streaming cpuid to haswell");
}
}
}

void UNFAIR::processKernel(KernelPatcher &patcher, DeviceInfo *info) {
if (disableUnfair)
return;

WEG::getVideoArgument(info, "unfairgva", &unfairGva, sizeof(unfairGva));
if (unfairGva == 0) {
DBGLOG("unfair", "disabling unfair gva due to missing boot argument");
disableUnfair = true;
return;
}

DBGLOG("unfair", "activating with %d bitmask", unfairGva);

if ((unfairGva & UnfairCustomAppleGvaBoardId) != 0) {
auto entry = IORegistryEntry::fromPath("/", gIODTPlane);
if (entry) {
DBGLOG("unfair", "setting hwgva-id to iMacPro1,1");
entry->setProperty("hwgva-id", const_cast<char *>("Mac-7BA5B2D9E42DDD94"), static_cast<uint32_t>(sizeof("Mac-7BA5B2D9E42DDD94")));
entry->release();
} else {
SYSLOG("shiki", "failed to obtain iodt tree");
unfairGva &= ~UnfairCustomAppleGvaBoardId;
}
}

KernelPatcher::RouteRequest csRoute("_cs_validate_page", csValidatePage, orgCsValidatePage);
if (!patcher.routeMultipleLong(KernelPatcher::KernelID, &csRoute, 1)) {
SYSLOG("unfair", "failed to route cs validation pages");
}
}
71 changes: 71 additions & 0 deletions WhateverGreen/kern_unfair.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//
// kern_unfair.hpp
// WhateverGreen
//
// Copyright © 2021 vit9696. All rights reserved.
//

#ifndef kern_unfair_hpp
#define kern_unfair_hpp

#include <Headers/kern_patcher.hpp>
#include <Headers/kern_devinfo.hpp>
#include <Headers/kern_cpu.hpp>
#include <Headers/kern_user.hpp>

class UNFAIR {
public:
void init();
void deinit();

/**
* Property patching routine
*
* @param patcher KernelPatcher instance
* @param info device info
*/
void processKernel(KernelPatcher &patcher, DeviceInfo *info);

private:
/**
* Private self instance for callbacks
*/
static UNFAIR *callbackUNFAIR;

/**
* Disable unfair, based on mode
*/
bool disableUnfair {false};

/**
* GVA bitmask as specified in unfairgva boot argument / property.
*/
enum : uint32_t {
UnfairAllowHardwareDrmStreamDecoderOnOldCpuid = 1,
UnfairRelaxHdcpRequirements = 2,
UnfairCustomAppleGvaBoardId = 4,
UnfairDyldSharedCache = UnfairRelaxHdcpRequirements | UnfairCustomAppleGvaBoardId,
};

/**
* Patch rule bitmask (0 means none).
*/
uint32_t unfairGva {0};

/**
* Codesign page validation wrapper used for userspace patching
*/
static void csValidatePage(vnode *vp, memory_object_t pager, memory_object_offset_t page_offset, const void *data, int *validated_p, int *tainted_p, int *nx_p);

/**
* Original codesign page validation pointer.
*/
mach_vm_address_t orgCsValidatePage {0};

/**
* Cyrrent shared cache.
*/
const char *sharedCachePath {nullptr};
};

#endif /* kern_unfair_hpp */
Loading

0 comments on commit e5543d8

Please sign in to comment.