mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
468 lines
12 KiB
C
468 lines
12 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 <Library/DebugLib.h>
|
|
#include <Library/OcAppleKernelLib.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 = {
|
|
.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 = {
|
|
.Base = NULL,
|
|
.Find = mAppleIntelCPUPowerManagementPatch2Find,
|
|
.Mask = mAppleIntelCPUPowerManagementPatch2FindMask,
|
|
.Replace = mAppleIntelCPUPowerManagementPatch2Replace,
|
|
.ReplaceMask = mAppleIntelCPUPowerManagementPatch2ReplaceMask,
|
|
.Size = sizeof (mAppleIntelCPUPowerManagementPatch2Find),
|
|
.Count = 0,
|
|
.Skip = 0
|
|
};
|
|
|
|
RETURN_STATUS
|
|
PatchAppleCpuPmCfgLock (
|
|
IN OUT PRELINKED_CONTEXT *Context
|
|
)
|
|
{
|
|
RETURN_STATUS Status;
|
|
RETURN_STATUS Status2;
|
|
PATCHER_CONTEXT Patcher;
|
|
|
|
Status = PatcherInitContextFromPrelinked (
|
|
&Patcher,
|
|
Context,
|
|
"com.apple.driver.AppleIntelCPUPowerManagement"
|
|
);
|
|
|
|
if (!RETURN_ERROR (Status)) {
|
|
Status = PatcherApplyGenericPatch (&Patcher, &mAppleIntelCPUPowerManagementPatch);
|
|
if (RETURN_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "Failed to apply patch com.apple.driver.AppleIntelCPUPowerManagement - %r\n", Status));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "Patch success com.apple.driver.AppleIntelCPUPowerManagement\n"));
|
|
}
|
|
Status2 = PatcherApplyGenericPatch (&Patcher, &mAppleIntelCPUPowerManagementPatch2);
|
|
if (RETURN_ERROR (Status2)) {
|
|
DEBUG ((DEBUG_INFO, "Failed to apply patch com.apple.driver.AppleIntelCPUPowerManagement - %r\n", Status2));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "Patch success com.apple.driver.AppleIntelCPUPowerManagement\n"));
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "Failed to find com.apple.driver.AppleIntelCPUPowerManagement - %r\n", Status));
|
|
}
|
|
|
|
return RETURN_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)
|
|
|
|
RETURN_STATUS
|
|
PatchAppleXcpmCfgLock (
|
|
IN OUT PATCHER_CONTEXT *Patcher
|
|
)
|
|
{
|
|
RETURN_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 (!RETURN_ERROR (Status)) {
|
|
while (Record < Last) {
|
|
if (Record->xcpm_msr_num == 0xE2) {
|
|
DEBUG ((
|
|
DEBUG_INFO,
|
|
"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,
|
|
"Not matching _xcpm_core_scope_msrs data %u %u\n",
|
|
Record->xcpm_msr_num,
|
|
Record->xcpm_msr_applicable_cpus
|
|
));
|
|
break;
|
|
}
|
|
++Record;
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_WARN, "Failed to locate _xcpm_core_scope_msrs - %r\n", Status));
|
|
}
|
|
|
|
return Replacements > 0 ? EFI_SUCCESS : EFI_NOT_FOUND;
|
|
}
|
|
|
|
STATIC
|
|
UINT8
|
|
mRemoveUsbLimitV1Find[] = {
|
|
0xff, 0xff, 0x10
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mRemoveUsbLimitV1Replace[] = {
|
|
0xff, 0xff, 0x40
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mRemoveUsbLimitV1Patch = {
|
|
.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 = {
|
|
.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 = {
|
|
.Base = "__ZN16AppleUSBHostPort15setPortLocationEj",
|
|
.Find = mRemoveUsbLimitIoP1Find,
|
|
.Mask = NULL,
|
|
.Replace = mRemoveUsbLimitIoP1Replace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mRemoveUsbLimitIoP1Replace),
|
|
.Count = 1,
|
|
.Skip = 0,
|
|
.Limit = 4096
|
|
};
|
|
|
|
RETURN_STATUS
|
|
PatchUsbXhciPortLimit (
|
|
IN OUT PRELINKED_CONTEXT *Context
|
|
)
|
|
{
|
|
RETURN_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 (!RETURN_ERROR (Status)) {
|
|
Status = PatcherApplyGenericPatch (&Patcher, &mRemoveUsbLimitIoP1Patch);
|
|
if (RETURN_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "Failed to apply P1 patch com.apple.iokit.IOUSBHostFamily - %r\n", Status));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "Patch success com.apple.iokit.IOUSBHostFamily\n"));
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "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 (!RETURN_ERROR (Status)) {
|
|
Status = PatcherApplyGenericPatch (&Patcher, &mRemoveUsbLimitV2Patch);
|
|
if (!RETURN_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, "Patch success com.apple.driver.usb.AppleUSBXHCI\n"));
|
|
return RETURN_SUCCESS;
|
|
}
|
|
|
|
DEBUG ((DEBUG_INFO, "Failed to apply patch com.apple.driver.usb.AppleUSBXHCI - %r\n", Status));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "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 (!RETURN_ERROR (Status)) {
|
|
Status = PatcherApplyGenericPatch (&Patcher, &mRemoveUsbLimitV1Patch);
|
|
if (RETURN_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "Failed to apply patch com.apple.driver.usb.AppleUSBXHCIPCI - %r\n", Status));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "Patch success com.apple.driver.usb.AppleUSBXHCIPCI\n"));
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "Failed to find com.apple.driver.usb.AppleUSBXHCIPCI - %r\n", Status));
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
STATIC
|
|
UINT8
|
|
mIOAHCIBlockStoragePatchFind[] = {
|
|
0x41, 0x50, 0x50, 0x4C, 0x45, 0x20, 0x53, 0x53, 0x44, 0x00
|
|
};
|
|
|
|
STATIC
|
|
UINT8
|
|
mIOAHCIBlockStoragePatchReplace[] = {
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
STATIC
|
|
PATCHER_GENERIC_PATCH
|
|
mIOAHCIBlockStoragePatch = {
|
|
.Base = NULL,
|
|
.Find = mIOAHCIBlockStoragePatchFind,
|
|
.Mask = NULL,
|
|
.Replace = mIOAHCIBlockStoragePatchReplace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mIOAHCIBlockStoragePatchFind),
|
|
.Count = 1,
|
|
.Skip = 0
|
|
};
|
|
|
|
RETURN_STATUS
|
|
PatchThirdPartySsdTrim (
|
|
IN OUT PRELINKED_CONTEXT *Context
|
|
)
|
|
{
|
|
RETURN_STATUS Status;
|
|
PATCHER_CONTEXT Patcher;
|
|
|
|
Status = PatcherInitContextFromPrelinked (
|
|
&Patcher,
|
|
Context,
|
|
"com.apple.iokit.IOAHCIBlockStorage"
|
|
);
|
|
|
|
if (!RETURN_ERROR (Status)) {
|
|
Status = PatcherApplyGenericPatch (&Patcher, &mIOAHCIBlockStoragePatch);
|
|
if (RETURN_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "Failed to apply patch com.apple.iokit.IOAHCIBlockStorage - %r\n", Status));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "Patch success com.apple.iokit.IOAHCIBlockStorage\n"));
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "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 = {
|
|
.Base = NULL,
|
|
.Find = mIOAHCIPortPatchFind,
|
|
.Mask = NULL,
|
|
.Replace = mIOAHCIPortPatchReplace,
|
|
.ReplaceMask = NULL,
|
|
.Size = sizeof (mIOAHCIPortPatchFind),
|
|
.Count = 1,
|
|
.Skip = 0
|
|
};
|
|
|
|
RETURN_STATUS
|
|
PatchForceInternalDiskIcons (
|
|
IN OUT PRELINKED_CONTEXT *Context
|
|
)
|
|
{
|
|
RETURN_STATUS Status;
|
|
PATCHER_CONTEXT Patcher;
|
|
|
|
Status = PatcherInitContextFromPrelinked (
|
|
&Patcher,
|
|
Context,
|
|
"com.apple.driver.AppleAHCIPort"
|
|
);
|
|
|
|
if (!RETURN_ERROR (Status)) {
|
|
Status = PatcherApplyGenericPatch (&Patcher, &mIOAHCIPortPatch);
|
|
if (RETURN_ERROR (Status)) {
|
|
DEBUG ((DEBUG_INFO, "Failed to apply patch com.apple.driver.AppleAHCIPort - %r\n", Status));
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "Patch success com.apple.driver.AppleAHCIPort\n"));
|
|
}
|
|
} else {
|
|
DEBUG ((DEBUG_INFO, "Failed to find com.apple.driver.AppleAHCIPort - %r\n", Status));
|
|
}
|
|
|
|
return Status;
|
|
} |