diff --git a/Changelog.md b/Changelog.md index c199c839ef4..83663d9b904 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,7 @@ OpenCore Changelog #### v0.7.1 - Added `SyncTableIds` quirk to sync modified table OEM identifiers - Added CPU Info (MSRs) dumping to `SysReport` +- Fixed `PowerTimeoutKernelPanic` on macOS 12 #### v0.7.0 - Fixed NVRAM reset on firmware with write-protected `BootOptionSupport` diff --git a/Library/OcAppleKernelLib/CommonPatches.c b/Library/OcAppleKernelLib/CommonPatches.c index 80bb9faa0c0..e7604a0bc88 100644 --- a/Library/OcAppleKernelLib/CommonPatches.c +++ b/Library/OcAppleKernelLib/CommonPatches.c @@ -1386,6 +1386,49 @@ mPowerStateTimeoutPanicMasterPatch = { .Limit = 0 }; +STATIC +UINT8 +mPowerStateTimeoutPanicInlineFind[] = { + 0x80, 0x00, 0x01, 0x6F, ///< cmp byte ptr [rax+1], 6Fh ; 'o' + 0x75, 0x00, ///< jnz short fail + 0x80, 0x00, 0x02, 0x6D, ///< cmp byte ptr [rax+2], 6Dh ; 'm' + 0x75, 0x00, ///< jnz short fail +}; + +STATIC +UINT8 +mPowerStateTimeoutPanicInlineMask[] = { + 0xFF, 0x00, 0xFF, 0xFF, ///< cmp byte ptr [rax+1], 6Fh ; 'o' + 0xFF, 0x00, ///< jnz short fail + 0xFF, 0x00, 0xFF, 0xFF, ///< cmp byte ptr [rax+2], 6Dh ; 'm' + 0xFF, 0x00, ///< jnz short fail +}; + + +STATIC +UINT8 +mPowerStateTimeoutPanicInlineReplace[] = { + 0x80, 0x00, 0x01, 0x6E, ///< cmp byte ptr [rax+1], 6Fh ; 'n' + 0x75, 0x00, ///< jnz short fail + 0x80, 0x00, 0x02, 0x6D, ///< cmp byte ptr [rax+2], 6Dh ; 'm' + 0x75, 0x00, ///< jnz short fail +}; + +STATIC +PATCHER_GENERIC_PATCH +mPowerStateTimeoutPanicInlinePatch = { + .Comment = DEBUG_POINTER ("PowerStateTimeout"), + .Base = "__ZN9IOService12ackTimerTickEv", + .Find = mPowerStateTimeoutPanicInlineFind, + .Mask = mPowerStateTimeoutPanicInlineMask, + .Replace = mPowerStateTimeoutPanicInlineReplace, + .ReplaceMask = mPowerStateTimeoutPanicInlineMask, + .Size = sizeof (mPowerStateTimeoutPanicInlineFind), + .Count = 1, + .Skip = 0, + .Limit = 0x1000 +}; + STATIC EFI_STATUS PatchPowerStateTimeout ( @@ -1402,6 +1445,14 @@ PatchPowerStateTimeout ( return EFI_SUCCESS; } + Status = PatcherApplyGenericPatch (Patcher, &mPowerStateTimeoutPanicInlinePatch); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "OCAK: Patch success inline power state\n")); + return Status; + } + + DEBUG ((DEBUG_INFO, "OCAK: No inline power state patch - %r, trying fallback\n", Status)); + Status = PatcherApplyGenericPatch (Patcher, &mPowerStateTimeoutPanicMasterPatch); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_INFO, "OCAK: Failed to apply power state patch - %r\n", Status));