rewrite much of timings stuff

This commit is contained in:
souldbminersmwc
2025-08-30 11:59:19 -04:00
parent b5b509c828
commit fd91bc07d8
120 changed files with 19886 additions and 578 deletions

View File

@@ -1,8 +1,6 @@
/*
* Copyright (C) Switch-OC-Suite
*
* Copyright (c) 2023 hanai3Bi
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
@@ -30,7 +28,7 @@ volatile CustomizeTable C = {
* NO_ADJ_ALL: No timing adjustment for both Erista and Mariko.
* CUSTOMIZED_ALL: Replace with values in customized table for both Erista and Mariko.
*/
.mtcConf = AUTO_ADJ_ALL,
.mtcConf = CUSTOM_ADJ_ALL,
/* Common:
* - Boost Clock in kHz:
@@ -38,7 +36,7 @@ volatile CustomizeTable C = {
* Boost clock will be applied when applications request higher CPU frequency for quicker loading.
* This will be set regardless of whether sys-clk is enabled.
*/
.commonCpuBoostClock = 1785000,
.commonCpuBoostClock = 2295000,
/* - EMC Vddq (Erista Only) and RAM Vdd2 Voltage in uV
* Range: 1100'000 to 1250'000 uV
* Erista Default(HOS): 1125'000 (bootloader: 1100'000)
@@ -46,7 +44,7 @@ volatile CustomizeTable C = {
* Value should be divided evenly by 12'500.
* Not enabled by default.
*/
.commonEmcMemVolt = 1175000, // RAM Rated Voltage
.commonEmcMemVolt = 1212500,
/* Erista CPU:
* - Max Voltage in mV
@@ -68,7 +66,7 @@ volatile CustomizeTable C = {
* - Max Voltage in mV:
* Default voltage: 1120
*/
.marikoCpuMaxVolt = 1120,
.marikoCpuMaxVolt = 1160,
/* Mariko EMC(RAM):
* - RAM Clock in kHz:
@@ -79,39 +77,40 @@ volatile CustomizeTable C = {
* - System instabilities
* - NAND corruption
*/
.marikoEmcMaxClock = 1996800,
.marikoEmcMaxClock = 2400000,
/* - EMC Vddq (Mariko Only) Voltage in uV
* Range: 550'000 to 650'000 uV
* Value should be divided evenly by 5'000
* Value should be dicvided evenly by 5'000
* Default: 600'000
* Not enabled by default.
* This will not work without sys-clk-OC.
*/
.marikoEmcVddqVolt = 0,
.marikoEmcVddqVolt = 640000,
.marikoCpuUV = 0,
.marikoCpuUV = 1,
.marikoGpuUV = 0,
.marikoGpuUV = 2,
.commonGpuVoltOffset = 0,
.marikoEmcDvbShift = 0,
.marikoEmcDvbShift = 5,
.ramTimingPresetOne = 0,
.tRAS = 0,
.tRCD = 0,
.tREFpb = 0,
.tRFCpb = 0,
.tRPpb = 0,
.tRRD = 0,
.R2W = 0,
.tWTR = 0,
.ramTimingPresetTwo = 0,
.marikoGpuVoltArray = {635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, 660, 685, 715, 745, 765, 785},
.ramTimingPresetThree = 0,
.marikoCpuHighVoltOffset = 70,
.ramTimingPresetFour = 0,
.marikoB3 = 179,
.ramTimingPresetFive = 0,
.ramTimingPresetSix = 0,
.ramTimingPresetSeven = 0,
.marikoGpuVoltArray = {610, 610, 610, 610, 610, 610, 610, 610, 610, 610, 620, 640, 675, 710, 735, 785, 815},
.marikoCpuHighUV = 0,
/* Advanced Settings:
* - Erista CPU DVFS Table:
@@ -137,8 +136,6 @@ volatile CustomizeTable C = {
{ 1887000, { 1235000 }, { 5100873, -279186, 4747 } },
{ 1963500, { 1235000 }, { 5100873, -279186, 4747 } },
{ 2091000, { 1235000 }, { 5100873, -279186, 4747 } },
{ 2193000, { 1235000 }, { 5100873, -279186, 4747 } },
{ 2295000, { 1235000 }, { 5100873, -279186, 4747 } },
},
/* - Mariko CPU DVFS Table:
@@ -164,13 +161,15 @@ volatile CustomizeTable C = {
{ 1887000, { 1609246, -37515, 27 }, { 1120000 } },
{ 1963500, { 1675751, -38635, 27 }, { 1120000 } },
// Appending table
{ 2091000, { 1716501, -39395, 27 }, { 1235000 } },
{ 2193000, { 1775132, -40505, 27 }, { 1235000 } },
{ 2295000, { 1866287, -42005, 27 }, { 1235000 } },
// Unsafe
{ 2397000, { 1961107, -43506, 27 }, { 1235000 } },
{ 2499000, { 1754400, -35643, 27 }, { 1235000 } },
{ 2601000, { 1805897, -36331, 27 }, { 1235000 } },
{ 2091000, { 1580725, -33235, 113 }, { 1120000 } },
{ 2193000, { 1580725, -33235, 113 }, { 1235000 } },
{ 2295000, { 1635431, -34095, 113 }, { 1235000 } },
{ 2397000, { 1702903, -34955, 113 }, { 1235000 } },
{ 2499000, { 1754400, -35643, 113 }, { 1235000 } },
{ 2601000, { 1805897, -36331, 113 }, { 1235000 } },
{ 2703000, { 1857394, -37019, 113 }, { 1235000 } },
{ 2805000, { 1908891, -37707, 113 }, { 1235000 } },
{ 2907000, { 1960388, -38395, 113 }, { 1250000 } },
},
.marikoCpuDvfsTableSLT = {
@@ -226,47 +225,6 @@ volatile CustomizeTable C = {
* 1305600 might not work for some SoCs.
*/
.marikoGpuDvfsTable = {
{ 76800, {}, { 610000, } },
{ 153600, {}, { 610000, } },
{ 230400, {}, { 610000, } },
{ 307200, {}, { 610000, } },
{ 384000, {}, { 610000, } },
{ 460800, {}, { 610000, } },
{ 537600, {}, { 801688, -10900, -163, 298, -10599, 162 } },
{ 614400, {}, { 824214, -5743, -452, 238, -6325, 81 } },
{ 691200, {}, { 848830, -3903, -552, 119, -4030, -2 } },
{ 768000, {}, { 891575, -4409, -584, 0, -2849, 39 } },
{ 844800, {}, { 940071, -5367, -602, -60, -63, -93 } },
{ 921600, {}, { 986765, -6637, -614, -179, 1905, -13 } },
{ 998400, {}, { 1098475, -13529, -497, -179, 3626, 9 } },
{ 1075200, {}, { 1163644, -12688, -648, 0, 1077, 40 } },
{ 1152000, {}, { 1204812, -9908, -830, 0, 1469, 110 } },
{ 1228800, {}, { 1277303, -11675, -859, 0, 3722, 313 } },
{ 1267200, {}, { 1335531, -12567, -867, 0, 3681, 559 } },
// Appending table
{ 1305600, {}, { 1374130, -13725, -859, 0, 4442, 576 } },
},
.marikoGpuDvfsTableSLT = {
{ 76800, {}, { 590000, } },
{ 153600, {}, { 590000, } },
{ 230400, {}, { 590000, } },
{ 307200, {}, { 590000, } },
{ 384000, {}, { 590000, } },
{ 460800, {}, { 795089, -11096, -163, 298, -10421, 162 } },
{ 537600, {}, { 795089, -11096, -163, 298, -10421, 162 } },
{ 614400, {}, { 820606, -6285, -452, 238, -6182, 81 } },
{ 691200, {}, { 846289, -4565, -552, 119, -3958, -2 } },
{ 768000, {}, { 888720, -5110, -584, 0, -2849, 39 } },
{ 844800, {}, { 936634, -6089, -602, -60, -99, -93 } },
{ 921600, {}, { 982562, -7373, -614, -179, 1797, -13 } },
{ 998400, {}, { 1090179, -14125, -497, -179, 3518, 9 } },
{ 1075200, {}, { 1155798, -13465, -648, 0, 1077, 40 } },
{ 1152000, {}, { 1198568, -10904, -830, 0, 1469, 110 } },
{ 1228800, {}, { 1269988, -12707, -859, 0, 3722, 313 } },
{ 1267200, {}, { 1308155, -13694, -867, 0, 3681, 559 } },
},
.marikoGpuDvfsTableHiOPT = {
{ 76800, {}, { 590000, } },
{ 153600, {}, { 590000, } },
{ 230400, {}, { 590000, } },
@@ -284,6 +242,49 @@ volatile CustomizeTable C = {
{ 1152000, {}, { 1180029, -14534, -830, 0, 1469, 110 } },
{ 1228800, {}, { 1248293, -16383, -859, 0, 3722, 313 } },
{ 1267200, {}, { 1286399, -17475, -867, 0, 3681, 559 } },
// Appending table
{ 1305600, {}, { 1304130, -13725, -859, 0, 4442, 576 } },
},
.marikoGpuDvfsTableSLT = {
{ 76800, {}, { 635000, } },
{ 153600, {}, { 635000, } },
{ 230400, {}, { 635000, } },
{ 307200, {}, { 635000, } },
{ 384000, {}, { 635000, } },
{ 460800, {}, { 635000, } },
{ 537600, {}, { 635000, } },
{ 614400, {}, { 635000, } },
{ 691200, {}, { 635000, } },
{ 768000, {}, { 635000, } },
{ 844800, {}, { 635000, } },
{ 921600, {}, { 635000, } },
{ 998400, {}, { 901575, -4409, -584, 0, -2849, 39 } },
{ 1075200, {}, { 940071, -5367, -602, -60, -63, -93 } },
{ 1152000, {}, { 996765, -6637, -614, -179, 1905, -13 } },
{ 1228800, {}, { 1098475, -13529, -497, -179, 3626, 9 } },
{ 1267200, {}, { 1131060, -13109, -573, -90, 2352, 25 } },
{ 1305600, {}, { 1163644, -12688, -648, 0, 1077, 40 } },
},
.marikoGpuDvfsTableHiOPT = {
{ 76800, {}, { 550000, } },
{ 153600, {}, { 550000, } },
{ 230400, {}, { 550000, } },
{ 307200, {}, { 550000, } },
{ 384000, {}, { 550000, } },
{ 460800, {}, { 550000, } },
{ 537600, {}, { 550000, } },
{ 614400, {}, { 550000, } },
{ 691200, {}, { 550000, } },
{ 768000, {}, { 801688, -10900, -163, 298, -10599, 162 } },
{ 844800, {}, { 824214, -5743, -452, 238, -6325, 81 } },
{ 921600, {}, { 848830, -3903, -552, 119, -4030, -2 } },
{ 998400, {}, { 901575, -4409, -584, 0, -2849, 39 } },
{ 1075200, {}, { 940071, -5367, -602, -60, -63, -93 } },
{ 1152000, {}, { 996765, -6637, -614, -179, 1905, -13 } },
{ 1228800, {}, { 1098475, -13529, -497, -179, 3626, 9 } },
{ 1267200, {}, { 1131060, -13109, -573, -90, 2352, 25 } },
{ 1305600, {}, { 1163644, -12688, -648, 0, 1077, 40 } },
},
//.eristaMtcTable = const_cast<EristaMtcTable *>(&EristaMtcTablePlaceholder),
@@ -291,4 +292,4 @@ volatile CustomizeTable C = {
};
}
}

View File

@@ -1,8 +1,6 @@
/*
* Copyright (C) Switch-OC-Suite
*
* Copyright (c) 2023 hanai3Bi
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
@@ -59,15 +57,20 @@ typedef struct CustomizeTable {
u32 commonGpuVoltOffset;
// advanced config
u32 marikoEmcDvbShift;
u32 ramTimingPresetOne;
u32 ramTimingPresetTwo;
u32 ramTimingPresetThree;
u32 ramTimingPresetFour;
u32 ramTimingPresetFive;
u32 ramTimingPresetSix;
u32 ramTimingPresetSeven;
const u32 tRAS;
const u32 tRCD;
const u32 tREFpb;
const u32 tRFCpb;
const u32 tRPpb;
const double tRRD;
const u32 R2W;
const u32 tWTR;
//
u32 marikoGpuVoltArray[17];
u32 marikoGpuVoltArray[18];
u8 marikoCpuHighVoltOffset;
u8 marikoB3;
u8 marikoCpuHighUV;
CustomizeCpuDvfsTable eristaCpuDvfsTable;
CustomizeCpuDvfsTable marikoCpuDvfsTable;
CustomizeCpuDvfsTable marikoCpuDvfsTableSLT;
@@ -86,4 +89,4 @@ extern volatile CustomizeTable C;
//extern volatile EristaMtcTable EristaMtcTablePlaceholder;
//extern volatile MarikoMtcTable MarikoMtcTablePlaceholder;
}
}

View File

@@ -26,7 +26,7 @@ struct MarikoTiming {
uint32_t emc_rfc_slr;
uint32_t emc_ras;
uint32_t emc_rp;
uint32_t emc_r2w;
uint32_t emcR2W;
uint32_t emc_w2r;
uint32_t emc_r2p;
uint32_t emc_w2p;
@@ -257,7 +257,7 @@ struct EristaTiming {
uint32_t emc_rfc_slr;
uint32_t emc_ras;
uint32_t emc_rp;
uint32_t emc_r2w;
uint32_t emcR2W;
uint32_t emc_w2r;
uint32_t emc_r2p;
uint32_t emc_w2p;
@@ -777,7 +777,7 @@ struct MarikoMtcTable {
uint32_t mc_emem_arb_timing_wap2pre;
uint32_t mc_emem_arb_timing_r2r;
uint32_t mc_emem_arb_timing_w2w;
uint32_t mc_emem_arb_timing_r2w;
uint32_t mc_emem_arb_timingR2W;
uint32_t mc_emem_arb_timing_ccdmw;
uint32_t mc_emem_arb_timing_w2r;
uint32_t mc_emem_arb_timing_rfcpb;
@@ -1170,7 +1170,7 @@ struct EristaMtcTable {
uint32_t mc_emem_arb_timing_wap2pre;
uint32_t mc_emem_arb_timing_r2r;
uint32_t mc_emem_arb_timing_w2w;
uint32_t mc_emem_arb_timing_r2w;
uint32_t mc_emem_arb_timingR2W;
uint32_t mc_emem_arb_timing_ccdmw;
uint32_t mc_emem_arb_timing_w2r;
uint32_t mc_emem_arb_timing_rfcpb;

View File

@@ -1,235 +1,172 @@
/*
* Copyright (c) 2023 hanai3Bi
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* from GCC preprocessor output
*/
#pragma once
#pragma once
#include "oc_common.hpp"
#include "oc_common.hpp"
namespace ams::ldr::oc {
#define MAX(A, B) std::max(A, B)
#define MIN(A, B) std::min(A, B)
#define CEIL(A) std::ceil(A)
#define FLOOR(A) std::floor(A)
const u8 ramtmarker[4] = {'R', 'A', 'M', 'T'};
//Preset One
const std::array<u32, 6> tRCD_values = {18, 17, 16, 15, 14, 13};
const std::array<u32, 6> tRP_values = {18, 17, 16, 15, 14, 13};
const std::array<u32, 6> tRAS_values = {42, 39, 36, 34, 32, 30};
// Preset Two
const std::array<double, 5> tRRD_values = {10, 7.5, 6, 4, 3};
const std::array<double, 5> tFAW_values = {40, 30, 24, 16, 12};
// Preset Three
const std::array<u32, 6> tWR_values = {18, 15, 15, 12, 12, 8};
const std::array<double, 6> tRTP_values = {7.5, 7.5, 6, 6, 4, 4};
// Preset Four
const std::array<u32, 6> tRFC_values = {140, 120, 100, 80, 70, 60};
// Preset Five
const std::array<u32, 6> tWTR_values = {10, 8, 6, 4, 2, 1};
// Preset Six
const std::array<u32, 5> tREFpb_values = {488, 976, 1952, 3256, 9999};
const u32 TIMING_PRESET_ONE = C.ramTimingPresetOne;
const u32 TIMING_PRESET_TWO = C.ramTimingPresetTwo;
const u32 TIMING_PRESET_THREE = C.ramTimingPresetThree;
const u32 TIMING_PRESET_FOUR = C.ramTimingPresetFour;
const u32 TIMING_PRESET_FIVE = C.ramTimingPresetFive;
const u32 TIMING_PRESET_SIX = C.ramTimingPresetSix;
const u32 TIMING_PRESET_SEVEN = C.ramTimingPresetSeven;
// Burst Length
const u32 BL = 16;
// tRFCpb (refresh cycle time per bank) in ns for 8Gb density
const u32 tRFCpb = !TIMING_PRESET_FOUR ? 140 : tRFC_values[TIMING_PRESET_FOUR-1];
// tRFCab (refresh cycle time all banks) in ns for 8Gb density
const u32 tRFCab = !TIMING_PRESET_FOUR ? 280 : 2*tRFCpb;
// tRAS (row active time) in ns
const u32 tRAS = !TIMING_PRESET_ONE ? 42 : tRAS_values[TIMING_PRESET_ONE-1];
// tRPpb (row precharge time per bank) in ns
const u32 tRPpb = !TIMING_PRESET_ONE ? 18 : tRP_values[TIMING_PRESET_ONE-1];
// tRPab (row precharge time all banks) in ns
const u32 tRPab = !TIMING_PRESET_ONE ? 21 : tRPpb + 3;
// tRC (ACTIVATE-ACTIVATE command period same bank) in ns
const u32 tRC = tRPpb + tRAS;
// DQS output access time from CK_t/CK_c
const double tDQSCK_min = 1.5;
// DQS output access time from CK_t/CK_c
const double tDQSCK_max = 3.5;
// Write preamble (tCK)
const double tWPRE = 1.8;
// Read postamble (tCK)
const double tRPST = 0.4;
// WRITE command to first DQS transition(max) (tCK)
const double tDQSS_max = 1.25;
// DQ-to-DQS offset(max) (ns)
const double tDQS2DQ_max = 0.8;
// DQS_t, DQS_c to DQ skew total, per group, per access (DBI Disabled)
const double tDQSQ = 0.18;
// Write-to-Read delay
const u32 tWTR = !TIMING_PRESET_FIVE ? 10 : tWTR_values[TIMING_PRESET_FIVE-1];
// Internal READ-to-PRE-CHARGE command delay in ns
const double tRTP = !TIMING_PRESET_THREE ? 7.5 : tRTP_values[TIMING_PRESET_THREE-1];
// write recovery time
const u32 tWR = !TIMING_PRESET_THREE ? 18 : tWR_values[TIMING_PRESET_THREE-1];
// Read to refresh delay
const u32 tR2REF = tRTP + tRPpb;
// tRCD (RAS-CAS delay) in ns
const u32 tRCD = !TIMING_PRESET_ONE ? 18 : tRCD_values[TIMING_PRESET_ONE-1];
// tRRD (Active bank-A to Active bank-B) in ns
const double tRRD = !TIMING_PRESET_TWO ? 10. : tRRD_values[TIMING_PRESET_TWO-1];
// tREFpb (average refresh interval per bank) in ns for 8Gb density
const u32 tREFpb = !TIMING_PRESET_SIX ? 488 : tREFpb_values[TIMING_PRESET_SIX-1];
// tREFab (average refresh interval all 8 banks) in ns for 8Gb density
// const u32 tREFab = tREFpb * 8;
// tPDEX2WR, tPDEX2RD (timing delay from exiting powerdown mode to a write/read command) in ns
// const u32 tPDEX2 = 10;
// Exit power-down to next valid command delay
const double tXP = 10;
// Delay from valid command to CKE input LOW in ns
const double tCMDCKE = 1.75;
// tACT2PDEN (timing delay from an activate, MRS or EMRS command to power-down entry) in ns
// Valid clock and CS requirement after CKE input LOW after MRW command
const u32 tMRWCKEL = 14;
// Valid CS requirement after CKE input LOW
const double tCKELCS = 5;
// Valid CS requirement before CKE input HIGH
const double tCSCKEH = 1.75;
// tXSR (SELF REFRESH exit to next valid command delay) in ns
const double tXSR = tRFCab + 7.5;
// tCKE (minimum pulse width(HIGH and LOW pulse width)) in ns
const double tCKE = 7.5;
// Minimum self refresh time (entry to exit)
const u32 tSR = 15;
// tFAW (Four-bank Activate Window) in ns
const u32 tFAW = !TIMING_PRESET_TWO ? 40 : tFAW_values[TIMING_PRESET_TWO-1];
// Valid Clock requirement before CKE Input HIGH in ns
const double tCKCKEH = 1.75;
// p78 The first valid data is available RL × t CK + t DQSCK + t DQSQ
//const u32 QUSE = RL + CEIL(tDQSCK_min/tCK_avg + tDQSQ);
namespace pcv::erista {
// tCK_avg (average clock period) in ns
const double tCK_avg = 1000'000. / C.eristaEmcMaxClock;
// Write Latency
const u32 WL = 14 - 2*TIMING_PRESET_SEVEN;
// Read Latency
const u32 RL = 32 - 4*TIMING_PRESET_SEVEN;
// minimum number of cycles from any read command to any write command, irrespective of bank
const u32 R2W = CEIL (RL + CEIL(tDQSCK_max/tCK_avg) + BL/2 - WL + tWPRE + FLOOR(tRPST)) + 6;
// Delay Time From WRITE-to-READ
const u32 W2R = WL + BL/2 + 1 + CEIL(tWTR/tCK_avg) - 6;
// write-to-precharge time for commands to the same bank in cycles
const u32 WTP = WL + BL/2 + 1 + CEIL(tWR/tCK_avg) - 8;
// #_of_rows per die for 8Gb density
const u32 numOfRows = 65536;
// {REFRESH, REFRESH_LO} = max[(tREF/#_of_rows) / (emc_clk_period) - 64, (tREF/#_of_rows) / (emc_clk_period) * 97%]
// emc_clk_period = dram_clk / 2;
// 1600 MHz: 5894, but N' set to 6176 (~4.8% margin)
const u32 REFRESH = MIN((u32)65472, u32(std::ceil((double(tREFpb) * C.eristaEmcMaxClock / numOfRows * 1.048 / 2 - 64))) / 4 * 4);
const u32 REFBW = MIN((u32)65536, REFRESH+64);
// Write With Auto Precharge to to Power-Down Entry
const u32 WTPDEN = WTP + 1 + CEIL(tDQSS_max/tCK_avg) + CEIL(tDQS2DQ_max/tCK_avg) + 6;
// Additional time after t XP hasexpired until the MRR commandmay be issued
const double tMRRI = tRCD + 3 * tCK_avg;
// tPDEX2MRR (timing delay from exiting powerdown mode to MRR command) in ns
const double tPDEX2MRR = tXP + tMRRI;
}
namespace pcv::mariko {
// tCK_avg (average clock period) in ns
const double tCK_avg = 1000'000. / C.marikoEmcMaxClock;
// Write Latency
const u32 WL = 14 - 2*TIMING_PRESET_SEVEN;
// Read Latency
const u32 RL = 32 - 4*TIMING_PRESET_SEVEN;
// minimum number of cycles from any read command to any write command, irrespective of bank
const u32 R2W = CEIL (RL + CEIL(tDQSCK_max/tCK_avg) + BL/2 - WL + tWPRE + FLOOR(tRPST));
// Delay Time From WRITE-to-READ
const u32 W2R = WL + BL/2 + 1 + CEIL(tWTR/tCK_avg);
// write-to-precharge time for commands to the same bank in cycles
const u32 WTP = WL + BL/2 + 1 + CEIL(tWR/tCK_avg);
// Read-To-MRW delay
const u32 RTM = RL + BL/2 + CEIL(tDQSCK_max/tCK_avg) + FLOOR(tRPST) + CEIL(7.5/tCK_avg);
// Write-To-MRW/MRR delay
const u32 WTM = WL + 1 + BL/2 + CEIL(7.5/tCK_avg);
// Read With AP-To-MRW/MRR delay
const u32 RATM = RTM + CEIL(tRTP/tCK_avg) - 8;
// Write With AP-To-MRW/MRR delay
const u32 WATM = WTM + CEIL(tWR/tCK_avg);
// #_of_rows per die for 8Gb density
const u32 numOfRows = 65536;
// {REFRESH, REFRESH_LO} = max[(tREF/#_of_rows) / (emc_clk_period) - 64, (tREF/#_of_rows) / (emc_clk_period) * 97%]
// emc_clk_period = dram_clk / 2;
// 1600 MHz: 5894, but N' set to 6176 (~4.8% margin)
const u32 REFRESH = MIN((u32)65472, u32(std::ceil((double(tREFpb) * C.marikoEmcMaxClock / numOfRows * 1.048 / 2 - 64))) / 4 * 4);
const u32 REFBW = MIN((u32)65536, REFRESH+64);
// Write With Auto Precharge to to Power-Down Entry
const u32 WTPDEN = WTP + 1 + CEIL(tDQSS_max/tCK_avg) + CEIL(tDQS2DQ_max/tCK_avg) + 6;
// Additional time after t XP hasexpired until the MRR commandmay be issued
const double tMRRI = tRCD + 3 * tCK_avg;
// tPDEX2MRR (timing delay from exiting powerdown mode to MRR command) in ns
const double tPDEX2MRR = tXP + tMRRI;
}
}
namespace ams::ldr::oc {
#define MAX(A, B) std::max(A, B)
#define MIN(A, B) std::min(A, B)
#define CEIL(A) std::ceil(A)
#define FLOOR(A) std::floor(A)
// Burst Length
const u32 BL = 16;
// tRFCab (refresh cycle time all banks) in ns for 8Gb density
const u32 tRFCab = 2*C.tRFCpb;
// C.tRAS (row active time) in ns
// C.tRPpb (row precharge time per bank) in ns
// tRPab (row precharge time all banks) in ns
const u32 tRPab = C.tRPpb + 3;
// tRC (ACTIVATE-ACTIVATE command period same bank) in ns
const u32 tRC = C.tRPpb + C.tRAS;
// DQS output access time from CK_t/CK_c
const double tDQSCK_min = 1.5;
// DQS output access time from CK_t/CK_c
const double tDQSCK_max = 3.5;
// Write preamble (tCK)
const double tWPRE = 1.8;
// Read postamble (tCK)
const double tRPST = 0.4;
// WRITE command to first DQS transition(max) (tCK)
const double tDQSS_max = 1.25;
// DQ-to-DQS offset(max) (ns)
const double tDQS2DQ_max = 0.8;
// DQS_t, DQS_c to DQ skew total, per group, per access (DBI Disabled)
const double tDQSQ = 0.18;
// Write-to-Read delay
// Internal READ-to-PRE-CHARGE command delay in ns
const double tRTP = 7.5;
// write recovery time
const u32 tWR = 18;
// Read to refresh delay
const u32 tR2REF = tRTP + C.tRPpb;
// C.tRCD (RAS-CAS delay) in ns
// C.tRRD (Active bank-A to Active bank-B) in ns
// C.tREFpb (average refresh interval per bank) in ns for 8Gb density
// tREFab (average refresh interval all 8 banks) in ns for 8Gb density
// const u32 tREFab = C.tREFpb * 8;
// tPDEX2WR, tPDEX2RD (timing delay from exiting powerdown mode to a write/read command) in ns
// const u32 tPDEX2 = 10;
// Exit power-down to next valid command delay
const double tXP = 10;
// Delay from valid command to CKE input LOW in ns
const double tCMDCKE = 1.75;
// tACT2PDEN (timing delay from an activate, MRS or EMRS command to power-down entry) in ns
// Valid clock and CS requirement after CKE input LOW after MRW command
const u32 tMRWCKEL = 14;
// Valid CS requirement after CKE input LOW
const double tCKELCS = 5;
// Valid CS requirement before CKE input HIGH
const double tCSCKEH = 1.75;
// tXSR (SELF REFRESH exit to next valid command delay) in ns
const double tXSR = tRFCab + 7.5;
// tCKE (minimum pulse width(HIGH and LOW pulse width)) in ns
const double tCKE = 7.5;
// Minimum self refresh time (entry to exit)
const u32 tSR = 15;
// tFAW (Four-bank Activate Window) in ns
const u32 tFAW = 40;
// Valid Clock requirement before CKE Input HIGH in ns
const double tCKCKEH = 1.75;
// p78 The first valid data is available RL × t CK + t DQSCK + t DQSQ
//const u32 QUSE = RL + CEIL(tDQSCK_min/tCK_avg + tDQSQ);
namespace pcv::erista {
// tCK_avg (average clock period) in ns
const double tCK_avg = 1000'000. / C.eristaEmcMaxClock;
// Write Latency
const u32 WL = 14;
// Read Latency
const u32 RL = 32;
// minimum number of cycles from any read command to any write command, irrespective of bank
// Delay Time From WRITE-to-READ
const u32 W2R = WL + BL/2 + 1 + CEIL(C.tWTR/tCK_avg) - 6;
// write-to-precharge time for commands to the same bank in cycles
const u32 WTP = WL + BL/2 + 1 + CEIL(tWR/tCK_avg) - 8;
// #_of_rows per die for 8Gb density
const u32 numOfRows = 65536;
// {REFRESH, REFRESH_LO} = max[(tREF/#_of_rows) / (emc_clk_period) - 64, (tREF/#_of_rows) / (emc_clk_period) * 97%]
// emc_clk_period = dram_clk / 2;
// 1600 MHz: 5894, but N' set to 6176 (~4.8% margin)
const u32 REFRESH = MIN((u32)65472, u32(std::ceil((double(C.tREFpb) * C.eristaEmcMaxClock / numOfRows * 1.048 / 2 - 64))) / 4 * 4);
const u32 REFBW = MIN((u32)65536, REFRESH+64);
// Write With Auto Precharge to to Power-Down Entry
const u32 WTPDEN = WTP + 1 + CEIL(tDQSS_max/tCK_avg) + CEIL(tDQS2DQ_max/tCK_avg) + 6;
// Additional time after t XP hasexpired until the MRR commandmay be issued
const double tMRRI = C.tRCD + 3 * tCK_avg;
// tPDEX2MRR (timing delay from exiting powerdown mode to MRR command) in ns
const double tPDEX2MRR = tXP + tMRRI;
}
namespace pcv::mariko {
// tCK_avg (average clock period) in ns
const double tCK_avg = 1000'000. / C.marikoEmcMaxClock;
// Write Latency
const u32 WL = 14;
// Read Latency
const u32 RL = 32;
// minimum number of cycles from any read command to any write command, irrespective of bank
// Delay Time From WRITE-to-READ
const u32 W2R = WL + BL/2 + 1 + CEIL(C.tWTR/tCK_avg);
// write-to-precharge time for commands to the same bank in cycles
const u32 WTP = WL + BL/2 + 1 + CEIL(tWR/tCK_avg);
// Read-To-MRW delay
const u32 RTM = RL + BL/2 + CEIL(tDQSCK_max/tCK_avg) + FLOOR(tRPST) + CEIL(7.5/tCK_avg);
// Write-To-MRW/MRR delay
const u32 WTM = WL + 1 + BL/2 + CEIL(7.5/tCK_avg);
// Read With AP-To-MRW/MRR delay
const u32 RATM = RTM + CEIL(tRTP/tCK_avg) - 8;
// Write With AP-To-MRW/MRR delay
const u32 WATM = WTM + CEIL(tWR/tCK_avg);
// #_of_rows per die for 8Gb density
const u32 numOfRows = 65536;
// {REFRESH, REFRESH_LO} = max[(tREF/#_of_rows) / (emc_clk_period) - 64, (tREF/#_of_rows) / (emc_clk_period) * 97%]
// emc_clk_period = dram_clk / 2;
// 1600 MHz: 5894, but N' set to 6176 (~4.8% margin)
const u32 REFRESH = MIN((u32)65472, u32(std::ceil((double(C.tREFpb) * C.marikoEmcMaxClock / numOfRows * 1.048 / 2 - 64))) / 4 * 4);
const u32 REFBW = MIN((u32)65536, REFRESH+64);
// Write With Auto Precharge to to Power-Down Entry
const u32 WTPDEN = WTP + 1 + CEIL(tDQSS_max/tCK_avg) + CEIL(tDQS2DQ_max/tCK_avg) + 6;
// Additional time after t XP hasexpired until the MRR commandmay be issued
const double tMRRI = C.tRCD + 3 * tCK_avg;
// tPDEX2MRR (timing delay from exiting powerdown mode to MRR command) in ns
const double tPDEX2MRR = tXP + tMRRI;
}
}

View File

@@ -77,13 +77,13 @@ Result Test_PcvDvfsTable() {
// Customized table default
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.eristaCpuDvfsTable)) == 19);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoCpuDvfsTable)) == 21);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoCpuDvfsTableSLT)) == 22);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoCpuDvfsTable)) == 22);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoCpuDvfsTableSLT)) == 25);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.eristaGpuDvfsTable)) == 12);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoGpuDvfsTable)) == 17);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoGpuDvfsTableSLT)) == 17);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoGpuDvfsTableHiOPT)) == 17);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoGpuDvfsTable)) == 18);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoGpuDvfsTableSLT)) == 18);
assert(GetDvfsTableEntryCount((cvb_entry_t *)(&ams::ldr::oc::C.marikoGpuDvfsTableHiOPT)) == 18);
constexpr size_t limit = ams::ldr::oc::pcv::DvfsTableEntryLimit;
cvb_entry_t customized_table[limit] = {};

View File

@@ -1,8 +1,6 @@
/*
* Copyright (C) Switch-OC-Suite
*
* Copyright (c) 2023 hanai3Bi
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
@@ -114,11 +112,11 @@ void SafetyCheck() {
sValidator validators[] = {
{ C.commonCpuBoostClock, 1020'000, 3000'000, true },
{ C.commonEmcMemVolt, 1100'000, 1250'000 },
{ C.commonEmcMemVolt, 1000'000, 1350'000 },
{ C.eristaCpuMaxVolt, 1100, 1300 },
{ C.eristaEmcMaxClock, 1600'000, 2131'200 },
{ C.marikoCpuMaxVolt, 1100, 1300 },
{ C.marikoEmcMaxClock, 1600'000, 2800'000 },
{ C.marikoCpuMaxVolt, 800, 1160 },
{ C.marikoEmcMaxClock, 1600'000, 3200'000 },
{ C.marikoEmcVddqVolt, 550'000, 650'000 },
{ eristaCpuDvfsMaxFreq, 1785'000, 3000'000 },
{ marikoCpuDvfsMaxFreq, 1785'000, 3000'000 },
@@ -143,4 +141,4 @@ void Patch(uintptr_t mapped_nso, size_t nso_size) {
#endif
}
}
}

View File

@@ -1,8 +1,6 @@
/*
* Copyright (C) Switch-OC-Suite
*
* Copyright (c) 2023 hanai3Bi
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.

View File

@@ -1,8 +1,6 @@
/*
* Copyright (C) Switch-OC-Suite
*
* Copyright (c) 2023 hanai3Bi
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
@@ -87,16 +85,16 @@ void MemMtcTableAutoAdjust(EristaMtcTable* table) {
WRITE_PARAM_ALL_REG(table, emc_rc, GET_CYCLE_CEIL(tRC));
WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(tRFCab));
WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(tRFCpb));
WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE_CEIL(tRAS));
WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(tRPpb));
WRITE_PARAM_ALL_REG(table, emc_r2w, R2W);
WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(C.tRFCpb));
WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE_CEIL(C.tRAS));
WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(C.tRPpb));
WRITE_PARAM_ALL_REG(table, emcR2W, C.R2W);
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(tRTP));
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(tRCD));
WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(tRCD));
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(tRRD));
WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(C.tRCD));
WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(C.tRCD));
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(C.tRRD));
WRITE_PARAM_ALL_REG(table, emc_refresh, REFRESH);
WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, REFRESH / 4);
WRITE_PARAM_ALL_REG(table, emc_pdex2wr, GET_CYCLE_CEIL(tXP));
@@ -123,19 +121,19 @@ void MemMtcTableAutoAdjust(EristaMtcTable* table) {
constexpr u32 MC_ARB_DIV = 4;
constexpr u32 MC_ARB_SFA = 2;
table->burst_mc_regs.mc_emem_arb_timing_rcd = CEIL(GET_CYCLE_CEIL(tRCD) / MC_ARB_DIV) - 2;
table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV) - 1 + MC_ARB_SFA;
table->burst_mc_regs.mc_emem_arb_timing_rcd = CEIL(GET_CYCLE_CEIL(C.tRCD) / MC_ARB_DIV) - 2;
table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(C.tRPpb) / MC_ARB_DIV) - 1 + MC_ARB_SFA;
table->burst_mc_regs.mc_emem_arb_timing_rc = CEIL(GET_CYCLE_CEIL(tRC) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(tRAS) / MC_ARB_DIV) - 2;
table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(C.tRAS) / MC_ARB_DIV) - 2;
table->burst_mc_regs.mc_emem_arb_timing_faw = CEIL(GET_CYCLE_CEIL(tFAW) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(tRRD) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(C.tRRD) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(GET_CYCLE_CEIL(tRTP) / MC_ARB_DIV);
table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(WTP / MC_ARB_DIV);
//table->burst_mc_regs.mc_emem_arb_timing_r2r = CEIL(table->burst_regs.emc_rext / MC_ARB_DIV) - 1 + MC_ARB_SFA;
//table->burst_mc_regs.mc_emem_arb_timing_w2w = CEIL(table->burst_regs.emc_wext / MC_ARB_DIV) - 1 + MC_ARB_SFA;
table->burst_mc_regs.mc_emem_arb_timing_r2w = CEIL(R2W / MC_ARB_DIV) - 1 + MC_ARB_SFA;
table->burst_mc_regs.mc_emem_arb_timingR2W = CEIL(C.R2W / MC_ARB_DIV) - 1 + MC_ARB_SFA;
table->burst_mc_regs.mc_emem_arb_timing_w2r = CEIL(W2R / MC_ARB_DIV) - 1 + MC_ARB_SFA;
table->burst_mc_regs.mc_emem_arb_timing_rfcpb = CEIL(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV);
table->burst_mc_regs.mc_emem_arb_timing_rfcpb = CEIL(GET_CYCLE_CEIL(C.tRFCpb) / MC_ARB_DIV);
//table->burst_mc_regs.mc_emem_arb_timing_ccdmw = CEIL(tCCDMW / MC_ARB_DIV) -1 + MC_ARB_SFA;
}
@@ -146,72 +144,58 @@ void MemMtcTableCustomAdjust(EristaMtcTable* table) {
constexpr u32 MC_ARB_DIV = 4;
constexpr u32 MC_ARB_SFA = 2;
if (TIMING_PRESET_ONE) {
WRITE_PARAM_ALL_REG(table, emc_rc, GET_CYCLE_CEIL(tRC));
WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE_CEIL(tRAS));
WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(tRPpb));
WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE_CEIL(tRPab));
WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(tRCD));
WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(tRCD));
WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, GET_CYCLE_CEIL(tPDEX2MRR));
WRITE_PARAM_ALL_REG(table, emc_rc, GET_CYCLE_CEIL(tRC));
WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE_CEIL(C.tRAS));
WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(C.tRPpb));
WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE_CEIL(tRPab));
WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(C.tRCD));
WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(C.tRCD));
WRITE_PARAM_ALL_REG(table, emc_pdex2mrr, GET_CYCLE_CEIL(tPDEX2MRR));
table->burst_mc_regs.mc_emem_arb_timing_rcd = CEIL(GET_CYCLE_CEIL(tRCD) / MC_ARB_DIV - 2);
table->burst_mc_regs.mc_emem_arb_timing_rc = CEIL(GET_CYCLE_CEIL(tRC) / MC_ARB_DIV - 1);
table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV - 1 + MC_ARB_SFA);
table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(tRAS) / MC_ARB_DIV - 2);
}
table->burst_mc_regs.mc_emem_arb_timing_rcd = CEIL(GET_CYCLE_CEIL(C.tRCD) / MC_ARB_DIV - 2);
table->burst_mc_regs.mc_emem_arb_timing_rc = CEIL(GET_CYCLE_CEIL(tRC) / MC_ARB_DIV - 1);
table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(C.tRPpb) / MC_ARB_DIV - 1 + MC_ARB_SFA);
table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(C.tRAS) / MC_ARB_DIV - 2);
if (TIMING_PRESET_TWO) {
WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE_CEIL(tFAW));
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(tRRD));
WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE_CEIL(tFAW));
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(C.tRRD));
table->burst_mc_regs.mc_emem_arb_timing_faw = CEIL(GET_CYCLE_CEIL(tFAW) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(tRRD) / MC_ARB_DIV) - 1;
}
table->burst_mc_regs.mc_emem_arb_timing_faw = CEIL(GET_CYCLE_CEIL(tFAW) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(C.tRRD) / MC_ARB_DIV) - 1;
if (TIMING_PRESET_THREE) {
WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(tRTP));
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(tRTP));
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(GET_CYCLE_CEIL(tRTP) / MC_ARB_DIV);
table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(WTP / MC_ARB_DIV);
}
table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(GET_CYCLE_CEIL(tRTP) / MC_ARB_DIV);
table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(WTP / MC_ARB_DIV);
if (TIMING_PRESET_FOUR) {
WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(tRFCab));
WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(tRFCpb));
WRITE_PARAM_ALL_REG(table, emc_txsr, MIN(GET_CYCLE_CEIL(tXSR), (u32)0x3fe));
WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE_CEIL(tXSR), (u32)0x3fe));
WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(tRFCab));
WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(C.tRFCpb));
WRITE_PARAM_ALL_REG(table, emc_txsr, MIN(GET_CYCLE_CEIL(tXSR), (u32)0x3fe));
WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE_CEIL(tXSR), (u32)0x3fe));
table->burst_mc_regs.mc_emem_arb_timing_rfcpb = CEIL(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV);
}
table->burst_mc_regs.mc_emem_arb_timing_rfcpb = CEIL(GET_CYCLE_CEIL(C.tRFCpb) / MC_ARB_DIV);
if (TIMING_PRESET_FIVE) {
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
table->burst_mc_regs.mc_emem_arb_timing_w2r = CEIL(W2R / MC_ARB_DIV) - 1 + MC_ARB_SFA;
}
table->burst_mc_regs.mc_emem_arb_timing_w2r = CEIL(W2R / MC_ARB_DIV) - 1 + MC_ARB_SFA;
if (TIMING_PRESET_SIX) {
WRITE_PARAM_ALL_REG(table, emc_refresh, REFRESH);
WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, REFRESH / 4);
WRITE_PARAM_ALL_REG(table, emc_trefbw, REFBW);
}
WRITE_PARAM_ALL_REG(table, emc_refresh, REFRESH);
WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, REFRESH / 4);
WRITE_PARAM_ALL_REG(table, emc_trefbw, REFBW);
if (TIMING_PRESET_SEVEN) {
WRITE_PARAM_ALL_REG(table, emc_r2w, R2W);
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(WTP / MC_ARB_DIV);
table->burst_mc_regs.mc_emem_arb_timing_r2w = CEIL(R2W / MC_ARB_DIV) - 1 + MC_ARB_SFA;
table->burst_mc_regs.mc_emem_arb_timing_w2r = CEIL(W2R / MC_ARB_DIV) - 1 + MC_ARB_SFA;
}
WRITE_PARAM_ALL_REG(table, emcR2W, C.R2W);
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(WTP / MC_ARB_DIV);
table->burst_mc_regs.mc_emem_arb_timingR2W = CEIL(C.R2W / MC_ARB_DIV) - 1 + MC_ARB_SFA;
table->burst_mc_regs.mc_emem_arb_timing_w2r = CEIL(W2R / MC_ARB_DIV) - 1 + MC_ARB_SFA;
u32 DA_TURNS = 0;
DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_r2w / 2) << 16; //R2W TURN
DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timingR2W / 2) << 16; //C.R2W TURN
DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_w2r / 2) << 24; //W2R TURN
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_da_turns, DA_TURNS);
u32 DA_COVERS = 0;

View File

@@ -1,8 +1,6 @@
/*
* Copyright (C) Switch-OC-Suite
*
* Copyright (c) 2023 hanai3Bi
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
@@ -74,12 +72,16 @@ Result CpuVoltDfll(u32* ptr) {
if (C.marikoCpuUV) {
if (C.marikoCpuUV == 1) {
PATCH_OFFSET(&(entry->tune0_low), 0x0000FF90); //process_id 0
} else if (C.marikoCpuUV == 2) {
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
}
else if (C.marikoCpuUV == 2) {
PATCH_OFFSET(&(entry->tune0_low), 0x0000FFA0); //process_id 1
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
}
PATCH_OFFSET(&(entry->tune0_high), 0x0000FFFF);
PATCH_OFFSET(&(entry->tune1_low), 0x021107FF);
PATCH_OFFSET(&(entry->tune1_high), 0x00000000);
}
R_SUCCEED();
@@ -184,10 +186,10 @@ void MemMtcTableAutoAdjust(MarikoMtcTable* table, const MarikoMtcTable* ref) {
WRITE_PARAM_ALL_REG(table, emc_rc, GET_CYCLE_CEIL(tRC));
WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(tRFCab));
WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(tRFCpb));
WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE_CEIL(tRAS));
WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(tRPpb));
WRITE_PARAM_ALL_REG(table, emc_r2w, R2W);
WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(C.tRFCpb));
WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE_CEIL(C.tRAS));
WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(C.tRPpb));
WRITE_PARAM_ALL_REG(table, emcR2W, C.R2W);
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(tRTP));
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
@@ -196,9 +198,9 @@ void MemMtcTableAutoAdjust(MarikoMtcTable* table, const MarikoMtcTable* ref) {
WRITE_PARAM_ALL_REG(table, emc_tratm, RATM);
WRITE_PARAM_ALL_REG(table, emc_twatm, WATM);
//WRITE_PARAM_ALL_REG(table, emc_tr2ref, GET_CYCLE_CEIL(tR2REF));
WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(tRCD));
WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(tRCD));
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(tRRD));
WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(C.tRCD));
WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(C.tRCD));
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(C.tRRD));
WRITE_PARAM_ALL_REG(table, emc_rext, 26);
WRITE_PARAM_ALL_REG(table, emc_refresh, REFRESH);
WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, REFRESH / 4);
@@ -238,21 +240,21 @@ void MemMtcTableAutoAdjust(MarikoMtcTable* table, const MarikoMtcTable* ref) {
constexpr u32 MC_ARB_SFA = 2;
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_cfg, C.marikoEmcMaxClock / (33.3 * 1000) / MC_ARB_DIV); //CYCLES_PER_UPDATE: The number of mcclk cycles per deadline timer update
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_rcd, CEIL(GET_CYCLE_CEIL(tRCD) / MC_ARB_DIV) - 2)
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_rp, CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV) - 1 + MC_ARB_SFA)
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_rcd, CEIL(GET_CYCLE_CEIL(C.tRCD) / MC_ARB_DIV) - 2)
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_rp, CEIL(GET_CYCLE_CEIL(C.tRPpb) / MC_ARB_DIV) - 1 + MC_ARB_SFA)
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_rc, CEIL(GET_CYCLE_CEIL(tRC) / MC_ARB_DIV) - 1)
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_ras, CEIL(GET_CYCLE_CEIL(tRAS) / MC_ARB_DIV) - 2)
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_ras, CEIL(GET_CYCLE_CEIL(C.tRAS) / MC_ARB_DIV) - 2)
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_faw, CEIL(GET_CYCLE_CEIL(tFAW) / MC_ARB_DIV) - 1)
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_rrd, CEIL(GET_CYCLE_CEIL(tRRD) / MC_ARB_DIV) - 1)
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_rrd, CEIL(GET_CYCLE_CEIL(C.tRRD) / MC_ARB_DIV) - 1)
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_rap2pre, CEIL(GET_CYCLE_CEIL(tRTP) / MC_ARB_DIV))
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_wap2pre, CEIL((WTP) / MC_ARB_DIV))
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_r2r, CEIL(table->burst_regs.emc_rext / MC_ARB_DIV) - 1 + MC_ARB_SFA)
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_r2w, CEIL((R2W) / MC_ARB_DIV) - 1 + MC_ARB_SFA)
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timingR2W, CEIL((C.R2W) / MC_ARB_DIV) - 1 + MC_ARB_SFA)
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_w2r, CEIL((W2R) / MC_ARB_DIV) - 1 + MC_ARB_SFA)
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_rfcpb, CEIL(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV))
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_timing_rfcpb, CEIL(GET_CYCLE_CEIL(C.tRFCpb) / MC_ARB_DIV))
u32 DA_TURNS = 0;
DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_r2w / 2) << 16; //R2W TURN
DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timingR2W / 2) << 16; //C.R2W TURN
DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_w2r / 2) << 24; //W2R TURN
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_da_turns, DA_TURNS);
u32 DA_COVERS = 0;
@@ -318,7 +320,7 @@ void MemMtcTableAutoAdjust(MarikoMtcTable* table, const MarikoMtcTable* ref) {
table->pllmb_ss_ctrl1 = 0x0b55fe01;
table->pllmb_ss_ctrl2 = 0x10170b55;
table->dram_timings.t_rp = tRPpb;
table->dram_timings.t_rp = C.tRPpb;
table->dram_timings.t_rfc = tRFCab;
//table->dram_timings.rl = 32;
@@ -332,79 +334,64 @@ void MemMtcTableCustomAdjust(MarikoMtcTable* table) {
constexpr u32 MC_ARB_DIV = 4;
constexpr u32 MC_ARB_SFA = 2;
if (TIMING_PRESET_ONE) {
WRITE_PARAM_ALL_REG(table, emc_rc, GET_CYCLE_CEIL(tRC));
WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE_CEIL(tRAS));
WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(tRPpb));
WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE_CEIL(tRPab));
WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(tRCD));
WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(tRCD));
WRITE_PARAM_ALL_REG(table, emc_pdex2mrr,GET_CYCLE_CEIL(tPDEX2MRR));
WRITE_PARAM_ALL_REG(table, emc_rc, GET_CYCLE_CEIL(tRC));
WRITE_PARAM_ALL_REG(table, emc_ras, GET_CYCLE_CEIL(C.tRAS));
WRITE_PARAM_ALL_REG(table, emc_rp, GET_CYCLE_CEIL(C.tRPpb));
WRITE_PARAM_ALL_REG(table, emc_trpab, GET_CYCLE_CEIL(tRPab));
WRITE_PARAM_ALL_REG(table, emc_rd_rcd, GET_CYCLE_CEIL(C.tRCD));
WRITE_PARAM_ALL_REG(table, emc_wr_rcd, GET_CYCLE_CEIL(C.tRCD));
WRITE_PARAM_ALL_REG(table, emc_pdex2mrr,GET_CYCLE_CEIL(tPDEX2MRR));
table->burst_mc_regs.mc_emem_arb_timing_rcd = CEIL(GET_CYCLE_CEIL(tRCD) / MC_ARB_DIV) - 2;
table->burst_mc_regs.mc_emem_arb_timing_rc = CEIL(GET_CYCLE_CEIL(tRC) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(tRPpb) / MC_ARB_DIV) - 1 + MC_ARB_SFA;
table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(tRAS) / MC_ARB_DIV) - 2;
table->burst_mc_regs.mc_emem_arb_timing_rcd = CEIL(GET_CYCLE_CEIL(C.tRCD) / MC_ARB_DIV) - 2;
table->burst_mc_regs.mc_emem_arb_timing_rc = CEIL(GET_CYCLE_CEIL(tRC) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rp = CEIL(GET_CYCLE_CEIL(C.tRPpb) / MC_ARB_DIV) - 1 + MC_ARB_SFA;
table->burst_mc_regs.mc_emem_arb_timing_ras = CEIL(GET_CYCLE_CEIL(C.tRAS) / MC_ARB_DIV) - 2;
}
if (TIMING_PRESET_TWO) {
WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE_CEIL(tFAW));
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(tRRD));
WRITE_PARAM_ALL_REG(table, emc_tfaw, GET_CYCLE_CEIL(tFAW));
WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(C.tRRD));
table->burst_mc_regs.mc_emem_arb_timing_faw = CEIL(GET_CYCLE_CEIL(tFAW) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(tRRD) / MC_ARB_DIV) - 1;
}
table->burst_mc_regs.mc_emem_arb_timing_faw = CEIL(GET_CYCLE_CEIL(tFAW) / MC_ARB_DIV) - 1;
table->burst_mc_regs.mc_emem_arb_timing_rrd = CEIL(GET_CYCLE_CEIL(C.tRRD) / MC_ARB_DIV) - 1;
if (TIMING_PRESET_THREE) {
WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(tRTP));
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
WRITE_PARAM_ALL_REG(table, emc_tratm, RATM);
WRITE_PARAM_ALL_REG(table, emc_twatm, WATM);
WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
WRITE_PARAM_ALL_REG(table, emc_r2p, GET_CYCLE_CEIL(tRTP));
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
WRITE_PARAM_ALL_REG(table, emc_tratm, RATM);
WRITE_PARAM_ALL_REG(table, emc_twatm, WATM);
WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(GET_CYCLE_CEIL(tRTP) / MC_ARB_DIV);
table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(WTP / MC_ARB_DIV);
}
table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(GET_CYCLE_CEIL(tRTP) / MC_ARB_DIV);
table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(WTP / MC_ARB_DIV);
if (TIMING_PRESET_FOUR) {
WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(tRFCab));
WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(tRFCpb));
WRITE_PARAM_ALL_REG(table, emc_txsr, MIN(GET_CYCLE_CEIL(tXSR), (u32)0x3fe));
WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE_CEIL(tXSR), (u32)0x3fe));
WRITE_PARAM_ALL_REG(table, emc_rfc, GET_CYCLE_CEIL(tRFCab));
WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(C.tRFCpb));
WRITE_PARAM_ALL_REG(table, emc_txsr, MIN(GET_CYCLE_CEIL(tXSR), (u32)0x3fe));
WRITE_PARAM_ALL_REG(table, emc_txsrdll, MIN(GET_CYCLE_CEIL(tXSR), (u32)0x3fe));
table->burst_mc_regs.mc_emem_arb_timing_rfcpb = CEIL(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV);
}
table->burst_mc_regs.mc_emem_arb_timing_rfcpb = CEIL(GET_CYCLE_CEIL(C.tRFCpb) / MC_ARB_DIV);
if (TIMING_PRESET_FIVE) {
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
table->burst_mc_regs.mc_emem_arb_timing_w2r = CEIL(W2R / MC_ARB_DIV) - 1 + MC_ARB_SFA;
}
table->burst_mc_regs.mc_emem_arb_timing_w2r = CEIL(W2R / MC_ARB_DIV) - 1 + MC_ARB_SFA;
if (TIMING_PRESET_SIX) {
WRITE_PARAM_ALL_REG(table, emc_refresh, REFRESH);
WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, REFRESH / 4);
WRITE_PARAM_ALL_REG(table, emc_trefbw, REFBW);
}
WRITE_PARAM_ALL_REG(table, emc_refresh, REFRESH);
WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, REFRESH / 4);
WRITE_PARAM_ALL_REG(table, emc_trefbw, REFBW);
if (TIMING_PRESET_SEVEN) {
WRITE_PARAM_ALL_REG(table, emc_r2w, R2W);
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
WRITE_PARAM_ALL_REG(table, emc_trtm, RTM);
WRITE_PARAM_ALL_REG(table, emc_twtm, WTM);
WRITE_PARAM_ALL_REG(table, emc_tratm, RATM);
WRITE_PARAM_ALL_REG(table, emc_twatm, WATM);
WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
WRITE_PARAM_ALL_REG(table, emcR2W, C.R2W);
WRITE_PARAM_ALL_REG(table, emc_w2r, W2R);
WRITE_PARAM_ALL_REG(table, emc_w2p, WTP);
WRITE_PARAM_ALL_REG(table, emc_trtm, RTM);
WRITE_PARAM_ALL_REG(table, emc_twtm, WTM);
WRITE_PARAM_ALL_REG(table, emc_tratm, RATM);
WRITE_PARAM_ALL_REG(table, emc_twatm, WATM);
WRITE_PARAM_ALL_REG(table, emc_rw2pden, WTPDEN);
table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(WTP / MC_ARB_DIV);
table->burst_mc_regs.mc_emem_arb_timing_r2w = CEIL(R2W / MC_ARB_DIV) - 1 + MC_ARB_SFA;
table->burst_mc_regs.mc_emem_arb_timing_w2r = CEIL(W2R / MC_ARB_DIV) - 1 + MC_ARB_SFA;
}
table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(WTP / MC_ARB_DIV);
table->burst_mc_regs.mc_emem_arb_timingR2W = CEIL(C.R2W / MC_ARB_DIV) - 1 + MC_ARB_SFA;
table->burst_mc_regs.mc_emem_arb_timing_w2r = CEIL(W2R / MC_ARB_DIV) - 1 + MC_ARB_SFA;
u32 DA_TURNS = 0;
DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_r2w / 2) << 16; //R2W TURN
DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timingR2W / 2) << 16; //C.R2W TURN
DA_TURNS |= u8(table->burst_mc_regs.mc_emem_arb_timing_w2r / 2) << 24; //W2R TURN
WRITE_PARAM_BURST_MC_REG(table, mc_emem_arb_da_turns, DA_TURNS);
u32 DA_COVERS = 0;
@@ -626,4 +613,4 @@ void Patch(uintptr_t mapped_nso, size_t nso_size) {
}
}
}
}

View File

@@ -0,0 +1,74 @@
#!python3
import sys
import os
def file_replace_str(file_path, search_replace_list):
assert file_path
assert search_replace_list
with open(file_path, "r") as f:
content = f.read()
for entry in search_replace_list:
(search, replace) = entry
if search in content:
content = content.replace(search, replace)
else:
assert replace in content, f"Pattern \"{search}\" not found"
with open(file_path, "w") as f:
f.write(content)
dir_path = os.path.dirname(__file__)
os.chdir(dir_path)
os.system("git reset --hard")
ldr_process_creation = os.path.join(dir_path, "ldr_process_creation.cpp")
file_replace_str(ldr_process_creation,
[("""#include "ldr_ro_manager.hpp"
namespace ams::ldr {""",
"""#include "ldr_ro_manager.hpp"
#include "oc/oc_loader.hpp"
namespace ams::ldr {"""),
(""" NsoHeader g_nso_headers[Nso_Count];
Result ValidateProgramVersion(ncm::ProgramId program_id, u32 version) {""",
""" NsoHeader g_nso_headers[Nso_Count];
/* Pcv/Ptm check cache. */
bool g_is_pcv;
bool g_is_ptm;
Result ValidateProgramVersion(ncm::ProgramId program_id, u32 version) {"""),
(""" R_UNLESS(meta->aci->program_id <= meta->acid->program_id_max, ldr::ResultInvalidProgramId());
/* Validate the kernel capabilities. */""",
""" R_UNLESS(meta->aci->program_id <= meta->acid->program_id_max, ldr::ResultInvalidProgramId());
/* Check if nca is pcv or ptm */
g_is_pcv = meta->aci->program_id == ncm::SystemProgramId::Pcv;
g_is_ptm = meta->aci->program_id == ncm::SystemProgramId::Ptm;
/* Validate the kernel capabilities. */"""),
(""" LocateAndApplyIpsPatchesToModule(nso_header->module_id, map_address, nso_size);
}""",
""" LocateAndApplyIpsPatchesToModule(nso_header->module_id, map_address, nso_size);
/* Apply pcv and ptm patches. */
if (g_is_pcv)
oc::pcv::Patch(map_address, nso_size);
if (g_is_ptm)
oc::ptm::Patch(map_address, nso_size);
}""")])
ldr_meta = os.path.join(dir_path, "ldr_meta.cpp")
file_replace_str(ldr_meta,
[(""" Result ValidateAcidSignature(Meta *meta) {
/* Loader did not check signatures prior to 10.0.0. */""",
""" Result ValidateAcidSignature(Meta *meta) {
R_SUCCEED();
/* Loader did not check signatures prior to 10.0.0. */""")])