diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp index 06298463..2ba074e2 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp @@ -42,7 +42,7 @@ volatile CustomizeTable C = { /* Available: 66MHz step rate, 100MHz step rate and jedec. */ /* Jedec freqs are 1333MHz, 1600MHz, 1866MHz, 2133MHz, 2400MHz, 2666MHz, 2933MHz, 3200MHz. */ -.stepMode = StepMode_66MHz, +.stepMode = StepMode_Jedec, .marikoEmcMaxClock = 2933000, /* 1866MHz @ 1866tWRL is guaranteed to work on all Mariko units */ .marikoEmcVddqVolt = 600000, 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 3bb05150..fbb60197 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp @@ -591,6 +591,63 @@ namespace ams::ldr::hoc::pcv::mariko { } } + std::vector newEmcList; + void MtcGenerateJedecTable() { + const u32 jedecFreqs[] = { 1866000, 1996000, 2133000, 2400000, 2666000, 2933000, 3200000 }; + constexpr u32 JedecFreqCount = std::size(jedecFreqs); + + for (u32 i = 0; i < JedecFreqCount; ++i) { + if (jedecFreqs[i] <= C.marikoEmcMaxClock) { + newEmcList.push_back(jedecFreqs[i]); + } else { + break; + } + } + + newEmcList.resize(std::min(newEmcList.size(), DvfsTableEntryLimit)); + } + + void MtcGenerateFreqTables() { + if (C.marikoEmcMaxClock <= EmcClkOSLimit) { + return; + } + + newEmcList.clear(); + newEmcList.reserve(DvfsTableEntryCount); + newEmcList.insert(newEmcList.end(), std::begin(EmcListDefault), std::end(EmcListDefault)); + + u32 stepRate = 0; + switch (C.stepMode) { + case StepMode_66MHz: + stepRate = 66667; + break; + case StepMode_100MHz: + stepRate = 100000; + break; + case StepMode_Jedec: + MtcGenerateJedecTable(); + return; + default: + stepRate = 66667; + break; + } + + constexpr u32 RoundHz = 1000; + for (u32 stepIndex = 1;; ++stepIndex) { + u32 newFreq = EmcClkOSLimit + stepIndex * stepRate; + newFreq = (newFreq / RoundHz) * RoundHz; + if (newFreq > C.marikoEmcMaxClock) { + if (newEmcList.back() != C.marikoEmcMaxClock) { + newEmcList.push_back(static_cast(C.marikoEmcMaxClock)); + } + break; + } + newEmcList.push_back(newFreq); + } + + newEmcList.resize(std::min(newEmcList.size(), DvfsTableEntryLimit)); + } + Result VerifyMtcTable(MarikoMtcTable *tableStart, u32 expectedFreq) { R_UNLESS(tableStart->rate_khz == expectedFreq, ldr::ResultInvalidMtcTable()); R_UNLESS(tableStart->rev == MTC_TABLE_REV, ldr::ResultInvalidMtcTable()); @@ -639,55 +696,13 @@ namespace ams::ldr::hoc::pcv::mariko { void PrepareMtcMemoryRegion(u8 *firstTable, MarikoMtcTable *usedTable) { memmove(firstTable, usedTable, mariko::MtcFullTableSize); - /* Clear all other tables */ + /* Clear all other tables. */ /* 1 erista table is excluded because it's always before firstTable. */ /* We also exclude the used table obviously. */ constexpr size_t RemainingRegionSize = (mariko::MtcFullTableSize) * (mariko::MtcFullTableCount - 1) + (erista::MtcFullTableSize * (erista::MtcFullTableCount - 1)); memset(firstTable + mariko::MtcFullTableSize, 0, RemainingRegionSize); } - std::vector newEmcList; - void MtcGenerateFreqTables() { - constexpr u32 RoundHz = 1000; - - u32 stepRate = 0; - switch (C.stepMode) { - case StepMode_66MHz: - stepRate = 66667; - break; - case StepMode_100MHz: - stepRate = 100000; - break; - case StepMode_Jedec: - break; - default: - stepRate = 66667; - break; - } - - newEmcList.clear(); - newEmcList.reserve(DvfsTableEntryCount); - newEmcList.insert(newEmcList.end(), std::begin(EmcListDefault), std::end(EmcListDefault)); - - if (C.marikoEmcMaxClock <= EmcClkOSLimit) { - return; - } - - for (u32 stepIndex = 1;; ++stepIndex) { - u32 newFreq = EmcClkOSLimit + stepIndex * stepRate; - newFreq = (newFreq / RoundHz) * RoundHz; - if (newFreq > C.marikoEmcMaxClock) { - if (newEmcList.back() != C.marikoEmcMaxClock) { - newEmcList.push_back(static_cast(C.marikoEmcMaxClock)); - } - break; - } - newEmcList.push_back(newFreq); - } - - newEmcList.resize(std::min(newEmcList.size(), DvfsTableEntryLimit)); - } - void MtcExtendTables(MarikoMtcTable *table) { for (u32 i = mariko::MtcTableCountDefault; i < newEmcList.size(); ++i) { std::memcpy(&table[i], &table[i - 1], sizeof(MarikoMtcTable));