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 10e70395..3ba1d333 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_common.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_common.hpp @@ -125,7 +125,7 @@ namespace ams::ldr::hoc::pcv { u32 unkStepMaybe; u32 vmin; u32 unkZero4[3]; - u32 pllMinMilliVoltsMaybe; + u32 pllMinMilliVolts; u32 vmax; u32 unkScale2; u32 speedoScale; 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 6cad4558..0d42cd67 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.cpp @@ -67,10 +67,11 @@ namespace ams::ldr::hoc::pcv::erista { Result CpuVoltDfll(u32* ptr) { CvbCpuDfllData *entry = reinterpret_cast(ptr); - R_UNLESS(entry->tune0_low == 0xFFEAD0FF, ldr::ResultInvalidCpuVoltDfllEntry()); - R_UNLESS(entry->tune0_high == 0x0, ldr::ResultInvalidCpuVoltDfllEntry()); - R_UNLESS(entry->tune1_low == 0x0, ldr::ResultInvalidCpuVoltDfllEntry()); - R_UNLESS(entry->tune1_high == 0x0, ldr::ResultInvalidCpuVoltDfllEntry()); + + R_UNLESS(entry->tune0_low == 0xFFEAD0FF, ldr::ResultInvalidCpuVoltDfllEntry()); + R_UNLESS(entry->tune0_high == 0x0, ldr::ResultInvalidCpuVoltDfllEntry()); + R_UNLESS(entry->tune1_low == 0x0, ldr::ResultInvalidCpuVoltDfllEntry()); + R_UNLESS(entry->tune1_high == 0x0, ldr::ResultInvalidCpuVoltDfllEntry()); if (!C.eristaCpuUV) { R_SKIP(); @@ -100,6 +101,7 @@ namespace ams::ldr::hoc::pcv::erista { default: break; } + R_SUCCEED(); } @@ -121,10 +123,10 @@ namespace ams::ldr::hoc::pcv::erista { } if (C.eristaGpuVmin) { - PATCH_OFFSET(ptr , C.eristaGpuVmin); - PATCH_OFFSET(ptr + 3, C.eristaGpuVmin); - PATCH_OFFSET(ptr + 6, C.eristaGpuVmin); - PATCH_OFFSET(ptr + 9, C.eristaGpuVmin); + PATCH_OFFSET(ptr, C.eristaGpuVmin); + PATCH_OFFSET(ptr + 3, C.eristaGpuVmin); + PATCH_OFFSET(ptr + 6, C.eristaGpuVmin); + PATCH_OFFSET(ptr + 9, C.eristaGpuVmin); PATCH_OFFSET(ptr + 12, C.eristaGpuVmin); } @@ -165,8 +167,10 @@ namespace ams::ldr::hoc::pcv::erista { } u32 asm_patch[2] = { asm_set_rd(asm_set_imm16(GpuAsmPattern[0], max_clock), rd), - asm_set_rd(asm_set_imm16(GpuAsmPattern[1], max_clock >> 16), rd)}; - PATCH_OFFSET(ptr32, asm_patch[0]); + asm_set_rd(asm_set_imm16(GpuAsmPattern[1], max_clock >> 16), rd) + }; + + PATCH_OFFSET(ptr32, asm_patch[0]); PATCH_OFFSET(ptr32 + 1, asm_patch[1]); R_SUCCEED(); @@ -210,7 +214,9 @@ namespace ams::ldr::hoc::pcv::erista { } u32 trefbw = refresh_raw + 0x40; - trefbw = MIN(trefbw, static_cast(0x3FFF)); + trefbw = MIN(trefbw, static_cast(0x3FFF)); + + const u32 dyn_self_ref_control = (static_cast(7605.0 / tCK_avg) + 260) | (table->burst_regs.emc_dyn_self_ref_control & 0xffff0000); CalculateTimings(tCK_avg); @@ -239,7 +245,6 @@ namespace ams::ldr::hoc::pcv::erista { WRITE_PARAM_ALL_REG(table, emc_refresh, refresh_raw); WRITE_PARAM_ALL_REG(table, emc_pre_refresh_req_cnt, refresh_raw / 4); WRITE_PARAM_ALL_REG(table, emc_trefbw, trefbw); - const u32 dyn_self_ref_control = (static_cast(7605.0 / tCK_avg) + 260) | (table->burst_regs.emc_dyn_self_ref_control & 0xffff0000); WRITE_PARAM_ALL_REG(table, emc_dyn_self_ref_control, dyn_self_ref_control); WRITE_PARAM_ALL_REG(table, emc_pdex2wr, pdex2rw); WRITE_PARAM_ALL_REG(table, emc_pdex2rd, pdex2rw); @@ -280,7 +285,7 @@ namespace ams::ldr::hoc::pcv::erista { /* 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; @@ -325,8 +330,8 @@ namespace ams::ldr::hoc::pcv::erista { table->la_scale_regs.mc_ptsa_grant_decrement = grant_decrement; constexpr u32 MaskHigh = 0xFF00FFFF; - constexpr u32 Mask2 = 0xFFFFFF00; - constexpr u32 Mask3 = 0xFF00FF00; + constexpr u32 Mask2 = 0xFFFFFF00; + constexpr u32 Mask3 = 0xFF00FF00; const u32 allowance1 = static_cast(0x32000 / (table->rate_khz / 0x3E8)) & 0xFF; const u32 allowance2 = static_cast(0x9C40 / (table->rate_khz / 0x3E8)) & 0xFF; @@ -354,10 +359,10 @@ namespace ams::ldr::hoc::pcv::erista { 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->emc_cfg_2 = 0x11083D; - table->min_volt = (u32)std::min(static_cast(1050), 900 + C.emcDvbShift * 25); + table->emc_cfg_2 = 0x11083D; + table->min_volt = std::clamp(900 + (C.emcDvbShift * 25), 900, 1050); } /* Probably more intuitive to point to 40800 rather than 1600000, but oh well. */ 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 0c590cc4..11f9041d 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_erista.hpp @@ -140,7 +140,7 @@ namespace ams::ldr::hoc::pcv::erista { MtcTableIndex index; }; - constexpr MtcDramIndex mtcIndexTable[] = { + const inline MtcDramIndex mtcIndexTable[] = { { ICOSA_4GB_SAMSUNG_K4F6E304HB_MGCH, T210SdevEmcDvfsTableS4gb01, }, { ICOSA_4GB_MICRON_MT53B512M32D2NP_062_WTC, T210SdevEmcDvfsTableS4gb01, }, { ICOSA_6GB_SAMSUNG_K4FHE3D4HM_MGCH, T210SdevEmcDvfsTableS6gb01, }, 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 2427da54..7df32b54 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.cpp @@ -94,23 +94,29 @@ namespace ams::ldr::hoc::pcv::mariko { } Result CpuVoltDVFS(u32 *ptr) { - if (MatchesPattern(ptr, cpuVoltagePatchOffsets, cpuVoltagePatchValues)) { - if (C.marikoCpuLowVmin) { - PATCH_OFFSET(ptr, C.marikoCpuLowVmin); - } + CvbMeta *cpuCvbMeta = reinterpret_cast(reinterpret_cast(ptr) - offsetof(CvbMeta, vmin)); - if (C.marikoCpuHighVmin) { - PATCH_OFFSET(ptr - 2, C.marikoCpuHighVmin); - } + R_UNLESS(cpuCvbMeta->highVmin == CpuHighVminOfficial, ldr::ResultInvalidCpuMinVolt()); + R_UNLESS(cpuCvbMeta->unkStepMaybe == 38, ldr::ResultInvalidCpuMinVolt()); + R_UNLESS(cpuCvbMeta->vmax == CpuVoltOfficial, ldr::ResultInvalidCpuMinVolt()); + R_UNLESS(cpuCvbMeta->unkScale2 == 1000, ldr::ResultInvalidCpuMinVolt()); + R_UNLESS(cpuCvbMeta->speedoScale == 100, ldr::ResultInvalidCpuMinVolt()); + R_UNLESS(cpuCvbMeta->voltageScale == 1000, ldr::ResultInvalidCpuMinVolt()); + R_UNLESS(cpuCvbMeta->unkZero5 == 0, ldr::ResultInvalidCpuMinVolt()); - if (C.marikoCpuMaxVolt) { - PATCH_OFFSET(ptr + 5, C.marikoCpuMaxVolt); - } - - R_SUCCEED(); + if (C.marikoCpuLowVmin) { + PATCH_OFFSET(&(cpuCvbMeta->vmin), C.marikoCpuLowVmin); } - R_THROW(ldr::ResultInvalidCpuMinVolt()); + if (C.marikoCpuHighVmin) { + PATCH_OFFSET(&(cpuCvbMeta->highVmin), C.marikoCpuHighVmin); + } + + if (C.marikoCpuMaxVolt) { + PATCH_OFFSET(&(cpuCvbMeta->vmax), C.marikoCpuMaxVolt); + } + + R_SUCCEED(); } Result CpuVoltThermals(u32 *ptr) { @@ -136,78 +142,78 @@ namespace ams::ldr::hoc::pcv::mariko { Result CpuVoltDfll(u32 *ptr) { CvbCpuDfllData *entry = reinterpret_cast(ptr); - R_UNLESS(entry->tune0_low == 0xFFCF, ldr::ResultInvalidCpuVoltDfllEntry()); - R_UNLESS(entry->tune0_high == 0x0, ldr::ResultInvalidCpuVoltDfllEntry()); - R_UNLESS(entry->tune1_low == 0x12207FF, ldr::ResultInvalidCpuVoltDfllEntry()); + R_UNLESS(entry->tune0_low == 0xFFCF, ldr::ResultInvalidCpuVoltDfllEntry()); + R_UNLESS(entry->tune0_high == 0x0, ldr::ResultInvalidCpuVoltDfllEntry()); + R_UNLESS(entry->tune1_low == 0x12207FF, ldr::ResultInvalidCpuVoltDfllEntry()); R_UNLESS(entry->tune1_high == 0x3FFF7FF, ldr::ResultInvalidCpuVoltDfllEntry()); switch (C.marikoCpuUVLow) { case 1: - PATCH_OFFSET(&(entry->tune0_low), 0xffa0); + PATCH_OFFSET(&(entry->tune0_low), 0xffa0); PATCH_OFFSET(&(entry->tune0_high), 0xffff); - PATCH_OFFSET(&(entry->tune1_low), 0x21107ff); - PATCH_OFFSET(&(entry->tune1_high), 0); + PATCH_OFFSET(&(entry->tune1_low), 0x21107ff); + PATCH_OFFSET(&(entry->tune1_high), 0x0); break; case 2: PATCH_OFFSET(&(entry->tune0_high), 0xffdf); - PATCH_OFFSET(&(entry->tune1_low), 0x21107ff); + PATCH_OFFSET(&(entry->tune1_low), 0x21107ff); PATCH_OFFSET(&(entry->tune1_high), 0x27207ff); break; case 3: - PATCH_OFFSET(&(entry->tune0_low), 0xffdf); + PATCH_OFFSET(&(entry->tune0_low), 0xffdf); PATCH_OFFSET(&(entry->tune0_high), 0xffdf); - PATCH_OFFSET(&(entry->tune1_low), 0x21107ff); + PATCH_OFFSET(&(entry->tune1_low), 0x21107ff); PATCH_OFFSET(&(entry->tune1_high), 0x27307ff); break; case 4: - PATCH_OFFSET(&(entry->tune0_low), 0xffff); + PATCH_OFFSET(&(entry->tune0_low), 0xffff); PATCH_OFFSET(&(entry->tune0_high), 0xffdf); - PATCH_OFFSET(&(entry->tune1_low), 0x21107ff); + PATCH_OFFSET(&(entry->tune1_low), 0x21107ff); PATCH_OFFSET(&(entry->tune1_high), 0x27407ff); break; case 5: PATCH_OFFSET(&(entry->tune0_high), 0xffdf); - PATCH_OFFSET(&(entry->tune1_low), 0x21607ff); + PATCH_OFFSET(&(entry->tune1_low), 0x21607ff); PATCH_OFFSET(&(entry->tune1_high), 0x27707ff); break; case 6: PATCH_OFFSET(&(entry->tune0_high), 0xffdf); - PATCH_OFFSET(&(entry->tune1_low), 0x21607ff); + PATCH_OFFSET(&(entry->tune1_low), 0x21607ff); PATCH_OFFSET(&(entry->tune1_high), 0x27807ff); break; case 7: PATCH_OFFSET(&(entry->tune0_high), 0xdfff); - PATCH_OFFSET(&(entry->tune1_low), 0x21607ff); + PATCH_OFFSET(&(entry->tune1_low), 0x21607ff); PATCH_OFFSET(&(entry->tune1_high), 0x27b07ff); break; case 8: - PATCH_OFFSET(&(entry->tune0_low), 0xdfff); + PATCH_OFFSET(&(entry->tune0_low), 0xdfff); PATCH_OFFSET(&(entry->tune0_high), 0xdfff); - PATCH_OFFSET(&(entry->tune1_low), 0x21707ff); + PATCH_OFFSET(&(entry->tune1_low), 0x21707ff); PATCH_OFFSET(&(entry->tune1_high), 0x27b07ff); break; case 9: - PATCH_OFFSET(&(entry->tune0_low), 0xdfff); + PATCH_OFFSET(&(entry->tune0_low), 0xdfff); PATCH_OFFSET(&(entry->tune0_high), 0xdfff); - PATCH_OFFSET(&(entry->tune1_low), 0x21707ff); + PATCH_OFFSET(&(entry->tune1_low), 0x21707ff); PATCH_OFFSET(&(entry->tune1_high), 0x27c07ff); break; case 10: - PATCH_OFFSET(&(entry->tune0_low), 0xdfff); + PATCH_OFFSET(&(entry->tune0_low), 0xdfff); PATCH_OFFSET(&(entry->tune0_high), 0xdfff); - PATCH_OFFSET(&(entry->tune1_low), 0x21707ff); + PATCH_OFFSET(&(entry->tune1_low), 0x21707ff); PATCH_OFFSET(&(entry->tune1_high), 0x27d07ff); break; case 11: - PATCH_OFFSET(&(entry->tune0_low), 0xdfff); + PATCH_OFFSET(&(entry->tune0_low), 0xdfff); PATCH_OFFSET(&(entry->tune0_high), 0xdfff); - PATCH_OFFSET(&(entry->tune1_low), 0x21707ff); + PATCH_OFFSET(&(entry->tune1_low), 0x21707ff); PATCH_OFFSET(&(entry->tune1_high), 0x27e07ff); break; case 12: - PATCH_OFFSET(&(entry->tune0_low), 0xdfff); + PATCH_OFFSET(&(entry->tune0_low), 0xdfff); PATCH_OFFSET(&(entry->tune0_high), 0xdfff); - PATCH_OFFSET(&(entry->tune1_low), 0x21707ff); + PATCH_OFFSET(&(entry->tune1_low), 0x21707ff); PATCH_OFFSET(&(entry->tune1_high), 0x27f07ff); break; default: @@ -216,7 +222,7 @@ namespace ams::ldr::hoc::pcv::mariko { switch (C.marikoCpuUVHigh) { case 1: - PATCH_OFFSET(&(entry->tune1_high), 0); + PATCH_OFFSET(&(entry->tune1_high), 0x0); PATCH_OFFSET(&(entry->tune0_high), 0xffff); break; case 2: @@ -301,7 +307,7 @@ namespace ams::ldr::hoc::pcv::mariko { asm_set_rd(asm_set_imm16(GpuAsmPattern[1], max_clock >> 16), rd) }; - PATCH_OFFSET(ptr32, asm_patch[0]); + PATCH_OFFSET(ptr32, asm_patch[0]); PATCH_OFFSET(ptr32 + 1, asm_patch[1]); R_SUCCEED(); @@ -366,7 +372,7 @@ namespace ams::ldr::hoc::pcv::mariko { } u32 trefbw = refresh_raw + 0x40; - trefbw = MIN(trefbw, static_cast(0x3FFF)); + trefbw = MIN(trefbw, static_cast(0x3FFF)); const u32 dyn_self_ref_control = (static_cast(7605.0 / tCK_avg) + 260) | (table->burst_regs.emc_dyn_self_ref_control & 0xffff0000); diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.hpp b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.hpp index eb234078..43258993 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.hpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/pcv/pcv_mariko.hpp @@ -48,11 +48,11 @@ namespace ams::ldr::hoc::pcv::mariko { { }, }; - constexpr u32 CpuClkOfficial = 1963'500; - constexpr u32 CpuVoltOfficial = 1120; - constexpr u32 CpuVminOfficial = 620; - - constexpr u32 CpuTune0Low = 0xFFCF; + constexpr u32 CpuClkOfficial = 1963'500; + constexpr u32 CpuVoltOfficial = 1120; + constexpr u32 CpuHighVminOfficial = 850; + constexpr u32 CpuVminOfficial = 620; + constexpr u32 CpuTune0Low = 0xFFCF; static const u32 cpuVoltagePatchValues[] = { 850, 38, 1120, 1000, 100, 1000, 0 }; static const s32 cpuVoltagePatchOffsets[] = { -2, -1, 5, 6, 7, 8, 9 }; @@ -230,7 +230,7 @@ namespace ams::ldr::hoc::pcv::mariko { MtcTableIndex index; }; - constexpr MtcDramIndex mtcIndexTable[] = { + const inline MtcDramIndex mtcIndexTable[] = { { HOAG_4GB_HYNIX_H9HCNNNBKMMLXR_NEE, T210b0SdevEmcDvfsTableH1y4gb01, }, { AULA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE, T210b0SdevEmcDvfsTableH1y4gb01, }, { IOWA_4GB_HYNIX_H9HCNNNBKMMLXR_NEE, T210b0SdevEmcDvfsTableH1y4gb01, },