nso start check, timing tbreak and some horrendous ui code

This commit is contained in:
Lightos1
2026-04-18 23:00:21 +02:00
parent 822e9f2817
commit 6a851d4095
8 changed files with 143 additions and 14 deletions

View File

@@ -59,8 +59,15 @@ volatile CustomizeTable C = {
.t7_tWTR = 0,
.t8_tREFI = 0,
/* At 1333WL, for some reason (incorrect ram timing config in mtc table?), tRP causes crashes at high reductions - 2 seems to be the most common limit. */
/* This is a lazy workaround until I find the issue... */
.t2_tRP_cap = 2,
/* Frequency where non low timings gets used. */
.timingEmcTbreak = DISABLED,
.low_t6_tRTW = DISABLED,
.low_t7_tWTR = DISABLED,
.readLatency = {
2133000,
2400000,

View File

@@ -105,6 +105,10 @@ typedef struct CustomizeTable {
u32 t2_tRP_cap;
u32 timingEmcTbreak;
u32 low_t6_tRTW;
u32 low_t7_tWTR;
u32 readLatency[4];
u32 writeLatency[4];

View File

@@ -146,14 +146,17 @@ namespace ams::ldr::hoc::pcv::mariko {
tRAS = tRAS_values[C.t3_tRAS];
tRRD = tRRD_values[C.t4_tRRD];
tRFCpb = tRFC_values[C.t5_tRFC];
u32 tWTR = 10 - tWTR_values[C.t7_tWTR];
u32 tRTW = C.t6_tRTW;
u32 tWTR = 10 - tWTR_values[C.t7_tWTR];
if (freq < C.timingEmcTbreak) {
tRTW = C.low_t6_tRTW;
tWTR = 10 - tWTR_values[C.low_t7_tWTR];
}
s32 finetRTW = C.fineTune_t6_tRTW;
s32 finetWTR = C.fineTune_t7_tWTR;
Log("Freq: %u\n", freq);
Log("WL: %u\n", WL);
Log("tRP value: %u\n\n", tRPpb);
tRC = tRAS + tRPpb;
tRFCab = tRFCpb * 2;
tXSR = static_cast<double>(tRFCab + 7.5);
@@ -161,7 +164,7 @@ namespace ams::ldr::hoc::pcv::mariko {
tRPab = tRPpb + 3;
tR2P = CEIL((RL * 0.426) - 2.0);
tR2W = FLOOR(FLOOR((5.0 / tCK_avg) + ((FLOOR(48.0 / WL) - 0.478) * 3.0)) / 1.501) + RL - (C.t6_tRTW * 3) + finetRTW;
tR2W = FLOOR(FLOOR((5.0 / tCK_avg) + ((FLOOR(48.0 / WL) - 0.478) * 3.0)) / 1.501) + RL - (tRTW * 3) + finetRTW;
tRTM = FLOOR((10.0 + RL) + (3.502 / tCK_avg)) + FLOOR(7.489 / tCK_avg);
tRATM = CEIL((tRTM - 10.0) + (RL * 0.426));

View File

@@ -591,7 +591,11 @@ namespace ams::ldr::hoc::pcv::mariko {
}
}
std::vector<u32> newEmcList;
namespace {
std::vector<u32> newEmcList;
u32 *nsoStart;
}
void MtcGenerateJedecTable() {
const u32 jedecFreqs[] = { 1866000, 1996000, 2133000, 2400000, 2666000, 2933000, 3200000 };
constexpr u32 JedecFreqCount = std::size(jedecFreqs);
@@ -718,6 +722,7 @@ namespace ams::ldr::hoc::pcv::mariko {
static const DramId dramId = [] {
DramId id = GetDramId();
id = IOWA_4GB_SAMSUNG_K4U6E3S4AA_MGCL;
return id;
}();
@@ -877,29 +882,37 @@ namespace ams::ldr::hoc::pcv::mariko {
}
Result MemMtcTableAsm(u32 *ptr) {
u32 adrp = *(ptr - 1);
constexpr u32 AddpOffset = 1;
constexpr u32 BrOffset = 12;
constexpr u32 MovOffset = 10;
/* Ensure we don't dereference memory before nso start. */
R_UNLESS(ptr - BrOffset >= nsoStart, ldr::ResultInvalidMtcTable());
u32 adrp = *(ptr - AddpOffset);
R_UNLESS(AsmCompareAdrpNoImm(adrp, MtcAdrpAsm), ldr::ResultInvalidMtcTable());
/* We don't check for matching register because both registers must be x0 in order to pass the previous checks. */
/* The correct instructions will always be x0 since the mtcTable pointer is returned. */
/* Pray this does not break. */
u32 br = *(ptr - 12);
u32 br = *(ptr - BrOffset);
R_UNLESS(AsmCompareBrNoRd(br, MtcBrAsm), ldr::ResultInvalidMtcTable());
/* Pray this does not break either. */
u32 mov = *(ptr - 10);
u32 mov = *(ptr - MovOffset);
R_UNLESS(asm_compare_no_rd(mov, MtcMovAsm), ldr::ResultInvalidMtcTable());
u8 movRd = asm_get_rd(mov);
u32 movCountPatch = asm_set_rd(asm_set_imm16(MtcMovAsm, newEmcList.size()), movRd);
PATCH_OFFSET(ptr - 12, NopIns);
PATCH_OFFSET(ptr - 10, movCountPatch);
PATCH_OFFSET(ptr - BrOffset, NopIns);
PATCH_OFFSET(ptr - MovOffset, movCountPatch);
R_SUCCEED();
}
void Patch(uintptr_t mapped_nso, size_t nso_size) {
nsoStart = reinterpret_cast<u32 *>(mapped_nso);
MtcGenerateFreqTables();
u32 CpuCvbDefaultMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(CpuCvbTableDefault)->freq);
u32 GpuCvbDefaultMaxFreq = static_cast<u32>(GetDvfsTableLastEntry(GpuCvbTableDefault)->freq);

View File

@@ -94,6 +94,10 @@ typedef enum {
KipConfigValue_t7_tWTR,
KipConfigValue_t8_tREFI,
KipConfigValue_timingEmcTbreak,
KipConfigValue_low_t6_tRTW,
KipConfigValue_low_t7_tWTR,
KipConfigValue_t2_tRP_cap,
KipConfigValue_read_latency_1333,
@@ -325,6 +329,13 @@ static inline const char* hocclkFormatConfigValue(HocClkConfigValue val, bool pr
case KipConfigValue_t8_tREFI:
return pretty ? "t8 - tREFI" : "t8_trefi";
case KipConfigValue_timingEmcTbreak:
return pretty ? "Timing Emc Tbreak" : "timingEmcTbreak";
case KipConfigValue_low_t6_tRTW:
return pretty ? "Low T6 - tRTW" : "low_t6_tRTW";
case KipConfigValue_low_t7_tWTR:
return pretty ? "Low T7 - tWTR" : "low_t7_tWTR";
case KipConfigValue_t2_tRP_cap:
return pretty ? "t2 - trp 1333WL Cap" : "t2_tRP_cap";
@@ -563,6 +574,9 @@ static inline uint64_t hocclkValidConfigValue(HocClkConfigValue val, uint64_t in
case KipConfigValue_t6_tRTW:
case KipConfigValue_t7_tWTR:
case KipConfigValue_t8_tREFI:
case KipConfigValue_timingEmcTbreak:
case KipConfigValue_low_t6_tRTW:
case KipConfigValue_low_t7_tWTR:
case KipConfigValue_t2_tRP_cap:
case KipConfigValue_read_latency_1333:
case KipConfigValue_read_latency_1600:

View File

@@ -897,6 +897,7 @@ protected:
freqSubmenu->setValue(R_ARROW);
this->listElement->addItem(freqSubmenu);
} else {
RamDisplayUnit unit = (RamDisplayUnit)this->configList->values[HocClkConfigValue_RamDisplayUnit];
std::vector<NamedValue> marikoMaxEmcClock = {
NamedValue("1600 MHz", 1600000),
NamedValue("1633 MHz", 1633000),
@@ -958,8 +959,6 @@ protected:
// NamedValue("3466MHz (Needs ridiculous Speedo/PLL)", 3466000),
// NamedValue("3500MHz (Needs ridiculous Speedo/PLL)", 3500000),
};
RamDisplayUnit unit = (RamDisplayUnit)this->configList->values[HocClkConfigValue_RamDisplayUnit];
for (auto& nv : marikoMaxEmcClock)
nv.name = formatMemClockKhzLabel(nv.value, unit);
@@ -1031,7 +1030,79 @@ protected:
NamedValue("+3", 3),
};
/* Yes this is duplicated code, yes I don't care. */
std::vector<NamedValue> timingTbreakFreqs = {
NamedValue("Disabled", 0),
NamedValue("1633 MHz", 1633000),
NamedValue("1666 MHz", 1666000),
NamedValue("1700 MHz", 1700000),
NamedValue("1733 MHz", 1733000),
NamedValue("1766 MHz", 1766000),
NamedValue("1800 MHz", 1800000),
NamedValue("1833 MHz", 1833000),
NamedValue("1866 MHz", 1866000, "JEDEC."),
NamedValue("1900 MHz", 1900000),
NamedValue("1933 MHz", 1933000),
NamedValue("1966 MHz", 1966000),
NamedValue("1996 MHz", 1996800, "JEDEC."),
NamedValue("2000 MHz", 2000000),
NamedValue("2033 MHz", 2033000),
NamedValue("2066 MHz", 2066000),
NamedValue("2100 MHz", 2100000),
NamedValue("2133 MHz", 2133000, "JEDEC."),
NamedValue("2166 MHz", 2166000),
NamedValue("2200 MHz", 2200000),
NamedValue("2233 MHz", 2233000),
NamedValue("2266 MHz", 2266000),
NamedValue("2300 MHz", 2300000),
NamedValue("2333 MHz", 2333000),
NamedValue("2366 MHz", 2366000),
NamedValue("2400 MHz", 2400000, "JEDEC."),
NamedValue("2433 MHz", 2433000),
NamedValue("2466 MHz", 2466000),
NamedValue("2500 MHz", 2500000),
NamedValue("2533 MHz", 2533000),
NamedValue("2566 MHz", 2566000),
NamedValue("2600 MHz", 2600000),
NamedValue("2633 MHz", 2633000),
NamedValue("2666 MHz", 2666000, "JEDEC."),
NamedValue("2700 MHz", 2700000),
NamedValue("2733 MHz", 2733000),
NamedValue("2766 MHz", 2766000),
NamedValue("2800 MHz", 2800000),
NamedValue("2833 MHz", 2833000),
NamedValue("2866 MHz", 2866000),
NamedValue("2900 MHz", 2900000),
NamedValue("2933 MHz", 2933000, "JEDEC."),
NamedValue("2966 MHz", 2966000),
NamedValue("3000 MHz", 3000000),
NamedValue("3033 MHz", 3033000),
NamedValue("3066 MHz", 3066000),
NamedValue("3100 MHz", 3100000),
NamedValue("3133 MHz", 3133000),
NamedValue("3166 MHz", 3166000),
NamedValue("3200 MHz", 3200000, "JEDEC."),
NamedValue("3233 MHz", 3233000, "High speedo needed"),
NamedValue("3266 MHz", 3266000, "High speedo needed!"),
NamedValue("3300 MHz", 3300000, "High speedo needed!"),
// NamedValue("3333MHz (Needs extreme Speedo/PLL)", 3333000),
// NamedValue("3366MHz (Needs extreme Speedo/PLL)", 3366000),
// NamedValue("3400MHz (Needs extreme Speedo/PLL)", 3400000),
// NamedValue("3433MHz (Needs ridiculous Speedo/PLL)", 3433000),
// NamedValue("3466MHz (Needs ridiculous Speedo/PLL)", 3466000),
// NamedValue("3500MHz (Needs ridiculous Speedo/PLL)", 3500000),
};
RamDisplayUnit unit = (RamDisplayUnit)this->configList->values[HocClkConfigValue_RamDisplayUnit];
for (size_t i = 1; i < timingTbreakFreqs.size(); ++i) {
auto &nv = timingTbreakFreqs[i];
nv.name = formatMemClockKhzLabel(nv.value, unit);
}
this->listElement->addItem(new tsl::elm::CategoryHeader("Advanced"));
addConfigButton(KipConfigValue_timingEmcTbreak, "RAM-Timing tBreak", ValueRange(0, 1, 1, "", 1), "tBreak", &thresholdsDisabled, {}, timingTbreakFreqs, false, true);
addConfigButton(KipConfigValue_low_t6_tRTW, "Low t6 tRTW", ValueRange(0, 10, 1, "", 1), "low tRTW", &thresholdsDisabled, {}, {}, false, true );
addConfigButton(KipConfigValue_low_t7_tWTR, "Low t7 tWTR", ValueRange(0, 10, 1, "", 1), "low tWTR", &thresholdsDisabled, {}, {}, false, true );
addConfigButton(KipConfigValue_t2_tRP_cap, "1333WL t2 RP Cap", ValueRange(0, 8, 1, "", 1), "tRP Cap", &thresholdsDisabled, {}, {}, false, true );
addConfigButton(KipConfigValue_t6_tRTW_fine_tune, "t6 tRTW Fine Tune", ValueRange(0, 4, 1, "", 0), "tRTW Fine Tune", &thresholdsDisabled, {}, t6_tRTW_fine_tune, false, true);
addConfigButton(KipConfigValue_t7_tWTR_fine_tune, "t7 tWTR Fine Tune", ValueRange(0, 6, 1, "", 0), "tWTR Fine Tune", &thresholdsDisabled, {}, t7_tWTR_fine_tune, false, true);

View File

@@ -71,6 +71,10 @@ namespace kip {
CUST_WRITE_FIELD_BATCH(&table, t7_tWTR, config::GetConfigValue(KipConfigValue_t7_tWTR));
CUST_WRITE_FIELD_BATCH(&table, t8_tREFI, config::GetConfigValue(KipConfigValue_t8_tREFI));
CUST_WRITE_FIELD_BATCH(&table, stepMode, config::GetConfigValue(KipConfigValue_stepMode));
CUST_WRITE_FIELD_BATCH(&table, timingEmcTbreak, config::GetConfigValue(KipConfigValue_timingEmcTbreak));
CUST_WRITE_FIELD_BATCH(&table, low_t6_tRTW, config::GetConfigValue(KipConfigValue_low_t6_tRTW));
CUST_WRITE_FIELD_BATCH(&table, low_t7_tWTR, config::GetConfigValue(KipConfigValue_low_t7_tWTR));
CUST_WRITE_FIELD_BATCH(&table, t2_tRP_cap, config::GetConfigValue(KipConfigValue_t2_tRP_cap));
CUST_WRITE_FIELD_BATCH(&table, readLatency1333, config::GetConfigValue(KipConfigValue_read_latency_1333));
@@ -202,6 +206,9 @@ namespace kip {
configValues.values[KipConfigValue_t8_tREFI] = cust_get_tREFI(&table);
configValues.values[KipConfigValue_stepMode] = cust_get_step_mode(&table);
configValues.values[KipConfigValue_timingEmcTbreak] = cust_get_timing_emc_tbreak(&table);
configValues.values[KipConfigValue_low_t6_tRTW] = cust_get_low_t6_tRTW(&table);
configValues.values[KipConfigValue_low_t7_tWTR] = cust_get_low_t7_tWTR(&table);
configValues.values[KipConfigValue_t2_tRP_cap] = cust_get_tRP_cap(&table);
configValues.values[KipConfigValue_read_latency_1333] = cust_get_read_latency_1333(&table);

View File

@@ -56,6 +56,10 @@ namespace kip {
u32 t2_tRP_cap;
u32 timingEmcTbreak;
u32 low_t6_tRTW;
u32 low_t7_tWTR;
/* These latencies are arrays in loader, but it's easier to handle it this way in the configurator. */
u32 readLatency1333, readLatency1600, readLatency1866, readLatency2133;
u32 writeLatency1333, writeLatency1600, writeLatency1866, writeLatency2133;
@@ -222,6 +226,9 @@ namespace kip {
static inline bool cust_set_tWTR(const char* p, u32 v) { CUST_WRITE_FIELD(p, t7_tWTR, v); }
static inline bool cust_set_tREFI(const char* p, u32 v) { CUST_WRITE_FIELD(p, t8_tREFI, v); }
static inline bool cust_set_tRP_cap(const char* p, u32 v) { CUST_WRITE_FIELD(p, t2_tRP_cap, v); }
static inline bool cust_set_timing_emc_tbreak(const char* p, u32 v) { CUST_WRITE_FIELD(p, timingEmcTbreak, v); }
static inline bool cust_set_low_tRTW(const char* p, u32 v) { CUST_WRITE_FIELD(p, low_t6_tRTW, v); }
static inline bool cust_set_low_tWTR(const char* p, u32 v) { CUST_WRITE_FIELD(p, low_t7_tWTR, v); }
static inline bool cust_set_tRTW_fine_tune(const char* p, u32 v) { CUST_WRITE_FIELD(p, t6_tRTW_fine_tune, v); }
static inline bool cust_set_tWTR_fine_tune(const char* p, u32 v) { CUST_WRITE_FIELD(p, t7_tWTR_fine_tune, v); }
@@ -306,6 +313,9 @@ namespace kip {
static inline u32 cust_get_tWTR(const CustomizeTable* t) { return CUST_GET_FIELD(t, t7_tWTR); }
static inline u32 cust_get_tREFI(const CustomizeTable* t) { return CUST_GET_FIELD(t, t8_tREFI); }
static inline u32 cust_get_tRP_cap(const CustomizeTable* t) { return CUST_GET_FIELD(t, t2_tRP_cap); }
static inline u32 cust_get_timing_emc_tbreak(const CustomizeTable* t) { return CUST_GET_FIELD(t, timingEmcTbreak); }
static inline u32 cust_get_low_t6_tRTW(const CustomizeTable* t) { return CUST_GET_FIELD(t, low_t6_tRTW); }
static inline u32 cust_get_low_t7_tWTR(const CustomizeTable* t) { return CUST_GET_FIELD(t, low_t7_tWTR); }
static inline u32 cust_get_tRTW_fine_tune(const CustomizeTable* t) { return CUST_GET_FIELD(t, t6_tRTW_fine_tune); }
static inline u32 cust_get_tWTR_fine_tune(const CustomizeTable* t) { return CUST_GET_FIELD(t, t7_tWTR_fine_tune); }