diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp index 34c59947..69bf226d 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp @@ -50,16 +50,16 @@ volatile CustomizeTable C = { .emcDvbShift = 0, .marikoSocVmax = 0, /* 0 = stock limits (1450 - 1597 is 1050mV, 1598-1708 is 1025mV, 1709+ is 1000mV). */ -// Primary -.t1_tRCD = 0, -.t2_tRP = 0, -.t3_tRAS = 0, -// Secondary -.t4_tRRD = 0, -.t5_tRFC = 0, -.t6_tRTW = 0, -.t7_tWTR = 0, -.t8_tREFI = 0, +/* Primary. */ +.t1_tRCD = 0, +.t2_tRP = 0, +.t3_tRAS = 0, +/* Secondary. */ +.t4_tRRD = 0, +.t5_tRFC = 0, +.t6_tRTW = 0, +.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... */ diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/customize.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/customize.hpp index f4318cd4..a2d7c21f 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/customize.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/customize.hpp @@ -20,9 +20,8 @@ #pragma once -// Ensure to set KIP_VERSION and CUST_REV in sysmodule Makefile when updating these #define CUST_REV 2 -#define HOC_VERSION 220 +#define KIP_VERSION 220 #include "oc_common.hpp" #include "pcv/pcv_common.hpp" @@ -78,10 +77,10 @@ static_assert(sizeof(CustomizeCpuDvfsTable) == sizeof(pcv::cvb_entry_t) * pcv::D constexpr uint32_t ERISTA_MTC_MAGIC = 0x43544D45; // EMTC constexpr uint32_t MARIKO_MTC_MAGIC = 0x43544D4D; // MMTC -typedef struct CustomizeTable { +struct CustomizeTable { u8 cust[4] = {'C', 'U', 'S', 'T'}; - u32 custRev = CUST_REV; - u32 hocVersion = HOC_VERSION; + u32 custRev = CUST_REV; + u32 kipVersion = KIP_VERSION; u32 hpMode; @@ -169,7 +168,7 @@ typedef struct CustomizeTable { CustomizeGpuDvfsTable marikoGpuDvfsTableSLT; CustomizeGpuDvfsTable marikoGpuDvfsTableHiOPT; -} CustomizeTable; +}; extern volatile CustomizeTable C; diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/mariko/calculate_timings.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/mariko/calculate_timings.cpp index 7133ca36..fca368d8 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/mariko/calculate_timings.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/mariko/calculate_timings.cpp @@ -26,8 +26,8 @@ namespace ams::ldr::hoc::pcv::mariko { return; } - /* Fallback. */ - rext = 0x1A; + /* > 3200 */ + rext = 0x1E; } void SwitchLatency(volatile u32 &latency, u32 index, u32 latencyStep) { @@ -139,27 +139,27 @@ namespace ams::ldr::hoc::pcv::mariko { tRPpbIndex = MIN(C.t2_tRP_cap, C.t2_tRP); } - tRCD = tRCD_values[C.t1_tRCD]; - tRPpb = tRP_values[tRPpbIndex]; - tRAS = tRAS_values[C.t3_tRAS]; - tRRD = tRRD_values[C.t4_tRRD]; - tRFCpb = tRFC_values[C.t5_tRFC]; + tRCD = tRCD_values[C.t1_tRCD]; + tRPpb = tRP_values[tRPpbIndex]; + tRAS = tRAS_values[C.t3_tRAS]; + tRRD = tRRD_values[C.t4_tRRD]; + tRFCpb = tRFC_values[C.t5_tRFC]; u32 tRTW = C.t6_tRTW; u32 tWTR = 10 - tWTR_values[C.t7_tWTR]; if (freq < C.timingEmcTbreak) { - tRTW = C.low_t6_tRTW; + 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; - tRC = tRAS + tRPpb; - tRFCab = tRFCpb * 2; - tXSR = static_cast(tRFCab + 7.5); - tFAW = static_cast(tRRD * 4.0); - tRPab = tRPpb + 3; + tRC = tRAS + tRPpb; + tRFCab = tRFCpb * 2; + tXSR = static_cast(tRFCab + 7.5); + tFAW = static_cast(tRRD * 4.0); + 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 - (tRTW * 3) + finetRTW; diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/oc_log.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/oc_log.cpp index 911ccfae..c6d68bbd 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/oc_log.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/oc_log.cpp @@ -87,7 +87,7 @@ namespace ams::ldr::hoc { static bool initDone = false; log_ctx_t *log_ctx = (log_ctx_t*)working_buf; - SmcCopyFromIram(working_buf, IRAM_LOG_CTX_ADDR, sizeof(working_buf)); + R_DISCARD(SmcCopyFromIram(working_buf, IRAM_LOG_CTX_ADDR, sizeof(working_buf))); if (!initDone) { initDone = true; @@ -103,21 +103,25 @@ namespace ams::ldr::hoc { va_end(args); if (res < 0 || res >= (static_cast(max_log_sz - log_ctx->end))) { - SmcCopyToIram(IRAM_LOG_CTX_ADDR, working_buf, sizeof(working_buf)); + R_DISCARD(SmcCopyToIram(IRAM_LOG_CTX_ADDR, working_buf, sizeof(working_buf))); return; } log_ctx->end += res; - SmcCopyToIram(IRAM_LOG_CTX_ADDR, working_buf, sizeof(working_buf)); + R_DISCARD(SmcCopyToIram(IRAM_LOG_CTX_ADDR, working_buf, sizeof(working_buf))); } #endif #if defined(AMS_BUILD_FOR_AUDITING) || defined(AMS_BUILD_FOR_DEBUGGING) void ViewLog() { + if (spl::GetSocType() == spl::SocType_Mariko) { + return; + } + constexpr size_t PageSize = 4096; for (size_t ofs = 0; ofs < fatal_handler_bin_size; ofs += PageSize) { memcpy(&working_buf, fatal_handler_bin + ofs, std::min(fatal_handler_bin_size - ofs, PageSize)); - SmcCopyToIram(ATMOSPHERE_IRAM_PAYLOAD_BASE + ofs, &working_buf, std::min(fatal_handler_bin_size - ofs, PageSize)); + R_DISCARD(SmcCopyToIram(ATMOSPHERE_IRAM_PAYLOAD_BASE + ofs, &working_buf, std::min(fatal_handler_bin_size - ofs, PageSize))); } SmcRebootToIramPayload(); diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_common.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_common.hpp index 39d3decc..965a325a 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_common.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_common.hpp @@ -22,23 +22,23 @@ namespace ams::ldr::hoc::pcv { - typedef struct cvb_coefficients { + struct cvb_coefficients { s32 c0 = 0; s32 c1 = 0; s32 c2 = 0; s32 c3 = 0; s32 c4 = 0; s32 c5 = 0; - } cvb_coefficients; + }; - typedef struct cvb_entry_t { + struct cvb_entry_t { u64 freq; cvb_coefficients cvb_dfll_param; cvb_coefficients cvb_pll_param; - } cvb_entry_t; + }; static_assert(sizeof(cvb_entry_t) == 0x38); - typedef struct cvb_cpu_dfll_data { + struct cvb_cpu_dfll_data { u32 tune0_low; u32 tune0_high; u32 tune1_low; @@ -46,9 +46,9 @@ namespace ams::ldr::hoc::pcv { unsigned int tune_high_min_millivolts; unsigned int tune_high_margin_millivolts; unsigned long dvco_calibration_max; - } cvb_cpu_dfll_data; + }; - typedef struct __attribute__((packed)) div_nmp { + struct __attribute__((packed)) div_nmp { u8 divn_shift; u8 divn_width; u8 divm_shift; @@ -58,9 +58,9 @@ namespace ams::ldr::hoc::pcv { u8 override_divn_shift; u8 override_divm_shift; u8 override_divp_shift; - } div_nmp; + }; - typedef struct __attribute__((packed)) clk_pll_param { + struct __attribute__((packed)) clk_pll_param { u32 freq; u32 input_min; u32 input_max; @@ -74,9 +74,9 @@ namespace ams::ldr::hoc::pcv { struct div_nmp *div_nmp; u32 unk_1[4]; void (*unk_fn)(u64* unk_struct); // set_defaults? - } clk_pll_param; + }; - typedef struct __attribute__((packed)) dvfs_rail { + struct __attribute__((packed)) dvfs_rail { u32 id; u32 unk_0[5]; u32 freq; @@ -86,9 +86,9 @@ namespace ams::ldr::hoc::pcv { u32 step_mv; u32 max_mv; u32 unk_2[11]; - } dvfs_rail; + }; - typedef struct __attribute__((packed)) regulator { + struct __attribute__((packed)) regulator { u64 id; const char* name; u32 type; @@ -112,7 +112,7 @@ namespace ams::ldr::hoc::pcv { } type_2_3; }; u32 unk_x[60]; - } regulator; + }; static_assert(sizeof(regulator) == 0x120); constexpr u32 CpuClkOSLimit = 1785'000; 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 183fdcac..f655798d 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp @@ -216,7 +216,7 @@ namespace ams::ldr::hoc::pcv::erista { 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_rc, MIN(GET_CYCLE_CEIL(tRC), static_cast(0xB8))); + WRITE_PARAM_ALL_REG(table, emc_rc, MIN(GET_CYCLE_CEIL(tRC), static_cast(0xB9))); WRITE_PARAM_ALL_REG(table, emc_ras, MIN(GET_CYCLE_CEIL(tRAS), static_cast(0x7F))); WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(tRRD)); WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(tRFCpb)); @@ -362,10 +362,6 @@ namespace ams::ldr::hoc::pcv::erista { /* Probably more intuitive to point to 40800 rather than 1600000, but oh well. */ Result MemFreqMtcTable(u32 *ptr) { - if (GET_MAX_OF_ARR(maxEmcClocks) <= EmcClkOSLimit) { - R_SKIP(); - } - u32 khz_list[] = { 40800, 68000, 102000, 204000, 408000, 665600, 800000, 1065600, 1331200, 1600000 }; std::sort(maxEmcClocks, maxEmcClocks + std::size(maxEmcClocks)); u32 khz_list_size = std::size(khz_list); @@ -380,6 +376,10 @@ namespace ams::ldr::hoc::pcv::erista { R_UNLESS(table_list[mtcIndex]->rev == MTC_TABLE_REV, ldr::ResultInvalidMtcTable()); } + if (GET_MAX_OF_ARR(maxEmcClocks) <= EmcClkOSLimit) { + R_SKIP(); + } + /* If we oc ram at all, tables are always shifted by at least 1. */ u32 tableShifts = 1; for (u32 i = 0; i < std::size(maxEmcClocks) - 1; ++i) { @@ -451,21 +451,24 @@ namespace ams::ldr::hoc::pcv::erista { // } void Patch(uintptr_t mapped_nso, size_t nso_size) { + u32 CpuCvbDefaultMaxFreq = static_cast(GetDvfsTableLastEntry(CpuCvbTableDefault)->freq); + u32 GpuCvbDefaultMaxFreq = static_cast(GetDvfsTableLastEntry(GpuCvbTableDefault)->freq); + PatcherEntry patches[] = { - {"CPU Freq Table", CpuFreqCvbTable, 1, nullptr, static_cast(GetDvfsTableLastEntry(CpuCvbTableDefault)->freq)}, - {"CPU Volt DVFS", &CpuVoltDvfs, 1, nullptr, CpuVminOfficial}, - {"CPU Volt Thermals", &CpuVoltThermals, 1, nullptr, CpuVminOfficial}, - {"CPU Volt Dfll", &CpuVoltDfll, 1, nullptr, 0xFFEAD0FF}, - {"GPU Volt DVFS", &GpuVoltDVFS, 1, nullptr, GpuVminOfficial}, - {"GPU Volt Thermals", &GpuVoltThermals, 1, nullptr, GpuVminOfficial}, - {"GPU Freq Table", GpuFreqCvbTable, 1, nullptr, static_cast(GetDvfsTableLastEntry(GpuCvbTableDefault)->freq)}, - {"GPU Freq Asm", &GpuFreqMaxAsm, 2, &GpuMaxClockPatternFn}, - {"GPU PLL Max", &GpuFreqPllMax, 1, nullptr, GpuClkPllMax}, - // {"GPU PLL Limit", &GpuFreqPllLimit, 4, nullptr, GpuClkPllLimit}, - {"MEM Freq Mtc", &MemFreqMtcTable, 0, nullptr, EmcClkOSLimit}, - {"MEM Freq Max", &MemFreqMax, 0, nullptr, EmcClkOSLimit}, - {"MEM Freq PLLM", &MemFreqPllmLimit, 2, nullptr, EmcClkPllmLimit}, - {"MEM Volt", &MemVoltHandler, 2, nullptr, MemVoltHOS}, + {"CPU Freq Table", CpuFreqCvbTable, 1, nullptr, CpuCvbDefaultMaxFreq }, + {"CPU Volt DVFS", &CpuVoltDvfs, 1, nullptr, CpuVminOfficial }, + {"CPU Volt Thermals", &CpuVoltThermals, 1, nullptr, CpuVminOfficial }, + {"CPU Volt Dfll", &CpuVoltDfll, 1, nullptr, CpuTune0Low }, + {"GPU Volt DVFS", &GpuVoltDVFS, 1, nullptr, GpuVminOfficial }, + {"GPU Volt Thermals", &GpuVoltThermals, 1, nullptr, GpuVminOfficial }, + {"GPU Freq Table", GpuFreqCvbTable, 1, nullptr, GpuCvbDefaultMaxFreq }, + {"GPU Freq Asm", &GpuFreqMaxAsm, 2, &GpuMaxClockPatternFn }, + {"GPU PLL Max", & GpuFreqPllMax, 1, nullptr, GpuClkPllMax }, + // {"GPU PLL Limit", &GpuFreqPllLimit, 4, nullptr, GpuClkPllLimit }, + {"MEM Freq Mtc", &MemFreqMtcTable, 0, nullptr, EmcClkOSLimit }, + {"MEM Freq Max", &MemFreqMax, 0, nullptr, EmcClkOSLimit }, + {"MEM Freq PLLM", &MemFreqPllmLimit, 2, nullptr, EmcClkPllmLimit }, + {"MEM Volt", &MemVoltHandler, 2, nullptr, MemVoltHOS }, }; for (uintptr_t ptr = mapped_nso; ptr <= mapped_nso + nso_size - sizeof(EristaMtcTable); ptr += sizeof(u32)) { diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.hpp index c9b180ac..0c590cc4 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.hpp @@ -51,16 +51,16 @@ namespace ams::ldr::hoc::pcv::erista { }; constexpr u32 CpuVoltOfficial = 1227; - constexpr u32 CpuVminOfficial = 825; + constexpr u32 CpuTune0Low = 0xFFEAD0FF; constexpr u32 CpuVoltL4T = 1257'000; static const u32 cpuVoltDvfsPattern[] = { 1227, 1000, 100, 1000, 0 }; - static_assert(sizeof(cpuVoltDvfsPattern) == 0x14, "invalid cpuVoltDvfsPattern size"); + static_assert(sizeof(cpuVoltDvfsPattern) == 0x14, "Invalid cpuVoltDvfsPattern size"); static const u32 cpuVoltageThermalPattern[] = { 950, 1132, 0, 950, 1227, 0, 825, 1227, 15000, 825, 1170, 60000, 825, 1132, 80000 }; - static_assert(sizeof(cpuVoltageThermalPattern) == 0x3c, "invalid cpuVoltageThermalPattern size"); + static_assert(sizeof(cpuVoltageThermalPattern) == 0x3c, "Invalid cpuVoltageThermalPattern size"); constexpr u32 GpuClkPllLimit = 2'600'000; constexpr u32 GpuClkPllMax = 921'600'000; @@ -72,7 +72,7 @@ namespace ams::ldr::hoc::pcv::erista { static_assert(sizeof(gpuVoltDvfsPattern) == (sizeof(u32) * 6), "Invalid gpuVoltDvfsPattern"); static const u32 gpuVoltThermalPattern[] = { 950, 1132, 0, 810, 1132, 15000, 810, 1132, 30000, 810, 1132, 50000, 810, 1132, 70000, 810, 1132, 105000 }; - static_assert(sizeof(gpuVoltThermalPattern) == 0x48, "invalid gpuVoltageThermalPattern size"); + static_assert(sizeof(gpuVoltThermalPattern) == 0x48, "Invalid gpuVoltageThermalPattern size"); /* GPU Max Clock asm Pattern: * @@ -109,8 +109,8 @@ namespace ams::ldr::hoc::pcv::erista { { }, }; - constexpr u32 MemVoltHOS = 1125'000; - constexpr u32 EmcClkMinFreq = 40800; /* 40.8 MHz table only exists on erista. */ + constexpr u32 MemVoltHOS = 1125'000; + constexpr u32 EmcClkMinFreq = 40800; /* 40.8 MHz table only exists on erista. */ constexpr u32 EmcClkPllmLimit = 1866'000'000; constexpr u32 MTC_TABLE_REV = 7; @@ -123,13 +123,13 @@ namespace ams::ldr::hoc::pcv::erista { enum DramId { ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH = 0, ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE = 1, - ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WTC = 2, /* This doesn't have a table in pcv? Wtf? */ + ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WTC = 2, ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH = 4, - ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX = 7, /* No table, but expected */ + ICOSA_8GB_SAMSUNG_K4FBE3D4HM_MGXX = 7, }; enum MtcTableIndex { - T210SdevEmcDvfsTableS4gb01 = 0, /* HB-MGCH */ + T210SdevEmcDvfsTableS4gb01 = 0, /* HB-MGCH, WT:C */ T210SdevEmcDvfsTableS6gb01 = 1, /* HM-MGCH */ T210SdevEmcDvfsTableH4gb01 = 2, /* HR-NLE */ MtcTableIndex_Invalid = 3, @@ -141,9 +141,10 @@ namespace ams::ldr::hoc::pcv::erista { }; constexpr MtcDramIndex mtcIndexTable[] = { - { ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH, T210SdevEmcDvfsTableS4gb01, }, - { ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH, T210SdevEmcDvfsTableS6gb01, }, - { ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE, T210SdevEmcDvfsTableH4gb01, }, + { ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH, T210SdevEmcDvfsTableS4gb01, }, + { ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WTC, T210SdevEmcDvfsTableS4gb01, }, + { ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH, T210SdevEmcDvfsTableS6gb01, }, + { ICOSA_4GB_HYNIX_H9HCNNNBPUMLHR_NLE, T210SdevEmcDvfsTableH4gb01, }, }; void Patch(uintptr_t mapped_nso, size_t nso_size); 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 0a6e7f18..977ac881 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp @@ -79,16 +79,17 @@ namespace ams::ldr::hoc::pcv::mariko { Result CpuFreqVdd(u32 *ptr) { dvfs_rail *entry = reinterpret_cast(reinterpret_cast(ptr) - offsetof(dvfs_rail, freq)); - R_UNLESS(entry->id == 1, ldr::ResultInvalidCpuFreqVddEntry()); - R_UNLESS(entry->min_mv == 250'000, ldr::ResultInvalidCpuFreqVddEntry()); - R_UNLESS(entry->step_mv == 5000, ldr::ResultInvalidCpuFreqVddEntry()); - R_UNLESS(entry->max_mv == 1525'000, ldr::ResultInvalidCpuFreqVddEntry()); + R_UNLESS(entry->id == 1, ldr::ResultInvalidCpuFreqVddEntry()); + R_UNLESS(entry->min_mv == 250'000, ldr::ResultInvalidCpuFreqVddEntry()); + R_UNLESS(entry->step_mv == 5000, ldr::ResultInvalidCpuFreqVddEntry()); + R_UNLESS(entry->max_mv == 1525'000, ldr::ResultInvalidCpuFreqVddEntry()); if (C.marikoCpuUVHigh) { PATCH_OFFSET(ptr, CapCpuClock()); } else { PATCH_OFFSET(ptr, GetDvfsTableLastEntry(C.marikoCpuDvfsTable)->freq); } + R_SUCCEED(); } @@ -373,7 +374,7 @@ namespace ams::ldr::hoc::pcv::mariko { 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_rc, MIN(GET_CYCLE_CEIL(tRC), static_cast(0xB8))); + WRITE_PARAM_ALL_REG(table, emc_rc, MIN(GET_CYCLE_CEIL(tRC), static_cast(0xB9))); WRITE_PARAM_ALL_REG(table, emc_ras, MIN(GET_CYCLE_CEIL(tRAS), static_cast(0x7F))); WRITE_PARAM_ALL_REG(table, emc_rrd, GET_CYCLE_CEIL(tRRD)); WRITE_PARAM_ALL_REG(table, emc_rfcpb, GET_CYCLE_CEIL(tRFCpb)); @@ -432,22 +433,21 @@ namespace ams::ldr::hoc::pcv::mariko { WRITE_PARAM_ALL_REG(table, emc_rdv_early_mask, rdv); WRITE_PARAM_ALL_REG(table, emc_rdv_mask, rdv + 2); WRITE_PARAM_ALL_REG(table, emc_tr_rdv, rdv); - /* TODO: Check this out again at some point. */ WRITE_PARAM_ALL_REG(table, emc_cmd_brlshft_2, 0x24); WRITE_PARAM_ALL_REG(table, emc_cmd_brlshft_3, 0x24); /* This needs some clean up. */ constexpr double MC_ARB_DIV = 4.0; - constexpr u32 MC_ARB_SFA = 2; + constexpr u32 MC_ARB_SFA = 2; - table->burst_mc_regs.mc_emem_arb_cfg = table->rate_khz / (33.3 * 1000) / MC_ARB_DIV; - 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; - 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_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_rfcpb = CEIL(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV) - 1; + table->burst_mc_regs.mc_emem_arb_cfg = table->rate_khz / (33.3 * 1000) / MC_ARB_DIV; + 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; + 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_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_rfcpb = CEIL(GET_CYCLE_CEIL(tRFCpb) / MC_ARB_DIV) - 1; table->burst_mc_regs.mc_emem_arb_timing_rap2pre = CEIL(tR2P / MC_ARB_DIV); table->burst_mc_regs.mc_emem_arb_timing_wap2pre = CEIL(tW2P / MC_ARB_DIV) + MC_ARB_SFA; @@ -520,12 +520,12 @@ namespace ams::ldr::hoc::pcv::mariko { table->la_scale_regs.mc_latency_allowance_hc_1 = (table->la_scale_regs.mc_latency_allowance_hc_1 & Mask2) | allowance1; table->la_scale_regs.mc_latency_allowance_vi2_0 = (table->la_scale_regs.mc_latency_allowance_vi2_0 & Mask2) | allowance1; - table->dram_timings.t_rp = tRFCpb; + table->dram_timings.t_rp = tRFCpb; table->dram_timings.t_rfc = tRFCab; table->dram_timings.rl = RL; - table->emc_mrw2 = (table->emc_mrw2 & ~0xFFu) | static_cast(mrw2); - table->emc_cfg_2 = 0x11083D; + table->emc_mrw2 = (table->emc_mrw2 & ~0xFFu) | static_cast(mrw2); + table->emc_cfg_2 = 0x11083D; } void MemMtcPllmbDivisor(MarikoMtcTable *table) { @@ -538,11 +538,11 @@ namespace ams::ldr::hoc::pcv::mariko { bool remainder_check = (table->rate_khz - PllOscInKHz * (table->rate_khz / PllOscInKHz)) > (table->rate_khz - PllOscHalfKHz * divm_candidate_half) && static_cast(((target_freq_d / PllOscHalfKHz - divm_candidate_half - 0.5) * 8192.0)) != 0; - u32 divm_final = remainder_check + 1; + u32 divm_final = remainder_check + 1; table->pllmb_divm = divm_final; double div_step_d = static_cast(PllOscInKHz) / divm_final; - s32 divn_integer = static_cast(table->rate_khz / div_step_d); + s32 divn_integer = static_cast(table->rate_khz / div_step_d); table->pllmb_divn = divn_integer; u32 divn_fraction = static_cast((target_freq_d / div_step_d - divn_integer - 0.5) * 8192.0); @@ -553,34 +553,34 @@ namespace ams::ldr::hoc::pcv::mariko { s32 divn_fraction_ssc = static_cast((actual_freq_khz * 0.997 / div_step_d - divn_integer - 0.5) * 8192.0); double delta_scaled = (0.3 / div_step_d + 0.3 / div_step_d) * (divn_fraction - divn_fraction_ssc); - s32 delta_int = static_cast(delta_scaled); - double delta_frac = delta_scaled - delta_int; + s32 delta_int = static_cast(delta_scaled); + double delta_frac = delta_scaled - delta_int; u32 setup_value = 0; if (delta_frac <= 0.5) { double round_val = (delta_int + ROUND(delta_frac + delta_frac)) ? 0.5 : 0.0; - setup_value = ROUND(delta_frac + delta_frac) ? static_cast(round_val + round_val) | 0x1000 : static_cast(round_val); + setup_value = ROUND(delta_frac + delta_frac) ? static_cast(round_val + round_val) | 0x1000 : static_cast(round_val); } else { s32 frac_doubled = ROUND(delta_frac - 0.5 + delta_frac - 0.5); double round_val = 1.0; - setup_value = frac_doubled ? static_cast(round_val) : static_cast(round_val + round_val) | 0x1000; + setup_value = frac_doubled ? static_cast(round_val) : static_cast(round_val + round_val) | 0x1000; } u32 ctrl1 = static_cast(divn_fraction_ssc) | (static_cast(divn_fraction) << 16); - u32 ctrl2 = static_cast(divn_fraction) | (static_cast(setup_value) << 16); + u32 ctrl2 = static_cast(divn_fraction) | (static_cast(setup_value) << 16); - table->pllm_ss_ctrl1 = ctrl1; - table->pllm_ss_ctrl2 = ctrl2; + table->pllm_ss_ctrl1 = ctrl1; + table->pllm_ss_ctrl2 = ctrl2; table->pllmb_ss_ctrl1 = ctrl1; table->pllmb_ss_ctrl2 = ctrl2; } else { - table->pllm_ss_cfg &= 0xBFFFFFFF; + table->pllm_ss_cfg &= 0xBFFFFFFF; table->pllmb_ss_cfg &= 0xBFFFFFFF; - u64 pair = (static_cast(divn_fraction) << 32) | static_cast(table->rate_khz); - u32 pll_misc = (table->pllm_ss_ctrl2 & 0xFFFF0000) | static_cast((pair - actual_freq_khz) >> 32); + u64 pair = (static_cast(divn_fraction) << 32) | static_cast(table->rate_khz); + u32 pll_misc = (table->pllm_ss_ctrl2 & 0xFFFF0000) | static_cast((pair - actual_freq_khz) >> 32); - table->pllm_ss_ctrl2 = pll_misc; + table->pllm_ss_ctrl2 = pll_misc; table->pllmb_ss_ctrl2 = pll_misc; } } @@ -945,8 +945,9 @@ namespace ams::ldr::hoc::pcv::mariko { u8 movRd = asm_get_rd(mov); u32 movCountPatch = asm_set_rd(asm_set_imm16(MtcMovAsm, newEmcList.size()), movRd); - PATCH_OFFSET(ptr - BrOffset, NopIns); + PATCH_OFFSET(ptr - BrOffset, NopIns); PATCH_OFFSET(ptr - MovOffset, movCountPatch); + R_SUCCEED(); }