mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
1620 lines
44 KiB
C
1620 lines
44 KiB
C
/** @file
|
|
Commonly used kext patches.
|
|
|
|
Copyright (c) 2018, vit9696. All rights reserved.<BR>
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
**/
|
|
|
|
#include <Base.h>
|
|
|
|
#include <IndustryStandard/AppleIntelCpuInfo.h>
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/OcDebugLogLib.h>
|
|
#include <Library/OcAppleKernelLib.h>
|
|
#include <Library/PrintLib.h>
|
|
#include <Library/OcFileLib.h>
|
|
#include <Library/UefiLib.h>
|
|
|
|
STATIC
|
|
UINT8
|
|
mAppleIntelCPUPowerManagementPatchFind[] = {
|
|
0xB9, 0xE2, 0x00, 0x00, 0x00, // mov ecx, 0xe2
|
|
0x0F, 0x30 // wrmsr
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mAppleIntelCPUPowerManagementPatchReplace[] = {
|
|
0xB9, 0xE2, 0x00, 0x00, 0x00, // mov ecx, 0xe2
|
|
0x90, 0x90 // nop nop
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mAppleIntelCPUPowerManagementPatch = {
|
|
.Comment = DEBUG_POINTER ("AppleCpuPmCfgLock v1"),
|
|
.Base = NULL,
|
|
.Find = mAppleIntelCPUPowerManagementPatchFind,
|
|
.Mask = NULL,
|
|
.Replace = mAppleIntelCPUPowerManagementPatchReplace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mAppleIntelCPUPowerManagementPatchFind),
|
|
.Count = 0,
|
|
.Skip = 0
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mAppleIntelCPUPowerManagementPatch2Find[] = {
|
|
0xB9, 0xE2, 0x00, 0x00, 0x00, // mov ecx, 0xe2
|
|
0x48, 0x89, 0xF0, // mov rax, <some register>
|
|
0x0F, 0x30 // wrmsr
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mAppleIntelCPUPowerManagementPatch2FindMask[] = {
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
0xFF, 0xFF, 0xF0,
|
|
0xFF, 0xFF
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mAppleIntelCPUPowerManagementPatch2Replace[] = {
|
|
0x00, 0x00, 0x00, 0x00, 0x00, // leave as is
|
|
0x00, 0x00, 0x00, // leave as is
|
|
0x90, 0x90 // nop nop
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mAppleIntelCPUPowerManagementPatch2ReplaceMask[] = {
|
|
0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00,
|
|
0xFF, 0xFF
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mAppleIntelCPUPowerManagementPatch2 = {
|
|
.Comment = DEBUG_POINTER ("AppleCpuPmCfgLock v2"),
|
|
.Base = NULL,
|
|
.Find = mAppleIntelCPUPowerManagementPatch2Find,
|
|
.Mask = mAppleIntelCPUPowerManagementPatch2FindMask,
|
|
.Replace = mAppleIntelCPUPowerManagementPatch2Replace,
|
|
.ReplaceMask = mAppleIntelCPUPowerManagementPatch2ReplaceMask,
|
|
.Size = sizeof (mAppleIntelCPUPowerManagementPatch2Find),
|
|
.Count = 0,
|
|
.Skip = 0
|
|
};
|
|
|
|
EFI_STATUS
|
|
PatchAppleCpuPmCfgLock (
|
|
IN OUT PRELINKED_CONTEXT *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_STATUS Status2;
|
|
PATCHER_CONTEXT Patcher;
|
|
|
|
Status = PatcherInitContextFromPrelinked (
|
|
&Patcher,
|
|
Context,
|
|
"com.apple.driver.AppleIntelCPUPowerManagement"
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = PatcherApplyGenericPatch (&Patcher, &mAppleIntelCPUPowerManagementPatch);
|
|
if (!EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Patch v1 success com.apple.driver.AppleIntelCPUPowerManagement\n"));
|
|
}
|
|
|
|
Status2 = PatcherApplyGenericPatch (&Patcher, &mAppleIntelCPUPowerManagementPatch2);
|
|
if (!EFI_ERROR (Status2)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Patch v2 success com.apple.driver.AppleIntelCPUPowerManagement\n"));
|
|
}
|
|
|
|
if (EFI_ERROR (Status) && EFI_ERROR (Status2)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patches com.apple.driver.AppleIntelCPUPowerManagement - %r/%r\n", Status, Status2));
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to find com.apple.driver.AppleIntelCPUPowerManagement - %r\n", Status));
|
|
}
|
|
|
|
//
|
|
// At least one patch must be successful for this to work (e.g. first for 10.14).
|
|
//
|
|
return !EFI_ERROR (Status) ? Status : Status2;
|
|
}
|
|
|
|
#pragma pack(push, 1)
|
|
|
|
//
|
|
// XCPM record definition, extracted from XNU debug kernel.
|
|
//
|
|
typedef struct XCPM_MSR_RECORD_ {
|
|
UINT32 xcpm_msr_num;
|
|
UINT32 xcpm_msr_applicable_cpus;
|
|
UINT32 *xcpm_msr_flag_p;
|
|
UINT64 xcpm_msr_bits_clear;
|
|
UINT64 xcpm_msr_bits_set;
|
|
UINT64 xcpm_msr_initial_value;
|
|
UINT64 xcpm_msr_rb_value;
|
|
} XCPM_MSR_RECORD;
|
|
|
|
#pragma pack(pop)
|
|
|
|
STATIC
|
|
UINT8
|
|
mXcpmCfgLockRelFind[] = {
|
|
0xB9, 0xE2, 0x00, 0x00, 0x00, 0x0F, 0x30 // mov ecx, 0xE2 ; wrmsr
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mXcpmCfgLockRelReplace[] = {
|
|
0xB9, 0xE2, 0x00, 0x00, 0x00, 0x90, 0x90 // mov ecx, 0xE2 ; nop
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mXcpmCfgLockRelPatch = {
|
|
.Comment = DEBUG_POINTER ("XcpmCfgLockRel"),
|
|
.Base = "_xcpm_idle",
|
|
.Find = mXcpmCfgLockRelFind,
|
|
.Mask = NULL,
|
|
.Replace = mXcpmCfgLockRelReplace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mXcpmCfgLockRelFind),
|
|
.Count = 2,
|
|
.Skip = 0,
|
|
.Limit = 4096
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mXcpmCfgLockDbgFind[] = {
|
|
0xBF, 0xE2, 0x00, 0x00, 0x00, 0xE8 // mov edi, 0xE2 ; call (wrmsr64)
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mXcpmCfgLockDbgReplace[] = {
|
|
0xEB, 0x08, 0x90, 0x90, 0x90, 0xE8 // jmp LBL ; nop; nop; nop; call (wrmsr64); LBL:
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mXcpmCfgLockDbgPatch = {
|
|
.Comment = DEBUG_POINTER ("XcpmCfgLockDbg"),
|
|
.Base = "_xcpm_cst_control_evaluate",
|
|
.Find = mXcpmCfgLockDbgFind,
|
|
.Mask = NULL,
|
|
.Replace = mXcpmCfgLockDbgReplace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mXcpmCfgLockDbgFind),
|
|
.Count = 2,
|
|
.Skip = 0,
|
|
.Limit = 4096
|
|
};
|
|
|
|
EFI_STATUS
|
|
PatchAppleXcpmCfgLock (
|
|
IN OUT PATCHER_CONTEXT *Patcher
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
XCPM_MSR_RECORD *Record;
|
|
XCPM_MSR_RECORD *Last;
|
|
|
|
UINT32 Replacements;
|
|
|
|
Last = (XCPM_MSR_RECORD *) ((UINT8 *) MachoGetMachHeader64 (&Patcher->MachContext)
|
|
+ MachoGetFileSize (&Patcher->MachContext) - sizeof (XCPM_MSR_RECORD));
|
|
|
|
Replacements = 0;
|
|
|
|
Status = PatcherGetSymbolAddress (Patcher, "_xcpm_core_scope_msrs", (UINT8 **) &Record);
|
|
if (!EFI_ERROR (Status)) {
|
|
while (Record < Last) {
|
|
if (Record->xcpm_msr_num == 0xE2) {
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"OCAK: Replacing _xcpm_core_scope_msrs data %u %u\n",
|
|
Record->xcpm_msr_num,
|
|
Record->xcpm_msr_applicable_cpus
|
|
));
|
|
Record->xcpm_msr_applicable_cpus = 0;
|
|
++Replacements;
|
|
} else {
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"OCAK: Not matching _xcpm_core_scope_msrs data %u %u\n",
|
|
Record->xcpm_msr_num,
|
|
Record->xcpm_msr_applicable_cpus
|
|
));
|
|
break;
|
|
}
|
|
++Record;
|
|
}
|
|
|
|
//
|
|
// Now the HWP patch at _xcpm_idle() for Release XNU.
|
|
//
|
|
Status = PatcherApplyGenericPatch (
|
|
Patcher,
|
|
&mXcpmCfgLockRelPatch
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to locate _xcpm_idle release patch - %r, trying dbg\n", Status));
|
|
Status = PatcherApplyGenericPatch (
|
|
Patcher,
|
|
&mXcpmCfgLockDbgPatch
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_WARN, "OCAK: Failed to locate _xcpm_idle patches - %r\n", Status));
|
|
}
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_WARN, "OCAK: Failed to locate _xcpm_core_scope_msrs - %r\n", Status));
|
|
}
|
|
|
|
return Replacements > 0 ? EFI_SUCCESS : EFI_NOT_FOUND;
|
|
}
|
|
|
|
STATIC
|
|
UINT8
|
|
mMiscPwrMgmtRelFind[] = {
|
|
0xB9, 0xAA, 0x01, 0x00, 0x00, 0x0F, 0x30 // mov ecx, 0x1aa; wrmsr
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mMiscPwrMgmtRelReplace[] = {
|
|
0xB9, 0xAA, 0x01, 0x00, 0x00, 0x90, 0x90 // mov ecx, 0x1aa; nop
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mMiscPwrMgmtRelPatch = {
|
|
.Comment = DEBUG_POINTER ("MiscPwrMgmtRel"),
|
|
.Base = NULL,
|
|
.Find = mMiscPwrMgmtRelFind,
|
|
.Mask = NULL,
|
|
.Replace = mMiscPwrMgmtRelReplace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mMiscPwrMgmtRelFind),
|
|
.Count = 0,
|
|
.Skip = 0,
|
|
.Limit = 0
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mMiscPwrMgmtDbgFind[] = {
|
|
0xBF, 0xAA, 0x01, 0x00, 0x00, 0xE8 // mov edi, 0x1AA ; call (wrmsr64)
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mMiscPwrMgmtDbgReplace[] = {
|
|
0xEB, 0x08, 0x90, 0x90, 0x90, 0xE8 // jmp LBL ; nop; nop; nop; call (wrmsr64); LBL:
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mMiscPwrMgmtDbgPatch = {
|
|
//
|
|
// NOTE: This substitution is going to take place
|
|
// at both _xcpm_hwp_enable()
|
|
// and _xcpm_enable_hw_coordination() (which is inlined in Release XNU).
|
|
//
|
|
.Comment = DEBUG_POINTER ("MiscPwrMgmtDbg"),
|
|
.Base = NULL,
|
|
.Find = mMiscPwrMgmtDbgFind,
|
|
.Mask = NULL,
|
|
.Replace = mMiscPwrMgmtDbgReplace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mMiscPwrMgmtDbgFind),
|
|
.Count = 0,
|
|
.Skip = 0,
|
|
.Limit = 0
|
|
};
|
|
|
|
EFI_STATUS
|
|
PatchAppleXcpmExtraMsrs (
|
|
IN OUT PATCHER_CONTEXT *Patcher
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
XCPM_MSR_RECORD *Record;
|
|
XCPM_MSR_RECORD *Last;
|
|
UINT32 Replacements;
|
|
|
|
Last = (XCPM_MSR_RECORD *) ((UINT8 *) MachoGetMachHeader64 (&Patcher->MachContext)
|
|
+ MachoGetFileSize (&Patcher->MachContext) - sizeof (XCPM_MSR_RECORD));
|
|
|
|
Replacements = 0;
|
|
|
|
Status = PatcherGetSymbolAddress (Patcher, "_xcpm_pkg_scope_msrs", (UINT8 **) &Record);
|
|
if (!EFI_ERROR (Status)) {
|
|
while (Record < Last) {
|
|
//
|
|
// Most Record->xcpm_msr_applicable_cpus has
|
|
// 0xDC or 0xDE in its lower 16-bit and thus here we
|
|
// AND 0xFF0000FDU in order to match both. (The result will be 0xDC)
|
|
//
|
|
if ((Record->xcpm_msr_applicable_cpus & 0xFF0000FDU) == 0xDC) {
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"OCAK: Replacing _xcpm_pkg_scope_msrs data %u %u\n",
|
|
Record->xcpm_msr_num,
|
|
Record->xcpm_msr_applicable_cpus
|
|
));
|
|
Record->xcpm_msr_applicable_cpus = 0;
|
|
++Replacements;
|
|
} else {
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"OCAK: Not matching _xcpm_pkg_scope_msrs data %u %u\n",
|
|
Record->xcpm_msr_num,
|
|
Record->xcpm_msr_applicable_cpus
|
|
));
|
|
break;
|
|
}
|
|
++Record;
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_WARN, "OCAK: Failed to locate _xcpm_pkg_scope_msrs - %r\n", Status));
|
|
}
|
|
|
|
Status = PatcherGetSymbolAddress (Patcher, "_xcpm_SMT_scope_msrs", (UINT8 **) &Record);
|
|
if (!EFI_ERROR (Status)) {
|
|
while (Record < Last) {
|
|
if (Record->xcpm_msr_flag_p == NULL) {
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"OCAK: Replacing _xcpm_SMT_scope_msrs data %u %u\n",
|
|
Record->xcpm_msr_num,
|
|
Record->xcpm_msr_applicable_cpus
|
|
));
|
|
Record->xcpm_msr_applicable_cpus = 0;
|
|
++Replacements;
|
|
} else {
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"OCAK: Not matching _xcpm_SMT_scope_msrs data %u %u %p\n",
|
|
Record->xcpm_msr_num,
|
|
Record->xcpm_msr_applicable_cpus,
|
|
Record->xcpm_msr_flag_p
|
|
));
|
|
break;
|
|
}
|
|
++Record;
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_WARN, "OCAK: Failed to locate _xcpm_SMT_scope_msrs - %r\n", Status));
|
|
}
|
|
|
|
//
|
|
// Now patch writes to MSR_MISC_PWR_MGMT
|
|
//
|
|
Status = PatcherApplyGenericPatch (Patcher, &mMiscPwrMgmtRelPatch);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to patch writes to MSR_MISC_PWR_MGMT - %r, trying dbg\n", Status));
|
|
Status = PatcherApplyGenericPatch (Patcher, &mMiscPwrMgmtDbgPatch);
|
|
}
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Patched writes to MSR_MISC_PWR_MGMT\n"));
|
|
++Replacements;
|
|
} else {
|
|
DEBUG ((DEBUG_WARN, "OCAK: Failed to patch writes to MSR_MISC_PWR_MGMT - %r\n", Status));
|
|
}
|
|
|
|
return Replacements > 0 ? EFI_SUCCESS : EFI_NOT_FOUND;
|
|
}
|
|
|
|
STATIC
|
|
UINT8
|
|
mPerfCtrlFind1[] = {
|
|
0xB9, 0x99, 0x01, 0x00, 0x00, ///< mov ecx, 199h
|
|
0x0F, 0x30 ///< wrmsr
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mPerfCtrlFind2[] = {
|
|
0xB9, 0x99, 0x01, 0x00, 0x00, ///< mov ecx, 199h
|
|
0x31, 0xD2, ///< xor edx, edx
|
|
0x0F, 0x30 ///< wrmsr
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mPerfCtrlMax[] = {
|
|
0xB9, 0x99, 0x01, 0x00, 0x00, ///< mov ecx, 199h
|
|
0x31, 0xD2, ///< xor edx, edx
|
|
0xB8, 0x00, 0xFF, 0x00, 0x00, ///< mov eax, 0xFF00
|
|
0x0F, 0x30, ///< wrmsr
|
|
0xC3 ///< ret
|
|
};
|
|
|
|
EFI_STATUS
|
|
PatchAppleXcpmForceBoost (
|
|
IN OUT PATCHER_CONTEXT *Patcher
|
|
)
|
|
{
|
|
UINT8 *Start;
|
|
UINT8 *Last;
|
|
UINT8 *Current;
|
|
|
|
Start = (UINT8 *) MachoGetMachHeader64 (&Patcher->MachContext);
|
|
Last = Start + MachoGetFileSize (&Patcher->MachContext) - EFI_PAGE_SIZE*2;
|
|
Start += EFI_PAGE_SIZE;
|
|
Current = Start;
|
|
|
|
while (Current < Last) {
|
|
if (Current[0] == mPerfCtrlFind1[0]
|
|
&& Current[1] == mPerfCtrlFind1[1]
|
|
&& Current[2] == mPerfCtrlFind1[2]
|
|
&& Current[3] == mPerfCtrlFind1[3]) {
|
|
if (CompareMem (&Current[4], &mPerfCtrlFind1[4], sizeof (mPerfCtrlFind1) - 4) == 0
|
|
|| CompareMem (&Current[4], &mPerfCtrlFind2[4], sizeof (mPerfCtrlFind2) - 4) == 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
++Current;
|
|
}
|
|
|
|
if (Current == Last) {
|
|
DEBUG ((DEBUG_WARN, "OCAK: Failed to locate MSR_IA32_PERF_CONTROL write\n"));
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
Start = Current - EFI_PAGE_SIZE;
|
|
Current -= 4;
|
|
|
|
while (Current >= Start) {
|
|
if (Current[0] == 0x55
|
|
&& Current[1] == 0x48
|
|
&& Current[2] == 0x89
|
|
&& Current[3] == 0xE5) {
|
|
break;
|
|
}
|
|
|
|
--Current;
|
|
}
|
|
|
|
if (Current < Start) {
|
|
DEBUG ((DEBUG_WARN, "OCAK: Failed to locate MSR_IA32_PERF_CONTROL prologue\n"));
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
DEBUG ((DEBUG_INFO, "OCAK: Patch write max to MSR_IA32_PERF_CONTROL\n"));
|
|
CopyMem (Current, mPerfCtrlMax, sizeof (mPerfCtrlMax));
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
STATIC
|
|
UINT8
|
|
mRemoveUsbLimitV1Find[] = {
|
|
0xff, 0xff, 0x10
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mRemoveUsbLimitV1Replace[] = {
|
|
0xff, 0xff, 0x40
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mRemoveUsbLimitV1Patch = {
|
|
.Comment = DEBUG_POINTER ("RemoveUsbLimitV1"),
|
|
.Base = "__ZN15AppleUSBXHCIPCI11createPortsEv",
|
|
.Find = mRemoveUsbLimitV1Find,
|
|
.Mask = NULL,
|
|
.Replace = mRemoveUsbLimitV1Replace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mRemoveUsbLimitV1Replace),
|
|
.Count = 1,
|
|
.Skip = 0,
|
|
.Limit = 4096
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mRemoveUsbLimitV2Find[] = {
|
|
0x0f, 0x0f, 0x83
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mRemoveUsbLimitV2Replace[] = {
|
|
0x40, 0x0f, 0x83
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mRemoveUsbLimitV2Patch = {
|
|
.Comment = DEBUG_POINTER ("RemoveUsbLimitV2"),
|
|
.Base = "__ZN12AppleUSBXHCI11createPortsEv",
|
|
.Find = mRemoveUsbLimitV2Find,
|
|
.Mask = NULL,
|
|
.Replace = mRemoveUsbLimitV2Replace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mRemoveUsbLimitV2Replace),
|
|
.Count = 1,
|
|
.Skip = 0,
|
|
.Limit = 4096
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mRemoveUsbLimitIoP1Find[] = {
|
|
0x0f, 0x0f, 0x87
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mRemoveUsbLimitIoP1Replace[] = {
|
|
0x40, 0x0f, 0x87
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mRemoveUsbLimitIoP1Patch = {
|
|
.Comment = DEBUG_POINTER ("RemoveUsbLimitIoP1"),
|
|
.Base = "__ZN16AppleUSBHostPort15setPortLocationEj",
|
|
.Find = mRemoveUsbLimitIoP1Find,
|
|
.Mask = NULL,
|
|
.Replace = mRemoveUsbLimitIoP1Replace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mRemoveUsbLimitIoP1Replace),
|
|
.Count = 1,
|
|
.Skip = 0,
|
|
.Limit = 4096
|
|
};
|
|
|
|
EFI_STATUS
|
|
PatchUsbXhciPortLimit (
|
|
IN OUT PRELINKED_CONTEXT *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
PATCHER_CONTEXT Patcher;
|
|
|
|
//
|
|
// On 10.14.4 and newer IOUSBHostFamily also needs limit removal.
|
|
// Thanks to ydeng discovering this.
|
|
//
|
|
Status = PatcherInitContextFromPrelinked (
|
|
&Patcher,
|
|
Context,
|
|
"com.apple.iokit.IOUSBHostFamily"
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = PatcherApplyGenericPatch (&Patcher, &mRemoveUsbLimitIoP1Patch);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply P1 patch com.apple.iokit.IOUSBHostFamily - %r\n", Status));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.iokit.IOUSBHostFamily\n"));
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to find com.apple.iokit.IOUSBHostFamily - %r\n", Status));
|
|
}
|
|
|
|
//
|
|
// TODO: Implement some locationID hack in IOUSBHFamily.
|
|
// The location ID is a 32 bit number which is unique among all USB devices in the system,
|
|
// and which will not change on a system reboot unless the topology of the bus itself changes.
|
|
// See AppleUSBHostPort::setPortLocation():
|
|
// locationId = getLocationId();
|
|
// if (!(locationId & 0xF)) {
|
|
// int32_t shift = 20;
|
|
// while (locationId & (0xF << shift)) {
|
|
// shift -= 4;
|
|
// if (Shift < 0) { setLocationId(locationId); return; }
|
|
// }
|
|
// setLocationId(locationId | ((portNumber & 0xF) << shift));
|
|
// }
|
|
// The value (e.g. 0x14320000) is represented as follows: 0xAABCDEFG
|
|
// AA — Ctrl number 8 bits (e.g. 0x14, aka XHCI)
|
|
// B - Port number 4 bits (e.g. 0x3, aka SS03)
|
|
// C~F - Bus number 4 bits (e.g. 0x2, aka IOUSBHostHIDDevice)
|
|
//
|
|
// C~F are filled as many times as many USB Hubs are there on the port.
|
|
//
|
|
|
|
Status = PatcherInitContextFromPrelinked (
|
|
&Patcher,
|
|
Context,
|
|
"com.apple.driver.usb.AppleUSBXHCI"
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = PatcherApplyGenericPatch (&Patcher, &mRemoveUsbLimitV2Patch);
|
|
if (!EFI_ERROR (Status)) {
|
|
//
|
|
// We do not need to patch com.apple.driver.usb.AppleUSBXHCI if this patch was successful.
|
|
// Only legacy systems require com.apple.driver.usb.AppleUSBXHCI to be patched.
|
|
//
|
|
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.driver.usb.AppleUSBXHCI\n"));
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.driver.usb.AppleUSBXHCI - %r\n", Status));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to find com.apple.driver.usb.AppleUSBXHCI - %r\n", Status));
|
|
}
|
|
|
|
//
|
|
// If we are here, we are on legacy 10.13 or below, try the oldest patch.
|
|
//
|
|
Status = PatcherInitContextFromPrelinked (
|
|
&Patcher,
|
|
Context,
|
|
"com.apple.driver.usb.AppleUSBXHCIPCI"
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = PatcherApplyGenericPatch (&Patcher, &mRemoveUsbLimitV1Patch);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.driver.usb.AppleUSBXHCIPCI - %r\n", Status));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.driver.usb.AppleUSBXHCIPCI\n"));
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to find com.apple.driver.usb.AppleUSBXHCIPCI - %r\n", Status));
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
STATIC
|
|
UINT8
|
|
mIOAHCIBlockStoragePatchV1Find[] = {
|
|
0x41, 0x50, 0x50, 0x4C, 0x45, 0x20, 0x53, 0x53, 0x44, 0x00
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mIOAHCIBlockStoragePatchV1Replace[] = {
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mIOAHCIBlockStoragePatchV1 = {
|
|
.Comment = DEBUG_POINTER ("IOAHCIBlockStorageV1"),
|
|
.Base = NULL,
|
|
.Find = mIOAHCIBlockStoragePatchV1Find,
|
|
.Mask = NULL,
|
|
.Replace = mIOAHCIBlockStoragePatchV1Replace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mIOAHCIBlockStoragePatchV1Find),
|
|
.Count = 1,
|
|
.Skip = 0
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mIOAHCIBlockStoragePatchV2Find[] = {
|
|
0x41, 0x50, 0x50, 0x4C, 0x45, 0x00
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mIOAHCIBlockStoragePatchV2Replace[] = {
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mIOAHCIBlockStoragePatchV2 = {
|
|
.Comment = DEBUG_POINTER ("IOAHCIBlockStorageV2"),
|
|
.Base = NULL,
|
|
.Find = mIOAHCIBlockStoragePatchV2Find,
|
|
.Mask = NULL,
|
|
.Replace = mIOAHCIBlockStoragePatchV2Replace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mIOAHCIBlockStoragePatchV2Find),
|
|
.Count = 1,
|
|
.Skip = 0
|
|
};
|
|
|
|
EFI_STATUS
|
|
PatchThirdPartyDriveSupport (
|
|
IN OUT PRELINKED_CONTEXT *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
PATCHER_CONTEXT Patcher;
|
|
|
|
Status = PatcherInitContextFromPrelinked (
|
|
&Patcher,
|
|
Context,
|
|
"com.apple.iokit.IOAHCIBlockStorage"
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = PatcherApplyGenericPatch (&Patcher, &mIOAHCIBlockStoragePatchV1);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.iokit.IOAHCIBlockStorage V1 - %r\n", Status));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.iokit.IOAHCIBlockStorage V1\n"));
|
|
}
|
|
|
|
Status = PatcherApplyGenericPatch (&Patcher, &mIOAHCIBlockStoragePatchV2);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.iokit.IOAHCIBlockStorage V2 - %r\n", Status));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.iokit.IOAHCIBlockStorage V2\n"));
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to find com.apple.iokit.IOAHCIBlockStorage - %r\n", Status));
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
STATIC
|
|
UINT8
|
|
mIOAHCIPortPatchFind[] = {
|
|
0x45, 0x78, 0x74, 0x65, 0x72, 0x6E, 0x61, 0x6C
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mIOAHCIPortPatchReplace[] = {
|
|
0x49, 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x61, 0x6C
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mIOAHCIPortPatch = {
|
|
.Comment = DEBUG_POINTER ("IOAHCIPort"),
|
|
.Base = NULL,
|
|
.Find = mIOAHCIPortPatchFind,
|
|
.Mask = NULL,
|
|
.Replace = mIOAHCIPortPatchReplace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mIOAHCIPortPatchFind),
|
|
.Count = 1,
|
|
.Skip = 0
|
|
};
|
|
|
|
EFI_STATUS
|
|
PatchForceInternalDiskIcons (
|
|
IN OUT PRELINKED_CONTEXT *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
PATCHER_CONTEXT Patcher;
|
|
|
|
Status = PatcherInitContextFromPrelinked (
|
|
&Patcher,
|
|
Context,
|
|
"com.apple.driver.AppleAHCIPort"
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = PatcherApplyGenericPatch (&Patcher, &mIOAHCIPortPatch);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.driver.AppleAHCIPort - %r\n", Status));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.driver.AppleAHCIPort\n"));
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to find com.apple.driver.AppleAHCIPort - %r\n", Status));
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
STATIC
|
|
UINT8
|
|
mAppleIoMapperPatchFind[] = {
|
|
0x44, 0x4D, 0x41, 0x52, 0x00 // DMAR\0
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mAppleIoMapperPatchReplace[] = {
|
|
0x52, 0x41, 0x4D, 0x44, 0x00 // RAMD\0
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mAppleIoMapperPatch = {
|
|
.Comment = DEBUG_POINTER ("AppleIoMapper"),
|
|
.Base = NULL,
|
|
.Find = mAppleIoMapperPatchFind,
|
|
.Mask = NULL,
|
|
.Replace = mAppleIoMapperPatchReplace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mAppleIoMapperPatchFind),
|
|
.Count = 1,
|
|
.Skip = 0
|
|
};
|
|
|
|
EFI_STATUS
|
|
PatchAppleIoMapperSupport (
|
|
IN OUT PRELINKED_CONTEXT *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
PATCHER_CONTEXT Patcher;
|
|
|
|
Status = PatcherInitContextFromPrelinked (
|
|
&Patcher,
|
|
Context,
|
|
"com.apple.iokit.IOPCIFamily"
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = PatcherApplyGenericPatch (&Patcher, &mAppleIoMapperPatch);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.iokit.IOPCIFamily AppleIoMapper - %r\n", Status));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.iokit.IOPCIFamily AppleIoMapper\n"));
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to find com.apple.iokit.IOPCIFamily for AppleIoMapper - %r\n", Status));
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
STATIC
|
|
UINT8
|
|
mAppleDummyCpuPmPatchReplace[] = {
|
|
0xB8, 0x01, 0x00, 0x00, 0x00, 0xC3 // mov eax, 1 ; ret
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mAppleDummyCpuPmPatch = {
|
|
.Comment = DEBUG_POINTER ("DummyCpuPm"),
|
|
.Base = "__ZN28AppleIntelCPUPowerManagement5startEP9IOService",
|
|
.Find = NULL,
|
|
.Mask = NULL,
|
|
.Replace = mAppleDummyCpuPmPatchReplace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mAppleDummyCpuPmPatchReplace),
|
|
.Count = 1,
|
|
.Skip = 0
|
|
};
|
|
|
|
EFI_STATUS
|
|
PatchDummyPowerManagement (
|
|
IN OUT PRELINKED_CONTEXT *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
PATCHER_CONTEXT Patcher;
|
|
|
|
Status = PatcherInitContextFromPrelinked (
|
|
&Patcher,
|
|
Context,
|
|
"com.apple.driver.AppleIntelCPUPowerManagement"
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = PatcherApplyGenericPatch (&Patcher, &mAppleDummyCpuPmPatch);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch dummy AppleIntelCPUPowerManagement - %r\n", Status));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Patch success dummy AppleIntelCPUPowerManagement\n"));
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to find AppleIntelCPUPowerManagement for dummy - %r\n", Status));
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
STATIC
|
|
UINT8
|
|
mIncreasePciBarSizePatchFind[] = {
|
|
0x00, 0x00, 0x00, 0x40
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mIncreasePciBarSizePatchReplace[] = {
|
|
0x00, 0x00, 0x00, 0x80
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mIncreasePciBarSizePatch = {
|
|
.Comment = DEBUG_POINTER ("IncreasePciBarSize"),
|
|
.Base = "__ZN17IOPCIConfigurator24probeBaseAddressRegisterEP16IOPCIConfigEntryjj",
|
|
.Find = mIncreasePciBarSizePatchFind,
|
|
.Mask = NULL,
|
|
.Replace = mIncreasePciBarSizePatchReplace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mIncreasePciBarSizePatchFind),
|
|
.Count = 1,
|
|
.Skip = 0,
|
|
.Limit = EFI_PAGE_SIZE
|
|
};
|
|
|
|
EFI_STATUS
|
|
PatchIncreasePciBarSize (
|
|
IN OUT PRELINKED_CONTEXT *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
PATCHER_CONTEXT Patcher;
|
|
|
|
Status = PatcherInitContextFromPrelinked (
|
|
&Patcher,
|
|
Context,
|
|
"com.apple.iokit.IOPCIFamily"
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = PatcherApplyGenericPatch (&Patcher, &mIncreasePciBarSizePatch);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.iokit.IOPCIFamily IncreasePciBarSize - %r\n", Status));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.iokit.IOPCIFamily IncreasePciBarSize\n"));
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to find com.apple.iokit.IOPCIFamily for IncreasePciBarSize - %r\n", Status));
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
STATIC
|
|
CONST UINT8
|
|
mKernelCpuIdFindRelNew[] = {
|
|
0xB9, 0x8B, 0x00, 0x00, 0x00, 0x31, 0xC0, 0x31, 0xD2, 0x0F, 0x30, 0xB8, 0x01, 0x00, 0x00, 0x00, 0x31, 0xDB, 0x31, 0xC9, 0x31, 0xD2, 0x0F, 0xA2
|
|
};
|
|
|
|
STATIC
|
|
CONST UINT8
|
|
mKernelCpuIdFindRelOld[] = {
|
|
0xB9, 0x8B, 0x00, 0x00, 0x00, 0x31, 0xD2, 0x0F, 0x30, 0xB8, 0x01, 0x00, 0x00, 0x00, 0x31, 0xDB, 0x31, 0xC9, 0x31, 0xD2, 0x0F, 0xA2
|
|
};
|
|
|
|
STATIC
|
|
CONST UINT8
|
|
mKernelCpuidFindMcRel[] = {
|
|
0xB9, 0x8B, 0x00, 0x00, 0x00, 0x0F, 0x32
|
|
};
|
|
|
|
/**
|
|
cpu->cpuid_signature = 0x11111111;
|
|
cpu->cpuid_stepping = 0x22;
|
|
cpu->cpuid_model = 0x33;
|
|
cpu->cpuid_family = 0x44;
|
|
cpu->cpuid_type = 0x55555555;
|
|
cpu->cpuid_extmodel = 0x66;
|
|
cpu->cpuid_extfamily = 0x77;
|
|
cpu->cpuid_features = 0x8888888888888888;
|
|
cpu->cpuid_logical_per_package = 0x99999999;
|
|
cpu->cpuid_cpufamily = 0xAAAAAAAA;
|
|
return 0xAAAAAAAA;
|
|
**/
|
|
STATIC
|
|
CONST UINT8
|
|
mKernelCpuidReplaceDbg[] = {
|
|
0xC7, 0x47, 0x68, 0x11, 0x11, 0x11, 0x11, ///< mov dword ptr [rdi+68h], 11111111h
|
|
0xC6, 0x47, 0x50, 0x22, ///< mov byte ptr [rdi+50h], 22h
|
|
0x48, 0xB8, 0x55, 0x55, 0x55, 0x55, 0x44, 0x33, 0x66, 0x77, ///< mov rax, 7766334455555555h
|
|
0x48, 0x89, 0x47, 0x48, ///< mov [rdi+48h], rax
|
|
0x48, 0xB8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, ///< mov rax, 8888888888888888h
|
|
0x48, 0x89, 0x47, 0x58, ///< mov [rdi+58h], rax
|
|
0xC7, 0x87, 0xCC, 0x00, 0x00, 0x00, 0x99, 0x99, 0x99, 0x99, ///< mov dword ptr [rdi+0CCh], 99999999h
|
|
0xC7, 0x87, 0x88, 0x01, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, ///< mov dword ptr [rdi+188h], 0AAAAAAAAh
|
|
0xB8, 0xAA, 0xAA, 0xAA, 0xAA, ///< mov eax, 0AAAAAAAAh
|
|
0xC3 ///< retn
|
|
};
|
|
|
|
#pragma pack(push, 1)
|
|
|
|
typedef struct {
|
|
UINT8 Code1[3];
|
|
UINT32 Signature;
|
|
UINT8 Code2[3];
|
|
UINT8 Stepping;
|
|
UINT8 Code3[2];
|
|
UINT32 Type;
|
|
UINT8 Family;
|
|
UINT8 Model;
|
|
UINT8 ExtModel;
|
|
UINT8 ExtFamily;
|
|
UINT8 Code4[6];
|
|
UINT64 Features;
|
|
UINT8 Code5[10];
|
|
UINT32 LogicalPerPkg;
|
|
UINT8 Code6[6];
|
|
UINT32 AppleFamily1;
|
|
UINT8 Code7;
|
|
UINT32 AppleFamily2;
|
|
UINT8 Code8;
|
|
} INTERNAL_CPUID_FN_PATCH;
|
|
|
|
STATIC_ASSERT (
|
|
sizeof (INTERNAL_CPUID_FN_PATCH) == sizeof (mKernelCpuidReplaceDbg),
|
|
"Check your CPUID patch layout"
|
|
);
|
|
|
|
typedef struct {
|
|
UINT8 EaxCmd;
|
|
UINT32 EaxVal;
|
|
UINT8 EbxCmd;
|
|
UINT32 EbxVal;
|
|
UINT8 EcxCmd;
|
|
UINT32 EcxVal;
|
|
UINT8 EdxCmd;
|
|
UINT32 EdxVal;
|
|
} INTERNAL_CPUID_PATCH;
|
|
|
|
typedef struct {
|
|
UINT8 EdxCmd;
|
|
UINT32 EdxVal;
|
|
} INTERNAL_MICROCODE_PATCH;
|
|
|
|
#pragma pack(pop)
|
|
|
|
EFI_STATUS
|
|
PatchKernelCpuId (
|
|
IN OUT PATCHER_CONTEXT *Patcher,
|
|
IN OC_CPU_INFO *CpuInfo,
|
|
IN UINT32 *Data,
|
|
IN UINT32 *DataMask
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 *Record;
|
|
UINT8 *Last;
|
|
UINT32 Index;
|
|
UINT32 FoundSize;
|
|
INTERNAL_CPUID_PATCH *CpuidPatch;
|
|
INTERNAL_MICROCODE_PATCH *McPatch;
|
|
INTERNAL_CPUID_FN_PATCH *FnPatch;
|
|
CPUID_VERSION_INFO_EAX Eax;
|
|
CPUID_VERSION_INFO_EBX Ebx;
|
|
CPUID_VERSION_INFO_ECX Ecx;
|
|
CPUID_VERSION_INFO_EDX Edx;
|
|
BOOLEAN FoundReleaseKernel;
|
|
|
|
STATIC_ASSERT (
|
|
sizeof (mKernelCpuIdFindRelNew) > sizeof (mKernelCpuIdFindRelOld),
|
|
"Kernel CPUID patch seems wrong"
|
|
);
|
|
|
|
ASSERT (mKernelCpuIdFindRelNew[0] == mKernelCpuIdFindRelOld[0]
|
|
&& mKernelCpuIdFindRelNew[1] == mKernelCpuIdFindRelOld[1]
|
|
&& mKernelCpuIdFindRelNew[2] == mKernelCpuIdFindRelOld[2]
|
|
&& mKernelCpuIdFindRelNew[3] == mKernelCpuIdFindRelOld[3]
|
|
);
|
|
|
|
Last = ((UINT8 *) MachoGetMachHeader64 (&Patcher->MachContext)
|
|
+ MachoGetFileSize (&Patcher->MachContext) - EFI_PAGE_SIZE*2 - sizeof (mKernelCpuIdFindRelNew));
|
|
|
|
Status = PatcherGetSymbolAddress (Patcher, "_cpuid_set_info", (UINT8 **) &Record);
|
|
if (EFI_ERROR (Status) || Record >= Last) {
|
|
DEBUG ((DEBUG_WARN, "OCAK: Failed to locate _cpuid_set_info (%p) - %r\n", Record, Status));
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
FoundSize = 0;
|
|
|
|
for (Index = 0; Index < EFI_PAGE_SIZE; ++Index, ++Record) {
|
|
if (Record[0] == mKernelCpuIdFindRelNew[0]
|
|
&& Record[1] == mKernelCpuIdFindRelNew[1]
|
|
&& Record[2] == mKernelCpuIdFindRelNew[2]
|
|
&& Record[3] == mKernelCpuIdFindRelNew[3]) {
|
|
|
|
if (CompareMem (Record, mKernelCpuIdFindRelNew, sizeof (mKernelCpuIdFindRelNew)) == 0) {
|
|
FoundSize = sizeof (mKernelCpuIdFindRelNew);
|
|
break;
|
|
} else if (CompareMem (Record, mKernelCpuIdFindRelOld, sizeof (mKernelCpuIdFindRelOld)) == 0) {
|
|
FoundSize = sizeof (mKernelCpuIdFindRelOld);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
FoundReleaseKernel = FoundSize > 0;
|
|
|
|
//
|
|
// When patching the release kernel we do not allow reevaluating CPUID information,
|
|
// which is used to report OSXSAVE availability. This causes issues with some programs,
|
|
// like Docker using Hypervisor.framework, which rely on sysctl to track CPU feature.
|
|
//
|
|
// To workaround this we make sure to always report OSXSAVE bit when it is available
|
|
// regardless of the reevaluation performed by init_fpu in XNU.
|
|
//
|
|
// REF: https://github.com/acidanthera/bugtracker/issues/1035
|
|
//
|
|
if (FoundReleaseKernel
|
|
&& CpuInfo->CpuidVerEcx.Bits.XSAVE != 0
|
|
&& CpuInfo->CpuidVerEcx.Bits.OSXSAVE == 0
|
|
&& CpuInfo->CpuidVerEcx.Bits.AVX != 0) {
|
|
CpuInfo->CpuidVerEcx.Bits.OSXSAVE = 1;
|
|
}
|
|
|
|
Eax.Uint32 = (Data[0] & DataMask[0]) | (CpuInfo->CpuidVerEax.Uint32 & ~DataMask[0]);
|
|
Ebx.Uint32 = (Data[1] & DataMask[1]) | (CpuInfo->CpuidVerEbx.Uint32 & ~DataMask[1]);
|
|
Ecx.Uint32 = (Data[2] & DataMask[2]) | (CpuInfo->CpuidVerEcx.Uint32 & ~DataMask[2]);
|
|
Edx.Uint32 = (Data[3] & DataMask[3]) | (CpuInfo->CpuidVerEdx.Uint32 & ~DataMask[3]);
|
|
|
|
if (FoundReleaseKernel) {
|
|
CpuidPatch = (INTERNAL_CPUID_PATCH *) Record;
|
|
CpuidPatch->EaxCmd = 0xB8;
|
|
CpuidPatch->EaxVal = Eax.Uint32;
|
|
CpuidPatch->EbxCmd = 0xBB;
|
|
CpuidPatch->EbxVal = Ebx.Uint32;
|
|
CpuidPatch->EcxCmd = 0xB9;
|
|
CpuidPatch->EcxVal = Ecx.Uint32;
|
|
CpuidPatch->EdxCmd = 0xBA;
|
|
CpuidPatch->EdxVal = Edx.Uint32;
|
|
SetMem (
|
|
Record + sizeof (INTERNAL_CPUID_PATCH),
|
|
FoundSize - sizeof (INTERNAL_CPUID_PATCH),
|
|
0x90
|
|
);
|
|
Record += FoundSize;
|
|
|
|
for (Index = 0; Index < EFI_PAGE_SIZE - sizeof (mKernelCpuidFindMcRel); ++Index, ++Record) {
|
|
if (CompareMem (Record, mKernelCpuidFindMcRel, sizeof (mKernelCpuidFindMcRel)) == 0) {
|
|
McPatch = (INTERNAL_MICROCODE_PATCH *) Record;
|
|
McPatch->EdxCmd = 0xBA;
|
|
McPatch->EdxVal = CpuInfo->MicrocodeRevision;
|
|
SetMem (
|
|
Record + sizeof (INTERNAL_MICROCODE_PATCH),
|
|
sizeof (mKernelCpuidFindMcRel) - sizeof (INTERNAL_MICROCODE_PATCH),
|
|
0x90
|
|
);
|
|
return EFI_SUCCESS;
|
|
}
|
|
}
|
|
} else {
|
|
//
|
|
// Handle debug kernel here...
|
|
//
|
|
Status = PatcherGetSymbolAddress (Patcher, "_cpuid_set_cpufamily", (UINT8 **) &Record);
|
|
if (EFI_ERROR (Status) || Record >= Last) {
|
|
DEBUG ((DEBUG_WARN, "OCAK: Failed to locate _cpuid_set_cpufamily (%p) - %r\n", Record, Status));
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
CopyMem (Record, mKernelCpuidReplaceDbg, sizeof (mKernelCpuidReplaceDbg));
|
|
FnPatch = (INTERNAL_CPUID_FN_PATCH *) Record;
|
|
FnPatch->Signature = Eax.Uint32;
|
|
FnPatch->Stepping = (UINT8) Eax.Bits.SteppingId;
|
|
FnPatch->ExtModel = (UINT8) Eax.Bits.ExtendedModelId;
|
|
FnPatch->Model = (UINT8) Eax.Bits.Model | (UINT8) (Eax.Bits.ExtendedModelId << 4U);
|
|
FnPatch->Family = (UINT8) Eax.Bits.FamilyId;
|
|
FnPatch->Type = (UINT8) Eax.Bits.ProcessorType;
|
|
FnPatch->ExtFamily = (UINT8) Eax.Bits.ExtendedFamilyId;
|
|
FnPatch->Features = LShiftU64 (Ecx.Uint32, 32) | (UINT64) Edx.Uint32;
|
|
if (FnPatch->Features & CPUID_FEATURE_HTT) {
|
|
FnPatch->LogicalPerPkg = (UINT16) Ebx.Bits.MaximumAddressableIdsForLogicalProcessors;
|
|
} else {
|
|
FnPatch->LogicalPerPkg = 1;
|
|
}
|
|
|
|
FnPatch->AppleFamily1 = FnPatch->AppleFamily2 = OcCpuModelToAppleFamily (Eax);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
DEBUG ((DEBUG_WARN, "OCAK: Failed to find either CPUID patch (%u)\n", FoundSize));
|
|
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
STATIC
|
|
UINT8
|
|
mCustomSmbiosGuidPatchFind[] = {
|
|
0x45, 0x42, 0x39, 0x44, 0x32, 0x44, 0x33, 0x31
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mCustomSmbiosGuidPatchReplace[] = {
|
|
0x45, 0x42, 0x39, 0x44, 0x32, 0x44, 0x33, 0x35
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mCustomSmbiosGuidPatch = {
|
|
.Comment = DEBUG_POINTER ("CustomSmbiosGuid"),
|
|
.Base = NULL,
|
|
.Find = mCustomSmbiosGuidPatchFind,
|
|
.Mask = NULL,
|
|
.Replace = mCustomSmbiosGuidPatchReplace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mCustomSmbiosGuidPatchFind),
|
|
.Count = 1,
|
|
.Skip = 0
|
|
};
|
|
|
|
EFI_STATUS
|
|
PatchCustomSmbiosGuid (
|
|
IN OUT PRELINKED_CONTEXT *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
PATCHER_CONTEXT Patcher;
|
|
UINT32 Index;
|
|
|
|
STATIC CONST CHAR8 *Kexts[] = {
|
|
"com.apple.driver.AppleSMBIOS",
|
|
"com.apple.driver.AppleACPIPlatform"
|
|
};
|
|
|
|
for (Index = 0; Index < ARRAY_SIZE (Kexts); ++Index) {
|
|
Status = PatcherInitContextFromPrelinked (
|
|
&Patcher,
|
|
Context,
|
|
Kexts[Index]
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = PatcherApplyGenericPatch (&Patcher, &mCustomSmbiosGuidPatch);
|
|
if (!EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: SMBIOS Patch success %a\n", Kexts[Index]));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply SMBIOS patch %a - %r\n", Kexts[Index], Status));
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to find SMBIOS kext %a - %r\n", Kexts[Index], Status));
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
STATIC
|
|
UINT8
|
|
mPanicKextDumpPatchFind[] = {
|
|
0x00, 0x25, 0x2E, 0x2A, 0x73, 0x00 ///< \0%.*s\0
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mPanicKextDumpPatchReplace[] = {
|
|
0x00, 0x00, 0x2E, 0x2A, 0x73, 0x00
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mPanicKextDumpPatch = {
|
|
.Comment = DEBUG_POINTER ("PanicKextDump"),
|
|
.Base = NULL,
|
|
.Find = mPanicKextDumpPatchFind,
|
|
.Mask = NULL,
|
|
.Replace = mPanicKextDumpPatchReplace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mPanicKextDumpPatchFind),
|
|
.Count = 1,
|
|
.Skip = 0
|
|
};
|
|
|
|
EFI_STATUS
|
|
PatchPanicKextDump (
|
|
IN OUT PATCHER_CONTEXT *Patcher
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 *Record;
|
|
UINT8 *Last;
|
|
|
|
Last = ((UINT8 *) MachoGetMachHeader64 (&Patcher->MachContext)
|
|
+ MachoGetFileSize (&Patcher->MachContext) - EFI_PAGE_SIZE);
|
|
|
|
//
|
|
// This should work on 10.15 and all debug kernels.
|
|
//
|
|
Status = PatcherGetSymbolAddress (
|
|
Patcher,
|
|
"__ZN6OSKext19printKextPanicListsEPFiPKczE",
|
|
(UINT8 **) &Record
|
|
);
|
|
if (EFI_ERROR (Status) || Record >= Last) {
|
|
DEBUG ((DEBUG_WARN, "OCAK: Failed to locate printKextPanicLists (%p) - %r\n", Record, Status));
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
*Record = 0xC3;
|
|
|
|
//
|
|
// This one is for 10.13~10.14 release kernels, which do dumping inline.
|
|
// A bit risky, but let's hope it works well.
|
|
//
|
|
Status = PatcherApplyGenericPatch (Patcher, &mPanicKextDumpPatch);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply kext dump patch - %r\n", Status));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Patch success kext dump\n"));
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
STATIC
|
|
UINT8
|
|
mLapicKernelPanicPatchFind[] = {
|
|
// mov eax, gs:1Ch or gs:18h on 10.15.4+ or gs:20h on 11.0.
|
|
// cmp eax, cs:_master_cpu <- address masked out
|
|
0x65, 0x8B, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mLapicKernelPanicPatchMask[] = {
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mLapicKernelPanicPatchReplace[] = {
|
|
// xor eax, eax ; nop further
|
|
0x31, 0xC0, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mLapicKernelPanicPatch = {
|
|
.Comment = DEBUG_POINTER ("LapicKernelPanic"),
|
|
.Base = "_lapic_interrupt",
|
|
.Find = mLapicKernelPanicPatchFind,
|
|
.Mask = mLapicKernelPanicPatchMask,
|
|
.Replace = mLapicKernelPanicPatchReplace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mLapicKernelPanicPatchReplace),
|
|
.Count = 1,
|
|
.Skip = 0,
|
|
.Limit = 1024
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mLapicKernelPanicPatchLegacyFind[] = {
|
|
// mov eax, gs:1Ch on 10.9.5.
|
|
// lea rcx, _master_cpu
|
|
// cmp eax, [rcx]
|
|
0x65, 0x8B, 0x04, 0x25, 0x18, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mLapicKernelPanicPatchLegacyMask[] = {
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mLapicKernelPanicPatchLegacyReplace[] = {
|
|
// xor eax, eax ; nop further
|
|
0x31, 0xC0, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mLapicKernelPanicLegacyPatch = {
|
|
.Comment = DEBUG_POINTER ("LapicKernelPanicLegacy"),
|
|
.Base = "_lapic_interrupt",
|
|
.Find = mLapicKernelPanicPatchLegacyFind,
|
|
.Mask = mLapicKernelPanicPatchLegacyMask,
|
|
.Replace = mLapicKernelPanicPatchLegacyReplace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mLapicKernelPanicPatchLegacyReplace),
|
|
.Count = 1,
|
|
.Skip = 0,
|
|
.Limit = 1024
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mLapicKernelPanicMasterPatchFind[] = {
|
|
// cmp cs:_debug_boot_arg, 0 <- address masked out
|
|
0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mLapicKernelPanicMasterPatchMask[] = {
|
|
0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mLapicKernelPanicMasterPatchReplace[] = {
|
|
// xor eax, eax ; nop further
|
|
0x31, 0xC0, 0x90, 0x90, 0x90, 0x90, 0x90
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mLapicKernelPanicMasterPatch = {
|
|
.Comment = DEBUG_POINTER ("LapicKernelPanicMaster"),
|
|
.Base = "_lapic_interrupt",
|
|
.Find = mLapicKernelPanicMasterPatchFind,
|
|
.Mask = mLapicKernelPanicMasterPatchMask,
|
|
.Replace = mLapicKernelPanicMasterPatchReplace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mLapicKernelPanicMasterPatchFind),
|
|
.Count = 1,
|
|
.Skip = 0,
|
|
.Limit = 4096
|
|
};
|
|
|
|
EFI_STATUS
|
|
PatchLapicKernelPanic (
|
|
IN OUT PATCHER_CONTEXT *Patcher
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
//
|
|
// This one is for <= 10.15 release kernels.
|
|
// TODO: Fix debug kernels and check whether we want more patches.
|
|
//
|
|
Status = PatcherApplyGenericPatch (Patcher, &mLapicKernelPanicPatch);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply modern lapic patch - %r\n", Status));
|
|
|
|
Status = PatcherApplyGenericPatch (Patcher, &mLapicKernelPanicLegacyPatch);
|
|
if (!EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Patch success legacy lapic\n"));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply modern lapic patch - %r\n", Status));
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Patch success lapic\n"));
|
|
|
|
//
|
|
// Also patch away the master core check to never require lapic_dont_panic=1.
|
|
// This one is optional, and seems to never be required in real world.
|
|
//
|
|
Status = PatcherApplyGenericPatch (Patcher, &mLapicKernelPanicMasterPatch);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply extended lapic patch - %r\n", Status));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Patch success extended lapic\n"));
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
STATIC
|
|
UINT8
|
|
mPowerStateTimeoutPanicFind[] = {
|
|
// com.apple\0
|
|
0x63, 0x6F, 0x6D, 0x2E, 0x61, 0x70, 0x70, 0x6C, 0x65, 0x00
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mPowerStateTimeoutPanicReplace[] = {
|
|
// not.apple\0
|
|
0x6E, 0x6F, 0x74, 0x2E, 0x61, 0x70, 0x70, 0x6C, 0x65, 0x00
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mPowerStateTimeoutPanicMasterPatch = {
|
|
.Comment = DEBUG_POINTER ("PowerStateTimeout"),
|
|
.Base = NULL,
|
|
.Find = mPowerStateTimeoutPanicFind,
|
|
.Mask = NULL,
|
|
.Replace = mPowerStateTimeoutPanicReplace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mPowerStateTimeoutPanicFind),
|
|
.Count = 1,
|
|
.Skip = 0,
|
|
.Limit = 0
|
|
};
|
|
|
|
EFI_STATUS
|
|
PatchPowerStateTimeout (
|
|
IN OUT PATCHER_CONTEXT *Patcher
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
Status = PatcherApplyGenericPatch (Patcher, &mPowerStateTimeoutPanicMasterPatch);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply power state patch - %r\n", Status));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Patch success power state\n"));
|
|
}
|
|
|
|
//
|
|
// TODO: Implement a patch to not require setpowerstate_panic=0 on debug kernels.
|
|
//
|
|
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// There currently are 2 places main RTC checksum is calculated in AppleRTC.kext
|
|
// __ZN8AppleRTC14updateChecksumEv and __ZN8AppleRTC19rtcRecordTracePointEjjj.
|
|
// Since we do not want to completely break RTC and/or saving tracepoints to RTC
|
|
// we patch-out __ZN8AppleRTC8rtcWriteEjh call arguments (0x58 and 0x59) with
|
|
// invalid (out of range) value 0xFFFF in 4 places.
|
|
//
|
|
|
|
STATIC
|
|
UINT8
|
|
mAppleRtcChecksumPatchFind[] = {
|
|
0xBE, 0x58, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mAppleRtcChecksumPatchMask[] = {
|
|
0xFF, 0xFE, 0xFF, 0xFF, 0xFF
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mAppleRtcChecksumPatchReplace[] = {
|
|
0xBE, 0xFF, 0xFF, 0x00, 0x00
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mAppleRtcChecksumPatch = {
|
|
.Comment = DEBUG_POINTER ("DisableRtcChecksum"),
|
|
.Base = NULL,
|
|
.Find = mAppleRtcChecksumPatchFind,
|
|
.Mask = mAppleRtcChecksumPatchMask,
|
|
.Replace = mAppleRtcChecksumPatchReplace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mAppleRtcChecksumPatchFind),
|
|
.Count = 4,
|
|
.Skip = 0,
|
|
.Limit = 0
|
|
};
|
|
|
|
EFI_STATUS
|
|
PatchAppleRtcChecksum (
|
|
IN OUT PRELINKED_CONTEXT *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
PATCHER_CONTEXT Patcher;
|
|
|
|
Status = PatcherInitContextFromPrelinked (
|
|
&Patcher,
|
|
Context,
|
|
"com.apple.driver.AppleRTC"
|
|
);
|
|
|
|
if (!EFI_ERROR (Status)) {
|
|
Status = PatcherApplyGenericPatch (&Patcher, &mAppleRtcChecksumPatch);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.driver.AppleRTC DisableRtcChecksum - %r\n", Status));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Patch success com.apple.driver.AppleRTC DisableRtcChecksum\n"));
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "OCAK: Failed to find com.apple.driver.AppleRTC for DisableRtcChecksum - %r\n", Status));
|
|
}
|
|
|
|
return Status;
|
|
}
|