initial commit
This commit is contained in:
51
Source/Atmosphere/ldr_patcher.diff
Normal file
51
Source/Atmosphere/ldr_patcher.diff
Normal file
@@ -0,0 +1,51 @@
|
||||
--- stratosphere/loader/source/ldr_patcher.cpp @a672917
|
||||
+++ stratosphere/loader/source/ldr_patcher.cpp
|
||||
@@ -15,11 +15,27 @@
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "ldr_patcher.hpp"
|
||||
+#include "ldr_pcv_patch.hpp"
|
||||
|
||||
namespace ams::ldr {
|
||||
|
||||
namespace {
|
||||
|
||||
+ constexpr u8 PcvModuleId[2][20] = {
|
||||
+ { 0x91, 0xD6, 0x1D, 0x59, 0xD7, 0x00, 0x23, 0x78, 0xE3, 0x55, 0x84, 0xFC, 0x0B, 0x38, 0xC7, 0x69, 0x3A, 0x3A, 0xBA, 0xB5, }, //11.0.0
|
||||
+ { 0xC5, 0x03, 0xE9, 0x65, 0x50, 0xF3, 0x02, 0xE1, 0x21, 0x87, 0x31, 0x36, 0xB8, 0x14, 0xA5, 0x29, 0x86, 0x3D, 0x94, 0x9B, }, //12.0.0
|
||||
+ };
|
||||
+
|
||||
+ constexpr u8 NifmModuleId[2][20] = {
|
||||
+ { 0x7A, 0x43, 0xF8, 0x40, 0x33, 0x7C, 0x28, 0xD4, 0x53, 0x71, 0x88, 0x43, 0x60, 0x8E, 0xEF, 0xF7, 0x8A, 0xFD, 0x46, 0x0B, }, //11.0.0
|
||||
+ { 0xA8, 0x5F, 0x50, 0xFB, 0xA1, 0x0E, 0x06, 0xA3, 0xEB, 0xA3, 0xD3, 0xFA, 0xCB, 0x9E, 0x07, 0x5B, 0x21, 0x8C, 0x7D, 0x6D, },
|
||||
+ };
|
||||
+
|
||||
+ constexpr u8 AmModuleId[2][20] = {
|
||||
+ { 0x25, 0x50, 0x97, 0xEF, 0x11, 0xC0, 0x75, 0x9B, 0x1F, 0x36, 0x13, 0x2F, 0x73, 0xBD, 0xDB, 0x04, 0xC3, 0xEF, 0x9A, 0xBE, }, //11.0.0
|
||||
+ { 0x5E, 0x5F, 0x1C, 0xC2, 0x4D, 0x37, 0x45, 0x91, 0xAF, 0xC2, 0xA2, 0x33, 0x6C, 0x94, 0x53, 0xCC, 0xFA, 0x39, 0x61, 0xC1, },
|
||||
+ };
|
||||
+
|
||||
constexpr const char *NsoPatchesDirectory = "exefs_patches";
|
||||
|
||||
/* Exefs patches want to prevent modification of header, */
|
||||
@@ -113,6 +129,20 @@ namespace ams::ldr {
|
||||
|
||||
/* Apply IPS patches. */
|
||||
void LocateAndApplyIpsPatchesToModule(const u8 *build_id, uintptr_t mapped_nso, size_t mapped_size) {
|
||||
+ for(int i = 0; i < 2; i++)
|
||||
+ {
|
||||
+ if(memcmp(PcvModuleId[i], build_id, sizeof(PcvModuleId[i])) == 0) {
|
||||
+ ApplyPcvPatch(reinterpret_cast<u8 *>(mapped_nso), mapped_size, i);
|
||||
+ return; // Return here since pcv module loads before sd card can be mounted
|
||||
+ }
|
||||
+ else if(memcmp(NifmModuleId[i], build_id, sizeof(NifmModuleId[i])) == 0) {
|
||||
+ ApplyCtestPatch(reinterpret_cast<u8 *>(mapped_nso), mapped_size, i);
|
||||
+ }
|
||||
+ else if(memcmp(AmModuleId[i], build_id, sizeof(AmModuleId[i])) == 0) {
|
||||
+ ApplyCopyrightPatch(reinterpret_cast<u8 *>(mapped_nso), mapped_size, i);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (!EnsureSdCardMounted()) {
|
||||
return;
|
||||
}
|
||||
268
Source/Atmosphere/ldr_pcv_patch.cpp
Normal file
268
Source/Atmosphere/ldr_pcv_patch.cpp
Normal file
@@ -0,0 +1,268 @@
|
||||
// placed in Atmosphere/stratosphere/loader/source/
|
||||
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
#define EMC_OVERCLOCK 1
|
||||
#define EMC_OVERVOLT 1
|
||||
|
||||
namespace ams::ldr {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr u32 CtestOffset[2] = { 0xF400, 0x1079C };
|
||||
|
||||
constexpr u32 CopyrightOffset[2] = { 0xC6128, 0xCA414 }; //am_no_copyright port
|
||||
|
||||
constexpr u8 BehemothPatch[8] = { 0xE0, 0x03, 0x1F, 0xAA, 0xC0, 0x03, 0x5F, 0xD6 }; //🤔
|
||||
|
||||
typedef struct {
|
||||
u32 hz = 0;
|
||||
u32 volt = 0;
|
||||
u32 unk[6] = {0};
|
||||
s32 coeffs[6] = {0};
|
||||
} gpu_clock_table_t;
|
||||
|
||||
constexpr u32 EmcFreqOffsets[2][30] = {
|
||||
{ 0xD7C60, 0xD7C68, 0xD7C70, 0xD7C78, 0xD7C80, 0xD7C88, 0xD7C90, 0xD7C98, 0xD7CA0, 0xD7CA8, 0xE1800, 0xEEFA0, 0xF2478, 0xFE284, 0x10A304, 0x10D7DC, 0x110A40, 0x113CA4, 0x116F08, 0x11A16C, 0x11D3D0, 0x120634, 0x123898, 0x126AFC, 0x129D60, 0x12CFC4, 0x130228, 0x13BFE0, 0x140D00, 0x140D50, },
|
||||
{ 0xE1810, 0xE6530, 0xE6580, 0xE6AB0, 0xE6AB8, 0xE6AC0, 0xE6AC8, 0xE6AD0, 0xE6AD8, 0xE6AE0, 0xE6AE8, 0xE6AF0, 0xE6AF8, 0xF0650, 0xFDDF0, 0x1012C8, 0x10D0D4, 0x119154, 0x11C62C, 0x11F890, 0x122AF4, 0x125D58, 0x128FBC, 0x12C220, 0x12F484, 0x1326E8, 0x13594C, 0x138BB0, 0x13BE14, 0x13F078, }
|
||||
};
|
||||
// RAM freqs to choose: 1731200, 1862400, 1996800, 2131200
|
||||
constexpr u32 NewEmcFreq = 1862400;
|
||||
// RAM overclock could be UNSTABLE on some RAM without bumping up voltage,
|
||||
// and therefore show graphical glitches, hang randomly or even worse, corrupt your NAND
|
||||
|
||||
namespace Erista {
|
||||
|
||||
typedef struct {
|
||||
u32 hz = 0;
|
||||
u32 unk = 0;
|
||||
u32 volt = 0;
|
||||
u32 unk2[5] = {0};
|
||||
s32 coeffs[6] = {0};
|
||||
} cpu_clock_table_t;
|
||||
|
||||
/* CPU */
|
||||
constexpr u32 CpuVoltageLimitOffsets[2][3] = {
|
||||
{ 0xE1AC8, 0xE1AD4, 0xE37E4 },
|
||||
{ 0xF0918, 0xF0924, 0xF2634 },
|
||||
};
|
||||
constexpr u32 NewCpuVoltageLimit = 1358;
|
||||
static_assert(NewCpuVoltageLimit <= 1400);
|
||||
|
||||
constexpr u32 CpuTablesFreeSpace[2] = { 0xE3B78, 0xF29C8 };
|
||||
constexpr cpu_clock_table_t NewCpuTables[] = {
|
||||
{ 1887000, 0, 1240000, {}, { 5100873, -279186, 4747 } },
|
||||
{ 1963500, 0, 1262000, {}, { 5100873, -279186, 4747 } },
|
||||
{ 2091000, 0, 1298000, {}, { 5100873, -279186, 4747 } },
|
||||
{ 2193000, 0, 1328000, {}, { 5100873, -279186, 4747 } },
|
||||
{ 2295000, 0, 1358000, {}, { 5100873, -279186, 4747 } },
|
||||
};
|
||||
static_assert(sizeof(NewCpuTables) <= sizeof(cpu_clock_table_t)*16);
|
||||
|
||||
/* GPU */
|
||||
constexpr u32 GpuTablesFreeSpace[2] = { 0xE2B58, 0xF19A8 };
|
||||
constexpr gpu_clock_table_t NewGpuTables[] = {
|
||||
{ 998400, 0, {}, { 1316991, 8144, -940, 808, -21583, 226 } },
|
||||
{ 1075200, 0, {}, { 1358883, 8144, -940, 808, -21583, 226 } },
|
||||
};
|
||||
static_assert(sizeof(NewGpuTables) <= sizeof(gpu_clock_table_t)*20);
|
||||
|
||||
/* EMC */
|
||||
constexpr u32 EmcVolatageOffsets[2][2] = {
|
||||
{ 0x143998, 0x14399C },
|
||||
{ 0x142878, 0x14287C },
|
||||
};
|
||||
constexpr u32 NewEmcVoltage = 1150000;
|
||||
static_assert(NewEmcVoltage <= 1250000);
|
||||
// 1150mV for 1862.4 MHz and 1200 mV for 2131.2 MHz, according to the feedback in RetroNX Discord
|
||||
// 1125mV(HOS default) for 1731.2 MHz and 1175mV for 1996.8 MHz
|
||||
};
|
||||
|
||||
namespace Mariko {
|
||||
|
||||
typedef struct {
|
||||
u32 hz = 0;
|
||||
u32 unk1 = 0;
|
||||
s32 coeffs[6] = {0};
|
||||
u32 volt = 0;
|
||||
u32 unk3[5] = {0};
|
||||
} cpu_clock_table_t;
|
||||
|
||||
/* CPU */
|
||||
constexpr u32 CpuVoltageLimitOffsets[2][11] = {
|
||||
{ 0xE1A8C, 0xE1A98, 0xE1AA4, 0xE1AB0, 0xE1AF8, 0xE1B04, 0xE1B10, 0xE1B1C, 0xE1B28, 0xE1B34, 0xE1F4C },
|
||||
{ 0xF08DC, 0xF08E8, 0xF08F4, 0xF0900, 0xF0948, 0xF0954, 0xF0960, 0xF096C, 0xF0978, 0xF0984, 0xF0D9C },
|
||||
};
|
||||
constexpr u32 NewCpuVoltageLimit = 1220;
|
||||
static_assert(NewCpuVoltageLimit <= 1300); //1300mV hangs for me
|
||||
|
||||
constexpr u32 CpuVoltageCoeffTable[2][10] = {
|
||||
{ 0xE2140, 0xE2178, 0xE21B0, 0xE21E8, 0xE2220, 0xE2258, 0xE2290, 0xE22C8, 0xE2300, 0xE2338 },
|
||||
{ 0xF0F90, 0xF0FC8, 0xF1000, 0xF1038, 0xF1070, 0xF10A8, 0xF10E0, 0xF1118, 0xF1150, 0xF1188 },
|
||||
};
|
||||
constexpr u32 NewCpuVoltageCoeff = NewCpuVoltageLimit * 1000;
|
||||
|
||||
constexpr u32 CpuTablesFreeSpace[2] = { 0xE2350, 0xF11A0 };
|
||||
constexpr cpu_clock_table_t NewCpuTables[] = {
|
||||
{2091000, 0, {1719782, -40440, 27}, NewCpuVoltageCoeff, {}},
|
||||
{2193000, 0, {1809766, -41939, 27}, NewCpuVoltageCoeff, {}},
|
||||
{2295000, 0, {1904458, -43439, 27}, NewCpuVoltageCoeff, {}},
|
||||
{2397000, 0, {2004105, -44938, 27}, NewCpuVoltageCoeff, {}},
|
||||
/*{2499000, 0, {2108966, -46437, 27}, NewCpuVoltageCoeff, {}},
|
||||
{2601000, 0, {2219313, -47937, 27}, NewCpuVoltageCoeff, {}},
|
||||
{2703000, 0, {2335434, -49436, 27}, NewCpuVoltageCoeff, {}},
|
||||
{2805000, 0, {2457630, -50936, 27}, NewCpuVoltageCoeff, {}},
|
||||
{2907000, 0, {2586221, -52435, 27}, NewCpuVoltageCoeff, {}},
|
||||
{3009000, 0, {2721539, -53934, 27}, NewCpuVoltageCoeff, {}},*/
|
||||
// calculated using linear regression:
|
||||
// coeffs[0]=604531*exp(0.0000005*hz)
|
||||
// coeffs[1]=-0.0147*hz-9702.1
|
||||
};
|
||||
static_assert(sizeof(NewCpuTables) <= sizeof(cpu_clock_table_t)*14);
|
||||
|
||||
constexpr u32 MaxCpuClockOffset[2] = { 0xE2740, 0xF1590 };
|
||||
constexpr u32 NewMaxCpuClock = 2397000;
|
||||
|
||||
/* GPU */
|
||||
constexpr u32 GpuTablesFreeSpace[2] = { 0xE3410, 0xF2260 };
|
||||
constexpr gpu_clock_table_t NewGpuTables[] = {
|
||||
{ 1305600, 0, {}, {1380113, -13465, -874, 0, 2580, 648} },
|
||||
{ 1344000, 0, {}, {1420000, -14000, -870, 0, 2193, 824} },
|
||||
/*{ 1382400, 0, {}, {1423200, -14188, -868, 0, 2150, 830} },
|
||||
{ 1420800, 0, {}, {1426290, -14368, -860, 0, 2100, 850} },
|
||||
{ 1305600, 0, {}, {1380113, -13465, -874, 0, 2580, 648} },
|
||||
{ 1344000, 0, {}, {1420000, -14100, -870, 0, 2193, 824} },
|
||||
{ 1382400, 0, {}, {1426290, -14368, -860, 0, 2100, 850} },
|
||||
{ 1420800, 0, {}, {1450000, -14600, -860, 0, 2000, 850} },
|
||||
{ 1382400, 0, {}, {1454061, -14500, -868, 0, 2000, 900} },
|
||||
{ 1382400, 0, {}, {1474061, -15277, -866, 0, 1710, 1024} },
|
||||
{ 1382400, 0, {}, {1500000, -15500, -880, 0, 1000, 548} },
|
||||
{ 1420800, 0, {}, {1550000, -16500, -885, 0, 1500, 300} },*/
|
||||
// some arbitrary coeffs I guessed and tested, YMMV
|
||||
};
|
||||
static_assert(sizeof(NewGpuTables) <= sizeof(gpu_clock_table_t)*15);
|
||||
|
||||
constexpr u32 Reg1MaxGpuOffset[2] = { 0x2E0AC, 0x3F6CC };
|
||||
constexpr u8 Reg1NewMaxGpuClock[2][0xC] = {
|
||||
// Original: 1267MHz
|
||||
/*
|
||||
MOV W13,#0x5600
|
||||
MOVK W13,#0x13,LSL #16
|
||||
NOP
|
||||
*/
|
||||
// Bump to 1536MHz
|
||||
/*
|
||||
MOV W13,#0x7000
|
||||
MOVK W13,#0x17,LSL #16
|
||||
NOP
|
||||
*/
|
||||
//0x0D, 0xC0, 0x8A, 0x52, 0x6D, 0x02, 0xA0, 0x72, 0x1F, 0x20, 0x03, 0xD5
|
||||
{ 0x0D, 0x00, 0x8E, 0x52, 0xED, 0x02, 0xA0, 0x72, 0x1F, 0x20, 0x03, 0xD5 },
|
||||
{ 0x0B, 0x00, 0x8E, 0x52, 0xEB, 0x02, 0xA0, 0x72, 0x1F, 0x20, 0x03, 0xD5 },
|
||||
};
|
||||
|
||||
constexpr u32 Reg2MaxGpuOffset[2] = { 0x2E110, 0x3F730 };
|
||||
constexpr u8 Reg2NewMaxGpuClock[2][0x8] = {
|
||||
// Original: 1267MHz
|
||||
/*
|
||||
MOV W13,#0x5600
|
||||
MOVK W13,#0x13,LSL #16
|
||||
*/
|
||||
// Bump to 1536MHz
|
||||
/*
|
||||
MOV W13,#0x7000
|
||||
MOVK W13,#0x17,LSL #16
|
||||
*/
|
||||
//0x0D, 0xC0, 0x8A, 0x52, 0x6D, 0x02, 0xA0, 0x72
|
||||
{ 0x0D, 0x00, 0x8E, 0x52, 0xED, 0x02, 0xA0, 0x72, },
|
||||
{ 0x0B, 0x00, 0x8E, 0x52, 0xEB, 0x02, 0xA0, 0x72, },
|
||||
};
|
||||
|
||||
/* EMC */
|
||||
// Not available on Mariko
|
||||
/*constexpr u32 EmcVolatageOffsets[2][2] = {
|
||||
{
|
||||
0x145FE4, //max77812_dram
|
||||
0x144BA4, //max77812_dram
|
||||
},
|
||||
{
|
||||
0x143A84,
|
||||
0x144EC4,
|
||||
}
|
||||
};
|
||||
constexpr u32 NewEmcVoltage = 650000;
|
||||
static_assert(NewEmcVoltage <= 750000);*/
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void ApplyPcvPatch(u8 *mapped_module, size_t mapped_size, int i) {
|
||||
|
||||
/* Add new CPU and GPU clock tables for Erista */
|
||||
AMS_ABORT_UNLESS(Erista::CpuTablesFreeSpace[i] <= mapped_size && Erista::GpuTablesFreeSpace[i] <= mapped_size);
|
||||
std::memcpy(mapped_module + Erista::CpuTablesFreeSpace[i], Erista::NewCpuTables, sizeof(Erista::NewCpuTables));
|
||||
std::memcpy(mapped_module + Erista::GpuTablesFreeSpace[i], Erista::NewGpuTables, sizeof(Erista::NewGpuTables));
|
||||
|
||||
/* Patch max CPU voltage on Erista */
|
||||
for(int j = 0; j < 3; j++) {
|
||||
std::memcpy(mapped_module + Erista::CpuVoltageLimitOffsets[i][j], &Erista::NewCpuVoltageLimit, sizeof(Erista::NewCpuVoltageLimit));
|
||||
}
|
||||
|
||||
/* Add new CPU and GPU clock tables for Mariko */
|
||||
AMS_ABORT_UNLESS(Mariko::CpuTablesFreeSpace[i] <= mapped_size && Mariko::GpuTablesFreeSpace[i] <= mapped_size);
|
||||
std::memcpy(mapped_module + Mariko::CpuTablesFreeSpace[i], Mariko::NewCpuTables, sizeof(Mariko::NewCpuTables));
|
||||
std::memcpy(mapped_module + Mariko::GpuTablesFreeSpace[i], Mariko::NewGpuTables, sizeof(Mariko::NewGpuTables));
|
||||
|
||||
/* Patch Mariko max CPU and GPU clockrates */
|
||||
AMS_ABORT_UNLESS(Mariko::MaxCpuClockOffset[i] <= mapped_size && Mariko::Reg1MaxGpuOffset[i] <= mapped_size && Mariko::Reg2MaxGpuOffset[i] <= mapped_size);
|
||||
std::memcpy(mapped_module + Mariko::MaxCpuClockOffset[i], &Mariko::NewMaxCpuClock, sizeof(Mariko::NewMaxCpuClock));
|
||||
std::memcpy(mapped_module + Mariko::Reg1MaxGpuOffset[i], Mariko::Reg1NewMaxGpuClock, sizeof(Mariko::Reg1NewMaxGpuClock[i]));
|
||||
std::memcpy(mapped_module + Mariko::Reg2MaxGpuOffset[i], Mariko::Reg2NewMaxGpuClock, sizeof(Mariko::Reg2NewMaxGpuClock[i]));
|
||||
|
||||
/* Patch max cpu voltage on Mariko */
|
||||
for(int j = 0; j < 11; j++) {
|
||||
std::memcpy(mapped_module + Mariko::CpuVoltageLimitOffsets[i][j], &Mariko::NewCpuVoltageLimit, sizeof(Mariko::NewCpuVoltageLimit));
|
||||
}
|
||||
for(int j = 0; j < 10; j++) {
|
||||
std::memcpy(mapped_module + Mariko::CpuVoltageCoeffTable[i][j], &Mariko::NewCpuVoltageCoeff, sizeof(Mariko::NewCpuVoltageCoeff));
|
||||
}
|
||||
|
||||
/* Patch EMC clocks and voltage if enabled.
|
||||
Note: On Erista, this requires removing or modifiying minerva */
|
||||
if constexpr(EMC_OVERCLOCK) {
|
||||
for(u32 j = 0; j < sizeof(EmcFreqOffsets[i])/sizeof(u32); j++) {
|
||||
AMS_ABORT_UNLESS(EmcFreqOffsets[i][j] <= mapped_size);
|
||||
std::memcpy(mapped_module + EmcFreqOffsets[i][j], &NewEmcFreq, sizeof(NewEmcFreq));
|
||||
}
|
||||
}
|
||||
|
||||
if constexpr(EMC_OVERVOLT) {
|
||||
if(spl::GetSocType() == spl::SocType_Erista) {
|
||||
for(u32 j = 0; j < sizeof(Erista::EmcVolatageOffsets[i])/sizeof(u32); j++) {
|
||||
AMS_ABORT_UNLESS(Erista::EmcVolatageOffsets[i][j] <= mapped_size);
|
||||
std::memcpy(mapped_module + Erista::EmcVolatageOffsets[i][j], &Erista::NewEmcVoltage, sizeof(Erista::NewEmcVoltage));
|
||||
}
|
||||
}
|
||||
// Not available on Mariko
|
||||
/*else if(spl::GetSocType() == spl::SocType_Mariko) {
|
||||
for(u32 j = 0; j < sizeof(Mariko::EmcVolatageOffsets[i])/sizeof(u32); j++) {
|
||||
AMS_ABORT_UNLESS(Mariko::EmcVolatageOffsets[i][j] <= mapped_size);
|
||||
std::memcpy(mapped_module + Mariko::EmcVolatageOffsets[i][j], &Mariko::NewEmcVoltage, sizeof(Mariko::NewEmcVoltage));
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ApplyCtestPatch(u8 *mapped_module, size_t mapped_size, int i) {
|
||||
AMS_ABORT_UNLESS(CtestOffset[i] - 0x100 <= mapped_size);
|
||||
std::memcpy(mapped_module + CtestOffset[i] - 0x100, BehemothPatch, sizeof(BehemothPatch));
|
||||
}
|
||||
|
||||
void ApplyCopyrightPatch(u8 *mapped_module, size_t mapped_size, int i) {
|
||||
AMS_ABORT_UNLESS(CopyrightOffset[i] - 0x100 <= mapped_size);
|
||||
std::memcpy(mapped_module + CopyrightOffset[i] - 0x100, BehemothPatch, sizeof(BehemothPatch));
|
||||
}
|
||||
|
||||
}
|
||||
14
Source/Atmosphere/ldr_pcv_patch.hpp
Normal file
14
Source/Atmosphere/ldr_pcv_patch.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
// placed in Atmosphere/stratosphere/loader/source/
|
||||
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace ams::ldr {
|
||||
|
||||
void ApplyPcvPatch(u8 *mapped_module, size_t mapped_size, int i);
|
||||
|
||||
void ApplyCtestPatch(u8 *mapped_module, size_t mapped_size, int i);
|
||||
|
||||
void ApplyCopyrightPatch(u8 *mapped_module, size_t mapped_size, int i);
|
||||
|
||||
}
|
||||
160
Source/Patch/12-ptm.pchtxt
Normal file
160
Source/Patch/12-ptm.pchtxt
Normal file
@@ -0,0 +1,160 @@
|
||||
@nsobid-A79706954C6C45568B0FFE610627E2E89D8FB0D4
|
||||
@flag offset_shift 0x100
|
||||
|
||||
// PTM PerformanceConfiguration Patch for 12.0.x
|
||||
// Change all RAM freqs to 1862.4 MHz and Boost CPU freqs to 1963.5 MHz by default
|
||||
// RAM
|
||||
// 1731.2 MHz - 00043067
|
||||
// 1862.4 MHz - 00F8016F
|
||||
// 1996.8 MHz - 00C00477
|
||||
// 2131.2 MHz - 0088077F
|
||||
// CPU
|
||||
// 1963.5 MHz - E0A10875
|
||||
// 2295.0 MHz - C0EBCA88
|
||||
// All values are Little-Endian
|
||||
// See https://switchbrew.org/wiki/PTM_services#PerformanceConfiguration for details
|
||||
// Use IPSwitch(https://github.com/3096/ipswitch/) to convert into ips patch
|
||||
|
||||
//0x00010000: 1020, 384.0, 1600.0
|
||||
@enabled
|
||||
000C5E14 00F7CB3C
|
||||
000C5E18 00F7CB3C
|
||||
000C5E1C 0060E316
|
||||
000C5E20 0060E316
|
||||
000C5E24 00F8016F
|
||||
000C5E28 00F8016F
|
||||
|
||||
//0x00010001: 1020, 768.0, 1600.0
|
||||
@enabled
|
||||
000C5E34 00F7CB3C
|
||||
000C5E38 00F7CB3C
|
||||
000C5E3C 00C0C62D
|
||||
000C5E40 00C0C62D
|
||||
000C5E44 00F8016F
|
||||
000C5E48 00F8016F
|
||||
|
||||
//0x00010002: 1224, 691.0, 1600.0
|
||||
@enabled
|
||||
000C5E54 00C2F448
|
||||
000C5E58 00C2F448
|
||||
000C5E5C 00E03229
|
||||
000C5E60 00E03229
|
||||
000C5E64 00F8016F
|
||||
000C5E68 00F8016F
|
||||
|
||||
//0x00020000: 1020, 230.4, 1600.0
|
||||
@enabled
|
||||
000C5E74 00F7CB3C
|
||||
000C5E78 00F7CB3C
|
||||
000C5E7C 00A0BB0D
|
||||
000C5E80 00A0BB0D
|
||||
000C5E84 00F8016F
|
||||
000C5E88 00F8016F
|
||||
|
||||
//0x00020001: 1020, 307.2, 1600.0
|
||||
@enabled
|
||||
000C5E94 00F7CB3C
|
||||
000C5E98 00F7CB3C
|
||||
000C5E9C 00804F12
|
||||
000C5EA0 00804F12
|
||||
000C5EA4 00F8016F
|
||||
000C5EA8 00F8016F
|
||||
|
||||
//0x00020002: 1224, 230.4, 1600.0
|
||||
@enabled
|
||||
000C5EB4 00C2F448
|
||||
000C5EB8 00C2F448
|
||||
000C5EBC 00A0BB0D
|
||||
000C5EC0 00A0BB0D
|
||||
000C5EC4 00F8016F
|
||||
000C5EC8 00F8016F
|
||||
|
||||
//0x00020003: 1020, 307.2, 1331.2
|
||||
@enabled
|
||||
000C5ED4 00F7CB3C
|
||||
000C5ED8 00F7CB3C
|
||||
000C5EDC 00804F12
|
||||
000C5EE0 00804F12
|
||||
000C5EE4 00F8016F
|
||||
000C5EE8 00F8016F
|
||||
|
||||
//0x00020004: 1020, 384.0, 1331.2
|
||||
@enabled
|
||||
000C5EF4 00F7CB3C
|
||||
000C5EF8 00F7CB3C
|
||||
000C5EFC 0060E316
|
||||
000C5F00 0060E316
|
||||
000C5F04 00F8016F
|
||||
000C5F08 00F8016F
|
||||
|
||||
//0x00020005: 1020, 307.0, 1065.6
|
||||
@enabled
|
||||
000C5F14 00F7CB3C
|
||||
000C5F18 00F7CB3C
|
||||
000C5F1C 00804F12
|
||||
000C5F20 00804F12
|
||||
000C5F24 00F8016F
|
||||
000C5F28 00F8016F
|
||||
|
||||
//0x00020006: 1020, 384.0, 1065.6
|
||||
@enabled
|
||||
000C5F34 00F7CB3C
|
||||
000C5F38 00F7CB3C
|
||||
000C5F3C 0060E316
|
||||
000C5F40 0060E316
|
||||
000C5F44 00F8016F
|
||||
000C5F48 00F8016F
|
||||
|
||||
//0x92220007: 1020, 460.0, 1600.0
|
||||
@enabled
|
||||
000C5F54 00F7CB3C
|
||||
000C5F58 00F7CB3C
|
||||
000C5F5C 0040771B
|
||||
000C5F60 0040771B
|
||||
000C5F64 00F8016F
|
||||
000C5F68 00F8016F
|
||||
|
||||
//0x92220008: 1020, 460.0, 1331.2
|
||||
@enabled
|
||||
000C5F74 00F7CB3C
|
||||
000C5F78 00F7CB3C
|
||||
000C5F7C 0040771B
|
||||
000C5F80 0040771B
|
||||
000C5F84 00F8016F
|
||||
000C5F88 00F8016F
|
||||
|
||||
//0x92220009: 1785, 76.8, 1600.0
|
||||
@enabled
|
||||
000C5F94 E0A10875
|
||||
000C5F98 E0A10875
|
||||
000C5F9C 00E09304
|
||||
000C5FA0 00E09304
|
||||
000C5FA4 00F8016F
|
||||
000C5FA8 00F8016F
|
||||
|
||||
//0x9222000A: 1785, 76.8, 1331.2
|
||||
@enabled
|
||||
000C5FB4 E0A10875
|
||||
000C5FB8 E0A10875
|
||||
000C5FBC 00E09304
|
||||
000C5FC0 00E09304
|
||||
000C5FC4 00F8016F
|
||||
000C5FC8 00F8016F
|
||||
|
||||
//0x9222000B: 1020, 76.8, 1600.0
|
||||
@enabled
|
||||
000C5FD4 00F7CB3C
|
||||
000C5FD8 00F7CB3C
|
||||
000C5FDC 00E09304
|
||||
000C5FE0 00E09304
|
||||
000C5FE4 00F8016F
|
||||
000C5FE8 00F8016F
|
||||
|
||||
//0x9222000C: 1020, 76.8, 1331.2
|
||||
@enabled
|
||||
000C5FF4 00F7CB3C
|
||||
000C5FF8 00F7CB3C
|
||||
000C5FFC 00E09304
|
||||
000C6000 00E09304
|
||||
000C6004 00F8016F
|
||||
000C6008 00F8016F
|
||||
190
Source/Patch/ReverseNX-RT.diff
Normal file
190
Source/Patch/ReverseNX-RT.diff
Normal file
@@ -0,0 +1,190 @@
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index 3e35c18..6b42bc5 100644
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -8,3 +8,4 @@ build/
|
||||
*.nacp
|
||||
|
||||
*.nro
|
||||
+*.DS_Store
|
||||
diff --git a/Overlay/libs/Atmosphere-libs b/Overlay/libs/Atmosphere-libs
|
||||
index 2d522dc..bc08912 160000
|
||||
--- a/Overlay/libs/Atmosphere-libs
|
||||
+++ b/Overlay/libs/Atmosphere-libs
|
||||
@@ -1 +1 @@
|
||||
-Subproject commit 2d522dc6a12b2eb5eb3f103a8c5b5126ca301b1a
|
||||
+Subproject commit bc08912dd31bb172467add8e24b4f0adac431939
|
||||
diff --git a/Overlay/libs/libtesla b/Overlay/libs/libtesla
|
||||
index 6628524..a5ce77d 160000
|
||||
--- a/Overlay/libs/libtesla
|
||||
+++ b/Overlay/libs/libtesla
|
||||
@@ -1 +1 @@
|
||||
-Subproject commit 66285245361a02e5480c7bb7dac9ef6449ae6181
|
||||
+Subproject commit a5ce77d14f144a24c21684128ae79ef1e808734c
|
||||
diff --git a/Overlay/source/main.cpp b/Overlay/source/main.cpp
|
||||
index cec060c..7b7d8b1 100644
|
||||
--- a/Overlay/source/main.cpp
|
||||
+++ b/Overlay/source/main.cpp
|
||||
@@ -2,8 +2,12 @@
|
||||
#include <tesla.hpp> // The Tesla Header
|
||||
#include "dmntcht.h"
|
||||
|
||||
+#define PROCESS_MANAGEMENT_QLAUNCH_TID 0x0100000000001000ULL
|
||||
+
|
||||
bool def = true;
|
||||
+bool defChanged = false;
|
||||
bool isDocked = false;
|
||||
+bool isDockedChanged = false;
|
||||
bool PluginRunning = false;
|
||||
bool closed = false;
|
||||
Handle debug;
|
||||
@@ -17,6 +21,7 @@ bool dmntcht = false;
|
||||
bool SaltySD = false;
|
||||
bool bak = false;
|
||||
bool plugin = false;
|
||||
+bool sysclkComm = false;
|
||||
char DockedChar[32];
|
||||
char SystemChar[32];
|
||||
char PluginChar[36];
|
||||
@@ -54,6 +59,29 @@ bool isServiceRunning(const char *serviceName) {
|
||||
}
|
||||
}
|
||||
|
||||
+u64 GetCurrentApplicationId()
|
||||
+{
|
||||
+ // Copied from sys-clk
|
||||
+ Result rc = 0;
|
||||
+ std::uint64_t pid = 0;
|
||||
+ std::uint64_t tid = 0;
|
||||
+ rc = pmdmntGetApplicationProcessId(&pid);
|
||||
+
|
||||
+ if (rc == 0x20f)
|
||||
+ {
|
||||
+ return PROCESS_MANAGEMENT_QLAUNCH_TID;
|
||||
+ }
|
||||
+
|
||||
+ rc = pminfoGetProgramId(&tid, pid);
|
||||
+
|
||||
+ if (rc == 0x20f)
|
||||
+ {
|
||||
+ return PROCESS_MANAGEMENT_QLAUNCH_TID;
|
||||
+ }
|
||||
+
|
||||
+ return tid;
|
||||
+}
|
||||
+
|
||||
class GuiTest : public tsl::Gui {
|
||||
public:
|
||||
GuiTest(u8 arg1, u8 arg2, bool arg3) { }
|
||||
@@ -95,9 +123,10 @@ class GuiTest : public tsl::Gui {
|
||||
if (MAGIC == 0x06BA7E39) {
|
||||
auto *clickableListItem = new tsl::elm::ListItem("Change system control");
|
||||
clickableListItem->setClickListener([](u64 keys) {
|
||||
- if (keys & KEY_A) {
|
||||
+ if (keys & HidNpadButton_A) {
|
||||
if (PluginRunning == true) {
|
||||
def = !def;
|
||||
+ defChanged = true;
|
||||
if (dmntcht == true) {
|
||||
dmntchtWriteCheatProcessMemory(def_address, &def, 0x1);
|
||||
dmntchtReadCheatProcessMemory(def_address, &def, 0x1);
|
||||
@@ -120,9 +149,10 @@ class GuiTest : public tsl::Gui {
|
||||
|
||||
auto *clickableListItem2 = new tsl::elm::ListItem("Change mode");
|
||||
clickableListItem2->setClickListener([](u64 keys) {
|
||||
- if (keys & KEY_A) {
|
||||
+ if (keys & HidNpadButton_A) {
|
||||
if (PluginRunning == true && def == false) {
|
||||
isDocked =! isDocked;
|
||||
+ isDockedChanged = true;
|
||||
if (dmntcht == true) {
|
||||
dmntchtWriteCheatProcessMemory(docked_address, &isDocked, 0x1);
|
||||
dmntchtReadCheatProcessMemory(docked_address, &isDocked, 0x1);
|
||||
@@ -145,7 +175,7 @@ class GuiTest : public tsl::Gui {
|
||||
else if (SaltySD == true && plugin == true && check == false) {
|
||||
auto *clickableListItem = new tsl::elm::ListItem("(De)activate plugin");
|
||||
clickableListItem->setClickListener([](u64 keys) {
|
||||
- if (keys & KEY_A) {
|
||||
+ if (keys & HidNpadButton_A) {
|
||||
if (bak == false) {
|
||||
rename("sdmc:/SaltySD/plugins/ReverseNX-RT.elf", "sdmc:/SaltySD/plugins/ReverseNX-RT.elf.bak");
|
||||
bak = true;
|
||||
@@ -185,6 +215,38 @@ class GuiTest : public tsl::Gui {
|
||||
svcReadDebugProcessMemory(&isDocked, debug, docked_address, 0x1);
|
||||
svcCloseHandle(debug);
|
||||
}
|
||||
+ if (sysclkComm && isDockedChanged && def == false && bak == false)
|
||||
+ {
|
||||
+ uint8_t sysclkConfArr[9];
|
||||
+ u64 currentTID = GetCurrentApplicationId();
|
||||
+ if (currentTID != PROCESS_MANAGEMENT_QLAUNCH_TID)
|
||||
+ {
|
||||
+ for(int i = 0; i < 8; i++) // TID to hex
|
||||
+ sysclkConfArr[i] = currentTID >> 8*(7-i);
|
||||
+ sysclkConfArr[8] = isDocked + 1;
|
||||
+
|
||||
+ FILE* sysclkConf = fopen("/config/sys-clk/ReverseNX-RT.conf", "wb+");
|
||||
+ fwrite(sysclkConfArr, sizeof(sysclkConfArr), 1, sysclkConf);
|
||||
+ fclose(sysclkConf);
|
||||
+ }
|
||||
+ isDockedChanged = false;
|
||||
+ }
|
||||
+ if (sysclkComm && defChanged && def == true && bak == false) // change from force mode to system-controlled mode
|
||||
+ {
|
||||
+ uint8_t sysclkConfArr[9];
|
||||
+ u64 currentTID = GetCurrentApplicationId();
|
||||
+ if (currentTID != PROCESS_MANAGEMENT_QLAUNCH_TID)
|
||||
+ {
|
||||
+ for(int i = 0; i < 8; i++) // TID to hex
|
||||
+ sysclkConfArr[i] = currentTID >> 8*(7-i);
|
||||
+ sysclkConfArr[8] = 3;
|
||||
+
|
||||
+ FILE* sysclkConf = fopen("/config/sys-clk/ReverseNX-RT.conf", "wb+");
|
||||
+ fwrite(sysclkConfArr, sizeof(sysclkConfArr), 1, sysclkConf);
|
||||
+ fclose(sysclkConf);
|
||||
+ }
|
||||
+ defChanged = false;
|
||||
+ }
|
||||
i = 0;
|
||||
}
|
||||
else i++;
|
||||
@@ -202,7 +264,7 @@ class GuiTest : public tsl::Gui {
|
||||
}
|
||||
|
||||
// Called once every frame to handle inputs not handled by other UI elements
|
||||
- virtual bool handleInput(u64 keysDown, u64 keysHeld, touchPosition touchInput, JoystickPosition leftJoyStick, JoystickPosition rightJoyStick) override {
|
||||
+ virtual bool handleInput(u64 keysDown, u64 keysHeld, const HidTouchState &touchPos, HidAnalogStickState joyStickPosLeft, HidAnalogStickState joyStickPosRight) override {
|
||||
return false; // Return true here to singal the inputs have been consumed
|
||||
}
|
||||
};
|
||||
@@ -213,6 +275,7 @@ class OverlayTest : public tsl::Overlay {
|
||||
virtual void initServices() override {
|
||||
smInitialize();
|
||||
fsdevMountSdmc();
|
||||
+ pminfoInitialize();
|
||||
|
||||
SaltySD = CheckPort();
|
||||
if (SaltySD == false) return;
|
||||
@@ -234,6 +297,14 @@ class OverlayTest : public tsl::Overlay {
|
||||
else return;
|
||||
}
|
||||
|
||||
+ // Check if sys-clk exist
|
||||
+ temp = fopen("/atmosphere/contents/00FF0000636C6BFF/flags/boot2.flag", "r");
|
||||
+ if (temp != NULL)
|
||||
+ {
|
||||
+ sysclkComm = true;
|
||||
+ fclose(temp);
|
||||
+ }
|
||||
+
|
||||
if (R_FAILED(pmdmntGetApplicationProcessId(&PID))) remove("sdmc:/SaltySD/ReverseNX-RT.hex");
|
||||
else {
|
||||
check = true;
|
||||
@@ -284,6 +355,7 @@ class OverlayTest : public tsl::Overlay {
|
||||
virtual void exitServices() override {
|
||||
dmntchtExit();
|
||||
if (dmntcht == false) svcCloseHandle(debug);
|
||||
+ pminfoExit();
|
||||
fsdevUnmountDevice("sdmc");
|
||||
smExit();
|
||||
} // Callet at the end to clean up all services previously initialized
|
||||
997
Source/Patch/sys-clk.diff
Normal file
997
Source/Patch/sys-clk.diff
Normal file
@@ -0,0 +1,997 @@
|
||||
diff --git a/common/src/apm_profile_table.c b/common/src/apm_profile_table.c
|
||||
index 7439ff1..19f5b68 100644
|
||||
--- a/common/src/apm_profile_table.c
|
||||
+++ b/common/src/apm_profile_table.c
|
||||
@@ -23,8 +23,8 @@ SysClkApmConfiguration sysclk_g_apm_configurations[] = {
|
||||
{0x00020006, 1020000000, 384000000, 1065600000},
|
||||
{0x92220007, 1020000000, 460800000, 1600000000},
|
||||
{0x92220008, 1020000000, 460800000, 1331200000},
|
||||
- {0x92220009, 1785000000, 76800000, 1600000000},
|
||||
- {0x9222000A, 1785000000, 76800000, 1331200000},
|
||||
+ {0x92220009, 1963500000, 76800000, 1600000000},
|
||||
+ {0x9222000A, 1963500000, 76800000, 1331200000},
|
||||
{0x9222000B, 1020000000, 76800000, 1600000000},
|
||||
{0x9222000C, 1020000000, 76800000, 1331200000},
|
||||
{0, 0, 0, 0},
|
||||
diff --git a/common/src/clock_table.c b/common/src/clock_table.c
|
||||
index a8164dc..2765962 100644
|
||||
--- a/common/src/clock_table.c
|
||||
+++ b/common/src/clock_table.c
|
||||
@@ -11,11 +11,15 @@
|
||||
#include <stdint.h>
|
||||
|
||||
uint32_t sysclk_g_freq_table_mem_hz[] = {
|
||||
- 665600000,
|
||||
- 800000000,
|
||||
- 1065600000,
|
||||
+ //665600000,
|
||||
+ //800000000,
|
||||
+ //1065600000,
|
||||
1331200000,
|
||||
- 1600000000,
|
||||
+ //1600000000,
|
||||
+ 1731200000,
|
||||
+ 1862400000,
|
||||
+ 1996800000,
|
||||
+ 2131200000,
|
||||
0,
|
||||
};
|
||||
|
||||
@@ -32,6 +36,12 @@ uint32_t sysclk_g_freq_table_cpu_hz[] = {
|
||||
1581000000,
|
||||
1683000000,
|
||||
1785000000,
|
||||
+ 1887000000,
|
||||
+ 1963500000,
|
||||
+ 2091000000,
|
||||
+ 2193000000,
|
||||
+ 2295000000,
|
||||
+ 2397000000,
|
||||
0,
|
||||
};
|
||||
|
||||
@@ -48,5 +58,14 @@ uint32_t sysclk_g_freq_table_gpu_hz[] = {
|
||||
768000000,
|
||||
844800000,
|
||||
921600000,
|
||||
+ 998400000,
|
||||
+ 1075200000,
|
||||
+ 1152000000,
|
||||
+ 1228800000,
|
||||
+ 1267200000,
|
||||
+ 1305600000,
|
||||
+ 1344000000,
|
||||
+ //1382400000,
|
||||
+ //1420800000,
|
||||
0,
|
||||
};
|
||||
diff --git a/manager/src/advanced_settings_tab.cpp b/manager/src/advanced_settings_tab.cpp
|
||||
index 325d228..6d9725e 100644
|
||||
--- a/manager/src/advanced_settings_tab.cpp
|
||||
+++ b/manager/src/advanced_settings_tab.cpp
|
||||
@@ -77,7 +77,7 @@ AdvancedSettingsTab::AdvancedSettingsTab()
|
||||
});
|
||||
|
||||
// MEM
|
||||
- brls::SelectListItem *memFreqListItem = createFreqListItem(SysClkModule_MEM, context.overrideFreqs[SysClkModule_MEM] / 1000000);
|
||||
+ /*brls::SelectListItem *memFreqListItem = createFreqListItem(SysClkModule_MEM, context.overrideFreqs[SysClkModule_MEM] / 1000000);
|
||||
memFreqListItem->getValueSelectedEvent()->subscribe([](int result)
|
||||
{
|
||||
Result rc = result == 0 ?
|
||||
@@ -90,11 +90,11 @@ AdvancedSettingsTab::AdvancedSettingsTab()
|
||||
errorResult(result == 0 ? "sysclkIpcRemoveOverride" : "sysclkIpcSetOverride", rc);
|
||||
// TODO: Reset selected value
|
||||
}
|
||||
- });
|
||||
+ });*/
|
||||
|
||||
this->addView(cpuFreqListItem);
|
||||
this->addView(gpuFreqListItem);
|
||||
- this->addView(memFreqListItem);
|
||||
+ //this->addView(memFreqListItem);
|
||||
|
||||
// Config
|
||||
this->addView(new brls::Header("Configuration"));
|
||||
diff --git a/manager/src/app_profile_frame.cpp b/manager/src/app_profile_frame.cpp
|
||||
index 4ad9545..0ea6af3 100644
|
||||
--- a/manager/src/app_profile_frame.cpp
|
||||
+++ b/manager/src/app_profile_frame.cpp
|
||||
@@ -116,7 +116,7 @@ void AppProfileFrame::addFreqs(brls::List* list, SysClkProfile profile)
|
||||
list->addView(gpuListItem);
|
||||
|
||||
// MEM
|
||||
- brls::SelectListItem* memListItem = createFreqListItem(SysClkModule_MEM, this->profiles.mhzMap[profile][SysClkModule_MEM]);
|
||||
+ /*brls::SelectListItem* memListItem = createFreqListItem(SysClkModule_MEM, this->profiles.mhzMap[profile][SysClkModule_MEM]);
|
||||
|
||||
this->profiles.mhzMap[profile][SysClkModule_MEM] *= 1000000;
|
||||
|
||||
@@ -126,7 +126,7 @@ void AppProfileFrame::addFreqs(brls::List* list, SysClkProfile profile)
|
||||
|
||||
brls::Logger::debug("Caching freq for module %d and profile %d to %" PRIu32, SysClkModule_MEM, profile, this->profiles.mhzMap[profile][SysClkModule_MEM]);
|
||||
});
|
||||
- list->addView(memListItem);
|
||||
+ list->addView(memListItem);*/
|
||||
}
|
||||
|
||||
void AppProfileFrame::onProfileChanged()
|
||||
diff --git a/manager/src/cheat_sheet_tab.cpp b/manager/src/cheat_sheet_tab.cpp
|
||||
index 6823e0e..08a91bf 100644
|
||||
--- a/manager/src/cheat_sheet_tab.cpp
|
||||
+++ b/manager/src/cheat_sheet_tab.cpp
|
||||
@@ -19,6 +19,8 @@
|
||||
*/
|
||||
|
||||
#include "cheat_sheet_tab.h"
|
||||
+#include "ipc/client.h"
|
||||
+#include "utils.h"
|
||||
|
||||
#include <borealis.hpp>
|
||||
|
||||
@@ -28,8 +30,9 @@ CheatSheetTab::CheatSheetTab()
|
||||
this->addView(new brls::Header("CPU Clocks"));
|
||||
brls::Table *cpuTable = new brls::Table();
|
||||
|
||||
- cpuTable->addRow(brls::TableRowType::BODY, "Maximum", "1785 MHz");
|
||||
- cpuTable->addRow(brls::TableRowType::BODY, "Official Docked and Handheld", "1020 MHz");
|
||||
+ cpuTable->addRow(brls::TableRowType::BODY, "OC Suite Maximum", "2397.0 MHz");
|
||||
+ cpuTable->addRow(brls::TableRowType::BODY, "Official Boost", "1785.0 MHz");
|
||||
+ cpuTable->addRow(brls::TableRowType::BODY, "Official Docked and Handheld", "1020.0 MHz");
|
||||
|
||||
this->addView(cpuTable);
|
||||
|
||||
@@ -37,10 +40,10 @@ CheatSheetTab::CheatSheetTab()
|
||||
this->addView(new brls::Header("GPU Clocks"));
|
||||
brls::Table *gpuTable = new brls::Table();
|
||||
|
||||
- gpuTable->addRow(brls::TableRowType::BODY, "Maximum", "921 MHz");
|
||||
- gpuTable->addRow(brls::TableRowType::BODY, "Official Docked", "768 MHz");
|
||||
- gpuTable->addRow(brls::TableRowType::BODY, "Maximum Handheld", "460 MHz");
|
||||
- gpuTable->addRow(brls::TableRowType::BODY, "Official Handheld", "384 MHz");
|
||||
+ gpuTable->addRow(brls::TableRowType::BODY, "OC Suite Maximum", "1344.0 MHz");
|
||||
+ gpuTable->addRow(brls::TableRowType::BODY, "Official Maximum", "921.6 MHz");
|
||||
+ gpuTable->addRow(brls::TableRowType::BODY, "Official Docked", "768.0 MHz");
|
||||
+ gpuTable->addRow(brls::TableRowType::BODY, "Official Handheld", "384.0/460.8 MHz");
|
||||
|
||||
this->addView(gpuTable);
|
||||
|
||||
@@ -48,8 +51,20 @@ CheatSheetTab::CheatSheetTab()
|
||||
this->addView(new brls::Header("MEM Clocks"));
|
||||
brls::Table *memTable = new brls::Table();
|
||||
|
||||
- memTable->addRow(brls::TableRowType::BODY, "Maximum, Official Docked", "1600 MHz");
|
||||
- memTable->addRow(brls::TableRowType::BODY, "Official Handheld", "1331 MHz");
|
||||
+ // Get context
|
||||
+ SysClkContext context;
|
||||
+ Result rc = sysclkIpcGetCurrentContext(&context);
|
||||
+
|
||||
+ if (R_FAILED(rc))
|
||||
+ {
|
||||
+ brls::Logger::error("Unable to get context");
|
||||
+ errorResult("sysclkIpcGetCurrentContext", rc);
|
||||
+ brls::Application::crash("Could not get the current sys-clk context, please check that it is correctly installed and enabled.");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ memTable->addRow(brls::TableRowType::BODY, "OC Suite", formatFreq(context.freqs[SysClkModule_MEM]));
|
||||
+ memTable->addRow(brls::TableRowType::BODY, "Official", "1331.2/1600.0 MHz");
|
||||
|
||||
this->addView(memTable);
|
||||
}
|
||||
diff --git a/overlay/src/ui/gui/app_profile_gui.cpp b/overlay/src/ui/gui/app_profile_gui.cpp
|
||||
index 29adfe5..116c803 100644
|
||||
--- a/overlay/src/ui/gui/app_profile_gui.cpp
|
||||
+++ b/overlay/src/ui/gui/app_profile_gui.cpp
|
||||
@@ -62,7 +62,7 @@ void AppProfileGui::addProfileUI(SysClkProfile profile)
|
||||
this->listElement->addItem(new tsl::elm::CategoryHeader(sysclkFormatProfile(profile, true)));
|
||||
this->addModuleListItem(profile, SysClkModule_CPU, &sysclk_g_freq_table_cpu_hz[0]);
|
||||
this->addModuleListItem(profile, SysClkModule_GPU, &sysclk_g_freq_table_gpu_hz[0]);
|
||||
- this->addModuleListItem(profile, SysClkModule_MEM, &sysclk_g_freq_table_mem_hz[0]);
|
||||
+ //this->addModuleListItem(profile, SysClkModule_MEM, &sysclk_g_freq_table_mem_hz[0]);
|
||||
}
|
||||
|
||||
void AppProfileGui::listUI()
|
||||
diff --git a/overlay/src/ui/gui/global_override_gui.cpp b/overlay/src/ui/gui/global_override_gui.cpp
|
||||
index 3ea98e4..91742b7 100644
|
||||
--- a/overlay/src/ui/gui/global_override_gui.cpp
|
||||
+++ b/overlay/src/ui/gui/global_override_gui.cpp
|
||||
@@ -62,7 +62,7 @@ void GlobalOverrideGui::listUI()
|
||||
{
|
||||
this->addModuleListItem(SysClkModule_CPU, &sysclk_g_freq_table_cpu_hz[0]);
|
||||
this->addModuleListItem(SysClkModule_GPU, &sysclk_g_freq_table_gpu_hz[0]);
|
||||
- this->addModuleListItem(SysClkModule_MEM, &sysclk_g_freq_table_mem_hz[0]);
|
||||
+ //this->addModuleListItem(SysClkModule_MEM, &sysclk_g_freq_table_mem_hz[0]);
|
||||
}
|
||||
|
||||
void GlobalOverrideGui::refresh()
|
||||
diff --git a/sysmodule/src/clock_manager.cpp b/sysmodule/src/clock_manager.cpp
|
||||
index 46d7207..4139f34 100644
|
||||
--- a/sysmodule/src/clock_manager.cpp
|
||||
+++ b/sysmodule/src/clock_manager.cpp
|
||||
@@ -8,10 +8,14 @@
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
+#define FORCE_ALL_HANDHELD_MODES_TO_USE_DOCK_CLOCK
|
||||
+#include <nxExt.h>
|
||||
+#include "errors.h"
|
||||
#include "clock_manager.h"
|
||||
#include "file_utils.h"
|
||||
#include "clocks.h"
|
||||
#include "process_management.h"
|
||||
+#include <cstring>
|
||||
|
||||
ClockManager* ClockManager::instance = NULL;
|
||||
|
||||
@@ -59,6 +63,136 @@ ClockManager::~ClockManager()
|
||||
delete this->context;
|
||||
}
|
||||
|
||||
+bool ClockManager::IsCpuBoostMode()
|
||||
+{
|
||||
+ std::uint32_t confId = 0;
|
||||
+ Result rc = 0;
|
||||
+ rc = apmExtGetCurrentPerformanceConfiguration(&confId);
|
||||
+ ASSERT_RESULT_OK(rc, "apmExtGetCurrentPerformanceConfiguration");
|
||||
+ if(confId == 0x92220009 || confId == 0x9222000A)
|
||||
+ return true;
|
||||
+ else
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+SysClkProfile ClockManager::ReverseNXProfile(bool ForceDock)
|
||||
+{
|
||||
+ RealProfile = Clocks::GetCurrentProfile();
|
||||
+ switch(RealProfile)
|
||||
+ {
|
||||
+ case SysClkProfile_HandheldChargingOfficial:
|
||||
+#ifdef FORCE_ALL_HANDHELD_MODES_TO_USE_DOCK_CLOCK
|
||||
+ case SysClkProfile_HandheldChargingUSB:
|
||||
+ case SysClkProfile_HandheldCharging:
|
||||
+ case SysClkProfile_Handheld:
|
||||
+#endif
|
||||
+ if (ForceDock)
|
||||
+ return SysClkProfile_Docked;
|
||||
+ else
|
||||
+ return RealProfile;
|
||||
+ case SysClkProfile_Docked:
|
||||
+ if (ForceDock)
|
||||
+ return SysClkProfile_Docked;
|
||||
+ else
|
||||
+ return FileUtils::IsDownclockDockEnabled() ? SysClkProfile_HandheldChargingOfficial : SysClkProfile_Docked;
|
||||
+ default:
|
||||
+ return RealProfile;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void ClockManager::checkReverseNXTool()
|
||||
+{
|
||||
+ char ReverseNXToolAsm[] = "_ZN2nn2oe18GetPerformanceModeEv.asm64"; // Checking one asm64 file is enough
|
||||
+ char ReverseNXToolAsmPath[128];
|
||||
+ uint8_t flag = 0;
|
||||
+ snprintf(ReverseNXToolAsmPath, sizeof ReverseNXToolAsmPath, "/SaltySD/patches/%s", ReverseNXToolAsm);
|
||||
+
|
||||
+ FILE *readReverseNXToolAsm;
|
||||
+ readReverseNXToolAsm = fopen(ReverseNXToolAsmPath, "rb");
|
||||
+
|
||||
+ // Enforce mode globally: Enabled
|
||||
+ if(readReverseNXToolAsm != NULL)
|
||||
+ {
|
||||
+ checkReverseNXToolAsm(readReverseNXToolAsm, &flag);
|
||||
+ switch(flag)
|
||||
+ {
|
||||
+ case 1:
|
||||
+ FileUtils::LogLine("[mgr] ReverseNX-Tool patches detected: Enforce Handheld globally");
|
||||
+ this->context->profile = ReverseNXProfile(false);
|
||||
+ isDockedReverseNX = false;
|
||||
+ isEnabledReverseNX = true;
|
||||
+ isEnabledReverseNXTool = true;
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ FileUtils::LogLine("[mgr] ReverseNX-Tool patches detected: Enforce Docked globally");
|
||||
+ this->context->profile = ReverseNXProfile(true);
|
||||
+ isDockedReverseNX = true;
|
||||
+ isEnabledReverseNX = true;
|
||||
+ isEnabledReverseNXTool = true;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ snprintf(ReverseNXToolAsmPath, sizeof ReverseNXToolAsmPath, "/SaltySD/patches/%016lX/%s", this->context->applicationId, ReverseNXToolAsm);
|
||||
+ readReverseNXToolAsm = fopen(ReverseNXToolAsmPath, "rb");
|
||||
+ // Found game-specific setting
|
||||
+ if(readReverseNXToolAsm != NULL)
|
||||
+ {
|
||||
+ checkReverseNXToolAsm(readReverseNXToolAsm, &flag);
|
||||
+ switch(flag)
|
||||
+ {
|
||||
+ case 1:
|
||||
+ FileUtils::LogLine("[mgr] ReverseNX-Tool patches detected: Force Handheld in %016lX", this->context->applicationId);
|
||||
+ this->context->profile = ReverseNXProfile(false);
|
||||
+ isDockedReverseNX = false;
|
||||
+ isEnabledReverseNX = true;
|
||||
+ isEnabledReverseNXTool = true;
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ FileUtils::LogLine("[mgr] ReverseNX-Tool patches detected: Force Docked in %016lX", this->context->applicationId);
|
||||
+ this->context->profile = ReverseNXProfile(true);
|
||||
+ isDockedReverseNX = true;
|
||||
+ isEnabledReverseNX = true;
|
||||
+ isEnabledReverseNXTool = true;
|
||||
+ break;
|
||||
+ default:
|
||||
+ isEnabledReverseNXTool = false;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+bool ClockManager::GameStartBoost()
|
||||
+{
|
||||
+ if (tickStartBoost && this->GetConfig()->Enabled())
|
||||
+ {
|
||||
+ if (Clocks::GetCurrentHz(SysClkModule_CPU) != MAX_CPU)
|
||||
+ {
|
||||
+ Clocks::SetHz(SysClkModule_CPU, MAX_CPU);
|
||||
+ this->context->freqs[SysClkModule_CPU] = MAX_CPU;
|
||||
+ }
|
||||
+
|
||||
+ std::uint64_t applicationId = ProcessManagement::GetCurrentApplicationId();
|
||||
+ // If user exit the game
|
||||
+ if (applicationId != this->context->applicationId)
|
||||
+ {
|
||||
+ tickStartBoost = 0;
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (tickStartBoost == 1)
|
||||
+ {
|
||||
+ FileUtils::LogLine("[mgr] Boost done, reset to stock");
|
||||
+ Clocks::ResetToStock();
|
||||
+ }
|
||||
+ tickStartBoost--;
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
void ClockManager::SetRunning(bool running)
|
||||
{
|
||||
this->running = running;
|
||||
@@ -72,27 +206,75 @@ bool ClockManager::Running()
|
||||
void ClockManager::Tick()
|
||||
{
|
||||
std::scoped_lock lock{this->contextMutex};
|
||||
- if (this->RefreshContext() || this->config->Refresh())
|
||||
+
|
||||
+ if(!GameStartBoost())
|
||||
{
|
||||
- std::uint32_t hz = 0;
|
||||
- for (unsigned int module = 0; module < SysClkModule_EnumMax; module++)
|
||||
+ bool cpuBoost = FileUtils::IsBoostEnabled() ? IsCpuBoostMode() : false;
|
||||
+ if (this->RefreshContext() || this->config->Refresh())
|
||||
{
|
||||
- hz = this->context->overrideFreqs[module];
|
||||
-
|
||||
- if(!hz)
|
||||
+ std::uint32_t hz = 0;
|
||||
+ std::uint32_t hzForceOverride = 0;
|
||||
+ for (unsigned int module = 0; module < SysClkModule_EnumMax; module++)
|
||||
{
|
||||
- hz = this->config->GetAutoClockHz(this->context->applicationId, (SysClkModule)module, this->context->profile);
|
||||
- }
|
||||
+ hz = this->context->overrideFreqs[module];
|
||||
|
||||
- if (hz)
|
||||
- {
|
||||
- hz = Clocks::GetNearestHz((SysClkModule)module, this->context->profile, hz);
|
||||
+ if(!hz)
|
||||
+ {
|
||||
+ hz = this->config->GetAutoClockHz(this->context->applicationId, (SysClkModule)module, this->context->profile);
|
||||
+ hzForceOverride = this->config->GetAutoClockHz(0xA111111111111111, (SysClkModule)module, this->context->profile);
|
||||
+ if (!hz && hzForceOverride)
|
||||
+ hz = hzForceOverride;
|
||||
|
||||
- if (hz != this->context->freqs[module] && this->context->enabled)
|
||||
+ if(isEnabledReverseNX && !hz)
|
||||
+ {
|
||||
+ switch(module)
|
||||
+ {
|
||||
+ case SysClkModule_CPU:
|
||||
+ hz = 1020'000'000;
|
||||
+ break;
|
||||
+ case SysClkModule_GPU:
|
||||
+ if (!isDockedReverseNX && ((FileUtils::IsDownclockDockEnabled() && RealProfile == SysClkProfile_Docked)
|
||||
+ || RealProfile != SysClkProfile_Docked))
|
||||
+ hz = 460'800'000;
|
||||
+ else
|
||||
+ hz = 768'000'000;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ if (hz)
|
||||
{
|
||||
- FileUtils::LogLine("[mgr] %s clock set : %u.%u Mhz", Clocks::GetModuleName((SysClkModule)module, true), hz/1000000, hz/100000 - hz/1000000*10);
|
||||
- Clocks::SetHz((SysClkModule)module, hz);
|
||||
- this->context->freqs[module] = hz;
|
||||
+ hz = Clocks::GetNearestHz((SysClkModule)module, isEnabledReverseNX ? RealProfile : this->context->profile, hz);
|
||||
+
|
||||
+ if (hz != this->context->freqs[module] && this->context->enabled)
|
||||
+ {
|
||||
+ if (cpuBoost)
|
||||
+ {
|
||||
+ if (module == SysClkModule_CPU && hz < MAX_CPU)
|
||||
+ {
|
||||
+ hz = MAX_CPU;
|
||||
+ FileUtils::LogLine("[mgr] CpuBoostMode detected, bump CPU to max");
|
||||
+ }
|
||||
+ }
|
||||
+ FileUtils::LogLine("[mgr] %s clock set : %u.%u Mhz", Clocks::GetModuleName((SysClkModule)module, true), hz/1000000, hz/100000 - hz/1000000*10);
|
||||
+ Clocks::SetHz((SysClkModule)module, hz);
|
||||
+ this->context->freqs[module] = hz;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ else if (FileUtils::IsBoostEnabled())
|
||||
+ {
|
||||
+ // If user doesn't set any freq but with sys-clk enabled, then boost CPU in CpuBoostMode
|
||||
+ if(cpuBoost && this->GetConfig()->Enabled())
|
||||
+ {
|
||||
+ if(this->context->freqs[SysClkModule_CPU] != MAX_CPU)
|
||||
+ {
|
||||
+ FileUtils::LogLine("[mgr] CpuBoostMode detected, bump CPU to max");
|
||||
+ Clocks::SetHz(SysClkModule_CPU, MAX_CPU);
|
||||
+ this->context->freqs[SysClkModule_CPU] = MAX_CPU;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,6 +286,56 @@ void ClockManager::WaitForNextTick()
|
||||
svcSleepThread(this->GetConfig()->GetConfigValue(SysClkConfigValue_PollingIntervalMs) * 1000000ULL);
|
||||
}
|
||||
|
||||
+void ClockManager::checkReverseNXToolAsm(FILE* readFile, uint8_t* flag)
|
||||
+{
|
||||
+ // Copied from ReverseNXTool
|
||||
+ uint8_t Docked[0x10] = {0xE0, 0x03, 0x00, 0x32, 0xC0, 0x03, 0x5F, 0xD6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
+ uint8_t Handheld[0x10] = {0x00, 0x00, 0xA0, 0x52, 0xC0, 0x03, 0x5F, 0xD6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
+ uint8_t filebuffer[0x10] = {0};
|
||||
+ uint8_t cmpresult = 0;
|
||||
+ fread(&filebuffer, 1, 16, readFile);
|
||||
+ cmpresult = memcmp(filebuffer, Docked, sizeof(Docked));
|
||||
+ if (cmpresult != 0)
|
||||
+ {
|
||||
+ cmpresult = memcmp(filebuffer, Handheld, sizeof(Handheld));
|
||||
+ if (cmpresult != 0)
|
||||
+ *flag = 0; // Set to default
|
||||
+ else
|
||||
+ *flag = 1; // Handheld
|
||||
+ }
|
||||
+ else
|
||||
+ *flag = 2; // Docked
|
||||
+
|
||||
+ fclose(readFile);
|
||||
+}
|
||||
+
|
||||
+void ClockManager::checkReverseNXRT(bool recheckReverseNX, uint8_t* flag)
|
||||
+{
|
||||
+ FILE* readReverseNXRTConf = fopen(FILE_REVERSENX_RT_CONF_PATH, "rb");
|
||||
+ if (readReverseNXRTConf != NULL)
|
||||
+ {
|
||||
+ uint8_t ReverseNXRTConfArr[9];
|
||||
+ fread(ReverseNXRTConfArr, 9, 1, readReverseNXRTConf);
|
||||
+ fclose(readReverseNXRTConf);
|
||||
+ remove(FILE_REVERSENX_RT_CONF_PATH);
|
||||
+
|
||||
+ uint8_t currentTid[8];
|
||||
+ for(int i = 0; i < 8; i++)
|
||||
+ currentTid[i] = this->context->applicationId >> 8*(7-i);
|
||||
+
|
||||
+ uint8_t cmpresult = memcmp(currentTid, ReverseNXRTConfArr, sizeof(currentTid));
|
||||
+
|
||||
+ if (cmpresult == 0)
|
||||
+ *flag = ReverseNXRTConfArr[8]; // 1: Handheld, 2: Docked, 3: Reset
|
||||
+ else
|
||||
+ *flag = 0; // 0: Not applicable
|
||||
+ }
|
||||
+ else if (recheckReverseNX)
|
||||
+ *flag = prevReverseNXRT; // Use previous state when profile changes
|
||||
+ else
|
||||
+ *flag = 0;
|
||||
+}
|
||||
+
|
||||
bool ClockManager::RefreshContext()
|
||||
{
|
||||
bool hasChanged = false;
|
||||
@@ -120,21 +352,103 @@ bool ClockManager::RefreshContext()
|
||||
if (applicationId != this->context->applicationId)
|
||||
{
|
||||
FileUtils::LogLine("[mgr] TitleID change: %016lX", applicationId);
|
||||
+ prevReverseNXRT = 0; // Reset ReverseNX-RT previous state when Title ID changes
|
||||
this->context->applicationId = applicationId;
|
||||
hasChanged = true;
|
||||
+
|
||||
+ if (FileUtils::IsReverseNXEnabled() || recheckReverseNX)
|
||||
+ {
|
||||
+ // A new game starts or the real profile changes, then we need to check if ReverseNXTool patches are applied
|
||||
+ isEnabledReverseNX = false;
|
||||
+
|
||||
+ // Check if ReverseNXTool patches are applied
|
||||
+ if (applicationId != PROCESS_MANAGEMENT_QLAUNCH_TID)
|
||||
+ this->checkReverseNXTool();
|
||||
+ }
|
||||
+
|
||||
+ if (FileUtils::IsBoostStartEnabled() && this->context->applicationId != PROCESS_MANAGEMENT_QLAUNCH_TID)
|
||||
+ {
|
||||
+ // If a game starts and override for CPU clock is not enabled, then set MAX_CPU for 10 sec
|
||||
+ std::uint32_t overcpu = this->context->overrideFreqs[SysClkModule_CPU];
|
||||
+ if (!overcpu)
|
||||
+ {
|
||||
+ tickStartBoost = (std::uint32_t)( 10'000 / this->GetConfig()->GetConfigValue(SysClkConfigValue_PollingIntervalMs) ) + 1;
|
||||
+ FileUtils::LogLine("[mgr] A game starts, bump CPU to max for 10 sec");
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
+ if (!tickCheckReverseNXRT || recheckReverseNX)
|
||||
+ {
|
||||
+ uint8_t flag = 0;
|
||||
+ checkReverseNXRT(recheckReverseNX, &flag);
|
||||
+
|
||||
+ switch(flag)
|
||||
+ {
|
||||
+ case 1:
|
||||
+ FileUtils::LogLine("[mgr] ReverseNX-RT detected: Enforce Handheld Mode");
|
||||
+ this->context->profile = ReverseNXProfile(false);
|
||||
+ prevReverseNXRT = flag;
|
||||
+ isEnabledReverseNX = true;
|
||||
+ isDockedReverseNX = false;
|
||||
+ hasChanged = true;
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ FileUtils::LogLine("[mgr] ReverseNX-RT detected: Enforce Docked Mode");
|
||||
+ this->context->profile = ReverseNXProfile(true);
|
||||
+ prevReverseNXRT = flag;
|
||||
+ isEnabledReverseNX = true;
|
||||
+ isDockedReverseNX = true;
|
||||
+ hasChanged = true;
|
||||
+ break;
|
||||
+ case 3:
|
||||
+ FileUtils::LogLine("[mgr] ReverseNX-RT disabled: Reset to System-controlled Mode and recheck ReverseNX-Tool");
|
||||
+ RealProfile = Clocks::GetCurrentProfile();
|
||||
+ this->context->profile = RealProfile;
|
||||
+ prevReverseNXRT = 0;
|
||||
+ isEnabledReverseNX = false;
|
||||
+ isDockedReverseNX = false;
|
||||
+ hasChanged = true;
|
||||
+ if (this->context->applicationId != PROCESS_MANAGEMENT_QLAUNCH_TID)
|
||||
+ this->checkReverseNXTool();
|
||||
+ break;
|
||||
+ case 0:
|
||||
+ if (recheckReverseNX && isEnabledReverseNXTool && this->context->applicationId != PROCESS_MANAGEMENT_QLAUNCH_TID)
|
||||
+ this->checkReverseNXTool();
|
||||
+ break;
|
||||
+ }
|
||||
+ // Check once per sec
|
||||
+ tickCheckReverseNXRT = (std::uint32_t)( 1'000 / this->GetConfig()->GetConfigValue(SysClkConfigValue_PollingIntervalMs) ) + 1;
|
||||
+ }
|
||||
+ tickCheckReverseNXRT--;
|
||||
+
|
||||
+ if (recheckReverseNX)
|
||||
+ recheckReverseNX = false;
|
||||
+
|
||||
SysClkProfile profile = Clocks::GetCurrentProfile();
|
||||
- if (profile != this->context->profile)
|
||||
+ if (profile != this->context->profile && !isEnabledReverseNX)
|
||||
{
|
||||
FileUtils::LogLine("[mgr] Profile change: %s", Clocks::GetProfileName(profile, true));
|
||||
this->context->profile = profile;
|
||||
hasChanged = true;
|
||||
}
|
||||
+ if (profile != RealProfile && isEnabledReverseNX)
|
||||
+ {
|
||||
+ FileUtils::LogLine("[mgr] Profile change: %s, recheck ReverseNX", Clocks::GetProfileName(profile, true));
|
||||
+ this->context->profile = profile;
|
||||
+ RealProfile = profile;
|
||||
+ hasChanged = true;
|
||||
+ recheckReverseNX = true;
|
||||
+ }
|
||||
|
||||
// restore clocks to stock values on app or profile change
|
||||
if(hasChanged)
|
||||
{
|
||||
+ if (profile == SysClkProfile_Handheld)
|
||||
+ MAX_CPU = 1963'500'000;
|
||||
+ else
|
||||
+ MAX_CPU = 2295'000'000;
|
||||
Clocks::ResetToStock();
|
||||
}
|
||||
|
||||
@@ -142,7 +456,9 @@ bool ClockManager::RefreshContext()
|
||||
for (unsigned int module = 0; module < SysClkModule_EnumMax; module++)
|
||||
{
|
||||
hz = Clocks::GetCurrentHz((SysClkModule)module);
|
||||
- if (hz != 0 && hz != this->context->freqs[module])
|
||||
+ uint32_t cur_mhz = hz/1000'000;
|
||||
+ uint32_t be4_mhz = this->context->freqs[module]/1000'000;
|
||||
+ if (hz != 0 && cur_mhz != be4_mhz)
|
||||
{
|
||||
FileUtils::LogLine("[mgr] %s clock change: %u.%u Mhz", Clocks::GetModuleName((SysClkModule)module, true), hz/1000000, hz/100000 - hz/1000000*10);
|
||||
this->context->freqs[module] = hz;
|
||||
diff --git a/sysmodule/src/clock_manager.h b/sysmodule/src/clock_manager.h
|
||||
index 3eecb21..fd5dce2 100644
|
||||
--- a/sysmodule/src/clock_manager.h
|
||||
+++ b/sysmodule/src/clock_manager.h
|
||||
@@ -20,14 +20,32 @@
|
||||
class ClockManager
|
||||
{
|
||||
public:
|
||||
+ std::uint32_t MAX_CPU = 1963500000;
|
||||
+
|
||||
static ClockManager* GetInstance();
|
||||
static void Initialize();
|
||||
static void Exit();
|
||||
|
||||
+ bool recheckReverseNX = false;
|
||||
+ bool isEnabledReverseNX = false;
|
||||
+ bool isEnabledReverseNXTool = false;
|
||||
+ bool isDockedReverseNX = false;
|
||||
+ std::uint16_t tickCheckReverseNXRT = 0;
|
||||
+ std::uint16_t tickStartBoost = 0;
|
||||
+ char prevReverseNXRT = 0;
|
||||
+ SysClkProfile RealProfile;
|
||||
+
|
||||
+ bool IsCpuBoostMode();
|
||||
+ SysClkProfile ReverseNXProfile(bool);
|
||||
+ void checkReverseNXTool();
|
||||
+ bool GameStartBoost();
|
||||
+
|
||||
void SetRunning(bool running);
|
||||
bool Running();
|
||||
void Tick();
|
||||
void WaitForNextTick();
|
||||
+ void checkReverseNXToolAsm(FILE*, uint8_t*);
|
||||
+ void checkReverseNXRT(bool, uint8_t*);
|
||||
SysClkContext GetCurrentContext();
|
||||
Config* GetConfig();
|
||||
|
||||
diff --git a/sysmodule/src/clocks.cpp b/sysmodule/src/clocks.cpp
|
||||
index 62ef40f..3ef7e15 100644
|
||||
--- a/sysmodule/src/clocks.cpp
|
||||
+++ b/sysmodule/src/clocks.cpp
|
||||
@@ -12,6 +12,8 @@
|
||||
#include "clocks.h"
|
||||
#include "errors.h"
|
||||
|
||||
+bool Clocks::isMariko = false;
|
||||
+
|
||||
void Clocks::GetList(SysClkModule module, std::uint32_t **outClocks)
|
||||
{
|
||||
switch(module)
|
||||
@@ -60,6 +62,26 @@ void Clocks::Initialize()
|
||||
rc = tcInitialize();
|
||||
ASSERT_RESULT_OK(rc, "tcInitialize");
|
||||
}
|
||||
+
|
||||
+ // Check if it's Mariko
|
||||
+ u64 hardware_type = 0;
|
||||
+ splInitialize();
|
||||
+ splGetConfig(SplConfigItem_HardwareType, &hardware_type);
|
||||
+ splExit();
|
||||
+
|
||||
+ switch(hardware_type) {
|
||||
+ case 0: //Icosa
|
||||
+ case 1: //Copper
|
||||
+ break;
|
||||
+ case 2: //Hoag
|
||||
+ case 3: //Iowa
|
||||
+ case 4: //Calcio
|
||||
+ case 5: //Aula
|
||||
+ isMariko = true;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
void Clocks::Exit()
|
||||
@@ -171,7 +193,8 @@ void Clocks::ResetToStock()
|
||||
|
||||
Clocks::SetHz(SysClkModule_CPU, apmConfiguration->cpu_hz);
|
||||
Clocks::SetHz(SysClkModule_GPU, apmConfiguration->gpu_hz);
|
||||
- Clocks::SetHz(SysClkModule_MEM, apmConfiguration->mem_hz);
|
||||
+ // We don't need to set MEM freqs any more
|
||||
+ //Clocks::SetHz(SysClkModule_MEM, apmConfiguration->mem_hz);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -195,16 +218,16 @@ SysClkProfile Clocks::GetCurrentProfile()
|
||||
return SysClkProfile_Docked;
|
||||
}
|
||||
|
||||
- ChargerType chargerType;
|
||||
+ PsmChargerType chargerType;
|
||||
|
||||
rc = psmGetChargerType(&chargerType);
|
||||
ASSERT_RESULT_OK(rc, "psmGetChargerType");
|
||||
|
||||
- if(chargerType == ChargerType_Charger)
|
||||
+ if(chargerType == PsmChargerType_EnoughPower)
|
||||
{
|
||||
return SysClkProfile_HandheldChargingOfficial;
|
||||
}
|
||||
- else if(chargerType == ChargerType_Usb)
|
||||
+ else if(chargerType == PsmChargerType_LowPower || chargerType == PsmChargerType_NotSupported)
|
||||
{
|
||||
return SysClkProfile_HandheldChargingUSB;
|
||||
}
|
||||
@@ -214,6 +237,10 @@ SysClkProfile Clocks::GetCurrentProfile()
|
||||
|
||||
void Clocks::SetHz(SysClkModule module, std::uint32_t hz)
|
||||
{
|
||||
+ // We don't need to set MEM freqs any more
|
||||
+ if (module == SysClkModule_MEM)
|
||||
+ return;
|
||||
+
|
||||
Result rc = 0;
|
||||
|
||||
if(hosversionAtLeast(8,0,0))
|
||||
@@ -222,7 +249,6 @@ void Clocks::SetHz(SysClkModule module, std::uint32_t hz)
|
||||
|
||||
rc = clkrstOpenSession(&session, Clocks::GetPcvModuleId(module), 3);
|
||||
ASSERT_RESULT_OK(rc, "clkrstOpenSession");
|
||||
-
|
||||
rc = clkrstSetClockRate(&session, hz);
|
||||
ASSERT_RESULT_OK(rc, "clkrstSetClockRate");
|
||||
|
||||
@@ -248,7 +274,7 @@ std::uint32_t Clocks::GetCurrentHz(SysClkModule module)
|
||||
ASSERT_RESULT_OK(rc, "clkrstOpenSession");
|
||||
|
||||
rc = clkrstGetClockRate(&session, &hz);
|
||||
- ASSERT_RESULT_OK(rc, "clkrstSetClockRate");
|
||||
+ ASSERT_RESULT_OK(rc, "clkrstGetClockRate");
|
||||
|
||||
clkrstCloseSession(&session);
|
||||
}
|
||||
@@ -280,11 +306,11 @@ std::uint32_t Clocks::GetMaxAllowedHz(SysClkModule module, SysClkProfile profile
|
||||
{
|
||||
if(profile < SysClkProfile_HandheldCharging)
|
||||
{
|
||||
- return SYSCLK_GPU_HANDHELD_MAX_HZ;
|
||||
+ return isMariko ? 1536000000 : SYSCLK_GPU_HANDHELD_MAX_HZ;
|
||||
}
|
||||
else if(profile <= SysClkProfile_HandheldChargingUSB)
|
||||
{
|
||||
- return SYSCLK_GPU_UNOFFICIAL_CHARGER_MAX_HZ;
|
||||
+ return isMariko ? 1536000000 : SYSCLK_GPU_UNOFFICIAL_CHARGER_MAX_HZ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,6 +319,79 @@ std::uint32_t Clocks::GetMaxAllowedHz(SysClkModule module, SysClkProfile profile
|
||||
|
||||
std::uint32_t Clocks::GetNearestHz(SysClkModule module, std::uint32_t inHz)
|
||||
{
|
||||
+ // Hardcoded values to return, I don't know why it will bump to max when excessive OC
|
||||
+ if(module == SysClkModule_MEM)
|
||||
+ {
|
||||
+ switch(inHz)
|
||||
+ {
|
||||
+ case 1331000000:
|
||||
+ return 1331200000;
|
||||
+ case 1731000000:
|
||||
+ return 1731200000;
|
||||
+ case 1862000000:
|
||||
+ return 1862400000;
|
||||
+ case 1996000000:
|
||||
+ return 1996800000;
|
||||
+ default:
|
||||
+ return inHz;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if(module == SysClkModule_CPU)
|
||||
+ {
|
||||
+ switch(inHz)
|
||||
+ {
|
||||
+ case 1963000000:
|
||||
+ return 1963500000;
|
||||
+ default:
|
||||
+ return inHz;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if(module == SysClkModule_GPU)
|
||||
+ {
|
||||
+ switch(inHz)
|
||||
+ {
|
||||
+ case 76000000:
|
||||
+ return 76800000;
|
||||
+ case 153000000:
|
||||
+ return 153600000;
|
||||
+ case 230000000:
|
||||
+ return 230400000;
|
||||
+ case 307000000:
|
||||
+ return 307200000;
|
||||
+ case 460000000:
|
||||
+ return 460800000;
|
||||
+ case 537000000:
|
||||
+ return 537600000;
|
||||
+ case 614000000:
|
||||
+ return 614400000;
|
||||
+ case 691000000:
|
||||
+ return 691200000;
|
||||
+ case 844000000:
|
||||
+ return 844800000;
|
||||
+ case 921000000:
|
||||
+ return 921600000;
|
||||
+ case 998000000:
|
||||
+ return 998400000;
|
||||
+ case 1075000000:
|
||||
+ return 1075200000;
|
||||
+ case 1228000000:
|
||||
+ return 1228800000;
|
||||
+ case 1267000000:
|
||||
+ return 1267200000;
|
||||
+ case 1305000000:
|
||||
+ return 1305600000;
|
||||
+ case 1382000000:
|
||||
+ return 1382400000;
|
||||
+ case 1420000000:
|
||||
+ return 1420800000;
|
||||
+ default:
|
||||
+ return inHz;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return inHz;
|
||||
std::uint32_t *clockTable = NULL;
|
||||
GetList(module, &clockTable);
|
||||
|
||||
diff --git a/sysmodule/src/clocks.h b/sysmodule/src/clocks.h
|
||||
index 7f86be8..5ff180b 100644
|
||||
--- a/sysmodule/src/clocks.h
|
||||
+++ b/sysmodule/src/clocks.h
|
||||
@@ -16,6 +16,7 @@
|
||||
class Clocks
|
||||
{
|
||||
public:
|
||||
+ static bool isMariko;
|
||||
static void Exit();
|
||||
static void Initialize();
|
||||
static void ResetToStock();
|
||||
diff --git a/sysmodule/src/file_utils.cpp b/sysmodule/src/file_utils.cpp
|
||||
index 5503f44..8f91a1a 100644
|
||||
--- a/sysmodule/src/file_utils.cpp
|
||||
+++ b/sysmodule/src/file_utils.cpp
|
||||
@@ -9,12 +9,19 @@
|
||||
*/
|
||||
|
||||
#include "file_utils.h"
|
||||
+#include "clocks.h"
|
||||
+#include <dirent.h>
|
||||
+#include <filesystem>
|
||||
#include <nxExt.h>
|
||||
|
||||
static LockableMutex g_log_mutex;
|
||||
static LockableMutex g_csv_mutex;
|
||||
static std::atomic_bool g_has_initialized = false;
|
||||
static bool g_log_enabled = false;
|
||||
+static bool g_boost_enabled = false;
|
||||
+static bool g_boost_start_enabled = false;
|
||||
+static bool g_downclock_dock_enabled = false;
|
||||
+static bool g_reversenx_enabled = false;
|
||||
static std::uint64_t g_last_flag_check = 0;
|
||||
|
||||
extern "C" void __libnx_init_time(void);
|
||||
@@ -124,9 +131,55 @@ void FileUtils::RefreshFlags(bool force)
|
||||
g_log_enabled = false;
|
||||
}
|
||||
|
||||
+ // Only Enable Boost for Mariko
|
||||
+ if (Clocks::isMariko)
|
||||
+ {
|
||||
+ file = fopen(FILE_BOOST_FLAG_PATH, "r");
|
||||
+ if (file)
|
||||
+ {
|
||||
+ g_boost_enabled = true;
|
||||
+ fclose(file);
|
||||
+ } else {
|
||||
+ g_boost_enabled = false;
|
||||
+ }
|
||||
+
|
||||
+ file = fopen(FILE_BOOST_START_FLAG_PATH, "r");
|
||||
+ if (file)
|
||||
+ {
|
||||
+ g_boost_start_enabled = true;
|
||||
+ fclose(file);
|
||||
+ } else {
|
||||
+ g_boost_start_enabled = false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ file = fopen(FILE_DOWNCLOCK_DOCK_FLAG_PATH, "r");
|
||||
+ if (file)
|
||||
+ {
|
||||
+ g_downclock_dock_enabled = true;
|
||||
+ fclose(file);
|
||||
+ } else {
|
||||
+ g_downclock_dock_enabled = false;
|
||||
+ }
|
||||
+
|
||||
g_last_flag_check = now;
|
||||
}
|
||||
|
||||
+bool FileUtils::IsBoostEnabled()
|
||||
+{
|
||||
+ return g_boost_enabled;
|
||||
+}
|
||||
+
|
||||
+bool FileUtils::IsBoostStartEnabled()
|
||||
+{
|
||||
+ return g_boost_start_enabled;
|
||||
+}
|
||||
+
|
||||
+bool FileUtils::IsDownclockDockEnabled()
|
||||
+{
|
||||
+ return g_downclock_dock_enabled;
|
||||
+}
|
||||
+
|
||||
void FileUtils::InitializeAsync()
|
||||
{
|
||||
Thread initThread = {0};
|
||||
@@ -163,9 +216,23 @@ Result FileUtils::Initialize()
|
||||
FileUtils::LogLine("=== " TARGET " " TARGET_VERSION " ===");
|
||||
}
|
||||
|
||||
+ FILE *file = fopen(FILE_SALTYNX_PATH, "r");
|
||||
+ if (file)
|
||||
+ {
|
||||
+ g_reversenx_enabled = true;
|
||||
+ fclose(file);
|
||||
+ } else {
|
||||
+ g_reversenx_enabled = false;
|
||||
+ }
|
||||
+
|
||||
return rc;
|
||||
}
|
||||
|
||||
+bool FileUtils::IsReverseNXEnabled()
|
||||
+{
|
||||
+ return g_reversenx_enabled;
|
||||
+}
|
||||
+
|
||||
void FileUtils::Exit()
|
||||
{
|
||||
if (!g_has_initialized)
|
||||
diff --git a/sysmodule/src/file_utils.h b/sysmodule/src/file_utils.h
|
||||
index 4f1642e..336e63b 100644
|
||||
--- a/sysmodule/src/file_utils.h
|
||||
+++ b/sysmodule/src/file_utils.h
|
||||
@@ -22,6 +22,11 @@
|
||||
#define FILE_CONTEXT_CSV_PATH FILE_CONFIG_DIR "/context.csv"
|
||||
#define FILE_LOG_FLAG_PATH FILE_CONFIG_DIR "/log.flag"
|
||||
#define FILE_LOG_FILE_PATH FILE_CONFIG_DIR "/log.txt"
|
||||
+#define FILE_BOOST_FLAG_PATH FILE_CONFIG_DIR "/boost.flag"
|
||||
+#define FILE_BOOST_START_FLAG_PATH FILE_CONFIG_DIR "/boost_start.flag"
|
||||
+#define FILE_DOWNCLOCK_DOCK_FLAG_PATH FILE_CONFIG_DIR "/downclock_dock.flag"
|
||||
+#define FILE_SALTYNX_PATH "/atmosphere/contents/0000000000534C56/flags/boot2.flag" // Just check for SaltyNX boot flag
|
||||
+#define FILE_REVERSENX_RT_CONF_PATH FILE_CONFIG_DIR "/ReverseNX-RT.conf"
|
||||
|
||||
class FileUtils
|
||||
{
|
||||
@@ -30,6 +35,10 @@ class FileUtils
|
||||
static Result Initialize();
|
||||
static bool IsInitialized();
|
||||
static bool IsLogEnabled();
|
||||
+ static bool IsBoostEnabled();
|
||||
+ static bool IsBoostStartEnabled();
|
||||
+ static bool IsDownclockDockEnabled();
|
||||
+ static bool IsReverseNXEnabled();
|
||||
static void InitializeAsync();
|
||||
static void LogLine(const char *format, ...);
|
||||
static void WriteContextToCsv(const SysClkContext* context);
|
||||
Reference in New Issue
Block a user