diff --git a/README.md b/README.md index 6b3d0fa2..ee6238a5 100644 --- a/README.md +++ b/README.md @@ -46,11 +46,12 @@ Git clone Atmosphere, and move the cloned folder into build/
Insert Source/stratosphere folder into build/
Run build.sh -To build the configurator, clone it's repo (souldbminersmwc/ocs2-configurator)
-Run build.bat or cd into folder and run "python -m PyInstaller --onefile --add-data "assets;assets" --icon=assets/icon.ico --noconsole src/main.py"
+To build the configurator, cd into Source/Configurator
+Run build.bat or run "python -m PyInstaller --onefile --add-data "assets;assets" --icon=assets/icon.ico --noconsole src/main.py"
## Credits +Lightos for RAM timings
meha for Switch-Oc-Suite
sys-clk team for sys-clk
b0rd2death for Ultrahand sys-clk fork
diff --git a/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp b/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp index 701e66c9..38308077 100644 --- a/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp +++ b/Source/Atmosphere/stratosphere/loader/source/oc/customize.cpp @@ -474,7 +474,7 @@ volatile CustomizeTable C = { { 2091000, { 1235000 }, { 5400873, -289186, 4847 } }, { 2193000, { 1235000 }, { 5500873, -299186, 4947 } }, { 2295000, { 1235000 }, { 5600873, -239186, 5047 } }, - { 2397000, { 1235000 }, { 5700873, -249186, 5047 } }, + // { 2397000, { 1235000 }, { 5700873, -249186, 5047 } }, }, }; diff --git a/Source/sys-clk/common/include/sysclk/clock_manager.h b/Source/sys-clk/common/include/sysclk/clock_manager.h index 26628c85..74f329bd 100644 --- a/Source/sys-clk/common/include/sysclk/clock_manager.h +++ b/Source/sys-clk/common/include/sysclk/clock_manager.h @@ -24,6 +24,7 @@ typedef struct uint32_t temps[SysClkThermalSensor_EnumMax]; int32_t power[SysClkPowerSensor_EnumMax]; uint32_t ramLoad[SysClkRamLoad_EnumMax]; + uint32_t perfConfId; } SysClkContext; typedef struct diff --git a/Source/sys-clk/common/include/sysclk/config.h b/Source/sys-clk/common/include/sysclk/config.h index 420b7d1f..0128f66d 100644 --- a/Source/sys-clk/common/include/sysclk/config.h +++ b/Source/sys-clk/common/include/sysclk/config.h @@ -19,6 +19,8 @@ typedef enum { SysClkConfigValue_FreqLogIntervalMs, SysClkConfigValue_PowerLogIntervalMs, SysClkConfigValue_CsvWriteIntervalMs, + HocClkConfigValue_UncappedClocks, + HocClkConfigValue_OverwriteBoostMode, SysClkConfigValue_EnumMax, } SysClkConfigValue; @@ -40,6 +42,10 @@ static inline const char* sysclkFormatConfigValue(SysClkConfigValue val, bool pr return pretty ? "Power logging interval (ms)" : "power_log_interval_ms"; case SysClkConfigValue_CsvWriteIntervalMs: return pretty ? "CSV write interval (ms)" : "csv_write_interval_ms"; + case HocClkConfigValue_UncappedClocks: + return pretty ? "Uncapped Clocks" : "uncapped_clocks"; + case HocClkConfigValue_OverwriteBoostMode: + return pretty ? "Overwrite Boost Mode" : "ow_boost"; default: return NULL; } @@ -55,6 +61,8 @@ static inline uint64_t sysclkDefaultConfigValue(SysClkConfigValue val) case SysClkConfigValue_FreqLogIntervalMs: case SysClkConfigValue_PowerLogIntervalMs: case SysClkConfigValue_CsvWriteIntervalMs: + case HocClkConfigValue_UncappedClocks: + case HocClkConfigValue_OverwriteBoostMode: return 0ULL; default: return 0ULL; @@ -72,6 +80,9 @@ static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t in case SysClkConfigValue_PowerLogIntervalMs: case SysClkConfigValue_CsvWriteIntervalMs: return input >= 0; + case HocClkConfigValue_OverwriteBoostMode: + case HocClkConfigValue_UncappedClocks: + return (input & 0x1) == input; default: return false; } diff --git a/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp b/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp index 687fbb81..3917d5b7 100644 --- a/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp +++ b/Source/sys-clk/overlay/src/ui/gui/misc_gui.cpp @@ -7,436 +7,54 @@ MiscGui::MiscGui() { - - // Load current config values - configValues["uncapped_clocks"] = getConfigValue("uncapped_clocks"); - configValues["override_boost_mode"] = getConfigValue("override_boost_mode"); - configValues["auto_cpu_boost"] = getConfigValue("auto_cpu_boost"); - configValues["sync_reversenx"] = getConfigValue("sync_reversenx"); - // gpu_dvfs is handled separately as it's now a trackbar with integer values + this->configList = new SysClkConfigValueList {}; } MiscGui::~MiscGui() { + delete this->configList; this->configToggles.clear(); } -bool MiscGui::getConfigValue(const std::string& iniKey) -{ - FILE* file = fopen("/config/sys-clk/config.ini", "r"); - if (!file) { - // Return default values if file doesn't exist - return (iniKey == "gpu_dvfs"); // gpu_dvfs defaults to true, others default to false - } - - char line[512]; - bool inValuesSection = false; +void MiscGui::addConfigToggle(SysClkConfigValue configVal, const char* altName = nullptr) { + const char* configName = altName ? altName : sysclkFormatConfigValue(configVal, true); + tsl::elm::ToggleListItem* toggle = new tsl::elm::ToggleListItem(configName, this->configList->values[configVal]); + toggle->setStateChangedListener([this, configVal](bool state) { + this->configList->values[configVal] = uint64_t(state); + Result rc = sysclkIpcSetConfigValues(this->configList); + if (R_FAILED(rc)) + FatalGui::openWithResultCode("sysclkIpcSetConfigValues", rc); - size_t len; - while (fgets(line, sizeof(line), file)) { - // Remove newline if present - len = strlen(line); - if (len > 0 && line[len - 1] == '\n') { - line[len - 1] = '\0'; - } - - // Trim whitespace - char* start = line; - while (*start == ' ' || *start == '\t') start++; - char* end = start + strlen(start) - 1; - while (end > start && (*end == ' ' || *end == '\t')) { - *end = '\0'; - end--; - } - - // Check for [values] section - if (strcmp(start, "[values]") == 0) { - inValuesSection = true; - continue; - } - - // Check for new section - if (strlen(start) > 0 && start[0] == '[') { - inValuesSection = false; - continue; - } - - // Parse key=value in values section - if (inValuesSection) { - char* equalPos = strchr(start, '='); - if (equalPos != nullptr) { - *equalPos = '\0'; // Split the string - char* key = start; - char* value = equalPos + 1; - - if(iniKey == "uncapped_clocks") { - Result rc = sysclkIpcSetEnabled(value); - } - - // Trim key - char* keyEnd = key + strlen(key) - 1; - while (keyEnd > key && (*keyEnd == ' ' || *keyEnd == '\t')) { - *keyEnd = '\0'; - keyEnd--; - } - - // Trim value - while (*value == ' ' || *value == '\t') value++; - char* valueEnd = value + strlen(value) - 1; - while (valueEnd > value && (*valueEnd == ' ' || *valueEnd == '\t')) { - *valueEnd = '\0'; - valueEnd--; - } - - if (iniKey == key) { - bool result = (strcmp(value, "1") == 0); - fclose(file); - return result; - } - } - } - } - - fclose(file); - - // Return default values if key not found - return (iniKey == "gpu_dvfs"); // gpu_dvfs defaults to true, others default to false -} - -int MiscGui::getConfigIntValue(const std::string& iniKey, int defaultValue) -{ - FILE* file = fopen("/config/sys-clk/config.ini", "r"); - if (!file) { - return defaultValue; - } - - char line[512]; - bool inValuesSection = false; - - size_t len; - - while (fgets(line, sizeof(line), file)) { - // Remove newline if present - len = strlen(line); - if (len > 0 && line[len - 1] == '\n') { - line[len - 1] = '\0'; - } - - // Trim whitespace - char* start = line; - while (*start == ' ' || *start == '\t') start++; - char* end = start + strlen(start) - 1; - while (end > start && (*end == ' ' || *end == '\t')) { - *end = '\0'; - end--; - } - - // Check for [values] section - if (strcmp(start, "[values]") == 0) { - inValuesSection = true; - continue; - } - - // Check for new section - if (strlen(start) > 0 && start[0] == '[') { - inValuesSection = false; - continue; - } - - // Parse key=value in values section - if (inValuesSection) { - char* equalPos = strchr(start, '='); - if (equalPos != nullptr) { - *equalPos = '\0'; // Split the string - char* key = start; - char* value = equalPos + 1; - - // Trim key - char* keyEnd = key + strlen(key) - 1; - while (keyEnd > key && (*keyEnd == ' ' || *keyEnd == '\t')) { - *keyEnd = '\0'; - keyEnd--; - } - - // Trim value - while (*value == ' ' || *value == '\t') value++; - char* valueEnd = value + strlen(value) - 1; - while (valueEnd > value && (*valueEnd == ' ' || *valueEnd == '\t')) { - *valueEnd = '\0'; - valueEnd--; - } - - if (iniKey == key) { - int result = atoi(value); - fclose(file); - return result; - } - } - } - } - - fclose(file); - return defaultValue; -} - -void MiscGui::setConfigValue(const std::string& iniKey, bool value) -{ - if(iniKey == "uncapped_clocks") { - Result rc = sysclkIpcSetEnabled(value); - } - // Read the entire file - FILE* file = fopen("/config/sys-clk/config.ini", "r"); - std::vector lines; - - if (file) { - char line[512]; - size_t len; - while (fgets(line, sizeof(line), file)) { - // Remove newline if present - len = strlen(line); - if (len > 0 && line[len - 1] == '\n') { - line[len - 1] = '\0'; - } - lines.push_back(std::string(line)); - } - fclose(file); - } - - // Find and update the value - bool inValuesSection = false; - bool keyFound = false; - int valuesSectionIndex = -1; - - std::string trimmedLine; - size_t equalPos; - std::string key; - for (size_t i = 0; i < lines.size(); i++) { - trimmedLine = lines[i]; - trimmedLine.erase(0, trimmedLine.find_first_not_of(" \t")); - trimmedLine.erase(trimmedLine.find_last_not_of(" \t") + 1); - - if (trimmedLine == "[values]") { - inValuesSection = true; - valuesSectionIndex = i; - continue; - } - - if (trimmedLine.length() > 0 && trimmedLine[0] == '[') { - inValuesSection = false; - continue; - } - - if (inValuesSection) { - equalPos = trimmedLine.find('='); - if (equalPos != std::string::npos) { - key = trimmedLine.substr(0, equalPos); - key.erase(0, key.find_first_not_of(" \t")); - key.erase(key.find_last_not_of(" \t") + 1); - - if (key == iniKey) { - lines[i] = iniKey + "=" + (value ? "1" : "0"); - keyFound = true; - break; - } - } - } - } - - // If key wasn't found, add it to the values section - if (!keyFound) { - if (valuesSectionIndex == -1) { - // Add [values] section if it doesn't exist - lines.push_back("[values]"); - lines.push_back(iniKey + "=" + (value ? "1" : "0")); - } else { - // Add to existing values section - lines.insert(lines.begin() + valuesSectionIndex + 1, iniKey + "=" + (value ? "1" : "0")); - } - } - - // Write the file back - FILE* outFile = fopen("/config/sys-clk/config.ini", "w"); - if (outFile) { - for (const auto& fileLine : lines) { - fprintf(outFile, "%s\n", fileLine.c_str()); - } - fclose(outFile); - } -} - -void MiscGui::setConfigIntValue(const std::string& iniKey, int value) -{ - // Read the entire file - FILE* file = fopen("/config/sys-clk/config.ini", "r"); - std::vector lines; - - if (file) { - char line[512]; - size_t len; - while (fgets(line, sizeof(line), file)) { - // Remove newline if present - len = strlen(line); - if (len > 0 && line[len - 1] == '\n') { - line[len - 1] = '\0'; - } - lines.push_back(std::string(line)); - } - fclose(file); - } - - // Find and update the value - bool inValuesSection = false; - bool keyFound = false; - int valuesSectionIndex = -1; - - std::string trimmedLine; - size_t equalPos; - std::string key; - - for (size_t i = 0; i < lines.size(); i++) { - trimmedLine = lines[i]; - trimmedLine.erase(0, trimmedLine.find_first_not_of(" \t")); - trimmedLine.erase(trimmedLine.find_last_not_of(" \t") + 1); - - if (trimmedLine == "[values]") { - inValuesSection = true; - valuesSectionIndex = i; - continue; - } - - if (trimmedLine.length() > 0 && trimmedLine[0] == '[') { - inValuesSection = false; - continue; - } - - if (inValuesSection) { - equalPos = trimmedLine.find('='); - if (equalPos != std::string::npos) { - key = trimmedLine.substr(0, equalPos); - key.erase(0, key.find_first_not_of(" \t")); - key.erase(key.find_last_not_of(" \t") + 1); - - if (key == iniKey) { - lines[i] = iniKey + "=" + std::to_string(value); - keyFound = true; - break; - } - } - } - } - - // If key wasn't found, add it to the values section - if (!keyFound) { - if (valuesSectionIndex == -1) { - // Add [values] section if it doesn't exist - lines.push_back("[values]"); - lines.push_back(iniKey + "=" + std::to_string(value)); - } else { - // Add to existing values section - lines.insert(lines.begin() + valuesSectionIndex + 1, iniKey + "=" + std::to_string(value)); - } - } - - // Write the file back - FILE* outFile = fopen("/config/sys-clk/config.ini", "w"); - if (outFile) { - for (const auto& fileLine : lines) { - fprintf(outFile, "%s\n", fileLine.c_str()); - } - fclose(outFile); - } -} - -void MiscGui::addConfigToggle(const std::string& iniKey, const char* displayName) { - tsl::elm::ToggleListItem* toggle = new tsl::elm::ToggleListItem(displayName, configValues[iniKey]); - toggle->setStateChangedListener([this, iniKey](bool state) { - configValues[iniKey] = state; - setConfigValue(iniKey, state); this->lastContextUpdate = armGetSystemTick(); }); this->listElement->addItem(toggle); - this->configToggles[iniKey] = toggle; + this->configToggles[configVal] = toggle; } void MiscGui::updateConfigToggles() { - for (const auto& [key, toggle] : this->configToggles) { - if (toggle != nullptr) { - bool currentValue = getConfigValue(key); - configValues[key] = currentValue; - toggle->setState(currentValue); - } + for (const auto& [value, toggle] : this->configToggles) { + if (toggle != nullptr) + toggle->setState(this->configList->values[value]); } } void MiscGui::listUI() { + this->listElement->addItem(new tsl::elm::CategoryHeader("Config")); + addConfigToggle(HocClkConfigValue_UncappedClocks); + addConfigToggle(HocClkConfigValue_OverwriteBoostMode); - this->listElement->addItem(new tsl::elm::CategoryHeader("Settings")); - - this->enabledToggle = new tsl::elm::ToggleListItem("Enable", false); - enabledToggle->setStateChangedListener([this](bool state) { - Result rc = sysclkIpcSetEnabled(state); - if(R_FAILED(rc)) - { - FatalGui::openWithResultCode("sysclkIpcSetEnabled", rc); - } - - this->lastContextUpdate = armGetSystemTick(); - this->context->enabled = state; - }); - this->listElement->addItem(this->enabledToggle); - - // Add the 4 boolean config toggles using INI keys - addConfigToggle("uncapped_clocks", "Uncapped Clocks"); - addConfigToggle("override_boost_mode", "Override Boost Mode"); - addConfigToggle("auto_cpu_boost", "Auto CPU Boost"); - addConfigToggle("reversenx_sync", "Sync ReverseNX"); - - // Add GPU DVFS as a NamedStepTrackBar with V2 style - this->gpuDvfsTrackbar = new tsl::elm::NamedStepTrackBar("", { - "Off", - "Official Service Method", - "Hijack Method" - }, true, "GPU DVFS"); - - // Set initial value (default is 0 if not set) - int currentDvfsValue = getConfigIntValue("gpu_dvfs", 1); - // Ensure the value is within valid range (0-2) - currentDvfsValue = std::max(0, std::min(2, currentDvfsValue)); - this->gpuDvfsTrackbar->setProgress(static_cast(currentDvfsValue)); - - // Set up the value change listener to update the INI file - this->gpuDvfsTrackbar->setValueChangedListener([this](u8 value) { - // Ensure value is within expected range - const int intValue = static_cast(std::min(static_cast(2), value)); - setConfigIntValue("gpu_dvfs", intValue); - this->lastContextUpdate = armGetSystemTick(); - }); - - this->listElement->addItem(this->gpuDvfsTrackbar); } void MiscGui::refresh() { BaseMenuGui::refresh(); // Update the enabled toggle state - if(this->context) - { - this->enabledToggle->setState(this->context->enabled); - } - - // Update config values and toggle states every 60 frames (once per second at 60fps) if (this->context && ++frameCounter >= 60) { frameCounter = 0; + sysclkIpcGetConfigValues(this->configList); updateConfigToggles(); - - // Update GPU DVFS trackbar - if (this->gpuDvfsTrackbar != nullptr) { - int currentDvfsValue = getConfigIntValue("gpu_dvfs", 1); - // Ensure the value is within valid range (0-2) - currentDvfsValue = std::max(0, std::min(2, currentDvfsValue)); - this->gpuDvfsTrackbar->setProgress(static_cast(currentDvfsValue)); - } } -} \ No newline at end of file + +} diff --git a/Source/sys-clk/overlay/src/ui/gui/misc_gui.h b/Source/sys-clk/overlay/src/ui/gui/misc_gui.h index 8f7be10f..0ad9f266 100644 --- a/Source/sys-clk/overlay/src/ui/gui/misc_gui.h +++ b/Source/sys-clk/overlay/src/ui/gui/misc_gui.h @@ -9,22 +9,17 @@ class MiscGui : public BaseMenuGui public: MiscGui(); ~MiscGui(); + void listUI() override; void refresh() override; protected: + SysClkConfigValueList* configList; - std::unordered_map configToggles; - std::unordered_map configValues; - - void addConfigToggle(const std::string& iniKey, const char* displayName); + std::map configToggles; + void addConfigToggle(SysClkConfigValue, const char*); void updateConfigToggles(); - bool getConfigValue(const std::string& iniKey); - void setConfigValue(const std::string& iniKey, bool value); - int getConfigIntValue(const std::string& iniKey, int defaultValue); - void setConfigIntValue(const std::string& iniKey, int value); tsl::elm::ToggleListItem* enabledToggle; - tsl::elm::NamedStepTrackBar* gpuDvfsTrackbar; // Add this line u8 frameCounter = 60; }; \ No newline at end of file diff --git a/Source/sys-clk/sysmodule/lib/nxExt/include/nxExt/apm_ext.h b/Source/sys-clk/sysmodule/lib/nxExt/include/nxExt/apm_ext.h index b491a5ee..e1ad78cf 100644 --- a/Source/sys-clk/sysmodule/lib/nxExt/include/nxExt/apm_ext.h +++ b/Source/sys-clk/sysmodule/lib/nxExt/include/nxExt/apm_ext.h @@ -23,6 +23,18 @@ void apmExtExit(void); Result apmExtGetPerformanceMode(u32* out_mode); Result apmExtSysRequestPerformanceMode(u32 mode); Result apmExtGetCurrentPerformanceConfiguration(u32* out_conf); +Result apmExtSysRequestPerformanceMode(u32 mode); +Result apmExtSysSetCpuBoostMode(u32 mode); + +Result apmExtGetPerformanceMode(u32 *out_mode); +Result apmExtGetCurrentPerformanceConfiguration(u32 *out_conf); + +inline bool apmExtIsCPUBoosted(u32 conf_id) { // CPU boosted to 1785 MHz + return (conf_id == 0x92220009 || conf_id == 0x9222000A); +}; +inline bool apmExtIsBoostMode(u32 conf_id) { // GPU throttled to 76.8 MHz + return (conf_id >= 0x92220009 && conf_id <= 0x9222000C); +}; #ifdef __cplusplus } diff --git a/Source/sys-clk/sysmodule/src/clock_manager.cpp b/Source/sys-clk/sysmodule/src/clock_manager.cpp index 5ad25850..7b2fab4b 100644 --- a/Source/sys-clk/sysmodule/src/clock_manager.cpp +++ b/Source/sys-clk/sysmodule/src/clock_manager.cpp @@ -86,7 +86,25 @@ bool ClockManager::IsAssignableHz(SysClkModule module, std::uint32_t hz) std::uint32_t ClockManager::GetMaxAllowedHz(SysClkModule module, SysClkProfile profile) { - return 4294967294; // Integer limit, uncapped clocks ON + if (this->config->GetConfigValue(HocClkConfigValue_UncappedClocks)) + { + return 4294967294; // Integer limit, uncapped clocks ON + } + else + { + if(module == SysClkModule_GPU) + { + if(profile < SysClkProfile_HandheldCharging) + { + return Board::GetSocType() == SysClkSocType_Mariko ? 614400000 : 460800000; + } + else if(profile <= SysClkProfile_HandheldChargingUSB) + { + return 768000000; + } + } + } + return 0; } std::uint32_t ClockManager::GetNearestHz(SysClkModule module, std::uint32_t inHz, std::uint32_t maxHz) @@ -177,7 +195,7 @@ void ClockManager::Tick() maxHz = this->GetMaxAllowedHz((SysClkModule)module, this->context->profile); nearestHz = this->GetNearestHz((SysClkModule)module, targetHz, maxHz); - if (nearestHz != this->context->freqs[module] && this->context->enabled) + if (nearestHz != this->context->freqs[module] && this->context->enabled && !apmExtIsBoostMode(this->context->perfConfId) && this->config->GetConfigValue(HocClkConfigValue_OverwriteBoostMode)) { FileUtils::LogLine( "[mgr] %s clock set : %u.%u MHz (target = %u.%u MHz)", @@ -187,6 +205,9 @@ void ClockManager::Tick() Board::SetHz((SysClkModule)module, nearestHz); this->context->freqs[module] = nearestHz; + } else { + Board::ResetToStockCpu(); + Board::ResetToStockGpu(); } } } @@ -254,16 +275,17 @@ bool ClockManager::RefreshContext() else { FileUtils::LogLine("[mgr] %s override disabled", Board::GetModuleName((SysClkModule)module, true)); - switch(module) { - case SysClkModule_CPU: - Board::ResetToStockCpu(); - break; - case SysClkModule_GPU: - Board::ResetToStockGpu(); - break; - case SysClkModule_MEM: - Board::ResetToStockMem(); - break; + switch (module) + { + case SysClkModule_CPU: + Board::ResetToStockCpu(); + break; + case SysClkModule_GPU: + Board::ResetToStockGpu(); + break; + case SysClkModule_MEM: + Board::ResetToStockMem(); + break; } } this->context->overrideFreqs[module] = hz; diff --git a/dist/atmosphere/kips/hoc.kip b/dist/atmosphere/kips/hoc.kip index f3345ffe..f19aee2e 100644 Binary files a/dist/atmosphere/kips/hoc.kip and b/dist/atmosphere/kips/hoc.kip differ diff --git a/hocconfig.exe b/hocconfig.exe deleted file mode 100644 index 209dcad8..00000000 Binary files a/hocconfig.exe and /dev/null differ