diff --git a/NootedRed/kern_hwlibs.cpp b/NootedRed/kern_hwlibs.cpp index 6d97c0f8..dc1313d4 100644 --- a/NootedRed/kern_hwlibs.cpp +++ b/NootedRed/kern_hwlibs.cpp @@ -50,16 +50,31 @@ bool X5000HWLibs::processKext(KernelPatcher &patcher, size_t id, mach_vm_address PANIC_COND(!SolveRequestPlus::solveAll(patcher, id, solveRequests, slide, size), "hwlibs", "Failed to resolve symbols"); + bool ventura = getKernelVersion() >= KernelVersion::Ventura; + bool renoir = NRed::callback->chipType >= ChipType::Renoir; if (catalina) { RouteRequestPlus request {"__ZN16AmdTtlFwServices7getIpFwEjPKcP10_TtlFwInfo", wrapGetIpFw, this->orgGetIpFw}; PANIC_COND(!request.route(patcher, id, slide, size), "hwlibs", "Failed to route symbols"); } else { - RouteRequestPlus request {"__ZN35AMDRadeonX5000_AMDRadeonHWLibsX500025populateFirmwareDirectoryEv", - wrapPopulateFirmwareDirectory, this->orgPopulateFirmwareDirectory}; + RouteRequestPlus requests[] = { + {"__ZN35AMDRadeonX5000_AMDRadeonHWLibsX500025populateFirmwareDirectoryEv", + wrapPopulateFirmwareDirectory, this->orgPopulateFirmwareDirectory}, + {"_psp_bootloader_is_sos_running_3_1", hwLibsGeneralFailure, kPspBootloaderIsSosRunning31Pattern}, + {"_psp_bootloader_load_sysdrv_3_1", hwLibsNoop, kPspBootloaderLoadSysdrv31Pattern, + kPspBootloaderLoadSysdrv31Mask}, + {"_psp_bootloader_set_ecc_mode_3_1", hwLibsNoop, kPspBootloaderSetEccMode31Pattern}, + {"_psp_reset_3_1", hwLibsUnsupported, kPspReset31Pattern}, + {"_psp_bootloader_load_sos_3_1", pspBootloaderLoadSos10, kPspBootloaderLoadSos31Pattern, + kPspBootloaderLoadSos31Mask}, + {"_psp_security_feature_caps_set_3_1", + renoir ? pspSecurityFeatureCapsSet12 : pspSecurityFeatureCapsSet10, + ventura ? kPspSecurityFeatureCapsSet31VenturaPattern : kPspSecurityFeatureCapsSet31Pattern}, + }; - PANIC_COND(!request.route(patcher, id, slide, size), "hwlibs", "Failed to route symbols"); + PANIC_COND(!RouteRequestPlus::routeAll(patcher, id, requests, slide, size), "hwlibs", + "Failed to route symbols"); } RouteRequestPlus requests[] = { @@ -79,7 +94,7 @@ bool X5000HWLibs::processKext(KernelPatcher &patcher, size_t id, mach_vm_address "Failed to enable kernel writing"); if (orgDeviceTypeTable) { *orgDeviceTypeTable = {.deviceId = NRed::callback->deviceId, .deviceType = 6}; } - auto targetDeviceId = NRed::callback->chipType >= ChipType::Renoir ? 0x1636 : NRed::callback->deviceId; + auto targetDeviceId = renoir ? 0x1636 : NRed::callback->deviceId; for (; orgCapsInitTable->deviceId != 0xFFFFFFFF; orgCapsInitTable++) { if (orgCapsInitTable->familyId == AMDGPU_FAMILY_RAVEN && orgCapsInitTable->deviceId == targetDeviceId) { orgCapsInitTable->deviceId = NRed::callback->deviceId; @@ -146,7 +161,7 @@ bool X5000HWLibs::processKext(KernelPatcher &patcher, size_t id, mach_vm_address }; PANIC_COND(!LookupPatchPlus::applyAll(patcher, patches, slide, size), "hwlibs", "Failed to apply patches"); - if (getKernelVersion() >= KernelVersion::Ventura) { + if (ventura) { const LookupPatchPlus patches[] = { {&kextRadeonX5000HWLibs, kCailQueryAdapterInfoOriginal, kCailQueryAdapterInfoPatched, 1}, {&kextRadeonX5000HWLibs, kSDMAInitFunctionPointerListOriginal, kSDMAInitFunctionPointerListPatched, 1}, @@ -187,8 +202,87 @@ bool X5000HWLibs::wrapGetIpFw(void *that, uint32_t ipVersion, char *name, void * return FunctionCast(wrapGetIpFw, callback->orgGetIpFw)(that, ipVersion, name, out); } +CAILResult X5000HWLibs::hwLibsGeneralFailure() { return kCAILResultGeneralFailure; } +CAILResult X5000HWLibs::hwLibsUnsupported() { return kCAILResultUnsupported; } CAILResult X5000HWLibs::hwLibsNoop() { return kCAILResultSuccess; } +CAILResult X5000HWLibs::pspBootloaderLoadSos10(void *psp) { + size_t fieldBase = 0; + switch (getKernelVersion()) { + case KernelVersion::Catalina: + UNREACHABLE(); + case KernelVersion::BigSur: + [[fallthrough]]; + case KernelVersion::Monterey: + fieldBase = 0x3124; + break; + default: + fieldBase = 0x391C; + break; + } + getMember(psp, fieldBase) = NRed::callback->readReg32(MP_BASE + 0x7B); + getMember(psp, fieldBase + 0x4) = NRed::callback->readReg32(MP_BASE + 0x7A); + getMember(psp, fieldBase + 0x8) = NRed::callback->readReg32(MP_BASE + 0x7A); + return kCAILResultSuccess; +} + +CAILResult X5000HWLibs::pspSecurityFeatureCapsSet10(void *psp) { + size_t fieldBase = 0; + switch (getKernelVersion()) { + case KernelVersion::Catalina: + UNREACHABLE(); + case KernelVersion::BigSur: + [[fallthrough]]; + case KernelVersion::Monterey: + fieldBase = 0x3120; + break; + default: + fieldBase = 0x3918; + break; + } + auto &securityCaps = getMember(psp, fieldBase); + securityCaps &= ~static_cast(1); + auto &tOSVer = getMember(psp, fieldBase + 0x8); + if ((tOSVer & 0xFFFF0000) == 0x80000 && (tOSVer & 0xFF) > 0x50) { + auto policyVer = NRed::callback->readReg32(MP_BASE + 0x9B); + SYSLOG_COND((policyVer & 0xFF000000) != 0x0A000000, "hwlibs", "Invalid security policy version: 0x%X", + policyVer); + if (policyVer == 0xA02031A || ((policyVer & 0xFFFFFF00) == 0xA020400 && (policyVer & 0xFC) > 0x23) || + ((policyVer & 0xFFFFFF00) == 0xA020300 && (policyVer & 0xFE) > 0x1D)) { + securityCaps |= 1; + } + } + + return kCAILResultSuccess; +} + +CAILResult X5000HWLibs::pspSecurityFeatureCapsSet12(void *psp) { + size_t fieldBase = 0; + switch (getKernelVersion()) { + case KernelVersion::Catalina: + UNREACHABLE(); + case KernelVersion::BigSur: + [[fallthrough]]; + case KernelVersion::Monterey: + fieldBase = 0x3120; + break; + default: + fieldBase = 0x3918; + break; + } + auto &securityCaps = getMember(psp, fieldBase); + securityCaps &= ~static_cast(1); + auto &tOSVer = getMember(psp, fieldBase + 0x8); + if ((tOSVer & 0xFFFF0000) == 0x110000 && (tOSVer & 0xFF) > 0x2A) { + auto policyVer = NRed::callback->readReg32(MP_BASE + 0x9B); + SYSLOG_COND((policyVer & 0xFF000000) != 0xB000000, "hwlibs", "Invalid security policy version: 0x%X", + policyVer); + if ((policyVer & 0xFFFF0000) == 0xB090000 && (policyVer & 0xFE) > 0x35) { securityCaps |= 1; } + } + + return kCAILResultSuccess; +} + void X5000HWLibs::wrapUpdateSdmaPowerGating(void *cail, uint32_t mode) { FunctionCast(wrapUpdateSdmaPowerGating, callback->orgUpdateSdmaPowerGating)(cail, mode); switch (mode) { diff --git a/NootedRed/kern_hwlibs.hpp b/NootedRed/kern_hwlibs.hpp index 8ead8644..727b7835 100644 --- a/NootedRed/kern_hwlibs.hpp +++ b/NootedRed/kern_hwlibs.hpp @@ -25,7 +25,12 @@ class X5000HWLibs { static void wrapPopulateFirmwareDirectory(void *that); static bool wrapGetIpFw(void *that, uint32_t param1, char *name, void *out); + static CAILResult hwLibsGeneralFailure(); + static CAILResult hwLibsUnsupported(); static CAILResult hwLibsNoop(); + static CAILResult pspBootloaderLoadSos10(void *psp); + static CAILResult pspSecurityFeatureCapsSet10(void *psp); + static CAILResult pspSecurityFeatureCapsSet12(void *psp); static void wrapUpdateSdmaPowerGating(void *cail, uint32_t mode); static CAILResult wrapPspCmdKmSubmit(void *psp, void *ctx, void *param3, void *param4); }; diff --git a/NootedRed/kern_patterns.hpp b/NootedRed/kern_patterns.hpp index d721c1e5..4cbdc24d 100644 --- a/NootedRed/kern_patterns.hpp +++ b/NootedRed/kern_patterns.hpp @@ -99,6 +99,42 @@ static const uint8_t kDeviceCapabilityTblPattern[] = {0x82, 0x00, 0x00, 0x00, 0x 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xCA, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xCA, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00}; +static const uint8_t kPspReset31Pattern[] = {0x55, 0x48, 0x89, 0xE5, 0x53, 0x48, 0x83, 0xEC, 0x28, 0x31, 0xC0, 0x48, + 0x89, 0x45, 0xF0, 0x48, 0x89, 0x45, 0xE8, 0x48, 0x89, 0x45, 0xE0, 0x48, 0x89, 0x45, 0xD8, 0xB8, 0x01, 0x00, 0x00, + 0x00, 0x48, 0x85, 0xFF}; + +static const uint8_t kPspBootloaderLoadSysdrv31Pattern[] = {0x55, 0x48, 0x89, 0xE5, 0x41, 0x57, 0x41, 0x56, 0x41, 0x55, + 0x41, 0x54, 0x53, 0x48, 0x83, 0xEC, 0x28, 0x49, 0x89, 0xFC, 0x31, 0xDB, 0x48, 0x89, 0x5D, 0xD0, 0x48, 0x89, 0x5D, + 0xC8, 0x48, 0x89, 0x5D, 0xC0, 0x48, 0x89, 0x5D, 0xB8, 0x4C, 0x8B, 0xB7, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x8B, 0xBF, + 0x00, 0x00, 0x00, 0x00, 0xBE, 0x91, 0x00, 0x00, 0x00}; +static const uint8_t kPspBootloaderLoadSysdrv31Mask[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + +static const uint8_t kPspBootloaderSetEccMode31Pattern[] = {0x55, 0x48, 0x89, 0xE5, 0x41, 0x57, 0x41, 0x56, 0x41, 0x54, + 0x53, 0x48, 0x83, 0xEC, 0x20, 0x41, 0x89, 0xF7, 0x49, 0x89, 0xFE, 0x31, 0xDB, 0x48, 0x89, 0x5D, 0xD8, 0x48, 0x89, + 0x5D, 0xD0, 0x48, 0x89, 0x5D, 0xC8, 0x48, 0x89, 0x5D, 0xC0, 0xBE, 0xA4, 0x00, 0x00, 0x00, 0x31, 0xD2, 0xB9, 0x4B, + 0x00, 0x00, 0x00}; + +static const uint8_t kPspBootloaderIsSosRunning31Pattern[] = {0x55, 0x48, 0x89, 0xE5, 0xBE, 0x91, 0x00, 0x00, 0x00, + 0x31, 0xD2, 0xB9, 0x4B, 0x00, 0x00, 0x00}; + +static const uint8_t kPspBootloaderLoadSos31Pattern[] = {0x55, 0x48, 0x89, 0xE5, 0x41, 0x57, 0x41, 0x56, 0x41, 0x54, + 0x53, 0x48, 0x83, 0xEC, 0x20, 0x49, 0x89, 0xFF, 0x31, 0xDB, 0x48, 0x89, 0x5D, 0xD8, 0x48, 0x89, 0x5D, 0xD0, 0x48, + 0x89, 0x5D, 0xC8, 0x48, 0x89, 0x5D, 0xC0, 0x4C, 0x8B, 0xB7, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x8B, 0xA7, 0x00, 0x00, + 0x00, 0x00, 0xBE, 0x91, 0x00, 0x00, 0x00}; +static const uint8_t kPspBootloaderLoadSos31Mask[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; + +static const uint8_t kPspSecurityFeatureCapsSet31Pattern[] = {0x55, 0x48, 0x89, 0xE5, 0x80, 0xA7, 0x20, 0x31, 0x00, + 0x00}; + +static const uint8_t kPspSecurityFeatureCapsSet31VenturaPattern[] = {0x55, 0x48, 0x89, 0xE5, 0x8B, 0x87, 0x18, 0x39, + 0x00, 0x00}; + /** * `__ZZN37AMDRadeonX5000_AMDGraphicsAccelerator19createAccelChannelsEbE12channelTypes` * AMDRadeonX5000.kext