Files
Horizon-OC/Source/Patch/sys-clk.diff
2021-07-05 17:02:51 +08:00

998 lines
35 KiB
Diff

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);