Revert "revert"

This reverts commit 35fa56d3f7.
This commit is contained in:
souldbminersmwc
2025-08-28 07:33:43 -04:00
parent 2831d6618a
commit 3a82a7ae14
2 changed files with 671 additions and 672 deletions

View File

@@ -1,8 +1,6 @@
/* /*
* Copyright (C) Switch-OC-Suite * Copyright (C) Switch-OC-Suite
* *
* Copyright (c) 2023 hanai3Bi
*
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation. * version 2, as published by the Free Software Foundation.
@@ -16,131 +14,131 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "pcv.hpp" #include "pcv.hpp"
namespace ams::ldr::oc::pcv { namespace ams::ldr::oc::pcv {
Result MemFreqPllmLimit(u32* ptr) { Result MemFreqPllmLimit(u32* ptr) {
clk_pll_param* entry = reinterpret_cast<clk_pll_param *>(ptr); clk_pll_param* entry = reinterpret_cast<clk_pll_param *>(ptr);
R_UNLESS(entry->freq == entry->vco_max, ldr::ResultInvalidMemPllmEntry()); R_UNLESS(entry->freq == entry->vco_max, ldr::ResultInvalidMemPllmEntry());
// Double the max clk simply // Double the max clk simply
u32 max_clk = entry->freq * 2; u32 max_clk = entry->freq * 2;
entry->freq = max_clk; entry->freq = max_clk;
entry->vco_max = max_clk; entry->vco_max = max_clk;
R_SUCCEED(); R_SUCCEED();
} }
Result MemVoltHandler(u32* ptr) { Result MemVoltHandler(u32* ptr) {
// ptr value might be default_uv or max_uv // ptr value might be default_uv or max_uv
regulator* entries[2] = { regulator* entries[2] = {
reinterpret_cast<regulator *>(reinterpret_cast<u8 *>(ptr) - offsetof(regulator, type_1.default_uv)), reinterpret_cast<regulator *>(reinterpret_cast<u8 *>(ptr) - offsetof(regulator, type_1.default_uv)),
reinterpret_cast<regulator *>(reinterpret_cast<u8 *>(ptr) - offsetof(regulator, type_1.max_uv)), reinterpret_cast<regulator *>(reinterpret_cast<u8 *>(ptr) - offsetof(regulator, type_1.max_uv)),
}; };
constexpr u32 uv_step = 12'500; constexpr u32 uv_step = 12'500;
constexpr u32 uv_min = 600'000; constexpr u32 uv_min = 600'000;
auto validator = [](regulator* entry) { auto validator = [](regulator* entry) {
R_UNLESS(entry->id == 1, ldr::ResultInvalidRegulatorEntry()); R_UNLESS(entry->id == 1, ldr::ResultInvalidRegulatorEntry());
R_UNLESS(entry->type == 1, ldr::ResultInvalidRegulatorEntry()); R_UNLESS(entry->type == 1, ldr::ResultInvalidRegulatorEntry());
R_UNLESS(entry->type_1.volt_reg == 0x17, ldr::ResultInvalidRegulatorEntry()); R_UNLESS(entry->type_1.volt_reg == 0x17, ldr::ResultInvalidRegulatorEntry());
R_UNLESS(entry->type_1.step_uv == uv_step, ldr::ResultInvalidRegulatorEntry()); R_UNLESS(entry->type_1.step_uv == uv_step, ldr::ResultInvalidRegulatorEntry());
R_UNLESS(entry->type_1.min_uv == uv_min, ldr::ResultInvalidRegulatorEntry()); R_UNLESS(entry->type_1.min_uv == uv_min, ldr::ResultInvalidRegulatorEntry());
R_SUCCEED(); R_SUCCEED();
}; };
regulator* entry = nullptr; regulator* entry = nullptr;
for (auto& i : entries) { for (auto& i : entries) {
if (R_SUCCEEDED(validator(i))) if (R_SUCCEEDED(validator(i)))
entry = i; entry = i;
} }
R_UNLESS(entry, ldr::ResultInvalidRegulatorEntry()); R_UNLESS(entry, ldr::ResultInvalidRegulatorEntry());
u32 emc_uv = C.commonEmcMemVolt; u32 emc_uv = C.commonEmcMemVolt;
if (!emc_uv) if (!emc_uv)
R_SKIP(); R_SKIP();
if (emc_uv % uv_step) if (emc_uv % uv_step)
emc_uv = emc_uv / uv_step * uv_step; // rounding emc_uv = emc_uv / uv_step * uv_step; // rounding
PATCH_OFFSET(ptr, emc_uv); PATCH_OFFSET(ptr, emc_uv);
R_SUCCEED(); R_SUCCEED();
} }
void SafetyCheck() { void SafetyCheck() {
if (C.custRev != CUST_REV) if (C.custRev != CUST_REV)
CRASH("Triggered"); CRASH("Triggered");
struct sValidator { struct sValidator {
volatile u32 value; volatile u32 value;
u32 min; u32 min;
u32 max; u32 max;
bool value_required = false; bool value_required = false;
Result check() { Result check() {
if (!value_required && !value) if (!value_required && !value)
R_SUCCEED(); R_SUCCEED();
if (min && value < min) if (min && value < min)
R_THROW(ldr::ResultSafetyCheckFailure()); R_THROW(ldr::ResultSafetyCheckFailure());
if (max && value > max) if (max && value > max)
R_THROW(ldr::ResultSafetyCheckFailure()); R_THROW(ldr::ResultSafetyCheckFailure());
R_SUCCEED(); R_SUCCEED();
} }
}; };
u32 eristaCpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.eristaCpuDvfsTable)->freq); u32 eristaCpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.eristaCpuDvfsTable)->freq);
u32 marikoCpuDvfsMaxFreq = static_cast<u32>(C.marikoCpuUV ? GetDvfsTableLastEntry(C.marikoCpuDvfsTableSLT)->freq : GetDvfsTableLastEntry(C.marikoCpuDvfsTable)->freq); u32 marikoCpuDvfsMaxFreq = static_cast<u32>(C.marikoCpuUV ? GetDvfsTableLastEntry(C.marikoCpuDvfsTableSLT)->freq : GetDvfsTableLastEntry(C.marikoCpuDvfsTable)->freq);
u32 eristaGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.eristaGpuDvfsTable)->freq); u32 eristaGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.eristaGpuDvfsTable)->freq);
u32 marikoGpuDvfsMaxFreq; u32 marikoGpuDvfsMaxFreq;
switch (C.marikoGpuUV) { switch (C.marikoGpuUV) {
case 0: case 0:
marikoGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.marikoGpuDvfsTable)->freq); marikoGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.marikoGpuDvfsTable)->freq);
break; break;
case 1: case 1:
marikoGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.marikoGpuDvfsTableSLT)->freq); marikoGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.marikoGpuDvfsTableSLT)->freq);
break; break;
case 2: case 2:
marikoGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.marikoGpuDvfsTableHiOPT)->freq); marikoGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.marikoGpuDvfsTableHiOPT)->freq);
break; break;
default: default:
marikoGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.marikoGpuDvfsTable)->freq); marikoGpuDvfsMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(C.marikoGpuDvfsTable)->freq);
break; break;
} }
sValidator validators[] = { sValidator validators[] = {
{ C.commonCpuBoostClock, 1020'000, 3000'000, true }, { C.commonCpuBoostClock, 1020'000, 3000'000, true },
{ C.commonEmcMemVolt, 1100'000, 1250'000 }, { C.commonEmcMemVolt, 1000'000, 1350'000 },
{ C.eristaCpuMaxVolt, 1100, 1300 }, { C.eristaCpuMaxVolt, 1100, 1300 },
{ C.eristaEmcMaxClock, 1600'000, 2131'200 }, { C.eristaEmcMaxClock, 1600'000, 2131'200 },
{ C.marikoCpuMaxVolt, 1100, 1300 }, { C.marikoCpuMaxVolt, 800, 1160 },
{ C.marikoEmcMaxClock, 1600'000, 2800'000 }, { C.marikoEmcMaxClock, 1600'000, 3600'000 },
{ C.marikoEmcVddqVolt, 550'000, 650'000 }, { C.marikoEmcVddqVolt, 550'000, 650'000 },
{ eristaCpuDvfsMaxFreq, 1785'000, 3000'000 }, { eristaCpuDvfsMaxFreq, 1785'000, 3000'000 },
{ marikoCpuDvfsMaxFreq, 1785'000, 3000'000 }, { marikoCpuDvfsMaxFreq, 1785'000, 3000'000 },
{ eristaGpuDvfsMaxFreq, 768'000, 1536'000 }, { eristaGpuDvfsMaxFreq, 768'000, 1536'000 },
{ marikoGpuDvfsMaxFreq, 768'000, 1536'000 }, { marikoGpuDvfsMaxFreq, 768'000, 1536'000 },
}; };
for (auto& i : validators) { for (auto& i : validators) {
if (R_FAILED(i.check())) if (R_FAILED(i.check()))
CRASH("Triggered"); CRASH("Triggered");
} }
} }
void Patch(uintptr_t mapped_nso, size_t nso_size) { void Patch(uintptr_t mapped_nso, size_t nso_size) {
#ifdef ATMOSPHERE_IS_STRATOSPHERE #ifdef ATMOSPHERE_IS_STRATOSPHERE
SafetyCheck(); SafetyCheck();
bool isMariko = (spl::GetSocType() == spl::SocType_Mariko); bool isMariko = (spl::GetSocType() == spl::SocType_Mariko);
if (isMariko) if (isMariko)
mariko::Patch(mapped_nso, nso_size); mariko::Patch(mapped_nso, nso_size);
else else
erista::Patch(mapped_nso, nso_size); erista::Patch(mapped_nso, nso_size);
#endif #endif
} }
} }