chore: clean up repo
This commit is contained in:
@@ -1,287 +0,0 @@
|
||||
diff --git a/Overlay/Makefile b/Overlay/Makefile
|
||||
index 9656834..3b2ebd5 100644
|
||||
--- a/Overlay/Makefile
|
||||
+++ b/Overlay/Makefile
|
||||
@@ -38,7 +38,7 @@ include $(DEVKITPRO)/libnx/switch_rules
|
||||
# NACP building is skipped as well.
|
||||
#---------------------------------------------------------------------------------
|
||||
APP_TITLE := ReverseNX-RT
|
||||
-APP_VERSION := 1.1.1
|
||||
+APP_VERSION := 1.1.1-OC
|
||||
|
||||
TARGET := ReverseNX-RT-ovl
|
||||
BUILD := build
|
||||
diff --git a/Overlay/source/main.cpp b/Overlay/source/main.cpp
|
||||
index 810295c..2b3aa52 100644
|
||||
--- a/Overlay/source/main.cpp
|
||||
+++ b/Overlay/source/main.cpp
|
||||
@@ -1,7 +1,202 @@
|
||||
#define TESLA_INIT_IMPL // If you have more than one file using the tesla header, only define this in the main one
|
||||
#include <tesla.hpp> // The Tesla Header
|
||||
+#include <atomic>
|
||||
#include "SaltyNX.h"
|
||||
|
||||
+class ModeSync {
|
||||
+public:
|
||||
+ enum ReverseNXMode {
|
||||
+ ReverseNX_NotValid = 0,
|
||||
+ ReverseNX_SystemDefault = 0,
|
||||
+ ReverseNX_Handheld,
|
||||
+ ReverseNX_Docked,
|
||||
+ ReverseNX_Undefined,
|
||||
+ };
|
||||
+
|
||||
+ void SetMode(bool isDefault, bool setDock, char* descBuf, size_t bufSize) {
|
||||
+ auto changeHandler = [this](ReverseNXMode newMode) {
|
||||
+ if (this->currentMode == ReverseNX_Undefined || this->currentMode != newMode) {
|
||||
+ if (R_FAILED(this->ipc->SetMode(newMode))) {
|
||||
+ this->ipc->ipcStatus = Ipc::IpcStatus_ConnectFailed;
|
||||
+ return;
|
||||
+ }
|
||||
+ this->currentMode = newMode;
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ tsl::hlp::ScopeGuard updateBufGuard([&] { this->ipc->UpdateStatusDesc(descBuf, bufSize); });
|
||||
+
|
||||
+ if (isDefault) {
|
||||
+ changeHandler(ReverseNX_SystemDefault);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ changeHandler(setDock ? ReverseNX_Docked : ReverseNX_Handheld);
|
||||
+ }
|
||||
+
|
||||
+ ModeSync() {
|
||||
+ this->ipc = new Ipc;
|
||||
+ this->ipc->Init();
|
||||
+ }
|
||||
+
|
||||
+ ~ModeSync() {
|
||||
+ this->ipc->Exit();
|
||||
+ delete this->ipc;
|
||||
+ }
|
||||
+
|
||||
+protected:
|
||||
+ struct Ipc {
|
||||
+ #define API_VER 2
|
||||
+ #define SERVICE_NAME "sysclkOC"
|
||||
+
|
||||
+ enum SysClkIpcCmd {
|
||||
+ SysClkIpcCmd_GetApiVersion = 0,
|
||||
+ SysClkIpcCmd_GetConfigValues = 9,
|
||||
+ SysClkIpcCmd_SetReverseNXRTMode = 11,
|
||||
+ };
|
||||
+
|
||||
+ enum SysClkConfigValue {
|
||||
+ SysClkConfigValue_SyncReverseNXMode = 4,
|
||||
+ SysClkConfigValue_EnumMax = 8,
|
||||
+ };
|
||||
+
|
||||
+ struct SysClkConfigValueList {
|
||||
+ uint64_t values[SysClkConfigValue_EnumMax];
|
||||
+ };
|
||||
+
|
||||
+ enum IpcStatus {
|
||||
+ IpcStatus_OK,
|
||||
+
|
||||
+ IpcStatus_Unknown,
|
||||
+ IpcStatus_NotRunning,
|
||||
+ IpcStatus_InitFailed,
|
||||
+ IpcStatus_ConnectFailed,
|
||||
+ IpcStatus_UnsupportedVer,
|
||||
+
|
||||
+ IpcStatus_Count,
|
||||
+ };
|
||||
+
|
||||
+ static constexpr const char* IpcStatusStr[IpcStatus_Count] = {
|
||||
+ "",
|
||||
+
|
||||
+ "Unknown",
|
||||
+ "Err: Not running",
|
||||
+ "Err: Failed to init",
|
||||
+ "Err: Failed to connect",
|
||||
+ "Err: Unsupported version",
|
||||
+ };
|
||||
+
|
||||
+ Result Init() {
|
||||
+ Result rc = 0;
|
||||
+
|
||||
+ rc = IpcInitialize();
|
||||
+
|
||||
+ rc = GetStatus();
|
||||
+
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ void Exit() {
|
||||
+ if (--refCnt == 0)
|
||||
+ serviceClose(&service);
|
||||
+ }
|
||||
+
|
||||
+ bool IsServiceRunning() {
|
||||
+ Handle handle;
|
||||
+ SmServiceName name = smEncodeName(SERVICE_NAME);
|
||||
+ if (R_FAILED(smRegisterService(&handle, name, false, 1))) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ svcCloseHandle(handle);
|
||||
+ smUnregisterService(name);
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ Result IpcInitialize(void) {
|
||||
+ Result rc = 0;
|
||||
+ refCnt++;
|
||||
+
|
||||
+ if (serviceIsActive(&service))
|
||||
+ return 0;
|
||||
+
|
||||
+ rc = smGetService(&service, SERVICE_NAME);
|
||||
+
|
||||
+ if (R_FAILED(rc)) {
|
||||
+ this->ipcStatus = IpcStatus_InitFailed;
|
||||
+ rc = this->ipcStatus;
|
||||
+ this->Exit();
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ Result GetApiVersion(u32* outVer) {
|
||||
+ return serviceDispatchOut(&service, SysClkIpcCmd_GetApiVersion, *outVer);
|
||||
+ }
|
||||
+
|
||||
+ Result GetConfigValues(SysClkConfigValueList* outConfigValues) {
|
||||
+ return serviceDispatchOut(&service, SysClkIpcCmd_GetConfigValues, *outConfigValues);
|
||||
+ }
|
||||
+
|
||||
+ Result SetMode(ReverseNXMode mode) {
|
||||
+ return serviceDispatchIn(&service, SysClkIpcCmd_SetReverseNXRTMode, mode);
|
||||
+ }
|
||||
+
|
||||
+ Result GetStatus() {
|
||||
+ if (!IsServiceRunning()) {
|
||||
+ this->ipcStatus = IpcStatus_NotRunning;
|
||||
+ return this->ipcStatus;
|
||||
+ }
|
||||
+
|
||||
+ tsl::hlp::ScopeGuard exitSrvGuard([&] { this->Exit(); });
|
||||
+
|
||||
+ uint32_t api_ver;
|
||||
+ if (R_FAILED(GetApiVersion(&api_ver))) {
|
||||
+ this->ipcStatus = IpcStatus_ConnectFailed;
|
||||
+ return this->ipcStatus;
|
||||
+ }
|
||||
+
|
||||
+ if (api_ver != API_VER) {
|
||||
+ this->ipcStatus = IpcStatus_UnsupportedVer;
|
||||
+ return this->ipcStatus;
|
||||
+ }
|
||||
+
|
||||
+ SysClkConfigValueList* list = new SysClkConfigValueList;
|
||||
+ tsl::hlp::ScopeGuard listGuard([&] { delete list; });
|
||||
+
|
||||
+ if (R_FAILED(GetConfigValues(list))) {
|
||||
+ this->ipcStatus = IpcStatus_ConnectFailed;
|
||||
+ return this->ipcStatus;
|
||||
+ }
|
||||
+
|
||||
+ exitSrvGuard.dismiss();
|
||||
+
|
||||
+ shouldSync = bool(list->values[SysClkConfigValue_SyncReverseNXMode]);
|
||||
+ this->ipcStatus = IpcStatus_OK;
|
||||
+ return this->ipcStatus;
|
||||
+ }
|
||||
+
|
||||
+ void UpdateStatusDesc(char* buffer, size_t size) {
|
||||
+ snprintf(buffer, size,
|
||||
+ "Mode Sync: %s%s",
|
||||
+ IpcStatusStr[ipcStatus],
|
||||
+ (ipcStatus == IpcStatus_OK) ? (
|
||||
+ shouldSync ? "ON" : "OFF"
|
||||
+ ) : ""
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ Service service = {};
|
||||
+ std::atomic<std::size_t> refCnt = 0;
|
||||
+ IpcStatus ipcStatus = IpcStatus_Unknown;
|
||||
+ bool shouldSync = false;
|
||||
+ };
|
||||
+
|
||||
+ Ipc* ipc = nullptr;
|
||||
+ ReverseNXMode currentMode = ReverseNX_Undefined;
|
||||
+};
|
||||
+
|
||||
bool* def = 0;
|
||||
bool* isDocked = 0;
|
||||
bool* pluginActive = 0;
|
||||
@@ -17,6 +212,7 @@ bool plugin = false;
|
||||
char DockedChar[32];
|
||||
char SystemChar[32];
|
||||
char PluginChar[36];
|
||||
+char SysclkChar[0x40];
|
||||
uint64_t PID = 0;
|
||||
Handle remoteSharedMemory = 1;
|
||||
SharedMemory _sharedmemory = {};
|
||||
@@ -73,7 +269,7 @@ bool CheckPort () {
|
||||
|
||||
class GuiTest : public tsl::Gui {
|
||||
public:
|
||||
- GuiTest(u8 arg1, u8 arg2, bool arg3) { }
|
||||
+ GuiTest(ModeSync* p) : modeSync(p) { }
|
||||
|
||||
// Called when this Gui gets loaded to create the UI
|
||||
// Allocate all elements on the heap. libtesla will make sure to clean them up when not needed anymore
|
||||
@@ -112,6 +308,7 @@ public:
|
||||
else {
|
||||
renderer->drawString(SystemChar, false, x, y+40, 20, renderer->a(0xFFFF));
|
||||
renderer->drawString(DockedChar, false, x, y+60, 20, renderer->a(0xFFFF));
|
||||
+ renderer->drawString(SysclkChar, false, x, y+80, 20, renderer->a(0xFFFF));
|
||||
}
|
||||
}
|
||||
}), 100);
|
||||
@@ -190,6 +387,8 @@ public:
|
||||
|
||||
if (_def) sprintf(SystemChar, "Controlled by system: Yes");
|
||||
else sprintf(SystemChar, "Controlled by system: No");
|
||||
+
|
||||
+ modeSync->SetMode(_def, _isDocked, SysclkChar, sizeof(SysclkChar));
|
||||
}
|
||||
else i++;
|
||||
}
|
||||
@@ -200,6 +399,8 @@ public:
|
||||
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
|
||||
}
|
||||
+
|
||||
+ ModeSync* modeSync;
|
||||
};
|
||||
|
||||
class OverlayTest : public tsl::Overlay {
|
||||
@@ -248,9 +449,11 @@ public:
|
||||
|
||||
});
|
||||
|
||||
+ modeSync = new ModeSync;
|
||||
} // Called at the start to initialize all services necessary for this Overlay
|
||||
|
||||
virtual void exitServices() override {
|
||||
+ delete modeSync;
|
||||
shmemClose(&_sharedmemory);
|
||||
fsdevUnmountDevice("sdmc");
|
||||
} // Callet at the end to clean up all services previously initialized
|
||||
@@ -260,8 +463,10 @@ public:
|
||||
virtual void onHide() override {} // Called before overlay wants to change from visible to invisible state
|
||||
|
||||
virtual std::unique_ptr<tsl::Gui> loadInitialGui() override {
|
||||
- return initially<GuiTest>(1, 2, true); // Initial Gui to load. It's possible to pass arguments to it's constructor like this
|
||||
+ return initially<GuiTest>(modeSync); // Initial Gui to load. It's possible to pass arguments to it's constructor like this
|
||||
}
|
||||
+
|
||||
+ ModeSync* modeSync = nullptr;
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
@@ -1,241 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
#include <switch.h>
|
||||
|
||||
/* Recompile nx-hbloader with following added in config.json "kernel_capabilities"
|
||||
{
|
||||
"type": "map",
|
||||
"value": {
|
||||
"address": "0x60006000",
|
||||
"size": "0x1000",
|
||||
"is_ro": false,
|
||||
"is_io": true
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void waitForKey(PadState pad) {
|
||||
while (appletMainLoop())
|
||||
{
|
||||
padUpdate(&pad);
|
||||
|
||||
u64 kDown = padGetButtonsDown(&pad);
|
||||
|
||||
if (kDown & HidNpadButton_A)
|
||||
break;
|
||||
|
||||
if (kDown & HidNpadButton_Plus || kDown & HidNpadButton_B) {
|
||||
consoleExit(NULL);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
consoleUpdate(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#define CLK_RST_IO_BASE 0x60006000
|
||||
#define CLK_RST_IO_SIZE 0x1000
|
||||
|
||||
#define REG(OFFSET) (*reinterpret_cast<volatile u32 *>(OFFSET))
|
||||
#define GET_BITS(VAL, HIGH, LOW) ((VAL & ((1UL << (HIGH + 1UL)) - 1UL)) >> LOW)
|
||||
#define GET_BIT(VAL, BIT) GET_BITS(VAL, BIT, BIT)
|
||||
|
||||
static u64 clkrst_base = 0;
|
||||
static u64 clkrst_size = 0;
|
||||
|
||||
// From jetson nano kernel
|
||||
typedef enum {
|
||||
/* divider = 2 */
|
||||
CLK_PLLX = 5,
|
||||
CLK_PLLM = 2,
|
||||
CLK_PLLMB = 37,
|
||||
/* PLLX & PLLG are backup PLLs for CPU & GPU */
|
||||
/* divider = 1 */
|
||||
CLK_CCLK_G = 18, // A57 CPU cluster
|
||||
CLK_EMC = 36,
|
||||
} PTO_ID; // PLL Test Output Register ID
|
||||
|
||||
/* See if GM20B clock GPC PLL regs are accessible. */
|
||||
|
||||
#define PLLX_MISC0 0xE4
|
||||
#define PLLM_MISC2 0x9C
|
||||
|
||||
double ptoGetMHz(PTO_ID pto_id, u32 divider = 1, u32 presel_reg = 0, u32 presel_mask = 0) {
|
||||
u32 pre_val, val, presel_val;
|
||||
|
||||
if (presel_reg) {
|
||||
val = REG(clkrst_base + presel_reg);
|
||||
usleep(10);
|
||||
presel_val = val & presel_mask;
|
||||
val &= ~presel_mask;
|
||||
val |= presel_mask;
|
||||
REG(clkrst_base + presel_reg) = val;
|
||||
usleep(10);
|
||||
}
|
||||
|
||||
constexpr u32 cycle_count = 16;
|
||||
pre_val = REG(clkrst_base + 0x60);
|
||||
val = BIT(23) | BIT(13) | (cycle_count - 1);
|
||||
val |= pto_id << 14;
|
||||
|
||||
REG(clkrst_base + 0x60) = val;
|
||||
usleep(10);
|
||||
REG(clkrst_base + 0x60) = val | BIT(10);
|
||||
usleep(10);
|
||||
REG(clkrst_base + 0x60) = val;
|
||||
usleep(10);
|
||||
REG(clkrst_base + 0x60) = val | BIT(9);
|
||||
usleep(500);
|
||||
|
||||
while(REG(clkrst_base + 0x64) & BIT(31))
|
||||
;
|
||||
|
||||
val = REG(clkrst_base + 0x64);
|
||||
val &= 0xFFFFFF;
|
||||
val *= divider;
|
||||
|
||||
double rate_mhz = (u64)val * 32768. / cycle_count / 1000. / 1000.;
|
||||
usleep(10);
|
||||
REG(clkrst_base + 0x60) = pre_val;
|
||||
usleep(10);
|
||||
|
||||
if (presel_reg) {
|
||||
val = REG(clkrst_base + presel_reg);
|
||||
usleep(10);
|
||||
val &= ~presel_mask;
|
||||
val |= presel_val;
|
||||
REG(clkrst_base + presel_reg) = val;
|
||||
usleep(10);
|
||||
}
|
||||
|
||||
return rate_mhz;
|
||||
}
|
||||
|
||||
int main() {
|
||||
consoleInit(NULL);
|
||||
PadState pad;
|
||||
padConfigureInput(1, HidNpadStyleSet_NpadStandard);
|
||||
padInitializeDefault(&pad);
|
||||
|
||||
// Get clkrst MMIO virtual address
|
||||
Result rc = svcQueryIoMapping(&clkrst_base, &clkrst_size, CLK_RST_IO_BASE, CLK_RST_IO_SIZE);
|
||||
if (R_FAILED(rc)) {
|
||||
printf("[ERROR] svcQueryIoMapping: 0x%X\n", rc);
|
||||
consoleUpdate(NULL);
|
||||
waitForKey(pad);
|
||||
consoleExit(NULL);
|
||||
}
|
||||
|
||||
printf("clkrst_base: 0x%lX\nclkrst_size: 0x%lX\n", clkrst_base, clkrst_size);
|
||||
|
||||
{
|
||||
#define CLKRST_PLLX_BASE 0xE0
|
||||
u32 pllx_base = REG(clkrst_base + CLKRST_PLLX_BASE);
|
||||
printf("\n"\
|
||||
"PLLX_BASE: 0x%X\n"\
|
||||
"PLLX_ENABLE: %lu\n"\
|
||||
"PLLX_REF_DIS: %lu\n"\
|
||||
"PLLX_LOCK: %lu\n"\
|
||||
"PLLX_DIVP: %lu\n"\
|
||||
"PLLX_DIVN: %lu\n"\
|
||||
"PLLX_DIVM: %lu\n",
|
||||
pllx_base,
|
||||
GET_BIT(pllx_base, 30),
|
||||
GET_BIT(pllx_base, 29),
|
||||
GET_BIT(pllx_base, 27),
|
||||
GET_BITS(pllx_base, 24, 20),
|
||||
GET_BITS(pllx_base, 15, 8),
|
||||
GET_BITS(pllx_base, 7, 0));
|
||||
}
|
||||
|
||||
{
|
||||
#define CLKRST_PLLX_MISC 0xE4
|
||||
u32 pllx_misc = REG(clkrst_base + CLKRST_PLLX_MISC);
|
||||
printf("\n"\
|
||||
"PLLX_MISC: 0x%X\n"\
|
||||
"PLLX_FO_G_DISABLE: %lu\n"\
|
||||
"PLLX_PTS: %lu\n"\
|
||||
"PLLX_LOCK_ENABLE: %lu\n",
|
||||
pllx_misc,
|
||||
GET_BIT(pllx_misc, 28),
|
||||
GET_BITS(pllx_misc, 23, 22),
|
||||
GET_BIT(pllx_misc, 18));
|
||||
}
|
||||
|
||||
{
|
||||
#define CLKRST_PLLMB_SS_CFG 0x780
|
||||
u32 pllmb_ss_cfg = REG(clkrst_base + CLKRST_PLLMB_SS_CFG);
|
||||
printf("\n"\
|
||||
"PLLMB_SS_CFG: 0x%X\n"\
|
||||
"PLLMB_EN_SDM: %lu\n"\
|
||||
"PLLMB_EN_SSC: %lu\n",
|
||||
pllmb_ss_cfg,
|
||||
GET_BIT(pllmb_ss_cfg, 31),
|
||||
GET_BIT(pllmb_ss_cfg, 30));
|
||||
}
|
||||
|
||||
{
|
||||
#define CLKRST_PLLMB_SS_CTRL1 0x784
|
||||
u32 pllmb_ss_ctrl1 = REG(clkrst_base + CLKRST_PLLMB_SS_CTRL1);
|
||||
printf("\n"\
|
||||
"PLLMB_SS_CTRL1: 0x%X\n"\
|
||||
"PLLMB_SDM_SSC_MAX: %lu\n"\
|
||||
"PLLMB_SDM_SSC_MIN: %lu\n",
|
||||
pllmb_ss_ctrl1,
|
||||
GET_BITS(pllmb_ss_ctrl1, 31, 16),
|
||||
GET_BITS(pllmb_ss_ctrl1, 15, 0));
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
#define CLKRST_PLLM_BASE 0x90
|
||||
u32 pllm_base = REG(clkrst_base + CLKRST_PLLM_BASE);
|
||||
printf("\n"\
|
||||
"PLLM_BASE: 0x%X\n"\
|
||||
"PLLM_DIVP: %lu\n"\
|
||||
"PLLM_DIVN: %lu\n"\
|
||||
"PLLM_DIVM: %lu\n",
|
||||
pllm_base,
|
||||
GET_BITS(pllm_base, 24, 20),
|
||||
GET_BITS(pllm_base, 15, 8),
|
||||
GET_BITS(pllm_base, 7, 0));
|
||||
}
|
||||
|
||||
{
|
||||
#define CLKRST_PLLMB_BASE 0x5e8
|
||||
u32 pllmb_base = REG(clkrst_base + CLKRST_PLLMB_BASE);
|
||||
printf("\n"\
|
||||
"PLLMB_BASE: 0x%X\n"\
|
||||
"PLLMB_DIVP: %lu\n"\
|
||||
"PLLMB_DIVN: %lu\n"\
|
||||
"PLLMB_DIVM: %lu\n",
|
||||
pllmb_base,
|
||||
GET_BITS(pllmb_base, 24, 20),
|
||||
GET_BITS(pllmb_base, 15, 8),
|
||||
GET_BITS(pllmb_base, 7, 0));
|
||||
}
|
||||
|
||||
printf("\n"\
|
||||
"EMC: %6.1f MHz\n"\
|
||||
"CCLK_G: %6.1f MHz\n"\
|
||||
"PLLX: %6.1f MHz\n"\
|
||||
"PLLM: %6.1f MHz\n"\
|
||||
"PLLMB: %6.1f MHz\n",
|
||||
ptoGetMHz(CLK_EMC),
|
||||
ptoGetMHz(CLK_CCLK_G),
|
||||
ptoGetMHz(CLK_PLLX, 2, PLLX_MISC0, BIT(22)),
|
||||
ptoGetMHz(CLK_PLLM, 2, PLLM_MISC2, BIT(8)),
|
||||
ptoGetMHz(CLK_PLLMB, 2, PLLM_MISC2, BIT(9))
|
||||
);
|
||||
|
||||
waitForKey(pad);
|
||||
|
||||
consoleExit(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
@echo off
|
||||
set ROOT=build
|
||||
set PATCHES=Atmosphere-Patches
|
||||
set PATCHES=Source/Atmosphere-Patches
|
||||
copy "%PATCHES%\secmon_memory_layout.hpp" "%ROOT%\libraries\libexosphere/include/exosphere/secmon/" /Y
|
||||
copy "%PATCHES%\secmon_emc_access_table_data.inc" "%ROOT%\exosphere/program/source/smc/" /Y
|
||||
copy "%PATCHES%\secmon_soctherm_access_table_data.inc" "%ROOT%\exosphere/program/source/smc/" /Y
|
||||
|
||||
129
gpu_volt.py
129
gpu_volt.py
@@ -1,129 +0,0 @@
|
||||
# Copyright 2023 hanai3Bi
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms and conditions of the GNU General Public License,
|
||||
# version 2, as published by the Free Software Foundation.
|
||||
|
||||
# This program is distributed in the hope it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
# more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import math
|
||||
|
||||
gpu_dvfs_table_0 = [
|
||||
[ 610000, 0 , 0 , 0 , 0 , 0 ],
|
||||
[ 610000, 0 , 0 , 0 , 0 , 0 ],
|
||||
[ 610000, 0 , 0 , 0 , 0 , 0 ],
|
||||
[ 610000, 0 , 0 , 0 , 0 , 0 ],
|
||||
[ 610000, 0 , 0 , 0 , 0 , 0 ],
|
||||
[ 610000, 0 , 0 , 0 , 0 , 0 ],
|
||||
[ 801688, -10900, -163, 298, -10599, 162 ],
|
||||
[ 824214, -5743, -452, 238, -6325, 81 ],
|
||||
[ 848830, -3903, -552, 119, -4030, -2 ],
|
||||
[ 891575, -4409, -584, 0, -2849, 39 ],
|
||||
[ 940071, -5367, -602, -60, -63, -93 ],
|
||||
[ 986765, -6637, -614, -179, 1905, -13 ],
|
||||
[ 1098475, -13529, -497, -179, 3626, 9 ],
|
||||
[ 1163644, -12688, -648, 0, 1077, 40 ],
|
||||
[ 1204812, -9908, -830, 0, 1469, 110 ],
|
||||
[ 1277303, -11675, -859, 0, 3722, 313 ],
|
||||
[ 1335531, -12567, -867, 0, 3681, 559 ]
|
||||
]
|
||||
|
||||
gpu_dvfs_table_1 = [
|
||||
[ 590000, 0 , 0 , 0 , 0 , 0 ],
|
||||
[ 590000, 0 , 0 , 0 , 0 , 0 ],
|
||||
[ 590000, 0 , 0 , 0 , 0 , 0 ],
|
||||
[ 590000, 0 , 0 , 0 , 0 , 0 ],
|
||||
[ 590000, 0 , 0 , 0 , 0 , 0 ],
|
||||
[ 795089, -11096, -163, 298, -10421, 162 ],
|
||||
[ 795089, -11096, -163, 298, -10421, 162 ],
|
||||
[ 820606, -6285, -452, 238, -6182, 81 ],
|
||||
[ 846289, -4565, -552, 119, -3958, -2 ],
|
||||
[ 888720, -5110, -584, 0, -2849, 39 ],
|
||||
[ 936634, -6089, -602, -60, -99, -93 ],
|
||||
[ 982562, -7373, -614, -179, 1797, -13 ],
|
||||
[ 1090179, -14125, -497, -179, 3518, 9 ],
|
||||
[ 1155798, -13465, -648, 0, 1077, 40 ],
|
||||
[ 1198568, -10904, -830, 0, 1469, 110 ],
|
||||
[ 1269988, -12707, -859, 0, 3722, 313 ],
|
||||
[ 1308155, -13694, -867, 0, 3681, 559 ]
|
||||
]
|
||||
gpu_dvfs_table_2 = [
|
||||
[ 590000, 0 , 0 , 0 , 0 , 0 ],
|
||||
[ 590000, 0 , 0 , 0 , 0 , 0 ],
|
||||
[ 590000, 0 , 0 , 0 , 0 , 0 ],
|
||||
[ 590000, 0 , 0 , 0 , 0 , 0 ],
|
||||
[ 590000, 0 , 0 , 0 , 0 , 0 ],
|
||||
[ 590000, 0 , 0 , 0 , 0 , 0 ],
|
||||
[ 590000, 0 , 0 , 0 , 0 , 0 ],
|
||||
[ 590000, 0 , 0 , 0 , 0 , 0 ],
|
||||
[ 838712, -7304, -552, 119, -3750, -2 ],
|
||||
[ 880210, -7955, -584, 0, -2849, 39 ],
|
||||
[ 926398, -8892, -602, -60, -384, -93 ],
|
||||
[ 970060, -10108, -614, -179, 1508, -13 ],
|
||||
[ 1065665, -16075, -497, -179, 3213, 9 ],
|
||||
[ 1132576, -16093, -648, 0, 1077, 40 ],
|
||||
[ 1180029, -14534, -830, 0, 1469, 110 ],
|
||||
[ 1248293, -16383, -859, 0, 3722, 313 ],
|
||||
[ 1286399, -17475, -867, 0, 3681, 559 ]
|
||||
]
|
||||
|
||||
gpu_freq_table = [76800, 153600, 230400, 307200, 384000, 460800, 537600, 614400, 691200, 768000, 844800, 921600, 998400, 1075200, 1152000, 1228800, 1267200]
|
||||
|
||||
temp_list = [20, 30, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90]
|
||||
|
||||
def round_closest(value, scale):
|
||||
if (value > 0):
|
||||
return (((value) + ((scale) / 2)) / (scale))
|
||||
else:
|
||||
return (((value) - ((scale) / 2)) / (scale))
|
||||
|
||||
def round5(number):
|
||||
return int(math.ceil(number / 5.0)) * 5
|
||||
|
||||
speedo = int(input("Enter gpu speedo: "))
|
||||
|
||||
table = int(input("Enter gpu table (0~2): "))
|
||||
if (table == 0):
|
||||
gpu_dvfs_table = gpu_dvfs_table_0
|
||||
elif (table == 1):
|
||||
gpu_dvfs_table = gpu_dvfs_table_1
|
||||
else:
|
||||
gpu_dvfs_table = gpu_dvfs_table_2
|
||||
|
||||
offset = int(input("Enter gpu offset: "))
|
||||
for i in range(17):
|
||||
gpu_dvfs_table[i][0] -= offset*1000
|
||||
|
||||
print("\t\t", end="")
|
||||
|
||||
for temp in temp_list:
|
||||
print(temp, "°C\t", end="")
|
||||
print()
|
||||
|
||||
for entry in range(17):
|
||||
print(float(gpu_freq_table[entry]/1000),end="")
|
||||
print("\t\t", end="")
|
||||
|
||||
mv = round_closest(gpu_dvfs_table[entry][2] * speedo , 100)
|
||||
mv = round_closest( (mv + gpu_dvfs_table[entry][1]) * speedo , 100) + gpu_dvfs_table[entry][0]
|
||||
#mv = round5(mv/1000)
|
||||
|
||||
for temp in temp_list:
|
||||
mvt = round_closest(gpu_dvfs_table[entry][3] * speedo , 100) + gpu_dvfs_table[entry][4] + round_closest(gpu_dvfs_table[entry][5] * temp , 10)
|
||||
mvt = round_closest(mvt * temp , 10)
|
||||
#mvt = round5(mvt/1000)
|
||||
final_volt = math.ceil ((mv + mvt) / 1000)
|
||||
vmin = 610 if table == 0 else 590
|
||||
final_volt = max(final_volt, vmin)
|
||||
final_volt = round5(final_volt)
|
||||
print(final_volt, "\t", end="")
|
||||
print()
|
||||
|
||||
#input("Press enter to exit")
|
||||
|
||||
272
guide.md
272
guide.md
@@ -1,272 +0,0 @@
|
||||
# Mariko OC Guide
|
||||
|
||||
*Made with love by Dominatorul. Some parts of this guide belong to ChanseyIsTheBest and Lightos_*
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
- [Safety Disclaimer](#safety-disclaimer)
|
||||
- [Mariko Limits](#mariko-limits)
|
||||
- [Monitoring Your Switch](#monitoring-your-switch)
|
||||
- [Checking Speedo and RAM Type](#checking-speedo-and-ram-type)
|
||||
- [RAM Tiers](#ram-tiers-higher-is-better)
|
||||
- [OC Settings for Horizon OCE](#oc-settings-for-hoc)
|
||||
- [CPU Settings](#cpu-settings)
|
||||
- [GPU Settings](#gpu-settings)
|
||||
- [RAM Settings](#ram-settings)
|
||||
- [Clock Settings](#clock-settings)
|
||||
- [Mariko Max Safe on Battery](#mariko-max-safe-on-battery-hac-001-01-heg-001)
|
||||
- [Switch Lite Max Safe Clocks on Battery](#switch-lite-max-safe-clocks-on-battery-hdh-001)
|
||||
- [Mariko Max Clocks Docked and Plugged](#mariko-max-clocks-docked-and-plugged-hac-001-01-heg-001)
|
||||
- [Switch Lite Max Clocks Plugged](#switch-lite-max-clocks-plugged-hdh-001)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [How to test stability](https://rentry.co/howtoteststability)
|
||||
|
||||
---
|
||||
|
||||
# Safety Disclaimer
|
||||
!!! info ** Overclocking is inherently risky as it pushes the system beyond its original design. The risk level depends on how much you overclock and whether you stay within the limits of the chip and hardware.**
|
||||
|
||||
!!! danger **Unstable RAM overclocking can cause SYSNAND/EMUNAND corruption and SD card corruption, particularly if done on SYSNAND. Test the overclock settings on EMUNAND and back it up before installing Horizon OC.**
|
||||
|
||||
---
|
||||
|
||||
# Mariko Limits
|
||||
|
||||
### Mariko PMIC Limits
|
||||
- Mariko uses a **5A CPU / 10A GPU PMIC** for power delivery.
|
||||
- Staying within these limits is essential for safe operation.
|
||||
- Exceeding the **PMIC limit** slightly is possible, but not recommended and should be done with caution.
|
||||
|
||||
Reducing the voltage (**undervolting, UV**) decreases power draw, current, heat and helps avoid exceeding pmic limit.
|
||||
|
||||
### Charger IC Limit:
|
||||
- 18W limit restricts overclocking for both Erista and Mariko units (12W on Switch Lite). This is the main limiting factor, but the PMIC current limits for CPU and GPU will be reached first.
|
||||
|
||||
### GPU Scheduling
|
||||
|
||||
This setting adjusts how much of your GPU can be utilized:
|
||||
|
||||
- **On:** Limits GPU usage to ~96.7%
|
||||
- **Off:** Limits GPU usage to ~99.7% (up to ~5% performance boost)
|
||||
- **Recommended:** GPU scheduling **off**.
|
||||
!!! danger ** Warning:** Disabling GPU Scheduling will slightly increase power draw. Use it with caution.
|
||||
|
||||
---
|
||||
|
||||
# Monitoring Your Switch
|
||||
- Use status monitor overlay to indicate if you've bypassed the charger IC limit (e.g., -1W displayed while charging).
|
||||
- To get the best results, be sure your battery is 10-90% to display the real charging
|
||||
|
||||
---
|
||||
|
||||
# Checking Speedo and RAM Type
|
||||
|
||||
1. Boot Hekate.
|
||||
2. Go to Console Info > HW & Fuses.
|
||||
3. Note your DRAM ID, CPU Speedo 0, CPU Speedo 2, and SoC Speedo.
|
||||
- Speedos typically range from 1450 to 1810. A higher speedo means less voltage is needed for the same clock speed. A speedo of 1650 is generally considered good.
|
||||
|
||||
**Speedo Brackets**
|
||||
> - Speedos are divided into **brackets**.
|
||||
> - **CPU UV mode** depends on the position within your bracket, but the resulting **voltage** depends on your specific speedo.
|
||||
> - It doesn’t matter how high you can set CPU UV mode — what matters is using your **maximum possible** CPU UV mode.
|
||||
|
||||
---
|
||||
|
||||
# RAM Tiers (Higher is better)
|
||||
|
||||
| Tier | RAM ID |
|
||||
|-------------|------------------|
|
||||
| GOD-tier | NEI/NEE, WT:B |
|
||||
| S-tier | WT:F |
|
||||
| A-tier | AA-MGCR, AA-MGCL |
|
||||
| B-tier | AM-MGCJ, WT:E |
|
||||
| C-tier | AB-MGCL |
|
||||
| D-tier | NME |
|
||||
|
||||
---
|
||||
|
||||
# OC Settings for Horizon OC
|
||||
|
||||
## CPU Setting
|
||||
|
||||
- **Voltage Limit:**
|
||||
- **1120 mV:** Safe — recommended
|
||||
- **1160 mV:** Use with caution
|
||||
- **1235 mV:** Dangerous. Only use if you know what you are doing
|
||||
|
||||
- **Boost Clock**
|
||||
- Whatever is within **Voltage Limit**.
|
||||
|
||||
- **Undervolt Mode:** 1–6 (start with 2).
|
||||
- Increase gradually if stable and find your highest stable value.
|
||||
- If the console fails to boot, lower the value.
|
||||
|
||||
- **Vmin:** 590 mV
|
||||
- In case you experience issues with low Freq UV, try raising Low Freq Vmin to 610-620mV.
|
||||
- Going below 590mV is not recommended as it may mess up the cpu table.
|
||||
|
||||
> **ℹ️ Note:** Exceeding the PMIC limit during **Boost Mode** is safe, as it only occurs for short bursts (typically under 30 seconds), preventing long-term hardware stress.
|
||||
|
||||
## GPU Settings
|
||||
|
||||
- **Undervolt Mode:** 2
|
||||
|
||||
- **Auto VMIN:**
|
||||
- When RAM is overclocked, the minimum gpu voltage requirement is raised.
|
||||
- Auto vmin automatically adjusts your vmin based on your ram clock.
|
||||
- When using the base ram clocks (1600 MHz), **Auto VMIN** is not active
|
||||
- **2 (Hijack method):** Recommended — provides the lowest value possible.
|
||||
- **1 (Official service method):** Use only if you encounter issues with mode 2.
|
||||
|
||||
- **Auto VMIN Offset:** Auto
|
||||
|
||||
- **Vmin:** 550–620 mV
|
||||
- Typically not worth adjusting, as you should always use max RAM.
|
||||
|
||||
- **Vmax:** 800 mV
|
||||
|
||||
- **Voltage Offset:** 0
|
||||
|
||||
## RAM Settings
|
||||
|
||||
- **DRAM Timing:**
|
||||
- **0 — AUTO_ADJ:** Auto-adjust MTC table with LPDDR4 3733 Mbps specs, 16Gb density. Change timing with Advanced Config (Default).
|
||||
- **1 — AUTO_ADJ_HP:** Same as AUTO_ADJ, but with RAM power-down disabled.
|
||||
|
||||
> **ℹ️ Tip:** AUTO_ADJ_HP improves latency, but some RAM modules may not handle it well.
|
||||
> - First, find your max RAM clocks and timings with **AUTO_ADJ**.
|
||||
> - Then test AUTO_ADJ_HP. If stable, use it — otherwise, stick to AUTO_ADJ.
|
||||
|
||||
- **DVB Shift:** 1–5
|
||||
- Boosts SoC voltage to help stabilize RAM, especially at high frequencies (2400 MHz+).
|
||||
- It's adviced to start of with a DVB shift of 4 and only lower it to 2-3 after finding your max ram speed.
|
||||
- Higher DVB shift does not increase power draw, but it is going to increase heat slightly.
|
||||
- Undervolting DVB is pointless.
|
||||
|
||||
### RAM Configuration Based on Tier List
|
||||
|
||||
| Tier | RAM ID | Ram Clock | VDD2 | VDDQ | Common Timings | Super Tight (ST) Timings |
|
||||
|------|-----------------|------------|--------|-------|--------------------------|----------------------------|
|
||||
| GOD | NEI/NEE/x267 | 2900-3500 | 1175 mV| 640 mV| (3-3-2) 2-5-5-4-6 | (4-4-4) 3-7-6-5-6 |
|
||||
| GOD | WT:B | 2700-3200 | 1175 mV| 600 mV| (4-4-5) 5-2-6-5-6 | (6-6-7) 7-2-6-5-6 |
|
||||
| S | AA-MGCL/MGCR | 2300–3100 | 1175 mV| 640 mV| (4-4-5) 5-5-6-7-6 | (4-4-8) 6-5-7-8-6 |
|
||||
| S | WT:F | 2500–2800 | 1175 mV| 600 mV| (4-4-2) 5-4-6-3-6 | (5-5-4) 5-5-6-5-6 |
|
||||
| A | AM-MGCJ | 2500–2866 | 1175 mV| 640 mV| (3-2-4) 2-4-4-4-6 | (4-3-8) 2-5-4-4-6 |
|
||||
| A | WT:E | 2300-2800 | 1175 mV| 600 mV| (2-2-2) 2-4-4-4-6 | (3-5-3) 3-5-4-5-6 |
|
||||
| B | NME | 2600-2800 | 1175 mV| 640 mV| (2-2-1) 0-1-4-3-6 | (3-3-4) 0-1-4-4-6 |
|
||||
| C | AB-MGCL | 2133–2500 | 1175 mV| 640 mV| (4-4-4) 4-4-5-6-6 | (4-4-8) 5-5-6-8-6 |
|
||||
|
||||
|
||||
### RAM Tuning Notes
|
||||
|
||||
> **💡 Extra Headroom:** For an additional 66–100 MHz, try **1212.5 mV**. This can also help with tighter timings.
|
||||
> ### ℹ️ Manufacturer’s Safe Limit
|
||||
> - **1175 mV** is the absolute safe value guaranteed by the manufacturer.
|
||||
> - Above this level, nothing is guaranteed—silicon quality may vary.
|
||||
> - No damage from overvolting has been reported, but proceed at your own risk.
|
||||
> - Undervolting RAM is pointless, at least **1175 mV** should be used.
|
||||
|
||||
> **🧪 Testing Method:**
|
||||
|
||||
> 1. Set **DVB = 4** using the standard preset.
|
||||
> 2. Test with **ST (Super Tight)** timings.
|
||||
> * If ST timings are **unstable**,try **common timings** or **relax** them gradually in the following order:
|
||||
> `t5 → t4 → t7 → t6 → t3 → t2 → t1 → t8`
|
||||
> * If ST timings are **stable**, **push beyond ST** for maximum performance by tightening parameters in this order:
|
||||
> `t8 → t1 → t2 → t3 → t6 → t7 → t4 → t5`
|
||||
|
||||
> **⚡ Performance:** ST timings provide enhanced performance over common timings.
|
||||
|
||||
> **⚠️ Stability Notes:**
|
||||
> - Lower **T5** or **T6** if you encounter issues.
|
||||
> - RAM contributes the most to overall performance — prioritize finding your maximum frequency first.
|
||||
> - Rarely, some modules may fail even with common timings. If so, lower timings until stable.
|
||||
|
||||
## Fine Tuning (GPU)
|
||||
This section is optional but recommended as it may lower voltages further.
|
||||
- **Voltage Offset:** 5–20
|
||||
- The UV2 table by default is very tight but it is slightly loose in some cases.
|
||||
- Voltage Offset can be used to tighten it further.
|
||||
- Test with 5, 10, 15 or 20 when using UV2.
|
||||
- Some GPUs may require **0** for stability.
|
||||
- With very rare speedo bracket positions, higher UV offsets may work, test carefully.
|
||||
|
||||
- **Auto VMIN Offset:**
|
||||
- Auto at first, lower it as much as possible once you find your maximum ram frequency.
|
||||
- Test **Auto VMIN Offset** stability at a medium frequency (``998 MHz`` for instance), otherwise the GPU voltage may dominate over the **Auto VMIN** voltage.
|
||||
- This helps improving battery in handheld mode with high RAM OC.
|
||||
- It's possible to add positive offset, but this shouldn't be used unless you have issues.
|
||||
|
||||
# Clock Settings (Safe)
|
||||
|
||||
### Mariko Max Safe on Battery [HAC-001(-01), HEG-001]
|
||||
*Switch units available from August 2019 and beyond, includes OLED & requires modchip*
|
||||
- **CPU:** 1963 MHz
|
||||
- **GPU:** 998 MHz
|
||||
- **RAM:** 2133 MHz – 2500+ MHz (use whatever is stable; 2400 MHz recommended for best battery life-to-performance ratio)
|
||||
!!! warning ** Note:** Drawing over 8.6W on battery will cause battery issues. Please avoid doing that for extended periods!
|
||||
|
||||
### Switch Lite Max Safe Clocks on Battery [HDH-001]
|
||||
- **CPU:** 1785 MHz
|
||||
- **GPU:** 921 MHz
|
||||
- **RAM:** 2133 MHz – 2500+ MHz (use whatever is stable; 2400 MHz recommended for best battery life-to-performance ratio)
|
||||
!!! warning ** Note:** Drawing over 6.5W on battery will cause battery issues. Please avoid doing that for extended periods!
|
||||
|
||||
!!! note Switch Lite limits are lower due to the 12W board power limit, but counts as Mariko for all other purposes.
|
||||
|
||||
### Mariko Max Clocks Docked and Plugged [HAC-001(-01), HEG-001]
|
||||
*Switch units available from
|
||||
|
||||
August 2019 and beyond, includes OLED & requires modchip*
|
||||
- **CPU:**
|
||||
- 2397 MHz: Safe to use.
|
||||
- 2500 MHz: May exceed **PMIC limit**, use carefully.
|
||||
- 2600 MHz: Exceeds pmic limit on most switches unless the voltage is kept low, around **1070 mV**.
|
||||
> Determining truly safe voltages is difficult; we are only working with estimates.
|
||||
> However, no damage has been reported from these recommendations.
|
||||
- **GPU:**
|
||||
- Sched **off**: 1228 MHz (safe with 1228 MHz voltage < 800 mV, otherwise use 1152 MHz)
|
||||
- Sched **on**: 1267 MHz (safe with 1228 MHz voltage < 800 mV)
|
||||
- 1228 MHz sched **off** outperforms 1267 MHz sched **on**, so it's recommended.
|
||||
- **RAM:**
|
||||
- 2133 MHz-3000 MHz+ (whatever is stable)
|
||||
|
||||
### Switch Lite Max Clocks Plugged [HDH-001]
|
||||
- **CPU:**
|
||||
- 2397 MHz: Safe to use.
|
||||
- 2500 MHz: May exceed **PMIC limit**, use carefully.
|
||||
- 2600 MHz: Exceeds pmic limit on most switches unless the voltage is kept low, around **1070 mV**.
|
||||
> Determining truly safe voltages is difficult; we are only working with estimates.
|
||||
> However, no damage has been reported from these recommendations.
|
||||
- **GPU:**
|
||||
- Sched **off**: 1228 MHz (safe with 1228 MHz voltage < 800 mV, otherwise use 1152 MHz)
|
||||
- Sched **on**: 1267 MHz (safe with 1228 MHz voltage < 800 mV)
|
||||
- 1228 MHz sched **off** outperforms 1267 MHz sched **on**, so it's recommended.
|
||||
- **RAM:**
|
||||
- 2133 MHz-2800 MHz+ (whatever is stable)
|
||||
|
||||
!!! note Switch Lite limits are lower due to the 12W board power limit, but counts as Mariko for all other purposes.
|
||||
|
||||
---
|
||||
|
||||
# Troubleshooting
|
||||
|
||||
**My Switch won't boot into EMUNAND after I have installed Horizon OC:**
|
||||
|
||||
- Your atmosphere version is likely not up-to-date, update your atmosphere version.
|
||||
- CPU UV level is too high, lower it or set it to 0.
|
||||
|
||||
**My configs are not being applied:**
|
||||
- Ensure you reboot your console after changing settings in Horizon OC.
|
||||
|
||||
**I can't set my clocks above 1785/921/1600:**
|
||||
- Your kip is not being loaded, check if it is located in `/atmosphere/kips`
|
||||
- Your hekate_ipl.ini file is not set up correctly:
|
||||
- Validate that your boot entry contains `kip1=atmosphere/kips/*.kip`
|
||||
- It has to be below `pkg3=atmosphere/package3` (or fss0)
|
||||
|
||||
# Need Help with Setup?
|
||||
|
||||
###Follow this [guide](https://rentry.co/howtoget60fps) for a step-by-step setup.
|
||||
@@ -1,127 +0,0 @@
|
||||
## `/atmosphere/config/system_settings.ini`
|
||||
|
||||
- Default Fan Control Parameters
|
||||
- [Info on tskin coefficients](https://github.com/masagrator/Status-Monitor-Overlay/blob/master/docs/modes.md#additional-info)
|
||||
- If (tskin > holdable_tskin and handheld mode) or (tskin > touchable_tskin and dock mode), then fan speed is set to 100% regardlessly.
|
||||
- https://switchbrew.org/wiki/System_Settings#tc
|
||||
|
||||
- Disable background services (For power saving in standby mode)
|
||||
- For power saving in standby mode
|
||||
- Do NOT add this if online service is in use.
|
||||
```ini
|
||||
[bgtc]
|
||||
enable_halfawake = u32!0x0
|
||||
minimum_interval_normal = u32!0x7FFFFFFF
|
||||
minimum_interval_save = u32!0x7FFFFFFF
|
||||
battery_threshold_save = u32!0x64
|
||||
battery_threshold_stop = u32!0x64
|
||||
|
||||
[npns]
|
||||
background_processing = u8!0x0
|
||||
sleep_periodic_interval = u32!0x7FFFFFFF
|
||||
sleep_processing_timeout = u32!0x0
|
||||
sleep_max_try_count = u32!0x0
|
||||
|
||||
[ns.notification]
|
||||
enable_download_task_list = u8!0x0
|
||||
enable_download_ticket = u8!0x0
|
||||
enable_network_update = u8!0x0
|
||||
enable_random_wait = u8!0x0
|
||||
enable_request_on_cold_boot = u8!0x0
|
||||
enable_send_rights_usage_status_request = u8!0x0
|
||||
enable_sync_elicense_request = u8!0x0
|
||||
enable_version_list = u8!0x0
|
||||
retry_interval_min = u32!0x7FFFFFFF
|
||||
retry_interval_max = u32!0x7FFFFFFF
|
||||
version_list_waiting_limit_bias = u32!0x7FFFFFFF
|
||||
version_list_waiting_limit_min = u32!0x7FFFFFFF
|
||||
|
||||
[account]
|
||||
na_required_for_network_service = u8!0x0
|
||||
na_license_verification_enabled = u8!0x0
|
||||
|
||||
[account.daemon]
|
||||
background_awaking_periodicity = u32!0x7FFFFFFF
|
||||
initial_schedule_delay = u32!0x7FFFFFFF
|
||||
profile_sync_interval = u32!0x7FFFFFFF
|
||||
na_info_refresh_interval = u32!0x7FFFFFFF
|
||||
|
||||
[capsrv]
|
||||
enable_album_screenshot_filedata_verification = u8!0x0
|
||||
enable_album_movie_filehash_verification = u8!0x0
|
||||
enable_album_movie_filesign_verification = u8!0x0
|
||||
|
||||
[friends]
|
||||
background_processing = u8!0x0
|
||||
|
||||
[notification.presenter]
|
||||
snooze_interval_in_seconds = u32!0x7FFFFFFF
|
||||
connection_retry_count = u32!0x0
|
||||
alarm_pattern_total_repeat_count = u32!0x0
|
||||
alarm_pattern_with_vibration_repeat_count = u32!0x0
|
||||
|
||||
[prepo]
|
||||
;background_processing = u8!0x0 (shutdown directly when entering sleep mode)
|
||||
transmission_interval_min = u32!0x7FFFFFFF
|
||||
transmission_retry_interval_min = u32!0x7FFFFFFF
|
||||
transmission_retry_interval_max = u32!0x7FFFFFFF
|
||||
transmission_interval_in_sleep = u32!0x7FFFFFFF
|
||||
statistics_save_interval_min = u32!0x7FFFFFFF
|
||||
statistics_post_interval = u32!0x7FFFFFFF
|
||||
save_system_report = u8!0x0
|
||||
|
||||
[olsc]
|
||||
default_auto_upload_global_setting = u8!0x0
|
||||
default_auto_download_global_setting = u8!0x0
|
||||
autonomy_registration_interval_seconds = u32!0x7FFFFFFF
|
||||
network_service_license_info_cache_expiration_seconds = u32!0x7FFFFFFF
|
||||
postponed_transfer_task_processing_interval_seconds = u32!0x7FFFFFFF
|
||||
retry_offset_seconds = u32!0x7FFFFFFF
|
||||
network_trouble_detection_span_seconds = u32!0x7FFFFFFF
|
||||
network_connection_polling_interval_seconds = u32!0x7FFFFFFF
|
||||
is_save_data_backup_policy_check_required = u8!0x0
|
||||
is_global_transfer_task_autonomy_registration_enabled = u8!0x0
|
||||
is_on_event_transfer_task_registration_enabled = u8!0x0
|
||||
is_periodic_transfer_task_registration_enabled = u8!0x0
|
||||
|
||||
[ntc]
|
||||
is_autonomic_correction_enabled = u8!0x0
|
||||
autonomic_correction_interval_seconds = u32!0x7FFFFFFF
|
||||
autonomic_correction_failed_retry_interval_seconds = u32!0x7FFFFFFF
|
||||
autonomic_correction_immediate_try_count_max = u32!0x0
|
||||
autonomic_correction_immediate_try_interval_milliseconds = u32!0x7FFFFFFF
|
||||
|
||||
[systemupdate]
|
||||
bgnup_retry_seconds = u32!0x7FFFFFFF
|
||||
|
||||
[ns.rights]
|
||||
skip_account_validation_on_rights_check = u8!0x1
|
||||
next_available_time_of_unexpected_error = u32!0x7FFFFFFF
|
||||
|
||||
[pctl]
|
||||
intermittent_task_interval_seconds = u32!0x7FFFFFFF
|
||||
|
||||
[sprofile]
|
||||
adjust_polling_interval_by_profile = u8!0x0
|
||||
polling_interval_sec_max = u32!0x7FFFFFFF
|
||||
polling_interval_sec_min = u32!0x7FFFFFFF
|
||||
```
|
||||
|
||||
- Parameters of game recording and streaming
|
||||
- ```ini
|
||||
[am.debug]
|
||||
continuous_recording_fps = u32!60 ; 30 or 60 FPS, default: 30
|
||||
continuous_recording_video_bit_rate = u32!0x780000 ; 7.5Mbps(0x780000 = 7,864,320), default: ~5Mbps(0x4C4B40), VBR(Variable Bitrate)
|
||||
continuous_recording_key_frame_count = u32!15 ; One I-frame in 15 frames (with other 14 P-frames), default: 15
|
||||
```
|
||||
- Recommended: [dvr-patches](https://github.com/exelix11/dvr-patches): Allow screenshot/recording in any games and remove overlay image (copyright notice or logo).
|
||||
- For optimal streaming experience, SysDVR via USB interface is recommended.
|
||||
- Known Issues (won't fix)
|
||||
- Game recordings may be less than 30 seconds if higher bitrate is used.
|
||||
- It has noticeable performance impacts in demanding games.
|
||||
- Video duration shown in album will be doubled, while the playback speed or mp4 file itself are not affected.
|
||||
|
||||
- Charging
|
||||
- https://switchbrew.org/wiki/System_Settings#psm
|
||||
- `enough_power_threshold_mw`
|
||||
- `cdp_dcp_input_current_limit_in_ma`: 5V CDP/DCP (BC1.2/QC?) Charger Current Limit
|
||||
@@ -1,46 +0,0 @@
|
||||
#!python3
|
||||
|
||||
import os
|
||||
import struct
|
||||
import sys
|
||||
|
||||
try:
|
||||
fpath = sys.argv[1]
|
||||
except IndexError:
|
||||
raise SystemExit(f"Usage: {sys.argv[0]} <path>")
|
||||
|
||||
file = open(fpath, "rb")
|
||||
file.seek(0)
|
||||
file_size = int.from_bytes(file.read(4), byteorder="little")
|
||||
|
||||
domain_key_value = {}
|
||||
|
||||
while file.tell() != file_size:
|
||||
domain_key_len = int.from_bytes(file.read(4), byteorder="little")
|
||||
domain_key = file.read(domain_key_len).decode().rstrip('\x00')
|
||||
domain, key = domain_key.split("!")
|
||||
|
||||
if not domain_key_value.get(domain):
|
||||
domain_key_value[domain] = {}
|
||||
|
||||
val_types = {1: "str", 2: "u8", 3: "u32"}
|
||||
val_type = val_types.get(int.from_bytes(file.read(1), byteorder="little"), "unknown")
|
||||
val_len = int.from_bytes(file.read(4), byteorder="little")
|
||||
val = file.read(val_len)
|
||||
|
||||
if val_type == "str":
|
||||
value = '"' + val.decode().rstrip('\x00') + '"'
|
||||
else:
|
||||
val_dec = int.from_bytes(val, byteorder="little")
|
||||
value = "0x" + format(val_dec, 'X')
|
||||
if val_type == "u32" and val_dec >= 10:
|
||||
val_dec = int.from_bytes(val, byteorder="little", signed=True)
|
||||
value += f" ; {val_dec}"
|
||||
|
||||
domain_key_value[domain][key] = f"{val_type}!{value}"
|
||||
|
||||
for domain in sorted(domain_key_value.keys()):
|
||||
print(f"[{domain}]")
|
||||
for key in sorted(domain_key_value[domain].keys()):
|
||||
print(f"{key} = {domain_key_value[domain][key]}")
|
||||
print()
|
||||
118
test_patch.sh
118
test_patch.sh
@@ -1,118 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
fw_dir="/Volumes/RAMDISK/NX-15.0.0/"
|
||||
tmp_dir="/Volumes/RAMDISK/"
|
||||
repack_out_dir="/Volumes/RAMDISK/out/"
|
||||
oc_test_dir="$HOME/Source/Switch-OC-Suite/Source/Atmosphere/stratosphere/loader/source/oc"
|
||||
prodkeys="$HOME/.switch/prod.keys"
|
||||
hactool_exe="$HOME/Source/hactool/hactool"
|
||||
nx2elf_exe="$HOME/Source/nx2elf/nx2elf"
|
||||
elf2nso_exe="$HOME/Source/switch-tools/elf2nso"
|
||||
hacpack_exe="$HOME/Source/hacPack/hacpack"
|
||||
|
||||
should_remove_tmp="Y"
|
||||
should_save_repack="Y"
|
||||
option_Mariko_Erista="M"
|
||||
|
||||
echo -e "\nExtracting nca..."
|
||||
out_pcv="${tmp_dir}pcv/"
|
||||
out_ptm="${tmp_dir}ptm/"
|
||||
mkdir -p "${out_pcv}"
|
||||
mkdir -p "${out_ptm}"
|
||||
cd $fw_dir
|
||||
|
||||
pcv_nca_name=""
|
||||
ptm_nca_name=""
|
||||
for file_00 in ./*.nca/00
|
||||
do
|
||||
if [ -e "${file_00}" ]; then
|
||||
echo "Processing \"*.nca/00\" files..."
|
||||
find "${fw_dir}" -type f -name "00" -exec sh -c 'DIR=$(dirname "{}"); FW_DIR=$(dirname "${DIR}"); mv "{}" "${FW_DIR}/00"; rm -r "${DIR}"; mv "${FW_DIR}/00" "${DIR}"' \;
|
||||
fi
|
||||
break
|
||||
done
|
||||
|
||||
for nca_file in ./*.nca
|
||||
do
|
||||
file_size=`wc -c "$nca_file" | awk '{print $1}'`
|
||||
if [[ "$nca_file" == *".cnmt."* || file_size -lt 16384 ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
titleid=`$hactool_exe -k $prodkeys --disablekeywarns -t nca $nca_file | grep 'Title ID'`
|
||||
|
||||
if [[ $titleid == *"010000000000001a"* ]]; then
|
||||
pcv_nca_name="$(basename $nca_file)"
|
||||
echo "$pcv_nca_name (pcv) -> $out_pcv"
|
||||
$hactool_exe -k $prodkeys --disablekeywarns -t nca $nca_file --exefsdir "$out_pcv" 1> /dev/null
|
||||
fi
|
||||
|
||||
if [[ $titleid == *"0100000000000010"* ]]; then
|
||||
ptm_nca_name="$(basename $nca_file)"
|
||||
echo "$ptm_nca_name (ptm) -> $out_ptm"
|
||||
$hactool_exe -k $prodkeys --disablekeywarns -t nca $nca_file --exefsdir "$out_ptm" 1> /dev/null
|
||||
fi
|
||||
done
|
||||
|
||||
echo -e "\nConverting nca to elf..."
|
||||
$nx2elf_exe "${out_pcv}main" 1> /dev/null
|
||||
$nx2elf_exe "${out_ptm}main" 1> /dev/null
|
||||
|
||||
echo -e "\nBuilding..."
|
||||
cd $oc_test_dir
|
||||
make test 1> /dev/null
|
||||
|
||||
echo -e "\nPatching..."
|
||||
|
||||
[ -z "$should_save_repack" ] && read -p "Save and repack to nca (y/N)? " should_save_repack
|
||||
SAVE_OPT=" "
|
||||
case $should_save_repack in
|
||||
Y|y ) SAVE_OPT="-s ";;
|
||||
esac
|
||||
|
||||
./test pcv $SAVE_OPT "${out_pcv}main.elf"
|
||||
./test ptm $SAVE_OPT "${out_ptm}main.elf"
|
||||
make clean 1> /dev/null
|
||||
|
||||
if [ ! -z $SAVE_OPT ]; then
|
||||
case $should_save_repack in
|
||||
Y|y )
|
||||
patched_ext=".mariko"
|
||||
[ -z "$option_Mariko_Erista" ] && read -p "[M]ariko (Default) | [E]rista ? " option_Mariko_Erista
|
||||
case $option_Mariko_Erista in
|
||||
E|e ) patched_ext=".erista";;
|
||||
esac
|
||||
mkdir -p "${repack_out_dir}"
|
||||
cd "${tmp_dir}"
|
||||
echo -e "\nRepacking pcv to ${repack_out_dir}${pcv_nca_name}..."
|
||||
TMP="${out_pcv}temp/"
|
||||
mkdir -p "${TMP}"
|
||||
$elf2nso_exe "${out_pcv}main.elf${patched_ext}" "${TMP}main" 1> /dev/null
|
||||
cp "${out_pcv}main.npdm" "${TMP}main.npdm"
|
||||
$hacpack_exe -k $prodkeys -o "${TMP}nca" --type nca --ncatype program --titleid 010000000000001A --exefsdir "${TMP}" 1> /dev/null
|
||||
find "${TMP}nca" -name "*.nca" -exec mv {} "${repack_out_dir}${pcv_nca_name}" \;
|
||||
|
||||
if [[ $patched_ext == ".mariko" ]]; then
|
||||
echo -e "\nRepacking ptm (Mariko Only) to ${repack_out_dir}${ptm_nca_name}..."
|
||||
TMP="${out_ptm}temp/"
|
||||
mkdir -p "${TMP}"
|
||||
$elf2nso_exe "${out_ptm}main.elf${patched_ext}" "${TMP}main" 1> /dev/null
|
||||
cp "${out_ptm}main.npdm" "${TMP}main.npdm"
|
||||
$hacpack_exe -k $prodkeys -o "${TMP}nca" --type nca --ncatype program --titleid 0100000000000010 --exefsdir "${TMP}" 1> /dev/null
|
||||
find "${TMP}nca" -name "*.nca" -exec mv {} "${repack_out_dir}${ptm_nca_name}" \;
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
[ -z "$should_remove_tmp" ] && read -p "Remove temp files (Y/n)? " should_remove_tmp
|
||||
case $should_remove_tmp in
|
||||
N|n )
|
||||
exit;;
|
||||
esac
|
||||
|
||||
rm -fr $out_pcv
|
||||
rm -fr $out_ptm
|
||||
rm -fr "${tmp_dir}hacpack_backup"
|
||||
|
||||
echo -e "\nDone!"
|
||||
Reference in New Issue
Block a user