use hooking for erista mrf

This commit is contained in:
Lightos1 committed 2026-07-27 14:58:14 +02:00
1 parent 3d5dbf77ea
commit 0befcd2d75
2 files changed
+24 -25

No files matched your search

@@ -24,6 +24,7 @@
#include "pcv_common.hpp" #include "pcv_common.hpp"
#include "pcv_erista.hpp" #include "pcv_erista.hpp"
#include "pcv_mariko.hpp" #include "pcv_mariko.hpp"
#include "pcv_hook.hpp"
namespace ams::ldr::hoc::pcv { namespace ams::ldr::hoc::pcv {
@@ -43,6 +43,7 @@ namespace ams::ldr::hoc::pcv::erista {
struct { struct {
u32 *getEristaMtcTableFnSite = nullptr; u32 *getEristaMtcTableFnSite = nullptr;
EristaMtcTable *mtcTable = nullptr; EristaMtcTable *mtcTable = nullptr;
bool foundMtcTablePattern = false;
} getMtcTableCache; } getMtcTableCache;
} }
@@ -638,49 +639,46 @@ namespace ams::ldr::hoc::pcv::erista {
return data->mtcTableAsm.mtcTable; return data->mtcTableAsm.mtcTable;
} }
bool foundMtcTablePattern = false;
Result MemMtcTableAsm(u32 *ptr) { Result MemMtcTableAsm(u32 *ptr) {
R_UNLESS(!foundMtcTablePattern, ldr::ResultInvalidMtcTablePattern()); /* Return if the pattern was already found. */
/* This pattern happens multiple times in this function., we only need to find it once. */
R_UNLESS(!getMtcTableCache.foundMtcTablePattern, ldr::ResultInvalidMtcTablePattern());
/* This is a mess but the compiler made this painful to patch so we must do it this way */ /* This is a mess but the compiler made this painful to patch so we must do it this way */
constexpr u32 AddpOffset = 1; constexpr u32 AddrpOffset = 1;
constexpr u32 MovOffset = 7; constexpr u32 MovOffset = 7;
constexpr u32 BlOffset = 5; constexpr u32 BlOffset = 5;
constexpr u32 MtcGoodBlOpcode = 0x97fe6cfc; constexpr u32 MovOffsetOld = 8;
// constexpr u32 MtcBadBlOpcode0 = 0x97ffae64; // bl nn::pcv::GetHardwareType
// constexpr u32 MtcBadBlOpcode1 = 0x940036d5; // bl strcmp
// constexpr u32 MtcBadAdrpAsm = 0xd00000a1; // adrp x1, s_ModuleResetStatus_
// constexpr s32 MtcBadBlOffset0 = 2;
// constexpr s32 MtcBadBlOffset1 = -1;
// constexpr s32 MtcBadAdrpOffset = 1;
/* Ensure we don't dereference memory before nso start. */ /* Ensure we don't dereference memory before nso start. */
R_UNLESS(ptr - MovOffset >= nsoStart, ldr::ResultInvalidMtcTablePattern()); R_UNLESS(ptr - MovOffset >= nsoStart, ldr::ResultInvalidMtcTablePattern());
u32 adrp = *(ptr - AddpOffset); u32 adrp = *(ptr - AddrpOffset);
R_UNLESS(AsmCompareAdrpNoImm(adrp, MtcAdrpAsm), ldr::ResultInvalidMtcTablePattern()); R_UNLESS(AsmCompareAdrpNoImm(adrp, MtcAdrpAsm), ldr::ResultInvalidMtcTablePattern());
/* Check for the branch instruction above the cbz to ensure we are patching the right location*/ /* Check for the branch instruction above the cbz to ensure we are patching the right location*/
u32 bl = *(ptr - BlOffset); u32 bl = *(ptr - BlOffset);
R_UNLESS(AsmBlCompareOpcodeOnly(bl, MtcGoodBlOpcode), ldr::ResultInvalidMtcTablePattern()); R_UNLESS(AsmBlCompareOpcodeOnly(bl, MtcBlIns), ldr::ResultInvalidMtcTablePattern());
/* Check for the mov that actually sets the mtc table count. */ /* Check for the mov that actually sets the mtc table count. */
u32 mov = *(ptr - MovOffset); u32 mov = *(ptr - MovOffset);
R_UNLESS(asm_compare_no_rd(mov, MtcMovAsm), ldr::ResultInvalidMtcTablePattern()); bool foundMov = false;
foundMov = asm_compare_no_rd(mov, MtcMovAsm);
if (!foundMov) {
mov = *(ptr + MovOffsetOld);
/* Check old firmware offset. */
foundMov = asm_compare_no_rd(mov, MtcMovAsm);
}
R_UNLESS(foundMov, ldr::ResultInvalidMtcTablePattern());
foundMtcTablePattern = true;
constexpr u32 PrologueWindow = 140; constexpr u32 PrologueWindow = 140;
u32 *functionPrologue = FindFnPrologue(ptr, PrologueWindow, nsoStart); u32 *functionPrologue = FindFnPrologue(ptr, PrologueWindow, nsoStart);
R_UNLESS(functionPrologue != nullptr, ldr::ResultInvalidMtcTablePattern()); R_UNLESS(functionPrologue != nullptr, ldr::ResultInvalidMtcTablePattern());
getMtcTableCache.getEristaMtcTableFnSite = functionPrologue; getMtcTableCache.getEristaMtcTableFnSite = functionPrologue;
R_SUCCEED(); getMtcTableCache.foundMtcTablePattern = true;
/* Patch out the count of the mov to our custom mtc table amount*/
u32 movCountPatch = asm_set_rd(asm_set_imm16(MtcMovAsm, newEmcList.size()), asm_get_rd(mov));
PATCH_OFFSET(ptr + MovOffset, movCountPatch);
R_SUCCEED(); R_SUCCEED();
} }
@@ -720,7 +718,7 @@ namespace ams::ldr::hoc::pcv::erista {
{"GPU Volt Thermals", &GpuVoltThermals, 1, nullptr, GpuVminOfficial }, {"GPU Volt Thermals", &GpuVoltThermals, 1, nullptr, GpuVminOfficial },
{"GPU Freq Table", GpuFreqCvbTable<false>, 1, nullptr, GpuCvbDefaultMaxFreq }, {"GPU Freq Table", GpuFreqCvbTable<false>, 1, nullptr, GpuCvbDefaultMaxFreq },
{"GPU Freq Asm", &GpuFreqMaxAsm, 2, &GpuMaxClockPatternFn }, {"GPU Freq Asm", &GpuFreqMaxAsm, 2, &GpuMaxClockPatternFn },
{"GPU PLL Max", & GpuFreqPllMax, 1, nullptr, GpuClkPllMax }, {"GPU PLL Max", &GpuFreqPllMax, 1, nullptr, GpuClkPllMax },
// {"GPU PLL Limit", &GpuFreqPllLimit, 4, nullptr, GpuClkPllLimit }, // {"GPU PLL Limit", &GpuFreqPllLimit, 4, nullptr, GpuClkPllLimit },
{"MEM Table Asm", &MemMtcTableAsm, 4, &MemMtcGetGetTablePatternFn }, {"MEM Table Asm", &MemMtcTableAsm, 4, &MemMtcGetGetTablePatternFn },
{"MEM Freq Mtc", &MemFreqMtcTable, 1, nullptr, EmcClkOSLimit }, {"MEM Freq Mtc", &MemFreqMtcTable, 1, nullptr, EmcClkOSLimit },