提交 ca6c8299 编写于 作者: V vit9696

OcAppleKernelLib: Rework `AppleCpuPmCfgLock` to support 10.6.8

上级 c8c9ee56
......@@ -2042,7 +2042,7 @@ blocking.
\texttt{AppleCpuPmCfgLock}\\
\textbf{Type}: \texttt{plist\ boolean}\\
\textbf{Failsafe}: \texttt{false}\\
\textbf{Requirement}: FIXME\\
\textbf{Requirement}: 10.6 (64-bit)\\
\textbf{Description}: Disables \texttt{PKG\_CST\_CONFIG\_CONTROL} (\texttt{0xE2})
MSR modification in AppleIntelCPUPowerManagement.kext, commonly causing early
kernel panic, when it is locked from writing.
......
......@@ -22,79 +22,19 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/OcFileLib.h>
#include <Library/UefiLib.h>
STATIC
UINT8
mAppleIntelCPUPowerManagementPatchFind[] = {
0xB9, 0xE2, 0x00, 0x00, 0x00, // mov ecx, 0xe2
0x0F, 0x30 // wrmsr
STATIC CONST UINT8 mMovEcxE2[] = {
0xB9, 0xE2, 0x00, 0x00, 0x00 // mov ecx, 0E2h
};
STATIC
UINT8
mAppleIntelCPUPowerManagementPatchReplace[] = {
0xB9, 0xE2, 0x00, 0x00, 0x00, // mov ecx, 0xe2
0x90, 0x90 // nop nop
STATIC CONST UINT8 mMovCxE2[] = {
0x66, 0xB9, 0xE2, 0x00 // mov cx, 0E2h
};
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 CONST UINT8 mWrmsr[] = {
0x0F, 0x30 // wrmsr
};
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
};
STATIC CONST UINTN mWrmsrMaxDistance = 32;
STATIC
EFI_STATUS
......@@ -103,27 +43,79 @@ PatchAppleCpuPmCfgLock (
IN UINT32 KernelVersion
)
{
EFI_STATUS Status;
EFI_STATUS Status2;
UINTN Count;
UINT8 *Walker;
UINT8 *WalkerEnd;
UINT8 *WalkerTmp;
Status = PatcherApplyGenericPatch (Patcher, &mAppleIntelCPUPowerManagementPatch);
if (!EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCAK: Patch v1 success com.apple.driver.AppleIntelCPUPowerManagement\n"));
if (Patcher == NULL) {
return EFI_NOT_FOUND;
}
Status2 = PatcherApplyGenericPatch (Patcher, &mAppleIntelCPUPowerManagementPatch2);
if (!EFI_ERROR (Status2)) {
DEBUG ((DEBUG_INFO, "OCAK: Patch v2 success com.apple.driver.AppleIntelCPUPowerManagement\n"));
}
Count = 0;
Walker = (UINT8 *) MachoGetMachHeader64 (&Patcher->MachContext);
WalkerEnd = Walker + MachoGetFileSize (&Patcher->MachContext) - mWrmsrMaxDistance;
if (EFI_ERROR (Status) && EFI_ERROR (Status2)) {
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patches com.apple.driver.AppleIntelCPUPowerManagement - %r/%r\n", Status, Status2));
}
//
// Thx to Clover developers for the approach.
//
while (Walker < WalkerEnd) {
//
// Match (e)cx 0E2h assignment.
//
if (Walker[0] == mMovEcxE2[0]
&& Walker[1] == mMovEcxE2[1]
&& Walker[2] == mMovEcxE2[2]
&& Walker[3] == mMovEcxE2[3]
&& Walker[4] == mMovEcxE2[4]) {
STATIC_ASSERT (sizeof (mMovEcxE2) == 5, "Unsupported mMovEcxE2");
Walker += sizeof (mMovCxE2);
} else if (Walker[0] == mMovCxE2[0]
&& Walker[1] == mMovCxE2[1]
&& Walker[2] == mMovCxE2[2]
&& Walker[3] == mMovCxE2[3]) {
STATIC_ASSERT (sizeof (mMovCxE2) == 4, "Unsupported mMovCxE2");
Walker += sizeof (mMovCxE2);
} else {
++Walker;
continue;
}
WalkerTmp = Walker + mWrmsrMaxDistance;
while (Walker < WalkerTmp) {
if (Walker[0] == mWrmsr[0]
&& Walker[1] == mWrmsr[1]) {
STATIC_ASSERT (sizeof (mWrmsr) == 2, "Unsupported mWrmsr");
++Count;
//
// Patch matched wrmsr with nop.
//
*Walker++ = 0x90;
*Walker++ = 0x90;
break;
} else if ((Walker[0] == 0xC9 && Walker[1] == 0xC3) ///< leave; ret
|| (Walker[0] == 0x5D && Walker[1] == 0xC3) ///< pop rbp; ret
|| (Walker[0] == 0xB9 && Walker[3] == 0 && Walker[4] == 0) ///< mov ecx, 00000xxxxh
|| (Walker[0] == 0x66 && Walker[1] == 0xB9 && Walker[3] == 0)) { ///< mov cx, 00xxh
//
// Stop searching upon matching return and reassign sequences.
//
Walker += 2;
break;
} else {
//
// Continue searching.
//
++Walker;
}
}
}
//
// At least one patch must be successful for this to work (e.g. first for 10.14).
// At least one patch must be successful for this to work.
//
return !EFI_ERROR (Status) ? Status : Status2;
return Count > 0 ? EFI_SUCCESS : EFI_NOT_FOUND;
}
#pragma pack(push, 1)
......@@ -210,6 +202,8 @@ PatchAppleXcpmCfgLock (
UINT32 Replacements;
ASSERT (Patcher != NULL);
if (!OcMatchDarwinVersion (KernelVersion, KERNEL_VERSION_MOUNTAIN_LION_MIN, 0)) {
DEBUG ((DEBUG_INFO, "OCAK: Skipping XcpmCfgLock on %u\n", KernelVersion));
return EFI_SUCCESS;
......@@ -339,6 +333,8 @@ PatchAppleXcpmExtraMsrs (
XCPM_MSR_RECORD *Last;
UINT32 Replacements;
ASSERT (Patcher != NULL);
if (!OcMatchDarwinVersion (KernelVersion, KERNEL_VERSION_MOUNTAIN_LION_MIN, 0)) {
DEBUG ((DEBUG_INFO, "OCAK: Skipping XcpmExtraMsrs on %u\n", KernelVersion));
return EFI_SUCCESS;
......@@ -464,6 +460,8 @@ PatchAppleXcpmForceBoost (
UINT8 *Last;
UINT8 *Current;
ASSERT (Patcher != NULL);
if (!OcMatchDarwinVersion (KernelVersion, KERNEL_VERSION_MOUNTAIN_LION_MIN, 0)) {
DEBUG ((DEBUG_INFO, "OCAK: Skipping XcpmForceBoost on %u\n", KernelVersion));
return EFI_SUCCESS;
......@@ -616,6 +614,10 @@ PatchUsbXhciPortLimit1 (
return EFI_SUCCESS;
}
if (Patcher == NULL) {
return EFI_NOT_FOUND;
}
Status = PatcherApplyGenericPatch (Patcher, &mRemoveUsbLimitIoP1Patch);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply port patch com.apple.iokit.IOUSBHostFamily - %r\n", Status));
......@@ -640,6 +642,10 @@ PatchUsbXhciPortLimit2 (
return EFI_SUCCESS;
}
if (Patcher == NULL) {
return EFI_NOT_FOUND;
}
//
// TODO: Implement some locationID hack in IOUSBHostFamily.
// The location ID is a 32 bit number which is unique among all USB devices in the system,
......@@ -693,11 +699,15 @@ PatchUsbXhciPortLimit3 (
{
EFI_STATUS Status;
if (!OcMatchDarwinVersion (KernelVersion, 0, KERNEL_VERSION_HIGH_SIERRA_MAX)) {
if (!OcMatchDarwinVersion (KernelVersion, KERNEL_VERSION_EL_CAPITAN_MIN, KERNEL_VERSION_HIGH_SIERRA_MAX)) {
DEBUG ((DEBUG_INFO, "OCAK: Skipping legacy port patch AppleUSBXHCIPCI on %u\n", KernelVersion));
return EFI_SUCCESS;
}
if (Patcher == NULL) {
return EFI_NOT_FOUND;
}
//
// If we are here, we are on legacy 10.13 or below, try the oldest patch.
//
......@@ -781,6 +791,10 @@ PatchThirdPartyDriveSupport (
{
EFI_STATUS Status;
if (Patcher == NULL) {
return EFI_NOT_FOUND;
}
Status = PatcherApplyGenericPatch (Patcher, &mIOAHCIBlockStoragePatchV1);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.iokit.IOAHCIBlockStorage V1 - %r\n", Status));
......@@ -847,6 +861,10 @@ PatchForceInternalDiskIcons (
{
EFI_STATUS Status;
if (Patcher == NULL) {
return EFI_NOT_FOUND;
}
Status = PatcherApplyGenericPatch (Patcher, &mIOAHCIPortPatch);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.driver.AppleAHCIPort - %r\n", Status));
......@@ -892,6 +910,10 @@ PatchAppleIoMapperSupport (
{
EFI_STATUS Status;
if (Patcher == NULL) {
return EFI_NOT_FOUND;
}
if (!OcMatchDarwinVersion (KernelVersion, KERNEL_VERSION_MOUNTAIN_LION_MIN, 0)) {
DEBUG ((DEBUG_INFO, "OCAK: Skipping AppleIoMapper patch on %u\n", KernelVersion));
return EFI_SUCCESS;
......@@ -936,6 +958,10 @@ PatchDummyPowerManagement (
{
EFI_STATUS Status;
if (Patcher == NULL) {
return EFI_NOT_FOUND;
}
Status = PatcherApplyGenericPatch (Patcher, &mAppleDummyCpuPmPatch);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch dummy AppleIntelCPUPowerManagement - %r\n", Status));
......@@ -982,6 +1008,10 @@ PatchIncreasePciBarSize (
{
EFI_STATUS Status;
if (Patcher == NULL) {
return EFI_NOT_FOUND;
}
Status = PatcherApplyGenericPatch (Patcher, &mIncreasePciBarSizePatch);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.iokit.IOPCIFamily IncreasePciBarSize - %r\n", Status));
......@@ -1344,6 +1374,8 @@ PatchKernelCpuId (
CPUID_VERSION_INFO_EDX Edx;
BOOLEAN FoundReleaseKernel;
ASSERT (Patcher != NULL);
STATIC_ASSERT (
sizeof (mKernelCpuIdFindRelNew) > sizeof (mKernelCpuIdFindRelOld),
"Kernel CPUID patch seems wrong"
......@@ -1514,7 +1546,11 @@ PatchCustomSmbiosGuid (
)
{
EFI_STATUS Status;
if (Patcher == NULL) {
return EFI_NOT_FOUND;
}
Status = PatcherApplyGenericPatch (Patcher, &mCustomSmbiosGuidPatch);
if (!EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCAK: SMBIOS Patch success\n"));
......@@ -1562,6 +1598,8 @@ PatchPanicKextDump (
UINT8 *Record;
UINT8 *Last;
ASSERT (Patcher != NULL);
if (!OcMatchDarwinVersion (KernelVersion, KERNEL_VERSION_HIGH_SIERRA_MIN, 0)) {
DEBUG ((DEBUG_INFO, "OCAK: Skipping XcpmCfgLock on %u\n", KernelVersion));
return EFI_SUCCESS;
......@@ -1716,6 +1754,8 @@ PatchLapicKernelPanic (
{
EFI_STATUS Status;
ASSERT (Patcher != NULL);
//
// This one is for <= 10.15 release kernels.
// TODO: Fix debug kernels and check whether we want more patches.
......@@ -1786,6 +1826,8 @@ PatchPowerStateTimeout (
{
EFI_STATUS Status;
ASSERT (Patcher != NULL);
if (!OcMatchDarwinVersion (KernelVersion, KERNEL_VERSION_CATALINA_MIN, 0)) {
DEBUG ((DEBUG_INFO, "OCAK: Skipping power state patch on %u\n", KernelVersion));
return EFI_SUCCESS;
......@@ -1855,6 +1897,10 @@ PatchAppleRtcChecksum (
{
EFI_STATUS Status;
if (Patcher == NULL) {
return EFI_NOT_FOUND;
}
Status = PatcherApplyGenericPatch (Patcher, &mAppleRtcChecksumPatch);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCAK: Failed to apply patch com.apple.driver.AppleRTC DisableRtcChecksum - %r\n", Status));
......
......@@ -1383,12 +1383,16 @@ MkextContextApplyQuirk (
ASSERT (KernelQuirk->BundleId != NULL);
Status = PatcherInitContextFromMkext (&Patcher, Context, KernelQuirk->BundleId);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCAK: Failed to find %a - %r\n", KernelQuirk->BundleId, Status));
return Status;
if (!EFI_ERROR (Status)) {
return KernelQuirk->PatchFunction (&Patcher, KernelVersion);
}
return KernelQuirk->PatchFunction (&Patcher, KernelVersion);
//
// It is up to the function to decice whether this is critical or not.
//
DEBUG ((DEBUG_INFO, "OCAK: Failed to mkext find %a - %r\n", KernelQuirk->BundleId, Status));
return KernelQuirk->PatchFunction (NULL, KernelVersion);
}
EFI_STATUS
......
......@@ -1151,7 +1151,7 @@ PrelinkedContextApplyPatch (
Status = PatcherInitContextFromPrelinked (&Patcher, Context, BundleId);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCAK: Failed to find %a - %r\n", BundleId, Status));
DEBUG ((DEBUG_INFO, "OCAK: Failed to pk find %a - %r\n", BundleId, Status));
return Status;
}
......@@ -1175,10 +1175,13 @@ PrelinkedContextApplyQuirk (
ASSERT (KernelQuirk->BundleId != NULL);
Status = PatcherInitContextFromPrelinked (&Patcher, Context, KernelQuirk->BundleId);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCAK: Failed to find %a - %r\n", KernelQuirk->BundleId, Status));
return Status;
if (!EFI_ERROR (Status)) {
return KernelQuirk->PatchFunction (&Patcher, KernelVersion);
}
return KernelQuirk->PatchFunction (&Patcher, KernelVersion);
//
// It is up to the function to decice whether this is critical or not.
//
DEBUG ((DEBUG_INFO, "OCAK: Failed to find %a - %r\n", KernelQuirk->BundleId, Status));
return KernelQuirk->PatchFunction (NULL, KernelVersion);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册