diff --git a/NootedRed/kern_hwlibs.cpp b/NootedRed/kern_hwlibs.cpp index dd757025..beb49bb8 100644 --- a/NootedRed/kern_hwlibs.cpp +++ b/NootedRed/kern_hwlibs.cpp @@ -30,11 +30,12 @@ bool X5000HWLibs::processKext(KernelPatcher &patcher, size_t id, mach_vm_address CAILDeviceTypeEntry *orgDeviceTypeTable = nullptr; DeviceCapabilityEntry *orgDevCapTable = nullptr; + auto catalina = getKernelVersion() == KernelVersion::Catalina; SolveRequestPlus solveRequests[] = { - {"__ZL15deviceTypeTable", orgDeviceTypeTable, kDeviceTypeTablePattern}, - {"__ZN11AMDFirmware14createFirmwareEPhjjPKc", this->orgCreateFirmware, kCreateFirmwarePattern}, + {"__ZL15deviceTypeTable", orgDeviceTypeTable, kDeviceTypeTablePattern, !catalina}, + {"__ZN11AMDFirmware14createFirmwareEPhjjPKc", this->orgCreateFirmware, kCreateFirmwarePattern, !catalina}, {"__ZN20AMDFirmwareDirectory11putFirmwareE16_AMD_DEVICE_TYPEP11AMDFirmware", this->orgPutFirmware, - kPutFirmwarePattern}, + kPutFirmwarePattern, !catalina}, {"__ZL20CAIL_ASIC_CAPS_TABLE", orgCapsTable, kCailAsicCapsTableHWLibsPattern}, {"_CAILAsicCapsInitTable", orgCapsInitTable, kCAILAsicCapsInitTablePattern}, {"_DeviceCapabilityTbl", orgDevCapTable, kDeviceCapabilityTblPattern}, @@ -45,21 +46,23 @@ bool X5000HWLibs::processKext(KernelPatcher &patcher, size_t id, mach_vm_address bool renoir = NRed::callback->chipType >= ChipType::Renoir; RouteRequestPlus requests[] = { {"__ZN35AMDRadeonX5000_AMDRadeonHWLibsX500025populateFirmwareDirectoryEv", wrapPopulateFirmwareDirectory, - this->orgPopulateFirmwareDirectory}, - {"_smu_get_fw_constants", hwLibsNoop, kSmuGetFwConstantsPattern, kSmuGetFwConstantsMask}, + this->orgPopulateFirmwareDirectory, !catalina}, + {catalina ? "_smu_get_external_fw" : "_smu_get_fw_constants", hwLibsNoop, kSmuGetFwConstantsPattern, + kSmuGetFwConstantsMask}, {"_smu_9_0_1_check_fw_status", hwLibsNoop, kSmu901CheckFwStatusPattern, kSmu901CheckFwStatusMask}, {"_smu_9_0_1_unload_smu", hwLibsNoop, kSmu901UnloadSmuPattern, kSmu901UnloadSmuMask}, {"_psp_cmd_km_submit", wrapPspCmdKmSubmit, this->orgPspCmdKmSubmit, kPspCmdKmSubmitPattern, kPspCmdKmSubmitMask, renoir}, {"_update_sdma_power_gating", wrapUpdateSdmaPowerGating, this->orgUpdateSdmaPowerGating, kUpdateSdmaPowerGatingPattern, kUpdateSdmaPowerGatingMask}, + {"__ZN16AmdTtlFwServices7getIpFwEjPKcP10_TtlFwInfo", wrapGetIpFw, this->orgGetIpFw, catalina}, }; PANIC_COND(!RouteRequestPlus::routeAll(patcher, id, requests, slide, size), "hwlibs", "Failed to route symbols"); PANIC_COND(MachInfo::setKernelWriting(true, KernelPatcher::kernelWriteLock) != KERN_SUCCESS, "hwlibs", "Failed to enable kernel writing"); - *orgDeviceTypeTable = {.deviceId = NRed::callback->deviceId, .deviceType = 6}; + if (!catalina) { *orgDeviceTypeTable = {.deviceId = NRed::callback->deviceId, .deviceType = 6}; } auto found = false; auto targetDeviceId = renoir && NRed::callback->deviceId != 0x1636 ? 0x1636 : NRed::callback->deviceId; while (orgCapsInitTable->deviceId != 0xFFFFFFFF) { @@ -82,7 +85,7 @@ bool X5000HWLibs::processKext(KernelPatcher &patcher, size_t id, mach_vm_address } orgCapsInitTable++; } - PANIC_COND(!found, "hwlibs", "Failed to find caps init table entry"); + PANIC_COND(!found, "hwlibs", "Failed to find init caps table entry"); found = false; while (orgDevCapTable->familyId) { if (orgDevCapTable->familyId == AMDGPU_FAMILY_RAVEN && orgDevCapTable->deviceId == targetDeviceId) { @@ -103,16 +106,16 @@ bool X5000HWLibs::processKext(KernelPatcher &patcher, size_t id, mach_vm_address auto ventura = getKernelVersion() >= KernelVersion::Ventura; auto monterey = getKernelVersion() >= KernelVersion::Monterey; const LookupPatchPlus patches[] = { - {&kextRadeonX5000HWLibs, kPspSwInitOriginal1, kPspSwInitPatched1, 1}, + {&kextRadeonX5000HWLibs, kPspSwInitOriginal1, kPspSwInitPatched1, 1, !catalina}, {&kextRadeonX5000HWLibs, kPspSwInitOriginal2, kPspSwInitOriginalMask2, kPspSwInitPatched2, - kPspSwInitPatchedMask2, 1}, + kPspSwInitPatchedMask2, 1, !catalina}, {&kextRadeonX5000HWLibs, kSmuInitFunctionPointerListOriginal, kSmuInitFunctionPointerListOriginalMask, kSmuInitFunctionPointerListPatched, kSmuInitFunctionPointerListPatchedMask, 1}, {&kextRadeonX5000HWLibs, kFullAsicResetOriginal, kFullAsicResetPatched, 1}, {&kextRadeonX5000HWLibs, kGcSwInitOriginal, kGcSwInitOriginalMask, kGcSwInitPatched, kGcSwInitPatchedMask, - 1}, + 1, !catalina}, {&kextRadeonX5000HWLibs, kGcSetFwEntryInfoOriginal, kGcSetFwEntryInfoOriginalMask, kGcSetFwEntryInfoPatched, - kGcSetFwEntryInfoPatchedMask, 1}, + kGcSetFwEntryInfoPatchedMask, 1, !catalina}, {&kextRadeonX5000HWLibs, kCreatePowerTuneServicesOriginal1, kCreatePowerTuneServicesPatched1, 1, !monterey}, {&kextRadeonX5000HWLibs, kCreatePowerTuneServicesMontereyOriginal1, kCreatePowerTuneServicesMontereyPatched1, 1, monterey}, @@ -136,8 +139,8 @@ void X5000HWLibs::wrapPopulateFirmwareDirectory(void *that) { bool isRenoirDerivative = NRed::callback->chipType >= ChipType::Renoir; - char filename[128] = {0}; - snprintf(filename, 128, "%s_vcn.bin", NRed::callback->getChipName()); + char filename[64] = {0}; + snprintf(filename, 64, "%s_vcn.bin", NRed::callback->getChipName()); auto *targetFn = isRenoirDerivative ? "ativvaxy_nv.dat" : "ativvaxy_rv.dat"; DBGLOG("wred", "%s => %s", filename, targetFn); @@ -181,3 +184,18 @@ CAILResult X5000HWLibs::wrapPspCmdKmSubmit(void *psp, void *ctx, void *param3, v return FunctionCast(wrapPspCmdKmSubmit, callback->orgPspCmdKmSubmit)(psp, ctx, param3, param4); } + +bool X5000HWLibs::wrapGetIpFw(void *that, uint32_t ipVersion, char *name, void *out) { + if (!strncmp(name, "ativvaxy_rv.dat", 16) || !strncmp(name, "ativvaxy_nv.dat", 16)) { + char filename[64] = {0}; + snprintf(filename, 64, "%s_vcn.bin", NRed::callback->getChipName()); + DBGLOG("wred", "getIpFw: %s => %s", filename, name); + + auto &fwDesc = getFWDescByName(filename); + auto *fwHeader = reinterpret_cast(fwDesc.data); + getMember(out, 0x0) = fwDesc.data + fwHeader->ucodeOff; + getMember(out, 0x8) = fwHeader->ucodeSize; + return true; + } + return FunctionCast(wrapGetIpFw, callback->orgGetIpFw)(that, ipVersion, name, out); +} diff --git a/NootedRed/kern_hwlibs.hpp b/NootedRed/kern_hwlibs.hpp index b5fbd37e..d993aaa6 100644 --- a/NootedRed/kern_hwlibs.hpp +++ b/NootedRed/kern_hwlibs.hpp @@ -21,9 +21,11 @@ class X5000HWLibs { t_putFirmware orgPutFirmware {nullptr}; mach_vm_address_t orgUpdateSdmaPowerGating {0}; mach_vm_address_t orgPspCmdKmSubmit {0}; + mach_vm_address_t orgGetIpFw {0}; static void wrapPopulateFirmwareDirectory(void *that); static void wrapUpdateSdmaPowerGating(void *cail, uint32_t mode); static CAILResult wrapPspCmdKmSubmit(void *psp, void *ctx, void *param3, void *param4); + static bool wrapGetIpFw(void *that, uint32_t param1, char *name, void *out); static CAILResult hwLibsNoop(); }; diff --git a/NootedRed/kern_nred.hpp b/NootedRed/kern_nred.hpp index 85e4e6e1..50b1fe8e 100644 --- a/NootedRed/kern_nred.hpp +++ b/NootedRed/kern_nred.hpp @@ -222,7 +222,7 @@ class NRed { uint16_t revision {0}; uint32_t pciRevision {0}; IOPCIDevice *iGPU {nullptr}; - OSMetaClass *metaClassMap[4][2] = {{nullptr}}; + OSMetaClass *metaClassMap[5][2] = {{nullptr}}; mach_vm_address_t orgSafeMetaCast {0}; mach_vm_address_t orgApplePanelSetDisplay {0}; diff --git a/NootedRed/kern_patches.hpp b/NootedRed/kern_patches.hpp index c4eeca4c..81567873 100644 --- a/NootedRed/kern_patches.hpp +++ b/NootedRed/kern_patches.hpp @@ -136,13 +136,15 @@ static const uint8_t kSDMAInitFunctionPointerListPatched[] = {0x39, 0xDB, 0x66, /** * `AMDRadeonX6000_AmdAsicInfoNavi::populateDeviceInfo` - * AMDRadeonX6000.kext + * AMDRadeonX6000Framebuffer.kext * Fix register read (0xD31 -> 0xD2F) and family ID (0x8F -> 0x8E). */ static const uint8_t kPopulateDeviceInfoOriginal[] {0xBE, 0x31, 0x0D, 0x00, 0x00, 0xFF, 0x90, 0x40, 0x01, 0x00, 0x00, - 0xC7, 0x43, 0x60, 0x8F, 0x00, 0x00, 0x00}; + 0xC7, 0x43, 0x00, 0x8F, 0x00, 0x00, 0x00}; +static const uint8_t kPopulateDeviceInfoMask[] {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}; static const uint8_t kPopulateDeviceInfoPatched[] {0xBE, 0x2F, 0x0D, 0x00, 0x00, 0xFF, 0x90, 0x40, 0x01, 0x00, 0x00, - 0xC7, 0x43, 0x60, 0x8E, 0x00, 0x00, 0x00}; + 0xC7, 0x43, 0x00, 0x8E, 0x00, 0x00, 0x00}; /** * `AmdAtomFwServices::initializeAtomDataTable` @@ -155,6 +157,14 @@ static const uint8_t kAmdAtomVramInfoNullCheckOriginal[] = {0x48, 0x89, 0x83, 0x static const uint8_t kAmdAtomVramInfoNullCheckPatched[] = {0x48, 0x89, 0x83, 0x90, 0x00, 0x00, 0x00, 0x66, 0x90, 0x66, 0x90, 0x66, 0x90, 0x66, 0x90, 0x90, 0x48, 0x8B, 0x7B, 0x18}; +/** Ditto */ +static const uint8_t kAmdAtomVramInfoNullCheckCatalinaOriginal[] = {0x48, 0x89, 0x83, 0x80, 0x00, 0x00, 0x00, 0x48, + 0x85, 0xC0, 0x74, 0x00}; +static const uint8_t kAmdAtomVramInfoNullCheckCatalinaMask[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00}; +static const uint8_t kAmdAtomVramInfoNullCheckCatalinaPatched[] = {0x48, 0x89, 0x83, 0x80, 0x00, 0x00, 0x00, 0x66, 0x90, + 0x66, 0x90, 0x90}; + /** * `AmdAtomFwServices::initializeAtomDataTable` * AMDRadeonX6000Framebuffer.kext @@ -171,10 +181,14 @@ static const uint8_t kAmdAtomPspDirectoryNullCheckPatched[] = {0x48, 0x89, 0x83, * AMDRadeonX6000Framebuffer.kext * Neutralise `AmdAtomVramInfo` null check. */ -static const uint8_t kGetFirmwareInfoNullCheckOriginal[] = {0x48, 0x83, 0xBB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x84, - 0x90, 0x00, 0x00, 0x00, 0x49, 0x89}; -static const uint8_t kGetFirmwareInfoNullCheckPatched[] = {0x48, 0x83, 0xBB, 0x90, 0x00, 0x00, 0x00, 0x00, 0x66, 0x90, - 0x66, 0x90, 0x66, 0x90, 0x49, 0x89}; +static const uint8_t kGetFirmwareInfoNullCheckOriginal[] = {0x48, 0x83, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x84, + 0x00, 0x00, 0x00, 0x00, 0x49, 0x89}; +static const uint8_t kGetFirmwareInfoNullCheckOriginalMask[] = {0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF}; +static const uint8_t kGetFirmwareInfoNullCheckPatched[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x90, + 0x66, 0x90, 0x66, 0x90, 0x00, 0x00}; +static const uint8_t kGetFirmwareInfoNullCheckPatchedMask[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00}; /** * `AMDRadeonX6000_AmdAgdcServices::getVendorInfo` @@ -228,6 +242,23 @@ static const uint8_t kStartHWEnginesPatched[] = {0x40, 0x83, 0xF0, 0x01}; static const uint8_t kAddrLibCreateOriginal[] = {0x41, 0x81, 0x7D, 0x08, 0x8D, 0x00, 0x00, 0x00}; static const uint8_t kAddrLibCreatePatched[] = {0x41, 0x81, 0x7D, 0x08, 0x8E, 0x00, 0x00, 0x00}; +/** + * `AMDRadeonX5000_AMDGraphicsAccelerator::createAccelChannels` + * AMDRadeonX5000.kext + * Catalina only. Change loop condition to skip SDMA1_HP. + */ +static const uint8_t kCreateAccelChannelsOriginal[] = {0x8D, 0x44, 0x09, 0x02}; +static const uint8_t kCreateAccelChannelsPatched[] = {0x8D, 0x44, 0x09, 0x01}; + +/** + * Mismatched `getTtlInterface` virtual calls + * AMDRadeonX6000.kext + */ +static const uint8_t kGetTtlInterfaceCallOriginal[] = {0x40, 0x80, 0x00, 0xFF, 0x90, 0xC8, 0x02, 0x00, 0x00}; +static const uint8_t kGetTtlInterfaceCallOriginalMask[] = {0xF0, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const uint8_t kGetTtlInterfaceCallPatched[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00}; +static const uint8_t kGetTtlInterfaceCallPatchedMask[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00}; + /** * Mismatched `getGpuDebugPolicy` virtual calls. * AMDRadeonX6000.kext @@ -235,6 +266,10 @@ static const uint8_t kAddrLibCreatePatched[] = {0x41, 0x81, 0x7D, 0x08, 0x8E, 0x static const uint8_t kGetGpuDebugPolicyCallOriginal[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0xC0, 0x03, 0x00, 0x00}; static const uint8_t kGetGpuDebugPolicyCallPatched[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0xC8, 0x03, 0x00, 0x00}; +/** Ditto */ +static const uint8_t kGetGpuDebugPolicyCallCatalinaOriginal[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0xC8, 0x03, 0x00, 0x00}; +static const uint8_t kGetGpuDebugPolicyCallCatalinaPatched[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0xC0, 0x03, 0x00, 0x00}; + /** * `AMDRadeonX6000_AMDHWChannel::submitCommandBuffer` * AMDRadeonX6000.kext @@ -246,6 +281,12 @@ static const uint8_t kHWChannelSubmitCommandBufferOriginal[] = {0x48, 0x8B, 0x07 static const uint8_t kHWChannelSubmitCommandBufferPatched[] = {0x48, 0x8B, 0x07, 0x66, 0x90, 0x66, 0x90, 0x66, 0x90, 0x48, 0x8B, 0x43}; +/** Ditto */ +static const uint8_t kHWChannelSubmitCommandBufferCatalinaOriginal[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0x20, 0x02, 0x00, + 0x00, 0x49, 0x8B, 0x45}; +static const uint8_t kHWChannelSubmitCommandBufferCatalinaPatched[] = {0x48, 0x8B, 0x07, 0x66, 0x90, 0x66, 0x90, 0x66, + 0x90, 0x49, 0x8B, 0x45}; + /** * Mismatched `getScheduler` virtual calls. * AMDRadeonX6000.kext @@ -257,6 +298,10 @@ static const uint8_t kGetSchedulerCallPatched[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, static const uint8_t kGetSchedulerCallVenturaOriginal[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0xB0, 0x03, 0x00, 0x00}; static const uint8_t kGetSchedulerCallVenturaPatched[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0xB8, 0x03, 0x00, 0x00}; +/** Ditto */ +static const uint8_t kGetSchedulerCallCatalinaOriginal[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0xC0, 0x03, 0x00, 0x00}; +static const uint8_t kGetSchedulerCallCatalinaPatched[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0xB8, 0x03, 0x00, 0x00}; + /** * Mismatched `isDeviceValid` virtual calls. * AMDRadeonX6000.kext @@ -265,9 +310,214 @@ static const uint8_t kIsDeviceValidCallOriginal[] = {0x48, 0x8B, 0x07, 0xFF, 0x9 static const uint8_t kIsDeviceValidCallPatched[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0x98, 0x02, 0x00, 0x00}; /** - * Mismatched `isDevicePCITunnelled` virtual call. - * `AMDRadeonX6000_AMDNavi10VideoContext::setSuspendResumeState` + * Mismatched `isDevicePCITunnelled` virtual calls. * AMDRadeonX6000.kext */ static const uint8_t kIsDevicePCITunnelledCallOriginal[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0xB0, 0x02, 0x00, 0x00}; static const uint8_t kIsDevicePCITunnelledCallPatched[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0xA8, 0x02, 0x00, 0x00}; + +/** + * Mismatched `getSML` virtual calls. + * AMDRadeonX6000.kext + */ +static const uint8_t kGetSMLCallOriginal[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0x98, 0x03, 0x00, 0x00}; +static const uint8_t kGetSMLCallPatched[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0x90, 0x03, 0x00, 0x00}; + +/** + * `AMDRadeonX6000_AMDHWDisplay::fillUBMSurface` + * AMDRadeonX6000.kext + * Mismatched `getUbmSwizzleMode` virtual call. + */ +static const uint8_t kGetUbmSwizzleModeCallOriginal[] = {0xFF, 0x91, 0x78, 0x04, 0x00, 0x00}; +static const uint8_t kGetUbmSwizzleModeCallPatched[] = {0xFF, 0x91, 0xA0, 0x04, 0x00, 0x00}; + +/** + * `AMDRadeonX6000_AMDHWDisplay::fillUBMSurface` + * AMDRadeonX6000.kext + * Mismatched `getUbmTileMode` virtual call. + */ +static const uint8_t kGetUbmTileModeCallOriginal[] = {0xFF, 0x90, 0x80, 0x04, 0x00, 0x00}; +static const uint8_t kGetUbmTileModeCallPatched[] = {0xFF, 0x90, 0xA8, 0x04, 0x00, 0x00}; + +/** + * `AMDRadeonX6000_AMDHWDisplay::writeUpdateFrameBufferOffsetCommands` + * AMDRadeonX6000.kext + * Mismatched `writeWaitForRenderingPipe` virtual call. + */ +static const uint8_t kWriteWaitForRenderingPipeCallOriginal[] = {0xFF, 0x90, 0xB8, 0x02, 0x00, 0x00, 0x89, 0x45, 0xAC}; +static const uint8_t kWriteWaitForRenderingPipeCallPatched[] = {0xFF, 0x90, 0xB0, 0x02, 0x00, 0x00, 0x89, 0x45, 0xAC}; + +/** + * `AMDRadeonX6000_AMDRTRing::WPTRDiagnostic` + * AMDRadeonX6000.kext + * Mismatched `dummyWPTRUpdateDiag` virtual call. + */ +static const uint8_t kDummyWPTRUpdateDiagCallOriginal[] = {0x48, 0x8B, 0x80, 0x50, 0x02, 0x00, 0x00}; +static const uint8_t kDummyWPTRUpdateDiagCallPatched[] = {0x48, 0x8B, 0x80, 0x48, 0x02, 0x00, 0x00}; + +/** + * `AMDRadeonX6000_AMDHWDisplay::init` + * AMDRadeonX6000.kext + * Mismatched `getPM4CommandsUtility` virtual call. + */ +static const uint8_t kGetPM4CommandUtilityCallOriginal[] = {0xFF, 0x90, 0xA0, 0x03, 0x00, 0x00}; +static const uint8_t kGetPM4CommandUtilityCallPatched[] = {0xFF, 0x90, 0x98, 0x03, 0x00, 0x00}; + +/** + * `AMDRadeonX6000_AMDRTRing::allocateMemoryResources` + * AMDRadeonX6000.kext + * Mismatched `getChannelDoorbellOffset` virtual call. + */ +static const uint8_t kGetChannelDoorbellOffsetCallOriginal[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0x88, 0x03, 0x00, 0x00}; +static const uint8_t kGetChannelDoorbellOffsetCallPatched[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0x80, 0x03, 0x00, 0x00}; + +/** + * `AMDRadeonX6000_AMDRTRing::allocateMemoryResources` + * AMDRadeonX6000.kext + * Mismatched `getDoorbellMemoryBaseAddress` virtual call. + */ +static const uint8_t kGetDoorbellMemoryBaseAddressCallOriginal[] = {0xFF, 0x90, 0x80, 0x03, 0x00, 0x00}; +static const uint8_t kGetDoorbellMemoryBaseAddressCallPatched[] = {0xFF, 0x90, 0x78, 0x03, 0x00, 0x00}; + +/** + * Mismatched `updateUtilizationStatisticsCounter` virtual calls. + * AMDRadeonX6000.kext + */ +static const uint8_t kUpdateUtilizationStatisticsCounterCallOriginal[] = {0x41, 0xFF, 0x90, 0xE0, 0x03, 0x00, 0x00}; +static const uint8_t kUpdateUtilizationStatisticsCounterCallPatched[] = {0x41, 0xFF, 0x90, 0xD8, 0x03, 0x00, 0x00}; + +/** + * `AMDRadeonX6000_AMDHWChannel::submitCommandBuffer` + * AMDRadeonX6000.kext + * Mismatched `dumpASICHangState` virtual calls. + */ +static const uint8_t kDumpASICHangStateCallOriginal[] = {0xFF, 0x90, 0xA8, 0x03, 0x00, 0x00}; +static const uint8_t kDumpASICHangStateCallPatched[] = {0xFF, 0x90, 0xA0, 0x03, 0x00, 0x00}; + +/** + * `AMDRadeonX6000_AMDHWChannel::init` + * AMDRadeonX6000.kext + * Mismatched `registerChannel` virtual call. + */ +static const uint8_t kRegisterChannelCallOriginal[] = {0x4C, 0x89, 0xEE, 0xFF, 0x90, 0x28, 0x03, 0x00, 0x00}; +static const uint8_t kRegisterChannelCallPatched[] = {0x4C, 0x89, 0xEE, 0xFF, 0x90, 0x20, 0x03, 0x00, 0x00}; + +/** + * Mismatched `disableGfxOff` virtual calls. + * AMDRadeonX6000.kext + */ +static const uint8_t kDisableGfxOffCallOriginal[] = {0xFF, 0x90, 0x00, 0x04, 0x00, 0x00}; +static const uint8_t kDisableGfxOffCallPatched[] = {0xFF, 0x90, 0xF8, 0x03, 0x00, 0x00}; + +/** + * Mismatched `enableGfxOff` virtual calls. + * AMDRadeonX6000.kext + */ +static const uint8_t kEnableGfxOffCallOriginal[] = {0xFF, 0x90, 0x08, 0x04, 0x00, 0x00}; +static const uint8_t kEnableGfxOffCallPatched[] = {0xFF, 0x90, 0x00, 0x04, 0x00, 0x00}; + +/** + * Mismatched `getHWMemory` virtual calls. + * AMDRadeonX6000.kext + */ +static const uint8_t kGetHWMemoryCallOriginal[] = {0x18, 0x48, 0x8B, 0x07, 0xFF, 0x90, 0xE0, 0x02, 0x00, 0x00, 0x48}; +static const uint8_t kGetHWMemoryCallPatched[] = {0x18, 0x48, 0x8B, 0x07, 0xFF, 0x90, 0xD8, 0x02, 0x00, 0x00, 0x48}; + +/** + * Mismatched `getHWGart` virtual calls. + * AMDRadeonX6000.kext + */ +static const uint8_t kGetHWGartCallOriginal[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0xE8, 0x02, 0x00, 0x00}; +static const uint8_t kGetHWGartCallPatched[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0xE0, 0x02, 0x00, 0x00}; + +/** + * Mismatched `getChannelCount` virtual calls. + * AMDRadeonX6000.kext + */ +static const uint8_t kGetChannelCountCallOriginal[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0x38, 0x03, 0x00, 0x00}; +static const uint8_t kGetChannelCountCallPatched[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0x30, 0x03, 0x00, 0x00}; + +/** + * Mismatched `flushSystemCaches` virtual calls. + * AMDRadeonX6000.kext + */ +static const uint8_t kFlushSystemCachesCallOriginal[] = {0xFF, 0x90, 0xA8, 0x04, 0x00, 0x00}; +static const uint8_t kFlushSystemCachesCallPatched[] = {0xFF, 0x90, 0xD0, 0x04, 0x00, 0x00}; + +/** + * Mismatched `getIOPCIDevice` virtual calls. + * AMDRadeonX6000.kext + */ +static const uint8_t kGetIOPCIDeviceCallOriginal[] = {0xFF, 0x90, 0x90, 0x03, 0x00, 0x00}; +static const uint8_t kGetIOPCIDeviceCallPatched[] = {0xFF, 0x90, 0x88, 0x03, 0x00, 0x00}; + +/** + * Mismatched `getHWRegisters` virtual calls. + * AMDRadeonX6000.kext + */ +static const uint8_t kGetHWRegistersCallOriginal[] = {0x40, 0x80, 0x00, 0xFF, 0x90, 0xD8, 0x02, 0x00, 0x00}; +static const uint8_t kGetHWRegistersCallOriginalMask[] = {0xF0, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const uint8_t kGetHWRegistersCallPatched[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0x00, 0x00, 0x00}; +static const uint8_t kGetHWRegistersCallPatchedMask[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00}; + +/** + * Mismatched `getChannelWriteBackFrameAddr` virtual calls. + * AMDRadeonX6000.kext + */ +static const uint8_t kGetChannelWriteBackFrameAddrCallOriginal[] = {0xFF, 0x90, 0x50, 0x03, 0x00, 0x00, 0x40}; +static const uint8_t kGetChannelWriteBackFrameAddrCallOriginalMask[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0}; +static const uint8_t kGetChannelWriteBackFrameAddrCallPatched[] = {0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00}; +static const uint8_t kGetChannelWriteBackFrameAddrCallPatchedMask[] = {0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00}; + +/** + * Mismatched `getChannelWriteBackFrameOffset` virtual calls. + * AMDRadeonX6000.kext + */ +static const uint8_t kGetChannelWriteBackFrameOffsetCall1Original[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0x48, 0x03, 0x00, + 0x00}; +static const uint8_t kGetChannelWriteBackFrameOffsetCall1Patched[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0x40, 0x03, 0x00, + 0x00}; + +static const uint8_t kGetChannelWriteBackFrameOffsetCall2Original[] = {0x89, 0xDE, 0xFF, 0x90, 0x48, 0x03, 0x00, 0x00}; +static const uint8_t kGetChannelWriteBackFrameOffsetCall2Patched[] = {0x89, 0xDE, 0xFF, 0x90, 0x40, 0x03, 0x00, 0x00}; + +/** + * Mismatched `getHWChannel` virtual calls. + * AMDRadeonX6000.kext + */ +static const uint8_t kGetHWChannelCall1Original[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0x20, 0x03, 0x00, 0x00, 0x48, 0x85, + 0xC0}; +static const uint8_t kGetHWChannelCall1Patched[] = {0x48, 0x8B, 0x07, 0xFF, 0x90, 0x18, 0x03, 0x00, 0x00, 0x48, 0x85, + 0xC0}; + +static const uint8_t kGetHWChannelCall2Original[] = {0x31, 0xD2, 0xFF, 0x90, 0x18, 0x03, 0x00, 0x00}; +static const uint8_t kGetHWChannelCall2Patched[] = {0x31, 0xD2, 0xFF, 0x90, 0x10, 0x03, 0x00, 0x00}; + +static const uint8_t kGetHWChannelCall3Original[] = {0x00, 0x00, 0x00, 0xFF, 0x90, 0x18, 0x03, 0x00, 0x00}; +static const uint8_t kGetHWChannelCall3Patched[] = {0x00, 0x00, 0x00, 0xFF, 0x90, 0x10, 0x03, 0x00, 0x00}; + +/** + * Mismatched `getHWAlignManager` virtual calls. + * AMDRadeonX6000.kext + */ +static const uint8_t kGetHWAlignManagerCall1Original[] = {0x48, 0x80, 0x00, 0xFF, 0x90, 0x00, 0x03, 0x00, 0x00}; +static const uint8_t kGetHWAlignManagerCall1OriginalMask[] = {0xFF, 0xF0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; +static const uint8_t kGetHWAlignManagerCall1Patched[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x02, 0x00, 0x00}; +static const uint8_t kGetHWAlignManagerCall1PatchedMask[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00}; + +static const uint8_t kGetHWAlignManagerCall2Original[] = {0x49, 0x89, 0xD4, 0xFF, 0x90, 0x00, 0x03, 0x00, 0x00}; +static const uint8_t kGetHWAlignManagerCall2Patched[] = {0x49, 0x89, 0xD4, 0xFF, 0x90, 0xF8, 0x02, 0x00, 0x00}; + +/** + * Mismatched `getHWEngine` virtual calls. + * AMDRadeonX6000.kext + */ +static const uint8_t kGetHWEngineCallOriginal[] = {0x00, 0x00, 0x00, 0xFF, 0x90, 0x10, 0x03, 0x00, 0x00}; +static const uint8_t kGetHWEngineCallPatched[] = {0x00, 0x00, 0x00, 0xFF, 0x90, 0x08, 0x03, 0x00, 0x00}; + +/** + * Mismatched `getAMDHWHandler` virtual calls. + * AMDRadeonX6000.kext + */ +static const uint8_t kGetAMDHWHandlerCallOriginal[] = {0xFF, 0x90, 0xD0, 0x02, 0x00, 0x00}; +static const uint8_t kGetAMDHWHandlerCallPatched[] = {0xFF, 0x90, 0xC8, 0x02, 0x00, 0x00}; diff --git a/NootedRed/kern_start.cpp b/NootedRed/kern_start.cpp index 60c26010..0c0e130f 100644 --- a/NootedRed/kern_start.cpp +++ b/NootedRed/kern_start.cpp @@ -24,7 +24,7 @@ PluginConfiguration ADDPR(config) { 1, &bootargBeta, 1, - KernelVersion::BigSur, + KernelVersion::Catalina, KernelVersion::Sonoma, []() { nred.init(); }, }; diff --git a/NootedRed/kern_x5000.cpp b/NootedRed/kern_x5000.cpp index bc732d36..b5e56e88 100644 --- a/NootedRed/kern_x5000.cpp +++ b/NootedRed/kern_x5000.cpp @@ -28,9 +28,12 @@ bool X5000::processKext(KernelPatcher &patcher, size_t id, mach_vm_address_t sli uint32_t *orgChannelTypes = nullptr; mach_vm_address_t startHWEngines = 0; + auto catalina = getKernelVersion() == KernelVersion::Catalina; SolveRequestPlus solveRequests[] = { - {"__ZZN37AMDRadeonX5000_AMDGraphicsAccelerator19createAccelChannelsEbE12channelTypes", orgChannelTypes, - kChannelTypesPattern}, + {catalina ? "__ZZN37AMDRadeonX5000_AMDGraphicsAccelerator22getAdditionalQueueListEPPK18_" + "AMDQueueSpecifierE27additionalQueueList_Default" : + "__ZZN37AMDRadeonX5000_AMDGraphicsAccelerator19createAccelChannelsEbE12channelTypes", + orgChannelTypes, kChannelTypesPattern}, {"__ZN31AMDRadeonX5000_AMDGFX9PM4EngineC1Ev", this->orgGFX9PM4EngineConstructor}, {"__ZN32AMDRadeonX5000_AMDGFX9SDMAEngineC1Ev", this->orgGFX9SDMAEngineConstructor}, {"__ZN39AMDRadeonX5000_AMDAccelSharedUserClient5startEP9IOService", this->orgAccelSharedUCStart}, @@ -39,6 +42,7 @@ bool X5000::processKext(KernelPatcher &patcher, size_t id, mach_vm_address_t sli {"__ZN37AMDRadeonX5000_AMDAccelDisplayMachine10gMetaClassE", NRed::callback->metaClassMap[1][0]}, {"__ZN34AMDRadeonX5000_AMDAccelDisplayPipe10gMetaClassE", NRed::callback->metaClassMap[2][0]}, {"__ZN30AMDRadeonX5000_AMDAccelChannel10gMetaClassE", NRed::callback->metaClassMap[3][1]}, + {"__ZN28AMDRadeonX5000_IAMDHWChannel10gMetaClassE", NRed::callback->metaClassMap[4][0]}, {"__ZN30AMDRadeonX5000_AMDGFX9Hardware32setupAndInitializeHWCapabilitiesEv", this->orgSetupAndInitializeHWCapabilities}, {"__ZN26AMDRadeonX5000_AMDHardware14startHWEnginesEv", startHWEngines}, @@ -60,14 +64,14 @@ bool X5000::processKext(KernelPatcher &patcher, size_t id, mach_vm_address_t sli {"__ZN31AMDRadeonX5000_IAMDSMLInterface18createSMLInterfaceEj", wrapCreateSMLInterface}, {"__ZN26AMDRadeonX5000_AMDHWMemory17adjustVRAMAddressEy", wrapAdjustVRAMAddress, this->orgAdjustVRAMAddress}, - {"__ZN37AMDRadeonX5000_AMDGraphicsAccelerator9newSharedEv", wrapNewShared}, - {"__ZN37AMDRadeonX5000_AMDGraphicsAccelerator19newSharedUserClientEv", wrapNewSharedUserClient}, + {"__ZN37AMDRadeonX5000_AMDGraphicsAccelerator9newSharedEv", wrapNewShared, !catalina}, + {"__ZN37AMDRadeonX5000_AMDGraphicsAccelerator19newSharedUserClientEv", wrapNewSharedUserClient, !catalina}, {"__ZN30AMDRadeonX5000_AMDGFX9Hardware25allocateAMDHWAlignManagerEv", wrapAllocateAMDHWAlignManager, this->orgAllocateAMDHWAlignManager}, {"__ZN43AMDRadeonX5000_AMDVega10GraphicsAccelerator13getDeviceTypeEP11IOPCIDevice", wrapGetDeviceType}, {"__ZN30AMDRadeonX5000_AMDGFX9Hardware20writeASICHangLogInfoEPPv", wrapReturnZero}, {"__ZN37AMDRadeonX5000_AMDGraphicsAccelerator23obtainAccelChannelGroupE11SS_PRIORITY", - wrapObtainAccelChannelGroup, this->orgObtainAccelChannelGroup, !ventura1304}, + wrapObtainAccelChannelGroup, this->orgObtainAccelChannelGroup, !catalina && !ventura1304}, {"__ZN37AMDRadeonX5000_AMDGraphicsAccelerator23obtainAccelChannelGroupE11SS_PRIORITYP27AMDRadeonX5000_" "AMDAccelTask", wrapObtainAccelChannelGroup1304, this->orgObtainAccelChannelGroup, ventura1304}, @@ -76,33 +80,59 @@ bool X5000::processKext(KernelPatcher &patcher, size_t id, mach_vm_address_t sli PANIC_COND(!RouteRequestPlus::routeAll(patcher, id, requests, slide, size), "x5000", "Failed to route symbols"); LookupPatchPlus const addrLibPatch {&kextRadeonX5000, kAddrLibCreateOriginal, kAddrLibCreatePatched, 1, - ventura1304}; + catalina || ventura1304}; PANIC_COND(!addrLibPatch.apply(patcher, slide, size), "x5000", - "Failed to apply Ventura 13.4+ Addr::Lib::Create patch: %d", patcher.getError()); + "Failed to apply Catalina & Ventura 13.4+ Addr::Lib::Create patch: %d", patcher.getError()); LookupPatchPlus const patch {&kextRadeonX5000, kStartHWEnginesOriginal, kStartHWEnginesMask, - kStartHWEnginesPatched, kStartHWEnginesMask, ventura ? 2U : 1}; + kStartHWEnginesPatched, kStartHWEnginesMask, ventura ? 2U : 1, !catalina}; PANIC_COND(!patch.apply(patcher, startHWEngines, PAGE_SIZE), "x5000", "Failed to patch startHWEngines"); - uint32_t findBpp64 = Dcn1Bpp64SwModeMask, replBpp64 = Dcn2Bpp64SwModeMask; - uint32_t findNonBpp64 = Dcn1NonBpp64SwModeMask, replNonBpp64 = Dcn2NonBpp64SwModeMask; - bool dcn2 = NRed::callback->chipType >= ChipType::Renoir; - const LookupPatchPlus swizzleModePatches[] = { - {&kextRadeonX5000, reinterpret_cast(&findBpp64), - reinterpret_cast(&replBpp64), sizeof(uint32_t), ventura1304 ? 2U : 4, dcn2}, - {&kextRadeonX5000, reinterpret_cast(&findNonBpp64), - reinterpret_cast(&replNonBpp64), sizeof(uint32_t), ventura1304 ? 2U : 4, dcn2}, - }; - PANIC_COND(!LookupPatchPlus::applyAll(patcher, swizzleModePatches, slide, size), "x5000", - "Failed to patch swizzle mode"); - - PANIC_COND(MachInfo::setKernelWriting(true, KernelPatcher::kernelWriteLock) != KERN_SUCCESS, "x5000", - "Failed to enable kernel writing"); - orgChannelTypes[5] = 1; // Fix createAccelChannels so that it only starts SDMA0 - orgChannelTypes[(getKernelVersion() >= KernelVersion::Monterey) ? 12 : 11] = - 0; // Fix getPagingChannel so that it gets SDMA0 - MachInfo::setKernelWriting(false, KernelPatcher::kernelWriteLock); - DBGLOG("x5000", "Applied SDMA1 patches"); + LookupPatchPlus const createAccelChannelsPatch {&kextRadeonX5000, kCreateAccelChannelsOriginal, + kCreateAccelChannelsPatched, 2, catalina}; + PANIC_COND(!createAccelChannelsPatch.apply(patcher, slide, size), "x5000", + "Failed to patch createAccelChannels"); + + if (!catalina) { + uint32_t findBpp64 = Dcn1Bpp64SwModeMask, replBpp64 = Dcn2Bpp64SwModeMask; + uint32_t findNonBpp64 = Dcn1NonBpp64SwModeMask, replNonBpp64 = Dcn2NonBpp64SwModeMask; + bool dcn2 = NRed::callback->chipType >= ChipType::Renoir; + const LookupPatchPlus swizzleModePatches[] = { + {&kextRadeonX5000, reinterpret_cast(&findBpp64), + reinterpret_cast(&replBpp64), sizeof(uint32_t), ventura1304 ? 2U : 4, dcn2}, + {&kextRadeonX5000, reinterpret_cast(&findNonBpp64), + reinterpret_cast(&replNonBpp64), sizeof(uint32_t), ventura1304 ? 2U : 4, dcn2}, + }; + PANIC_COND(!LookupPatchPlus::applyAll(patcher, swizzleModePatches, slide, size), "x5000", + "Failed to patch swizzle mode"); + + PANIC_COND(MachInfo::setKernelWriting(true, KernelPatcher::kernelWriteLock) != KERN_SUCCESS, "x5000", + "Failed to enable kernel writing"); + orgChannelTypes[5] = 1; // Fix createAccelChannels so that it only starts SDMA0 + orgChannelTypes[(getKernelVersion() >= KernelVersion::Monterey) ? 12 : 11] = + 0; // Fix getPagingChannel so that it gets SDMA0 + MachInfo::setKernelWriting(false, KernelPatcher::kernelWriteLock); + DBGLOG("x5000", "Applied SDMA1 patches"); + } else { + auto dcn2 = NRed::callback->chipType >= ChipType::Renoir; + uint32_t findNonBpp64 = 0x22222221; + uint32_t replNonBpp64 = dcn2 ? Dcn2NonBpp64SwModeMask : Dcn1NonBpp64SwModeMask; + uint32_t findBpp64 = 0x44444440; + uint32_t replBpp64Pt2 = dcn2 ? Dcn2Bpp64SwModeMask : Dcn1Bpp64SwModeMask; + uint32_t replBpp64 = replNonBpp64 ^ replBpp64Pt2; + uint32_t findBpp64Pt2 = 0x66666661; + LookupPatchPlus const swizzleModePatches[] = { + {&kextRadeonX5000, reinterpret_cast(&findNonBpp64), + reinterpret_cast(&replNonBpp64), sizeof(uint32_t), 2}, + {&kextRadeonX5000, reinterpret_cast(&findBpp64), + reinterpret_cast(&replBpp64), sizeof(uint32_t), 1}, + {&kextRadeonX5000, reinterpret_cast(&findBpp64Pt2), + reinterpret_cast(&replBpp64Pt2), sizeof(uint32_t), 1}, + }; + PANIC_COND(!LookupPatchPlus::applyAll(patcher, swizzleModePatches, slide, size), "x5000", + "Failed to patch swizzle mode"); + *orgChannelTypes = 1; // Make VMPT use SDMA0 instead of SDMA1 + } return true; } @@ -111,33 +141,52 @@ bool X5000::processKext(KernelPatcher &patcher, size_t id, mach_vm_address_t sli } bool X5000::wrapAllocateHWEngines(void *that) { + auto catalina = getKernelVersion() == KernelVersion::Catalina; + auto fieldBase = catalina ? 0x348 : 0x3B8; + auto *pm4 = OSObject::operator new(0x340); callback->orgGFX9PM4EngineConstructor(pm4); - getMember(that, 0x3B8) = pm4; + getMember(that, fieldBase) = pm4; auto *sdma0 = OSObject::operator new(0x250); callback->orgGFX9SDMAEngineConstructor(sdma0); - getMember(that, 0x3C0) = sdma0; + getMember(that, fieldBase + 0x8) = sdma0; auto *vcn0 = OSObject::operator new(0x2D8); X6000::callback->orgVCN2EngineConstructor(vcn0); - getMember(that, 0x3F8) = vcn0; + getMember(that, fieldBase + (catalina ? 0x30 : 0x40)) = vcn0; return true; } -enum HWCapability : uint64_t { - DisplayPipeCount = 0x04, // uint32_t - SECount = 0x34, // uint32_t - SHPerSE = 0x3C, // uint32_t - CUPerSH = 0x70, // uint32_t - HasUVD0 = 0x84, // bool - HasVCE = 0x86, // bool - HasVCN0 = 0x87, // bool +struct HWCapability { + enum : uint64_t { + DisplayPipeCount = 0x04, // uint32_t + SECount = 0x34, // uint32_t + SHPerSE = 0x3C, // uint32_t + CUPerSH = 0x70, // uint32_t + HasUVD0 = 0x84, // bool + HasVCE = 0x86, // bool + HasVCN0 = 0x87, // bool + HasSDMAPagingQueue = 0x98, // bool + }; +}; + +struct HWCapabilityCatalina { + enum : uint64_t { + DisplayPipeCount = 0x04, // uint32_t + SECount = 0x30, // uint32_t + SHPerSE = 0x34, // uint32_t + CUPerSH = 0x58, // uint32_t + HasUVD0 = 0x68, // bool + HasVCE = 0x6A, // bool + HasVCN0 = 0x6B, // bool + HasSDMAPagingQueue = 0x7C, // bool + }; }; template -static inline void setHWCapability(void *that, HWCapability capability, T value) { +static inline void setHWCapability(void *that, uint64_t capability, T value) { getMember(that, (getKernelVersion() >= KernelVersion::Ventura ? 0x30 : 0x28) + capability) = value; } @@ -149,16 +198,22 @@ void X5000::wrapSetupAndInitializeHWCapabilities(void *that) { auto *header = reinterpret_cast(fwDesc.data); auto *gpuInfo = reinterpret_cast(fwDesc.data + header->ucodeOff); - setHWCapability(that, HWCapability::SECount, gpuInfo->gcNumSe); - setHWCapability(that, HWCapability::SHPerSE, gpuInfo->gcNumShPerSe); - setHWCapability(that, HWCapability::CUPerSH, gpuInfo->gcNumCuPerSh); + auto catalina = getKernelVersion() == KernelVersion::Catalina; + setHWCapability(that, catalina ? HWCapabilityCatalina::SECount : HWCapability::SECount, gpuInfo->gcNumSe); + setHWCapability(that, catalina ? HWCapabilityCatalina::SHPerSE : HWCapability::SHPerSE, + gpuInfo->gcNumShPerSe); + setHWCapability(that, catalina ? HWCapabilityCatalina::CUPerSH : HWCapability::CUPerSH, + gpuInfo->gcNumCuPerSh); FunctionCast(wrapSetupAndInitializeHWCapabilities, callback->orgSetupAndInitializeHWCapabilities)(that); - setHWCapability(that, HWCapability::DisplayPipeCount, isRavenDerivative ? 4 : 6); - setHWCapability(that, HWCapability::HasUVD0, false); - setHWCapability(that, HWCapability::HasVCE, false); - setHWCapability(that, HWCapability::HasVCN0, true); + setHWCapability(that, catalina ? HWCapabilityCatalina::DisplayPipeCount : HWCapability::DisplayPipeCount, + isRavenDerivative ? 4 : 6); + setHWCapability(that, catalina ? HWCapabilityCatalina::HasUVD0 : HWCapability::HasUVD0, false); + setHWCapability(that, catalina ? HWCapabilityCatalina::HasVCE : HWCapability::HasVCE, false); + setHWCapability(that, catalina ? HWCapabilityCatalina::HasVCN0 : HWCapability::HasVCN0, true); + setHWCapability(that, catalina ? HWCapabilityCatalina::HasSDMAPagingQueue : HWCapability::HasSDMAPagingQueue, + false); } void *X5000::wrapGetHWChannel(void *that, uint32_t engineType, uint32_t ringId) { @@ -166,7 +221,9 @@ void *X5000::wrapGetHWChannel(void *that, uint32_t engineType, uint32_t ringId) return FunctionCast(wrapGetHWChannel, callback->orgGetHWChannel)(that, (engineType == 2) ? 1 : engineType, ringId); } -void X5000::wrapInitializeFamilyType(void *that) { getMember(that, 0x308) = AMDGPU_FAMILY_RAVEN; } +void X5000::wrapInitializeFamilyType(void *that) { + getMember(that, getKernelVersion() == KernelVersion::Catalina ? 0x2B4 : 0x308) = AMDGPU_FAMILY_RAVEN; +} void *X5000::wrapAllocateAMDHWDisplay(void *that) { return FunctionCast(wrapAllocateAMDHWDisplay, X6000::callback->orgAllocateAMDHWDisplay)(that); @@ -228,7 +285,7 @@ void *X5000::wrapObtainAccelChannelGroup1304(void *that, uint32_t priority, void } uint32_t X5000::wrapHwlConvertChipFamily(void *that, uint32_t, uint32_t) { - auto &settings = getMember(that, 0x5B10); + auto &settings = getMember(that, getKernelVersion() == KernelVersion::Catalina ? 0x5B18 : 0x5B10); bool renoir = NRed::callback->chipType >= ChipType::Renoir; settings.isArcticIsland = 1; settings.isRaven = 1; diff --git a/NootedRed/kern_x6000.cpp b/NootedRed/kern_x6000.cpp index 62114ac0..39917b61 100644 --- a/NootedRed/kern_x6000.cpp +++ b/NootedRed/kern_x6000.cpp @@ -24,31 +24,35 @@ bool X6000::processKext(KernelPatcher &patcher, size_t id, mach_vm_address_t sli if (kextRadeonX6000.loadIndex == id) { NRed::callback->setRMMIOIfNecessary(); - KernelPatcher::SolveRequest solveRequests[] = { + auto catalina = getKernelVersion() == KernelVersion::Catalina; + SolveRequestPlus solveRequests[] = { {"__ZN30AMDRadeonX6000_AMDVCN2HWEngineC1Ev", this->orgVCN2EngineConstructor}, {"__ZN31AMDRadeonX6000_AMDGFX10Hardware20allocateAMDHWDisplayEv", this->orgAllocateAMDHWDisplay}, {"__ZN42AMDRadeonX6000_AMDGFX10GraphicsAccelerator15newVideoContextEv", this->orgNewVideoContext}, {"__ZN31AMDRadeonX6000_IAMDSMLInterface18createSMLInterfaceEj", this->orgCreateSMLInterface}, - {"__ZN37AMDRadeonX6000_AMDGraphicsAccelerator9newSharedEv", this->orgNewShared}, - {"__ZN37AMDRadeonX6000_AMDGraphicsAccelerator19newSharedUserClientEv", this->orgNewSharedUserClient}, + {"__ZN37AMDRadeonX6000_AMDGraphicsAccelerator9newSharedEv", this->orgNewShared, !catalina}, + {"__ZN37AMDRadeonX6000_AMDGraphicsAccelerator19newSharedUserClientEv", this->orgNewSharedUserClient, + !catalina}, {"__ZN35AMDRadeonX6000_AMDAccelVideoContext10gMetaClassE", NRed::callback->metaClassMap[0][1]}, {"__ZN37AMDRadeonX6000_AMDAccelDisplayMachine10gMetaClassE", NRed::callback->metaClassMap[1][1]}, {"__ZN34AMDRadeonX6000_AMDAccelDisplayPipe10gMetaClassE", NRed::callback->metaClassMap[2][1]}, {"__ZN30AMDRadeonX6000_AMDAccelChannel10gMetaClassE", NRed::callback->metaClassMap[3][0]}, + {"__ZN28AMDRadeonX6000_IAMDHWChannel10gMetaClassE", NRed::callback->metaClassMap[4][1]}, {"__ZN33AMDRadeonX6000_AMDHWAlignManager224getPreferredSwizzleMode2EP33_ADDR2_COMPUTE_SURFACE_INFO_INPUT", this->orgGetPreferredSwizzleMode2}, }; - PANIC_COND(!patcher.solveMultiple(id, solveRequests, slide, size), "x6000", "Failed to resolve symbols"); + PANIC_COND(!SolveRequestPlus::solveAll(patcher, id, solveRequests, slide, size), "x6000", + "Failed to resolve symbols"); auto ventura = getKernelVersion() >= KernelVersion::Ventura; RouteRequestPlus requests[] = { {"__ZN37AMDRadeonX6000_AMDGraphicsAccelerator5startEP9IOService", wrapAccelStartX6000}, - {"__ZN39AMDRadeonX6000_AMDAccelSharedUserClient5startEP9IOService", wrapAccelSharedUCStartX6000}, - {"__ZN39AMDRadeonX6000_AMDAccelSharedUserClient4stopEP9IOService", wrapAccelSharedUCStopX6000}, + {"__ZN39AMDRadeonX6000_AMDAccelSharedUserClient5startEP9IOService", wrapAccelSharedUCStartX6000, !catalina}, + {"__ZN39AMDRadeonX6000_AMDAccelSharedUserClient4stopEP9IOService", wrapAccelSharedUCStopX6000, !catalina}, {"__ZN30AMDRadeonX6000_AMDGFX10Display23initDCNRegistersOffsetsEv", wrapInitDCNRegistersOffsets, this->orgInitDCNRegistersOffsets, NRed::callback->chipType < ChipType::Renoir}, {"__ZN29AMDRadeonX6000_AMDAccelShared11SurfaceCopyEPjyP12IOAccelEvent", wrapAccelSharedSurfaceCopy, - this->orgAccelSharedSurfaceCopy}, + this->orgAccelSharedSurfaceCopy, !catalina}, {"__ZN27AMDRadeonX6000_AMDHWDisplay17allocateScanoutFBEjP16IOAccelResource2S1_Py", wrapAllocateScanoutFB, this->orgAllocateScanoutFB, !ventura}, {"__ZN27AMDRadeonX6000_AMDHWDisplay14fillUBMSurfaceEjP17_FRAMEBUFFER_INFOP13_UBM_SURFINFO", @@ -61,19 +65,72 @@ bool X6000::processKext(KernelPatcher &patcher, size_t id, mach_vm_address_t sli PANIC_COND(!RouteRequestPlus::routeAll(patcher, id, requests, slide, size), "x6000", "Failed to route symbols"); auto monterey = getKernelVersion() == KernelVersion::Monterey; - const LookupPatchPlus patches[] = { - {&kextRadeonX6000, kHWChannelSubmitCommandBufferOriginal, kHWChannelSubmitCommandBufferPatched, 1}, + LookupPatchPlus const patches[] = { + {&kextRadeonX6000, kHWChannelSubmitCommandBufferCatalinaOriginal, + kHWChannelSubmitCommandBufferCatalinaPatched, 1, catalina}, + {&kextRadeonX6000, kHWChannelSubmitCommandBufferOriginal, kHWChannelSubmitCommandBufferPatched, 1, + !catalina}, + {&kextRadeonX6000, kDummyWPTRUpdateDiagCallOriginal, kDummyWPTRUpdateDiagCallPatched, 1, catalina}, {&kextRadeonX6000, kIsDeviceValidCallOriginal, kIsDeviceValidCallPatched, - ventura ? 23U : + catalina ? 20U : + ventura ? 23 : monterey ? 26 : 24}, - {&kextRadeonX6000, kIsDevicePCITunnelledCallOriginal, kIsDevicePCITunnelledCallPatched, ventura ? 3U : 1}, + {&kextRadeonX6000, kIsDevicePCITunnelledCallOriginal, kIsDevicePCITunnelledCallPatched, + catalina ? 9U : + ventura ? 3 : + 1}, + {&kextRadeonX6000, kWriteWaitForRenderingPipeCallOriginal, kWriteWaitForRenderingPipeCallPatched, 1, + catalina}, + {&kextRadeonX6000, kGetTtlInterfaceCallOriginal, kGetTtlInterfaceCallOriginalMask, + kGetTtlInterfaceCallPatched, kGetTtlInterfaceCallPatchedMask, 38, catalina}, + {&kextRadeonX6000, kGetAMDHWHandlerCallOriginal, kGetAMDHWHandlerCallPatched, 19, catalina}, + {&kextRadeonX6000, kGetAMDHWHandlerCallOriginal, kGetAMDHWHandlerCallPatched, 64, catalina, 1}, + {&kextRadeonX6000, kGetHWRegistersCallOriginal, kGetHWRegistersCallOriginalMask, kGetHWRegistersCallPatched, + kGetHWRegistersCallPatchedMask, 13, catalina}, + {&kextRadeonX6000, kGetHWMemoryCallOriginal, kGetHWMemoryCallPatched, 11, catalina}, + {&kextRadeonX6000, kGetHWGartCallOriginal, kGetHWGartCallPatched, 9, catalina}, + {&kextRadeonX6000, kGetHWAlignManagerCall1Original, kGetHWAlignManagerCall1OriginalMask, + kGetHWAlignManagerCall1Patched, kGetHWAlignManagerCall1PatchedMask, 33, catalina}, + {&kextRadeonX6000, kGetHWAlignManagerCall2Original, kGetHWAlignManagerCall2Patched, 1, catalina}, + {&kextRadeonX6000, kGetHWEngineCallOriginal, kGetHWEngineCallPatched, 31, catalina}, + {&kextRadeonX6000, kGetHWChannelCall1Original, kGetHWChannelCall1Patched, 2, catalina}, + {&kextRadeonX6000, kGetHWChannelCall2Original, kGetHWChannelCall2Patched, 53, catalina}, + {&kextRadeonX6000, kGetHWChannelCall3Original, kGetHWChannelCall3Patched, 20, catalina}, + {&kextRadeonX6000, kRegisterChannelCallOriginal, kRegisterChannelCallPatched, 1, catalina}, + {&kextRadeonX6000, kGetChannelCountCallOriginal, kGetChannelCountCallPatched, 7, catalina}, + {&kextRadeonX6000, kGetChannelWriteBackFrameOffsetCall1Original, + kGetChannelWriteBackFrameOffsetCall1Patched, 4, catalina}, + {&kextRadeonX6000, kGetChannelWriteBackFrameOffsetCall2Original, + kGetChannelWriteBackFrameOffsetCall2Patched, 1, catalina}, + {&kextRadeonX6000, kGetChannelWriteBackFrameAddrCallOriginal, kGetChannelWriteBackFrameAddrCallOriginalMask, + kGetChannelWriteBackFrameAddrCallPatched, kGetChannelWriteBackFrameAddrCallPatchedMask, 10, catalina}, + {&kextRadeonX6000, kGetDoorbellMemoryBaseAddressCallOriginal, kGetDoorbellMemoryBaseAddressCallPatched, 1, + catalina}, + {&kextRadeonX6000, kGetChannelDoorbellOffsetCallOriginal, kGetChannelDoorbellOffsetCallPatched, 1, + catalina}, + {&kextRadeonX6000, kGetIOPCIDeviceCallOriginal, kGetIOPCIDeviceCallPatched, 5, catalina}, + {&kextRadeonX6000, kGetSMLCallOriginal, kGetSMLCallPatched, 10, catalina}, + {&kextRadeonX6000, kGetPM4CommandUtilityCallOriginal, kGetPM4CommandUtilityCallPatched, 2, catalina}, + {&kextRadeonX6000, kDumpASICHangStateCallOriginal, kDumpASICHangStateCallPatched, 2, catalina}, {&kextRadeonX6000, kGetSchedulerCallVenturaOriginal, kGetSchedulerCallVenturaPatched, 24, ventura}, - {&kextRadeonX6000, kGetSchedulerCallOriginal, kGetSchedulerCallPatched, monterey ? 21U : 22, !ventura}, + {&kextRadeonX6000, kGetSchedulerCallOriginal, kGetSchedulerCallPatched, monterey ? 21U : 22, + !catalina && !ventura}, + {&kextRadeonX6000, kGetSchedulerCallCatalinaOriginal, kGetSchedulerCallCatalinaPatched, 22, catalina}, {&kextRadeonX6000, kGetGpuDebugPolicyCallOriginal, kGetGpuDebugPolicyCallPatched, (getKernelVersion() == KernelVersion::Ventura && getKernelMinorVersion() >= 5) ? 38U : ventura ? 37 : - 28}, + 28, + !catalina}, + {&kextRadeonX6000, kGetGpuDebugPolicyCallCatalinaOriginal, kGetGpuDebugPolicyCallCatalinaPatched, 27, + catalina}, + {&kextRadeonX6000, kUpdateUtilizationStatisticsCounterCallOriginal, + kUpdateUtilizationStatisticsCounterCallPatched, 2, catalina}, + {&kextRadeonX6000, kDisableGfxOffCallOriginal, kDisableGfxOffCallPatched, 17, catalina}, + {&kextRadeonX6000, kEnableGfxOffCallOriginal, kEnableGfxOffCallPatched, 16, catalina}, + {&kextRadeonX6000, kFlushSystemCachesCallOriginal, kFlushSystemCachesCallPatched, 4, catalina}, + {&kextRadeonX6000, kGetUbmSwizzleModeCallOriginal, kGetUbmSwizzleModeCallPatched, 1, catalina}, + {&kextRadeonX6000, kGetUbmTileModeCallOriginal, kGetUbmTileModeCallPatched, 1, catalina}, }; SYSLOG_COND(!LookupPatchPlus::applyAll(patcher, patches, slide, size), "x6000", "Failed to apply patches: %d", patcher.getError()); @@ -101,7 +158,9 @@ bool X6000::wrapAccelSharedUCStopX6000(void *that, void *provider) { void X6000::wrapInitDCNRegistersOffsets(void *that) { FunctionCast(wrapInitDCNRegistersOffsets, callback->orgInitDCNRegistersOffsets)(that); - auto fieldBase = getKernelVersion() > KernelVersion::Monterey ? 0x590 : 0x4830; + auto fieldBase = getKernelVersion() == KernelVersion::Catalina ? 0x4838 : + getKernelVersion() > KernelVersion::Monterey ? 0x590 : + 0x4830; auto base = getMember(that, fieldBase); getMember(that, fieldBase + 0x10) = base + mmHUBPREQ0_DCSURF_PRIMARY_SURFACE_ADDRESS; getMember(that, fieldBase + 0x48) = base + mmHUBPREQ1_DCSURF_PRIMARY_SURFACE_ADDRESS; diff --git a/NootedRed/kern_x6000fb.cpp b/NootedRed/kern_x6000fb.cpp index 55406bcd..3721721f 100644 --- a/NootedRed/kern_x6000fb.cpp +++ b/NootedRed/kern_x6000fb.cpp @@ -28,9 +28,10 @@ bool X6000FB::processKext(KernelPatcher &patcher, size_t id, mach_vm_address_t s CAILAsicCapsEntry *orgAsicCapsTable = nullptr; auto ventura = getKernelVersion() >= KernelVersion::Ventura; + auto catalina = getKernelVersion() == KernelVersion::Catalina; SolveRequestPlus solveRequests[] = { {"__ZL20CAIL_ASIC_CAPS_TABLE", orgAsicCapsTable, kCailAsicCapsTablePattern}, - {"_dce_driver_set_backlight", this->orgDceDriverSetBacklight, kDceDriverSetBacklight}, + {"_dce_driver_set_backlight", this->orgDceDriverSetBacklight, kDceDriverSetBacklight, !catalina}, {"__ZNK34AMDRadeonX6000_AmdRadeonController18messageAcceleratorE25_eAMDAccelIOFBRequestTypePvS1_S1_", this->orgMessageAccelerator, ventura}, }; @@ -45,12 +46,12 @@ bool X6000FB::processKext(KernelPatcher &patcher, size_t id, mach_vm_address_t s {"__ZN24AMDRadeonX6000_AmdLogger15initWithPciInfoEP11IOPCIDevice", wrapInitWithPciInfo, this->orgInitWithPciInfo, ADDPR(debugEnabled)}, {"__ZN34AMDRadeonX6000_AmdRadeonController10doGPUPanicEPKcz", wrapDoGPUPanic, ADDPR(debugEnabled)}, - {"_dce_panel_cntl_hw_init", wrapDcePanelCntlHwInit, this->orgDcePanelCntlHwInit, - kDcePanelCntlHwInitPattern}, + {"_dce_panel_cntl_hw_init", wrapDcePanelCntlHwInit, this->orgDcePanelCntlHwInit, kDcePanelCntlHwInitPattern, + !catalina}, {"__ZN35AMDRadeonX6000_AmdRadeonFramebuffer25setAttributeForConnectionEijm", wrapFramebufferSetAttribute, - this->orgFramebufferSetAttribute}, + this->orgFramebufferSetAttribute, !catalina}, {"__ZN35AMDRadeonX6000_AmdRadeonFramebuffer25getAttributeForConnectionEijPm", wrapFramebufferGetAttribute, - this->orgFramebufferGetAttribute}, + this->orgFramebufferGetAttribute, !catalina}, {"__ZNK22AmdAtomObjectInfo_V1_421getNumberOfConnectorsEv", wrapGetNumberOfConnectors, this->orgGetNumberOfConnectors, kGetNumberOfConnectorsPattern, kGetNumberOfConnectorsMask}, {"_IH_4_0_IVRing_InitHardware", wrapIH40IVRingInitHardware, this->orgIH40IVRingInitHardware, @@ -64,12 +65,17 @@ bool X6000FB::processKext(KernelPatcher &patcher, size_t id, mach_vm_address_t s PANIC_COND(!RouteRequestPlus::routeAll(patcher, id, requests, slide, size), "x6000fb", "Failed to route symbols"); - const LookupPatchPlus patches[] = { - {&kextRadeonX6000Framebuffer, kPopulateDeviceInfoOriginal, kPopulateDeviceInfoPatched, 1}, - {&kextRadeonX6000Framebuffer, kAmdAtomVramInfoNullCheckOriginal, kAmdAtomVramInfoNullCheckPatched, 1}, + LookupPatchPlus const patches[] = { + {&kextRadeonX6000Framebuffer, kPopulateDeviceInfoOriginal, kPopulateDeviceInfoMask, + kPopulateDeviceInfoPatched, kPopulateDeviceInfoMask, 1}, + {&kextRadeonX6000Framebuffer, kAmdAtomVramInfoNullCheckOriginal, kAmdAtomVramInfoNullCheckPatched, 1, + !catalina}, + {&kextRadeonX6000Framebuffer, kAmdAtomVramInfoNullCheckCatalinaOriginal, + kAmdAtomVramInfoNullCheckCatalinaMask, kAmdAtomVramInfoNullCheckCatalinaPatched, 1, catalina}, {&kextRadeonX6000Framebuffer, kAmdAtomPspDirectoryNullCheckOriginal, kAmdAtomPspDirectoryNullCheckPatched, - 1}, - {&kextRadeonX6000Framebuffer, kGetFirmwareInfoNullCheckOriginal, kGetFirmwareInfoNullCheckPatched, 1}, + 1, !catalina}, + {&kextRadeonX6000Framebuffer, kGetFirmwareInfoNullCheckOriginal, kGetFirmwareInfoNullCheckOriginalMask, + kGetFirmwareInfoNullCheckPatched, kGetFirmwareInfoNullCheckPatchedMask, 1}, {&kextRadeonX6000Framebuffer, kAgdcServicesGetVendorInfoOriginal, kAgdcServicesGetVendorInfoMask, kAgdcServicesGetVendorInfoPatched, kAgdcServicesGetVendorInfoMask, 1}, {&kextRadeonX6000Framebuffer, kControllerPowerUpOriginal, kControllerPowerUpOriginalMask,