diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/oc_common.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/oc_common.hpp index 1afddad1..bf05e26f 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/oc_common.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/oc_common.hpp @@ -99,4 +99,25 @@ namespace ams::ldr::hoc { R_SUCCEED(); } }; + + namespace panic { + /* Requires modifying g_ams_handlers in secmon_smc_handler.cpp */ + constexpr inline void SmcError(u32 rgb) { + SecmonArgs args = {}; + constexpr u32 SmcShowErrorID = 0xF0000005; + args.X[0] = SmcShowErrorID; + args.X[1] = rgb; + svcCallSecureMonitor(&args); + } + + constexpr inline u32 PackCode(u32 r, u32 g, u32 b) { + return ((r & 0xF) << 8) | ((g & 0xF) << 4) | ((b & 0xF) << 0); + } + + constexpr u32 Gpu = PackCode(0xF, 0x7, 0x0); + constexpr u32 Cpu = PackCode(0xF, 0x0, 0x0); + constexpr u32 Emc = PackCode(0x0, 0xF, 0xF); + constexpr u32 Patch = PackCode(0x8, 0x0, 0xF); + } + } diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.cpp index ec75c8d4..85f23a34 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv.cpp @@ -84,6 +84,7 @@ namespace ams::ldr::hoc::pcv { u32 min; u32 max; bool value_required = false; + u32 panic; Result check() { if (!value_required && !value) @@ -143,22 +144,27 @@ namespace ams::ldr::hoc::pcv { using namespace ams::ldr::hoc::pcv; sValidator validators[] = { - { C.eristaCpuBoostClock, 1020'000, 2295'000, true }, - { C.marikoCpuBoostClock, 1020'000, 2703'000, true }, - { C.commonEmcMemVolt, 912'500, 1350'000 }, // Official burst vmax for the RAMs is 1500mV - { C.eristaCpuMaxVolt, 1000, 1260 }, - { GET_MAX_OF_ARR(erista::maxEmcClocks), 1600'000, 2600'000 }, - { C.marikoCpuMaxVolt, 1000, 1200 }, - { C.marikoEmcMaxClock, 1600'000, 3500'000 }, - { C.marikoEmcVddqVolt, 250'000, 700'000 }, - { eristaCpuDvfsMaxFreq, 1785'000, 2295'000 }, - { marikoCpuDvfsMaxFreq, 1785'000, 2703'000 }, - { eristaGpuDvfsMaxFreq, 768'000, 1152'000 }, - { marikoGpuDvfsMaxFreq, 768'000, 1536'000 }, + { C.eristaCpuBoostClock, 1020'000, 2295'000, true, panic::Cpu }, + { C.marikoCpuBoostClock, 1020'000, 2703'000, true, panic::Cpu }, + { C.eristaCpuMaxVolt, 1000, 1260, false, panic::Cpu }, + { C.marikoCpuMaxVolt, 1000, 1200, false, panic::Cpu }, + { eristaCpuDvfsMaxFreq, 1785'000, 2295'000, false, panic::Cpu }, + { marikoCpuDvfsMaxFreq, 1785'000, 2703'000, false, panic::Cpu }, + { C.commonEmcMemVolt, 912'500, 1350'000, false, panic::Emc }, // Official burst vmax for the RAMs is 1500mV + { GET_MAX_OF_ARR(erista::maxEmcClocks), 1600'000, 2600'000, false, panic::Emc }, + { C.marikoEmcMaxClock, 1600'000, 3500'000, false, panic::Emc }, + { C.marikoEmcVddqVolt, 250'000, 700'000, false, panic::Emc }, + { eristaGpuDvfsMaxFreq, 768'000, 1152'000, false, panic::Gpu }, + { marikoGpuDvfsMaxFreq, 768'000, 1570'000, false, panic::Gpu }, + { C.marikoGpuVmax, 800, 960, false, panic::Gpu }, }; - for (auto& i : validators) { - if (R_FAILED(i.check())) { + for (auto &v : validators) { + if (R_FAILED(v.check())) { + #if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING) + panic::SmcError(v.panic); + #endif + CRASH("Validation FAIL"); } } diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp index 6dc035f0..83748a3f 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp @@ -474,7 +474,11 @@ namespace ams::ldr::hoc::pcv::erista { for (auto &entry : patches) { LOGGING("%s Count: %zu", entry.description, entry.patched_count); if (R_FAILED(entry.CheckResult())) { - CRASH(entry.description); + #if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING) + panic::SmcError(panic::Patch); + #else + CRASH(entry.description); + #endif } } } diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp index 2496a20b..b1ca5aa3 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp @@ -652,7 +652,7 @@ namespace ams::ldr::hoc::pcv::mariko { // Copy unmodified 1600000 table to tmp std::memcpy(reinterpret_cast(tmp), reinterpret_cast(table_max), sizeof(MarikoMtcTable)); - + /* Adjust timings properly according to the new frequency. */ MemMtcTableAutoAdjust(table_max); @@ -810,7 +810,11 @@ namespace ams::ldr::hoc::pcv::mariko { for (auto &entry : patches) { LOGGING("%s Count: %zu", entry.description, entry.patched_count); if (R_FAILED(entry.CheckResult())) { - CRASH(entry.description); + #if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING) + panic::SmcError(panic::Patch); + #else + CRASH(entry.description); + #endif } } }