diff --git a/Source/Horizon-OC-Monitor/Makefile b/Source/Horizon-OC-Monitor/Makefile index 9513c221..aad4ae07 100644 --- a/Source/Horizon-OC-Monitor/Makefile +++ b/Source/Horizon-OC-Monitor/Makefile @@ -38,7 +38,7 @@ include $(DEVKITPRO)/libnx/switch_rules # NACP building is skipped as well. #--------------------------------------------------------------------------------- APP_TITLE := Horizon OC Monitor -APP_VERSION := 1.3.2+r3-hoc +APP_VERSION := 1.3.2+r4-hoc TARGET := $(notdir $(CURDIR)) BUILD := build SOURCES := source diff --git a/Source/Horizon-OC-Monitor/README.md b/Source/Horizon-OC-Monitor/README.md deleted file mode 100644 index 25c9531b..00000000 --- a/Source/Horizon-OC-Monitor/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# Status Monitor Overlay -Monitor Your hardware in real time! - -This is an overlay homebrew dedicated to Nintendo Switch. -You need to have installed Tesla environment to use it. - -Tool contains five menus to choose, each one is explained [here](/docs/modes.md).
-Overlay supports customizations through config file, more [here](/docs/config.md). - -If it's not working in dock, you need to first start Status Monitor, then put Nintendo Switch to dock. - -# What is currently supported: -- CPU Usage for each core (Cores `#0`-`#2` are used by apps/games, Core `#3` is used by OS, background processes and also Tesla overlays) -- GPU Load -- CPU, GPU & RAM target frequencies (also real frequencies + RAM Load if [sys-clk 2.0.0_rc4+](https://github.com/retronx-team/sys-clk/releases) is installed, use only official RetroNX release for reliable results) -- Used RAM categorized to: (not supported by FWs <5.0.0) - - Total - - Application - - Applet - - System - - System Unsafe -- SoC, PCB & Skin temperatures (Skin temperature not supported by FWs <5.0.0) -- Fan Rotation Level -- PFPS, FPS, resolutions, game read speed (shows only if [my fork of SaltyNX](https://github.com/masagrator/SaltyNX/releases) is installed) -- Battery temperature, raw charge, age, average voltage, average current flow and average power flow -- Charger type, max voltage, and max current -- DSP usage (only for FW older than 17.0.0) -- NVDEC, NVENC and NVJPG clock rates -- Network type + Wi-fi password - -# Requirements: -- Ultrahand Overlay or Tesla Menu (version >=1.2.3) - -How to setup everything: [HERE](https://gist.github.com/masagrator/65fcbd5ad09243399268d145aaab899b) - ---- - -# Thanks to: -- RetroNX channel for helping with coding stuff -- SunTheCourier for sys-clk-Overlay from which I learned how to make my own Tesla homebrew -- Herbaciarz for providing screenshots from HDMI Grabber -- KazushiMe for writing code to read registers from max17050 chip -- CTCaer for Hekate from which I took max17050.h and calculation formulas for reading battery stats from max17050 chip -- ChanseyIsTheBest for testing Game Resolutions menu - -# FAQ: -Q: This homebrew has any impact on games? - -A: Negligible, you won't see any difference. Almost everything is done on Core `#3`, other cores usage is below 0.001%. - -# Troubleshooting: - -Q: When opening Full or Mini mode, overlay is showing that Core #3 usage is at 100% while everything else is showing 0, eventually leading to crash. Why this happens? - -A: There are few possible explanations: -1. You're using nifm services connection test patches (in short `nifm ctest patches`) that are included in various packs. Those patches allow to connect to network that has no internet connection. But they cause nifm to randomly rampage when connected to network. Find any folder in `atmosphere/exefs_patches` that has in folder name `nifm`, `nfim` and/or `ctest`, delete this folder and restart Switch (if you are using `sys-patch`, turn off `nifm` patching). If you must use it, only solution is to use this overlay only in airplane mode. -2. You're using some untested custom sysmodule that has no proper thread sleeping implemented. Find out in atmosphere/contents any sysmodule that you don't need, delete it and restart Switch. -3. Your Switch is using sigpatches, is not a primary device, is using linked account, and is connected to network. Delete sigpatches, change your Switch to primary device, unlink account, or disable Wi-Fi. - -Q: When opening Status Monitor overlays stop responding, or something that I am trying to open while Status Monitor is opened is freezing (f.e. Album or HB Menu). How to fix this? - -A: Issue comes from too much sysmodules accessing sdcard at once. You must limit amount of sysmodules that have such access (you can free one session by disabling logs in SaltyNX-Tool). diff --git a/Source/Horizon-OC-Monitor/docs/modes.md b/Source/Horizon-OC-Monitor/docs/modes.md index d2e8385e..665237dd 100644 --- a/Source/Horizon-OC-Monitor/docs/modes.md +++ b/Source/Horizon-OC-Monitor/docs/modes.md @@ -1,13 +1,13 @@ # Modes -Status Monitor Overlay from 1.0.0 release contains five modes to choose from Main Menu.
+Horizon OC Monitor Overlay from 1.0.0 release contains five modes to choose from Main Menu.
For additional functions you need to install: - [SaltyNX](https://github.com/masagrator/SaltyNX/releases) - [sys-clk 2.0.0_rc4+](https://github.com/retronx-team/sys-clk/releases) (using closed source forks of sys-clk can result in retrieving wrong real clockrates and ram load) # Full -This mode you can know from older releases of Status Monitor. It contains all informations properly described and supported with high precision. +This mode you can know from older releases of Horizon OC Monitor. It contains all informations properly described and supported with high precision. - CPU Usage - Real Frequency: `%.1f` = Real clockrate of all CPU cores in MHz (This shows only when sys-clk 2.0.0_4c+ is installed) diff --git a/Source/Horizon-OC-Monitor/include/sysclk/apm.h b/Source/Horizon-OC-Monitor/include/sysclk/apm.h new file mode 100644 index 00000000..e6442896 --- /dev/null +++ b/Source/Horizon-OC-Monitor/include/sysclk/apm.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) Souldbminer and Horizon OC Contributors + * + * 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 . + * + */ + +/* -------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * , , + * wrote this file. As long as you retain this notice you can do whatever you + * want with this stuff. If you meet any of us some day, and you think this + * stuff is worth it, you can buy us a beer in return. - The sys-clk authors + * -------------------------------------------------------------------------- + */ + + +#pragma once + +#include "board.h" + +typedef struct { + uint32_t id; + uint32_t cpu_hz; + uint32_t gpu_hz; + uint32_t mem_hz; +} SysClkApmConfiguration; + +extern SysClkApmConfiguration sysclk_g_apm_configurations[]; diff --git a/Source/Horizon-OC-Monitor/include/sysclk/board.h b/Source/Horizon-OC-Monitor/include/sysclk/board.h new file mode 100644 index 00000000..8462993f --- /dev/null +++ b/Source/Horizon-OC-Monitor/include/sysclk/board.h @@ -0,0 +1,204 @@ +/* + * Copyright (c) Souldbminer and Horizon OC Contributors + * + * 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 . + * + */ + +/* -------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * , , + * wrote this file. As long as you retain this notice you can do whatever you + * want with this stuff. If you meet any of us some day, and you think this + * stuff is worth it, you can buy us a beer in return. - The sys-clk authors + * -------------------------------------------------------------------------- + */ + + +#pragma once + +#include +#include +#include + +typedef enum +{ + SysClkSocType_Erista = 0, + SysClkSocType_Mariko, + SysClkSocType_EnumMax +} SysClkSocType; + +typedef enum +{ + HorizonOCConsoleType_Unknown = 0, + HorizonOCConsoleType_V1, + HorizonOCConsoleType_UnreleasedErista, + HorizonOCConsoleType_V2, + HorizonOCConsoleType_Lite, + HorizonOCConsoleType_UnreleasedMariko, + HorizonOCConsoleType_OLED, + HorizonOCConsoleType_EnumMax, +} HorizonOCConsoleType; + +typedef enum { + HocClkVoltage_SOC = 0, + HocClkVoltage_EMCVDD2, + HocClkVoltage_CPU, + HocClkVoltage_GPU, + HocClkVoltage_EMCVDDQ_MarikoOnly, + HocClkVoltage_Display, + HocClkVoltage_Battery, + HocClkVoltage_EnumMax, +} HocClkVoltage; + +typedef enum +{ + SysClkProfile_Handheld = 0, + SysClkProfile_HandheldCharging, + SysClkProfile_HandheldChargingUSB, + SysClkProfile_HandheldChargingOfficial, + SysClkProfile_Docked, + SysClkProfile_EnumMax +} SysClkProfile; + +typedef enum +{ + SysClkModule_CPU = 0, + SysClkModule_GPU, + SysClkModule_MEM, + SysClkModule_EnumMax, +} SysClkModule; + +typedef enum +{ + SysClkThermalSensor_SOC = 0, + SysClkThermalSensor_PCB, + SysClkThermalSensor_Skin, + HorizonOCThermalSensor_Battery, + HorizonOCThermalSensor_PMIC, + SysClkThermalSensor_EnumMax +} SysClkThermalSensor; + +typedef enum +{ + SysClkPowerSensor_Now = 0, + SysClkPowerSensor_Avg, + SysClkPowerSensor_EnumMax +} SysClkPowerSensor; + +typedef enum +{ + SysClkPartLoad_EMC = 0, + SysClkPartLoad_EMCCpu, + HocClkPartLoad_GPU, + HocClkPartLoad_CPUAvg, + HocClkPartLoad_BAT, + HocClkPartLoad_FAN, + SysClkPartLoad_EnumMax +} SysClkPartLoad; + + +typedef enum +{ + ReverseNX_NotFound = 0, + ReverseNX_SystemDefault = 0, + ReverseNX_Handheld, + ReverseNX_Docked, +} ReverseNXMode; + + +#define SYSCLK_ENUM_VALID(n, v) ((v) < n##_EnumMax) + +static inline const char* sysclkFormatModule(SysClkModule module, bool pretty) +{ + switch(module) + { + case SysClkModule_CPU: + return pretty ? "CPU" : "cpu"; + case SysClkModule_GPU: + return pretty ? "GPU" : "gpu"; + case SysClkModule_MEM: + return pretty ? "Memory" : "mem"; + default: + return NULL; + } +} + +static inline const char* sysclkFormatThermalSensor(SysClkThermalSensor thermSensor, bool pretty) +{ + switch(thermSensor) + { + case SysClkThermalSensor_SOC: + return pretty ? "SOC" : "soc"; + case SysClkThermalSensor_PCB: + return pretty ? "PCB" : "pcb"; + case SysClkThermalSensor_Skin: + return pretty ? "Skin" : "skin"; + default: + return NULL; + } +} + +static inline const char* sysclkFormatPowerSensor(SysClkPowerSensor powSensor, bool pretty) +{ + switch(powSensor) + { + case SysClkPowerSensor_Now: + return pretty ? "Now" : "now"; + case SysClkPowerSensor_Avg: + return pretty ? "Avg" : "avg"; + default: + return NULL; + } +} + +static inline const char* sysclkFormatProfile(SysClkProfile profile, bool pretty) +{ + switch(profile) + { + case SysClkProfile_Docked: + return pretty ? "Docked" : "docked"; + case SysClkProfile_Handheld: + return pretty ? "Handheld" : "handheld"; + case SysClkProfile_HandheldCharging: + return pretty ? "Charging" : "handheld_charging"; + case SysClkProfile_HandheldChargingUSB: + return pretty ? "USB Charger" : "handheld_charging_usb"; + case SysClkProfile_HandheldChargingOfficial: + return pretty ? "PD Charger" : "handheld_charging_official"; + default: + return NULL; + } +} + + +static inline const char* hocClkFormatVoltage(HocClkVoltage voltage, bool pretty) +{ + switch(voltage) + { + case HocClkVoltage_CPU: + return pretty ? "CPU" : "cpu"; + case HocClkVoltage_GPU: + return pretty ? "GPU" : "gpu"; + case HocClkVoltage_EMCVDD2: + return pretty ? "VDD2" : "emcvdd2"; + case HocClkVoltage_EMCVDDQ_MarikoOnly: + return pretty ? "VDDQ" : "vddq"; + case HocClkVoltage_SOC: + return pretty ? "SOC" : "soc"; + case HocClkVoltage_Display: + return pretty ? "SOC" : "soc"; + default: + return NULL; + } +} \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor/include/sysclk/client/ipc.h b/Source/Horizon-OC-Monitor/include/sysclk/client/ipc.h new file mode 100644 index 00000000..b61a0511 --- /dev/null +++ b/Source/Horizon-OC-Monitor/include/sysclk/client/ipc.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) Souldbminer and Horizon OC Contributors + * + * 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 . + * + */ + +/* -------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * , , + * wrote this file. As long as you retain this notice you can do whatever you + * want with this stuff. If you meet any of us some day, and you think this + * stuff is worth it, you can buy us a beer in return. - The sys-clk authors + * -------------------------------------------------------------------------- + */ + + +#pragma once + +#include "types.h" +#include "../config.h" +#include "../board.h" +#include "../ipc.h" + +bool sysclkIpcRunning(); +Result sysclkIpcInitialize(void); +void sysclkIpcExit(void); + +Result sysclkIpcGetAPIVersion(u32* out_ver); +Result sysclkIpcGetVersionString(char* out, size_t len); +Result sysclkIpcGetCurrentContext(SysClkContext* out_context); +Result sysclkIpcGetProfileCount(u64 tid, u8* out_count); +Result sysclkIpcSetEnabled(bool enabled); +Result sysclkIpcExitCmd(); +Result sysclkIpcSetOverride(SysClkModule module, u32 hz); +Result sysclkIpcGetProfiles(u64 tid, SysClkTitleProfileList* out_profiles); +Result sysclkIpcSetProfiles(u64 tid, SysClkTitleProfileList* profiles); +Result sysclkIpcGetConfigValues(SysClkConfigValueList* out_configValues); +Result sysclkIpcSetConfigValues(SysClkConfigValueList* configValues); +Result sysclkIpcGetFreqList(SysClkModule module, u32* list, u32 maxCount, u32* outCount); +Result sysclkIpcSetReverseNXRTMode(ReverseNXMode mode); +Result hocClkIpcSetKipData(); +Result hocClkIpcGetKipData(); + +static inline Result sysclkIpcRemoveOverride(SysClkModule module) +{ + return sysclkIpcSetOverride(module, 0); +} diff --git a/Source/Horizon-OC-Monitor/include/sysclk/client/types.h b/Source/Horizon-OC-Monitor/include/sysclk/client/types.h new file mode 100644 index 00000000..b2aec78d --- /dev/null +++ b/Source/Horizon-OC-Monitor/include/sysclk/client/types.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) Souldbminer and Horizon OC Contributors + * + * 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 . + * + */ + +/* -------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * , , + * wrote this file. As long as you retain this notice you can do whatever you + * want with this stuff. If you meet any of us some day, and you think this + * stuff is worth it, you can buy us a beer in return. - The sys-clk authors + * -------------------------------------------------------------------------- + */ + + +#pragma once + +#ifdef __SWITCH__ + +#include +#include + +#else + +#define R_FAILED(res) ((res) != 0) +#define R_SUCCEEDED(res) ((res) == 0) + +typedef std::uint32_t Result; +typedef std::uint32_t u32; +typedef std::int32_t s32; +typedef std::uint64_t u64; +typedef std::uint8_t u8; + +#endif diff --git a/Source/Horizon-OC-Monitor/include/sysclk/clock_manager.h b/Source/Horizon-OC-Monitor/include/sysclk/clock_manager.h new file mode 100644 index 00000000..7c94e948 --- /dev/null +++ b/Source/Horizon-OC-Monitor/include/sysclk/clock_manager.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) Souldbminer and Horizon OC Contributors + * + * 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 . + * + */ + +/* -------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * , , + * wrote this file. As long as you retain this notice you can do whatever you + * want with this stuff. If you meet any of us some day, and you think this + * stuff is worth it, you can buy us a beer in return. - The sys-clk authors + * -------------------------------------------------------------------------- + */ + + +#pragma once + +#include +#include "board.h" + +typedef struct +{ + uint8_t enabled; + uint64_t applicationId; + SysClkProfile profile; + uint32_t freqs[SysClkModule_EnumMax]; + uint32_t realFreqs[SysClkModule_EnumMax]; + uint32_t overrideFreqs[SysClkModule_EnumMax]; + uint32_t temps[SysClkThermalSensor_EnumMax]; + int32_t power[SysClkPowerSensor_EnumMax]; + uint32_t PartLoad[SysClkPartLoad_EnumMax]; + uint32_t voltages[HocClkVoltage_EnumMax]; + uint32_t perfConfId; + u8 fps; + u8 lcdFreq; + u8 fanLevel; +} SysClkContext; + +typedef struct +{ + union { + uint32_t mhz[+SysClkProfile_EnumMax * +SysClkModule_EnumMax]; + uint32_t mhzMap[+SysClkProfile_EnumMax][+SysClkModule_EnumMax]; + }; +} SysClkTitleProfileList; + +#define SYSCLK_FREQ_LIST_MAX 32 + +#define GLOBAL_PROFILE_ID 0xA111111111111111 \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor/include/sysclk/config.h b/Source/Horizon-OC-Monitor/include/sysclk/config.h new file mode 100644 index 00000000..51491ae8 --- /dev/null +++ b/Source/Horizon-OC-Monitor/include/sysclk/config.h @@ -0,0 +1,571 @@ +/* + * Copyright (c) Souldbminer and Horizon OC Contributors + * + * 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 . + * + */ + +/* -------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * , , + * wrote this file. As long as you retain this notice you can do whatever you + * want with this stuff. If you meet any of us some day, and you think this + * stuff is worth it, you can buy us a beer in return. - The sys-clk authors + * -------------------------------------------------------------------------- + */ + + +#pragma once + +#include +#include + +typedef enum { + SysClkConfigValue_PollingIntervalMs = 0, + SysClkConfigValue_TempLogIntervalMs, + SysClkConfigValue_FreqLogIntervalMs, + SysClkConfigValue_PowerLogIntervalMs, + SysClkConfigValue_CsvWriteIntervalMs, + + HocClkConfigValue_UncappedClocks, + HocClkConfigValue_OverwriteBoostMode, + + HocClkConfigValue_EristaMaxCpuClock, + HocClkConfigValue_EristaMaxGpuClock, + HocClkConfigValue_EristaMaxMemClock, + HocClkConfigValue_MarikoMaxCpuClock, + HocClkConfigValue_MarikoMaxGpuClock, + HocClkConfigValue_MarikoMaxMemClock, + + HocClkConfigValue_ThermalThrottle, + HocClkConfigValue_ThermalThrottleThreshold, + + HocClkConfigValue_HandheldGovernor, + HocClkConfigValue_DockedGovernor, + + HocClkConfigValue_HandheldTDP, + HocClkConfigValue_HandheldTDPLimit, + + HocClkConfigValue_LiteTDPLimit, + + HocClkConfigValue_EnforceBoardLimit, + + HocClkConfigValue_KipEditing, + HocClkConfigValue_KipFileName, + + HorizonOCConfigValue_BatteryChargeCurrent, + + KipConfigValue_custRev, + KipConfigValue_mtcConf, + KipConfigValue_hpMode, + + KipConfigValue_commonEmcMemVolt, + KipConfigValue_eristaEmcMaxClock, + KipConfigValue_marikoEmcMaxClock, + KipConfigValue_marikoEmcVddqVolt, + KipConfigValue_emcDvbShift, + + KipConfigValue_t1_tRCD, + KipConfigValue_t2_tRP, + KipConfigValue_t3_tRAS, + KipConfigValue_t4_tRRD, + KipConfigValue_t5_tRFC, + KipConfigValue_t6_tRTW, + KipConfigValue_t7_tWTR, + KipConfigValue_t8_tREFI, + KipConfigValue_mem_burst_read_latency, + KipConfigValue_mem_burst_write_latency, + + KipConfigValue_eristaCpuUV, + KipConfigValue_eristaCpuVmin, + KipConfigValue_eristaCpuMaxVolt, + KipConfigValue_eristaCpuUnlock, + + KipConfigValue_marikoCpuUVLow, + KipConfigValue_marikoCpuUVHigh, + KipConfigValue_tableConf, + KipConfigValue_marikoCpuLowVmin, + KipConfigValue_marikoCpuHighVmin, + KipConfigValue_marikoCpuMaxVolt, + KipConfigValue_marikoCpuMaxClock, + KipConfigValue_eristaCpuBoostClock, + KipConfigValue_marikoCpuBoostClock, + + KipConfigValue_eristaGpuUV, + KipConfigValue_eristaGpuVmin, + + KipConfigValue_marikoGpuUV, + KipConfigValue_marikoGpuVmin, + KipConfigValue_marikoGpuVmax, + + KipConfigValue_commonGpuVoltOffset, + KipConfigValue_gpuSpeedo, + KipConfigValue_marikoGpuFullUnlock, + + KipConfigValue_g_volt_76800, + KipConfigValue_g_volt_153600, + KipConfigValue_g_volt_230400, + KipConfigValue_g_volt_307200, + KipConfigValue_g_volt_384000, + KipConfigValue_g_volt_460800, + KipConfigValue_g_volt_537600, + KipConfigValue_g_volt_614400, + KipConfigValue_g_volt_691200, + KipConfigValue_g_volt_768000, + KipConfigValue_g_volt_844800, + KipConfigValue_g_volt_921600, + KipConfigValue_g_volt_998400, + KipConfigValue_g_volt_1075200, + KipConfigValue_g_volt_1152000, + KipConfigValue_g_volt_1228800, + KipConfigValue_g_volt_1267200, + KipConfigValue_g_volt_1305600, + KipConfigValue_g_volt_1344000, + KipConfigValue_g_volt_1382400, + KipConfigValue_g_volt_1420800, + KipConfigValue_g_volt_1459200, + KipConfigValue_g_volt_1497600, + KipConfigValue_g_volt_1536000, + + KipConfigValue_g_volt_e_76800, + KipConfigValue_g_volt_e_115200, + KipConfigValue_g_volt_e_153600, + KipConfigValue_g_volt_e_192000, + KipConfigValue_g_volt_e_230400, + KipConfigValue_g_volt_e_268800, + KipConfigValue_g_volt_e_307200, + KipConfigValue_g_volt_e_345600, + KipConfigValue_g_volt_e_384000, + KipConfigValue_g_volt_e_422400, + KipConfigValue_g_volt_e_460800, + KipConfigValue_g_volt_e_499200, + KipConfigValue_g_volt_e_537600, + KipConfigValue_g_volt_e_576000, + KipConfigValue_g_volt_e_614400, + KipConfigValue_g_volt_e_652800, + KipConfigValue_g_volt_e_691200, + KipConfigValue_g_volt_e_729600, + KipConfigValue_g_volt_e_768000, + KipConfigValue_g_volt_e_806400, + KipConfigValue_g_volt_e_844800, + KipConfigValue_g_volt_e_883200, + KipConfigValue_g_volt_e_921600, + KipConfigValue_g_volt_e_960000, + KipConfigValue_g_volt_e_998400, + KipConfigValue_g_volt_e_1036800, + KipConfigValue_g_volt_e_1075200, + + SysClkConfigValue_EnumMax, +} SysClkConfigValue; + +typedef struct { + uint64_t values[SysClkConfigValue_EnumMax]; +} SysClkConfigValueList; + +static inline const char* sysclkFormatConfigValue(SysClkConfigValue val, bool pretty) +{ + switch(val) + { + case SysClkConfigValue_PollingIntervalMs: + return pretty ? "Polling Interval (ms)" : "poll_interval_ms"; + case SysClkConfigValue_TempLogIntervalMs: + return pretty ? "Temperature logging interval (ms)" : "temp_log_interval_ms"; + case SysClkConfigValue_FreqLogIntervalMs: + return pretty ? "Frequency logging interval (ms)" : "freq_log_interval_ms"; + case SysClkConfigValue_PowerLogIntervalMs: + 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"; + + case HocClkConfigValue_EristaMaxCpuClock: + return pretty ? "Max CPU Clock" : "cpu_max_e"; + case HocClkConfigValue_EristaMaxGpuClock: + return pretty ? "Max GPU Clock" : "gpu_max_e"; + case HocClkConfigValue_EristaMaxMemClock: + return pretty ? "Erista Max MEM Clock" : "mem_max_e"; + + case HocClkConfigValue_MarikoMaxCpuClock: + return pretty ? "CPU Max Display Clock" : "cpu_max_m"; + case HocClkConfigValue_MarikoMaxGpuClock: + return pretty ? "Mariko Max GPU Clock" : "gpu_max_m"; + case HocClkConfigValue_MarikoMaxMemClock: + return pretty ? "Mariko Max MEM Clock" : "mem_max_m"; + + case HocClkConfigValue_ThermalThrottle: + return pretty ? "Thermal Throttle" : "thermal_throttle"; + + case HocClkConfigValue_ThermalThrottleThreshold: + return pretty ? "Thermal Throttle Threshold" : "thermal_throttle_threshold"; + + case HocClkConfigValue_HandheldGovernor: + return pretty ? "Handheld Governor" : "governor"; + case HocClkConfigValue_DockedGovernor: + return pretty ? "Docked Governor" : "governor_docked"; + + case HocClkConfigValue_HandheldTDP: + return pretty ? "Handheld TDP" : "handheld_tdp"; + + case HocClkConfigValue_HandheldTDPLimit: + return pretty ? "Handheld TDP Limit" : "tdp_limit"; + + case HocClkConfigValue_LiteTDPLimit: + return pretty ? "Lite TDP Limit" : "tdp_limit_l"; + + case HocClkConfigValue_EnforceBoardLimit: + return pretty ? "Enforce Board Limit" : "enforce_board_limit"; + + case HocClkConfigValue_KipEditing: + return pretty ? "Enable KIP Editing" : "kip_editing"; + + case HocClkConfigValue_KipFileName: + return pretty ? "KIP File Name" : "kip_file_name"; + + case HorizonOCConfigValue_BatteryChargeCurrent: + return pretty ? "Battery Charge Current" : "bat_charge_current"; + + // KIP config values + case KipConfigValue_custRev: + return pretty ? "Custom Revision" : "kip_cust_rev"; + case KipConfigValue_mtcConf: + return pretty ? "MTC Config" : "kip_mtc_conf"; + case KipConfigValue_hpMode: + return pretty ? "HP Mode" : "kip_hp_mode"; + + // EMC + case KipConfigValue_commonEmcMemVolt: + return pretty ? "Common EMC/MEM Voltage" : "common_emc_mem_volt"; + case KipConfigValue_eristaEmcMaxClock: + return pretty ? "Erista EMC Max Clock" : "erista_emc_max_clock"; + case KipConfigValue_marikoEmcMaxClock: + return pretty ? "Mariko EMC Max Clock" : "mariko_emc_max_clock"; + case KipConfigValue_marikoEmcVddqVolt: + return pretty ? "Mariko EMC VDDQ Voltage" : "mariko_emc_vddq_volt"; + case KipConfigValue_emcDvbShift: + return pretty ? "EMC DVB Shift" : "emc_dvb_shift"; + + // Memory timings + case KipConfigValue_t1_tRCD: + return pretty ? "t1 - tRCD" : "t1_trcd"; + case KipConfigValue_t2_tRP: + return pretty ? "t2 - tRP" : "t2_trp"; + case KipConfigValue_t3_tRAS: + return pretty ? "t3 - tRAS" : "t3_tras"; + case KipConfigValue_t4_tRRD: + return pretty ? "t4 - tRRD" : "t4_trrd"; + case KipConfigValue_t5_tRFC: + return pretty ? "t5 - tRFC" : "t5_trfc"; + case KipConfigValue_t6_tRTW: + return pretty ? "t6 - tRTW" : "t6_trtw"; + case KipConfigValue_t7_tWTR: + return pretty ? "t7 - tWTR" : "t7_twtr"; + case KipConfigValue_t8_tREFI: + return pretty ? "t8 - tREFI" : "t8_trefi"; + case KipConfigValue_mem_burst_read_latency: + return pretty ? "Memory Burst Read Latency" : "mem_burst_read_latency"; + case KipConfigValue_mem_burst_write_latency: + return pretty ? "Memory Burst Write Latency" : "mem_burst_write_latency"; + + // CPU – Erista + case KipConfigValue_eristaCpuUV: + return pretty ? "Erista CPU Undervolt" : "erista_cpu_uv"; + case KipConfigValue_eristaCpuVmin: + return pretty ? "Erista CPU vMin" : "erista_cpu_vmin"; + case KipConfigValue_eristaCpuMaxVolt: + return pretty ? "Erista CPU Max Voltage" : "erista_cpu_max_volt"; + case KipConfigValue_eristaCpuUnlock: + return pretty ? "Erista CPU Unlock" : "erista_cpu_unlock"; + + // CPU – Mariko + case KipConfigValue_marikoCpuUVLow: + return pretty ? "Mariko CPU Undervolt (Low)" : "mariko_cpu_uv_low"; + case KipConfigValue_marikoCpuUVHigh: + return pretty ? "Mariko CPU Undervolt (High)" : "mariko_cpu_uv_high"; + case KipConfigValue_tableConf: + return pretty ? "Table Config" : "kip_table_conf"; + case KipConfigValue_marikoCpuLowVmin: + return pretty ? "Mariko CPU Low Vmin" : "mariko_cpu_low_vmin"; + case KipConfigValue_marikoCpuHighVmin: + return pretty ? "Mariko CPU High Vmin" : "mariko_cpu_high_vmin"; + case KipConfigValue_marikoCpuMaxVolt: + return pretty ? "Mariko CPU Max Voltage" : "mariko_cpu_max_volt"; + + case KipConfigValue_eristaCpuBoostClock: + return pretty ? "Erista CPU Boost Clock" : "erista_cpu_boost_clock"; + case KipConfigValue_marikoCpuBoostClock: + return pretty ? "Mariko CPU Boost Clock" : "mariko_cpu_boost_clock"; + + case KipConfigValue_marikoCpuMaxClock: + return pretty ? "Mariko CPU Max Clock" : "mariko_cpu_max_clock"; + + // GPU – Erista + case KipConfigValue_eristaGpuUV: + return pretty ? "Erista GPU Undervolt" : "erista_gpu_uv"; + case KipConfigValue_eristaGpuVmin: + return pretty ? "Erista GPU Vmin" : "erista_gpu_vmin"; + + // GPU – Mariko + case KipConfigValue_marikoGpuUV: + return pretty ? "Mariko GPU Undervolt" : "mariko_gpu_uv"; + case KipConfigValue_marikoGpuVmin: + return pretty ? "Mariko GPU Vmin" : "mariko_gpu_vmin"; + case KipConfigValue_marikoGpuVmax: + return pretty ? "Mariko GPU Vmax" : "mariko_gpu_vmax"; + + case KipConfigValue_commonGpuVoltOffset: + return pretty ? "Common GPU Voltage Offset" : "common_gpu_volt_offset"; + case KipConfigValue_gpuSpeedo: + return pretty ? "GPU Speedo" : "gpu_speedo"; + case KipConfigValue_marikoGpuFullUnlock: + return pretty ? "Mariko GPU Full Unlock" : "mariko_gpu_full_unlock"; + + // Mariko GPU voltages (24) + case KipConfigValue_g_volt_76800: return pretty ? "Mariko GPU Volt 76 MHz" : "g_volt_76800"; + case KipConfigValue_g_volt_153600: return pretty ? "Mariko GPU Volt 153 MHz" : "g_volt_153600"; + case KipConfigValue_g_volt_230400: return pretty ? "Mariko GPU Volt 230 MHz" : "g_volt_230400"; + case KipConfigValue_g_volt_307200: return pretty ? "Mariko GPU Volt 307 MHz" : "g_volt_307200"; + case KipConfigValue_g_volt_384000: return pretty ? "Mariko GPU Volt 384 MHz" : "g_volt_384000"; + case KipConfigValue_g_volt_460800: return pretty ? "Mariko GPU Volt 460 MHz" : "g_volt_460800"; + case KipConfigValue_g_volt_537600: return pretty ? "Mariko GPU Volt 537 MHz" : "g_volt_537600"; + case KipConfigValue_g_volt_614400: return pretty ? "Mariko GPU Volt 614 MHz" : "g_volt_614400"; + case KipConfigValue_g_volt_691200: return pretty ? "Mariko GPU Volt 691 MHz" : "g_volt_691200"; + case KipConfigValue_g_volt_768000: return pretty ? "Mariko GPU Volt 768 MHz" : "g_volt_768000"; + case KipConfigValue_g_volt_844800: return pretty ? "Mariko GPU Volt 844 MHz" : "g_volt_844800"; + case KipConfigValue_g_volt_921600: return pretty ? "Mariko GPU Volt 921 MHz" : "g_volt_921600"; + case KipConfigValue_g_volt_998400: return pretty ? "Mariko GPU Volt 998 MHz" : "g_volt_998400"; + case KipConfigValue_g_volt_1075200: return pretty ? "Mariko GPU Volt 1075 MHz" : "g_volt_1075200"; + case KipConfigValue_g_volt_1152000: return pretty ? "Mariko GPU Volt 1152 MHz" : "g_volt_1152000"; + case KipConfigValue_g_volt_1228800: return pretty ? "Mariko GPU Volt 1228 MHz" : "g_volt_1228800"; + case KipConfigValue_g_volt_1267200: return pretty ? "Mariko GPU Volt 1267 MHz" : "g_volt_1267200"; + case KipConfigValue_g_volt_1305600: return pretty ? "Mariko GPU Volt 1305 MHz" : "g_volt_1305600"; + case KipConfigValue_g_volt_1344000: return pretty ? "Mariko GPU Volt 1344 MHz" : "g_volt_1344000"; + case KipConfigValue_g_volt_1382400: return pretty ? "Mariko GPU Volt 1382 MHz" : "g_volt_1382400"; + case KipConfigValue_g_volt_1420800: return pretty ? "Mariko GPU Volt 1420 MHz" : "g_volt_1420800"; + case KipConfigValue_g_volt_1459200: return pretty ? "Mariko GPU Volt 1459 MHz" : "g_volt_1459200"; + case KipConfigValue_g_volt_1497600: return pretty ? "Mariko GPU Volt 1497 MHz" : "g_volt_1497600"; + case KipConfigValue_g_volt_1536000: return pretty ? "Mariko GPU Volt 1536 MHz" : "g_volt_1536000"; + + // Erista GPU voltages (27) + case KipConfigValue_g_volt_e_76800: return pretty ? "Erista GPU Volt 76 MHz" : "g_volt_e_76800"; + case KipConfigValue_g_volt_e_115200: return pretty ? "Erista GPU Volt 115 MHz" : "g_volt_e_115200"; + case KipConfigValue_g_volt_e_153600: return pretty ? "Erista GPU Volt 153 MHz" : "g_volt_e_153600"; + case KipConfigValue_g_volt_e_192000: return pretty ? "Erista GPU Volt 192 MHz" : "g_volt_e_192000"; + case KipConfigValue_g_volt_e_230400: return pretty ? "Erista GPU Volt 230 MHz" : "g_volt_e_230400"; + case KipConfigValue_g_volt_e_268800: return pretty ? "Erista GPU Volt 268 MHz" : "g_volt_e_268800"; + case KipConfigValue_g_volt_e_307200: return pretty ? "Erista GPU Volt 307 MHz" : "g_volt_e_307200"; + case KipConfigValue_g_volt_e_345600: return pretty ? "Erista GPU Volt 345 MHz" : "g_volt_e_345600"; + case KipConfigValue_g_volt_e_384000: return pretty ? "Erista GPU Volt 384 MHz" : "g_volt_e_384000"; + case KipConfigValue_g_volt_e_422400: return pretty ? "Erista GPU Volt 422 MHz" : "g_volt_e_422400"; + case KipConfigValue_g_volt_e_460800: return pretty ? "Erista GPU Volt 460 MHz" : "g_volt_e_460800"; + case KipConfigValue_g_volt_e_499200: return pretty ? "Erista GPU Volt 499 MHz" : "g_volt_e_499200"; + case KipConfigValue_g_volt_e_537600: return pretty ? "Erista GPU Volt 537 MHz" : "g_volt_e_537600"; + case KipConfigValue_g_volt_e_576000: return pretty ? "Erista GPU Volt 576 MHz" : "g_volt_e_576000"; + case KipConfigValue_g_volt_e_614400: return pretty ? "Erista GPU Volt 614 MHz" : "g_volt_e_614400"; + case KipConfigValue_g_volt_e_652800: return pretty ? "Erista GPU Volt 652 MHz" : "g_volt_e_652800"; + case KipConfigValue_g_volt_e_691200: return pretty ? "Erista GPU Volt 691 MHz" : "g_volt_e_691200"; + case KipConfigValue_g_volt_e_729600: return pretty ? "Erista GPU Volt 729 MHz" : "g_volt_e_729600"; + case KipConfigValue_g_volt_e_768000: return pretty ? "Erista GPU Volt 768 MHz" : "g_volt_e_768000"; + case KipConfigValue_g_volt_e_806400: return pretty ? "Erista GPU Volt 806 MHz" : "g_volt_e_806400"; + case KipConfigValue_g_volt_e_844800: return pretty ? "Erista GPU Volt 844 MHz" : "g_volt_e_844800"; + case KipConfigValue_g_volt_e_883200: return pretty ? "Erista GPU Volt 883 MHz" : "g_volt_e_883200"; + case KipConfigValue_g_volt_e_921600: return pretty ? "Erista GPU Volt 921 MHz" : "g_volt_e_921600"; + case KipConfigValue_g_volt_e_960000: return pretty ? "Erista GPU Volt 960 MHz" : "g_volt_e_960000"; + case KipConfigValue_g_volt_e_998400: return pretty ? "Erista GPU Volt 998 MHz" : "g_volt_e_998400"; + case KipConfigValue_g_volt_e_1036800: return pretty ? "Erista GPU Volt 1036 MHz" : "g_volt_e_1036800"; + case KipConfigValue_g_volt_e_1075200: return pretty ? "Erista GPU Volt 1075 MHz" : "g_volt_e_1075200"; + + default: + return pretty ? "[cfg] no enum format string" : "err_no_format_string"; + } +} + +static inline uint64_t sysclkDefaultConfigValue(SysClkConfigValue val) +{ + switch(val) + { + case SysClkConfigValue_PollingIntervalMs: + return 300ULL; + case SysClkConfigValue_TempLogIntervalMs: + case SysClkConfigValue_FreqLogIntervalMs: + case SysClkConfigValue_PowerLogIntervalMs: + case SysClkConfigValue_CsvWriteIntervalMs: + case HocClkConfigValue_UncappedClocks: + case HocClkConfigValue_OverwriteBoostMode: + case HocClkConfigValue_KipFileName: + return 0ULL; + case HocClkConfigValue_EristaMaxCpuClock: + return 1785ULL; + case HocClkConfigValue_EristaMaxGpuClock: + return 921ULL; + case HocClkConfigValue_EristaMaxMemClock: + return 1600ULL; + + case HocClkConfigValue_MarikoMaxCpuClock: + return 1963ULL; + case HocClkConfigValue_MarikoMaxGpuClock: + return 1075ULL; + case HocClkConfigValue_MarikoMaxMemClock: + return 1862ULL; + + case HocClkConfigValue_ThermalThrottle: + case HocClkConfigValue_DockedGovernor: + case HocClkConfigValue_HandheldGovernor: + case HocClkConfigValue_HandheldTDP: + case HocClkConfigValue_EnforceBoardLimit: + case HocClkConfigValue_KipEditing: + return 1ULL; + case HocClkConfigValue_ThermalThrottleThreshold: + return 70ULL; + case HocClkConfigValue_HandheldTDPLimit: + return 8600ULL; + case HocClkConfigValue_LiteTDPLimit: + return 6400ULL; + case HorizonOCConfigValue_BatteryChargeCurrent: + return 0ULL; + default: + return 0ULL; + } +} + +static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t input) +{ + switch(val) + { + case HocClkConfigValue_EristaMaxCpuClock: + case HocClkConfigValue_EristaMaxGpuClock: + case HocClkConfigValue_EristaMaxMemClock: + case HocClkConfigValue_MarikoMaxCpuClock: + case HocClkConfigValue_MarikoMaxGpuClock: + case HocClkConfigValue_MarikoMaxMemClock: + case HocClkConfigValue_ThermalThrottleThreshold: + case HocClkConfigValue_HandheldTDPLimit: + case HocClkConfigValue_LiteTDPLimit: + case SysClkConfigValue_PollingIntervalMs: + return input > 0; + + case SysClkConfigValue_TempLogIntervalMs: + case SysClkConfigValue_FreqLogIntervalMs: + case SysClkConfigValue_PowerLogIntervalMs: + case SysClkConfigValue_CsvWriteIntervalMs: + case HocClkConfigValue_UncappedClocks: + case HocClkConfigValue_OverwriteBoostMode: + case HocClkConfigValue_ThermalThrottle: + case HocClkConfigValue_DockedGovernor: + case HocClkConfigValue_HandheldGovernor: + case HocClkConfigValue_HandheldTDP: + case HocClkConfigValue_EnforceBoardLimit: + case HocClkConfigValue_KipEditing: + case HocClkConfigValue_KipFileName: + return (input & 0x1) == input; + + case KipConfigValue_custRev: + case KipConfigValue_mtcConf: + case KipConfigValue_hpMode: + case KipConfigValue_commonEmcMemVolt: + case KipConfigValue_eristaEmcMaxClock: + case KipConfigValue_marikoEmcMaxClock: + case KipConfigValue_marikoEmcVddqVolt: + case KipConfigValue_emcDvbShift: + case KipConfigValue_t1_tRCD: + case KipConfigValue_t2_tRP: + case KipConfigValue_t3_tRAS: + case KipConfigValue_t4_tRRD: + case KipConfigValue_t5_tRFC: + case KipConfigValue_t6_tRTW: + case KipConfigValue_t7_tWTR: + case KipConfigValue_t8_tREFI: + case KipConfigValue_mem_burst_read_latency: + case KipConfigValue_mem_burst_write_latency: + case KipConfigValue_eristaCpuUV: + case KipConfigValue_eristaCpuMaxVolt: + case KipConfigValue_marikoCpuUVLow: + case KipConfigValue_marikoCpuUVHigh: + case KipConfigValue_tableConf: + case KipConfigValue_marikoCpuLowVmin: + case KipConfigValue_marikoCpuHighVmin: + case KipConfigValue_marikoCpuMaxVolt: + case KipConfigValue_eristaCpuBoostClock: + case KipConfigValue_marikoCpuBoostClock: + case KipConfigValue_marikoCpuMaxClock: + case KipConfigValue_eristaGpuUV: + case KipConfigValue_eristaGpuVmin: + case KipConfigValue_marikoGpuUV: + case KipConfigValue_marikoGpuVmin: + case KipConfigValue_marikoGpuVmax: + case KipConfigValue_commonGpuVoltOffset: + case KipConfigValue_gpuSpeedo: + case KipConfigValue_marikoGpuFullUnlock: + case KipConfigValue_g_volt_76800: + case KipConfigValue_g_volt_153600: + case KipConfigValue_g_volt_230400: + case KipConfigValue_g_volt_307200: + case KipConfigValue_g_volt_384000: + case KipConfigValue_g_volt_460800: + case KipConfigValue_g_volt_537600: + case KipConfigValue_g_volt_614400: + case KipConfigValue_g_volt_691200: + case KipConfigValue_g_volt_768000: + case KipConfigValue_g_volt_844800: + case KipConfigValue_g_volt_921600: + case KipConfigValue_g_volt_998400: + case KipConfigValue_g_volt_1075200: + case KipConfigValue_g_volt_1152000: + case KipConfigValue_g_volt_1228800: + case KipConfigValue_g_volt_1267200: + case KipConfigValue_g_volt_1305600: + case KipConfigValue_g_volt_1344000: + case KipConfigValue_g_volt_1382400: + case KipConfigValue_g_volt_1420800: + case KipConfigValue_g_volt_1459200: + case KipConfigValue_g_volt_1497600: + case KipConfigValue_g_volt_1536000: + case KipConfigValue_g_volt_e_76800: + case KipConfigValue_g_volt_e_115200: + case KipConfigValue_g_volt_e_153600: + case KipConfigValue_g_volt_e_192000: + case KipConfigValue_g_volt_e_230400: + case KipConfigValue_g_volt_e_268800: + case KipConfigValue_g_volt_e_307200: + case KipConfigValue_g_volt_e_345600: + case KipConfigValue_g_volt_e_384000: + case KipConfigValue_g_volt_e_422400: + case KipConfigValue_g_volt_e_460800: + case KipConfigValue_g_volt_e_499200: + case KipConfigValue_g_volt_e_537600: + case KipConfigValue_g_volt_e_576000: + case KipConfigValue_g_volt_e_614400: + case KipConfigValue_g_volt_e_652800: + case KipConfigValue_g_volt_e_691200: + case KipConfigValue_g_volt_e_729600: + case KipConfigValue_g_volt_e_768000: + case KipConfigValue_g_volt_e_806400: + case KipConfigValue_g_volt_e_844800: + case KipConfigValue_g_volt_e_883200: + case KipConfigValue_g_volt_e_921600: + case KipConfigValue_g_volt_e_960000: + case KipConfigValue_g_volt_e_998400: + case KipConfigValue_g_volt_e_1036800: + case KipConfigValue_g_volt_e_1075200: + case KipConfigValue_eristaCpuVmin: + case KipConfigValue_eristaCpuUnlock: + return true; + case HorizonOCConfigValue_BatteryChargeCurrent: + return ((input >= 1024) && (input <= 3072)) || !input; + default: + return false; + } +} \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor/include/sysclk/errors.h b/Source/Horizon-OC-Monitor/include/sysclk/errors.h new file mode 100644 index 00000000..f6c88b75 --- /dev/null +++ b/Source/Horizon-OC-Monitor/include/sysclk/errors.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) Souldbminer and Horizon OC Contributors + * + * 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 . + * + */ + +/* -------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * , , + * wrote this file. As long as you retain this notice you can do whatever you + * want with this stuff. If you meet any of us some day, and you think this + * stuff is worth it, you can buy us a beer in return. - The sys-clk authors + * -------------------------------------------------------------------------- + */ + + +#pragma once + +#define SYSCLK_ERROR_MODULE 388 +#define SYSCLK_ERROR(desc) ((SYSCLK_ERROR_MODULE & 0x1FF) | (SysClkError_##desc & 0x1FFF)<<9) + +typedef enum +{ + SysClkError_Generic = 0, + SysClkError_ConfigNotLoaded = 1, + SysClkError_ConfigSaveFailed = 2, + HocClkError_SocThermFail = 3, +} SysClkError; diff --git a/Source/Horizon-OC-Monitor/include/sysclk/ipc.h b/Source/Horizon-OC-Monitor/include/sysclk/ipc.h new file mode 100644 index 00000000..50d5ae01 --- /dev/null +++ b/Source/Horizon-OC-Monitor/include/sysclk/ipc.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) Souldbminer and Horizon OC Contributors + * + * 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 . + * + */ + +/* -------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * , , + * wrote this file. As long as you retain this notice you can do whatever you + * want with this stuff. If you meet any of us some day, and you think this + * stuff is worth it, you can buy us a beer in return. - The sys-clk authors + * -------------------------------------------------------------------------- + */ + + +#pragma once + +#include +#include "board.h" +#include "clock_manager.h" + +#define SYSCLK_IPC_API_VERSION 4 +#define SYSCLK_IPC_SERVICE_NAME "sys:clk" + +enum SysClkIpcCmd +{ + SysClkIpcCmd_GetApiVersion = 0, + SysClkIpcCmd_GetVersionString = 1, + SysClkIpcCmd_GetCurrentContext = 2, + SysClkIpcCmd_Exit = 3, + SysClkIpcCmd_GetProfileCount = 4, + SysClkIpcCmd_GetProfiles = 5, + SysClkIpcCmd_SetProfiles = 6, + SysClkIpcCmd_SetEnabled = 7, + SysClkIpcCmd_SetOverride = 8, + SysClkIpcCmd_GetConfigValues = 9, + SysClkIpcCmd_SetConfigValues = 10, + SysClkIpcCmd_GetFreqList = 11, + SysClkIpcCmd_SetReverseNXRTMode = 12, + HocClkIpcCmd_SetKipData = 13, + HocClkIpcCmd_GetKipData = 14, +}; + + +typedef struct +{ + uint64_t tid; + SysClkTitleProfileList profiles; +} SysClkIpc_SetProfiles_Args; + +typedef struct +{ + SysClkModule module; + uint32_t hz; +} SysClkIpc_SetOverride_Args; + +typedef struct +{ + SysClkModule module; + uint32_t maxCount; +} SysClkIpc_GetFreqList_Args; \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor/include/sysclk/psm_ext.h b/Source/Horizon-OC-Monitor/include/sysclk/psm_ext.h new file mode 100644 index 00000000..7065efbc --- /dev/null +++ b/Source/Horizon-OC-Monitor/include/sysclk/psm_ext.h @@ -0,0 +1,77 @@ +#pragma once + +#include + +typedef enum { + PsmPDC_NewPDO = 1, //Received new Power Data Object + PsmPDC_NoPD = 2, //No Power Delivery source is detected + PsmPDC_AcceptedRDO = 3 //Received and accepted Request Data Object +} PsmChargeInfoPDC; //BM92T series + +typedef enum { + PsmPowerRole_Sink = 1, + PsmPowerRole_Source = 2 +} PsmPowerRole; + +const char* PsmPowerRoleToStr(PsmPowerRole role); + +typedef enum { + PsmInfoChargerType_None = 0, + PsmInfoChargerType_PD = 1, + PsmInfoChargerType_TypeC_1500mA = 2, + PsmInfoChargerType_TypeC_3000mA = 3, + PsmInfoChargerType_DCP = 4, + PsmInfoChargerType_CDP = 5, + PsmInfoChargerType_SDP = 6, + PsmInfoChargerType_Apple_500mA = 7, + PsmInfoChargerType_Apple_1000mA = 8, + PsmInfoChargerType_Apple_2000mA = 9 +} PsmInfoChargerType; + +const char* PsmInfoChargerTypeToStr(PsmInfoChargerType type); + +typedef enum { + PsmFlags_NoHub = BIT(0), //If hub is disconnected + PsmFlags_Rail = BIT(8), //At least one Joy-con is charging from rail + PsmFlags_SPDSRC = BIT(12), //OTG + PsmFlags_ACC = BIT(16) //Accessory +} PsmChargeInfoFlags; + +typedef struct { + int32_t InputCurrentLimit; //Input (Sink) current limit in mA + int32_t VBUSCurrentLimit; //Output (Source/VBUS/OTG) current limit in mA + int32_t ChargeCurrentLimit; //Battery charging current limit in mA (512mA when Docked, 768mA when BatteryTemperature < 17.0 C) + int32_t ChargeVoltageLimit; //Battery charging voltage limit in mV (3952mV when BatteryTemperature >= 51.0 C) + int32_t unk_x10; //Possibly an emum, getting the same value as PowerRole in all tested cases + int32_t unk_x14; //Possibly flags + PsmChargeInfoPDC PDCState; //Power Delivery Controller State + int32_t BatteryTemperature; //Battery temperature in milli C + int32_t RawBatteryCharge; //Raw battery charged capacity per cent-mille (i.e. 100% = 100000 pcm) + int32_t VoltageAvg; //Voltage avg in mV (more in Notes) + int32_t BatteryAge; //Battery age (capacity full / capacity design) per cent-mille (i.e. 100% = 100000 pcm) + PsmPowerRole PowerRole; + PsmInfoChargerType ChargerType; + int32_t ChargerVoltageLimit; //Charger and external device voltage limit in mV + int32_t ChargerCurrentLimit; //Charger and external device current limit in mA + PsmChargeInfoFlags Flags; //Unknown flags +} PsmChargeInfo; + +typedef enum { + Psm_EnableBatteryCharging = 2, + Psm_DisableBatteryCharging = 3, + Psm_EnableFastBatteryCharging = 10, + Psm_DisableFastBatteryCharging = 11, + Psm_GetBatteryChargeInfoFields = 17, +} IPsmServerCmd; + +bool PsmIsChargerConnected(const PsmChargeInfo* info); +bool PsmIsCharging(const PsmChargeInfo* info); + +typedef enum { + PsmBatteryState_Discharging, + PsmBatteryState_ChargingPaused, + PsmBatteryState_FastCharging +} PsmBatteryState; + +PsmBatteryState PsmGetBatteryState(const PsmChargeInfo* info); +const char* PsmGetBatteryStateIcon(const PsmChargeInfo* info); \ No newline at end of file diff --git a/Source/Horizon-OC-Monitor/lang/de.json b/Source/Horizon-OC-Monitor/lang/de.json index f1c8cfb2..f7c9a332 100644 --- a/Source/Horizon-OC-Monitor/lang/de.json +++ b/Source/Horizon-OC-Monitor/lang/de.json @@ -1,5 +1,5 @@ { - "Status Monitor": "Status Monitor", + "Horizon OC Monitor": "Horizon OC Monitor", "Modes": "Modi", "Modes   Configure": "Modi   Konfigurieren", "Full": "Voll", diff --git a/Source/Horizon-OC-Monitor/lang/en.json b/Source/Horizon-OC-Monitor/lang/en.json index cedf584b..836b8f0d 100644 --- a/Source/Horizon-OC-Monitor/lang/en.json +++ b/Source/Horizon-OC-Monitor/lang/en.json @@ -1,5 +1,5 @@ { - "Status Monitor": "Status Monitor", + "Horizon OC Monitor": "Horizon OC Monitor", "Modes": "Modes", "Modes   Configure": "Modes   Configure", "Full": "Full", diff --git a/Source/Horizon-OC-Monitor/lang/es.json b/Source/Horizon-OC-Monitor/lang/es.json index f4eb1a4f..bacf1152 100644 --- a/Source/Horizon-OC-Monitor/lang/es.json +++ b/Source/Horizon-OC-Monitor/lang/es.json @@ -1,5 +1,5 @@ { - "Status Monitor": "Status Monitor", + "Horizon OC Monitor": "Horizon OC Monitor", "Modes": "Modos", "Modes   Configure": "Modos   Configurar", "Full": "Completo", diff --git a/Source/Horizon-OC-Monitor/lang/fr.json b/Source/Horizon-OC-Monitor/lang/fr.json index ebd2ad8b..95bc2d9e 100644 --- a/Source/Horizon-OC-Monitor/lang/fr.json +++ b/Source/Horizon-OC-Monitor/lang/fr.json @@ -1,5 +1,5 @@ { - "Status Monitor": "Status Monitor", + "Horizon OC Monitor": "Horizon OC Monitor", "Modes": "Modes", "Modes   Configure": "Modes   Configurer", "Full": "Complet", diff --git a/Source/Horizon-OC-Monitor/lang/it.json b/Source/Horizon-OC-Monitor/lang/it.json index 2eaddb63..3a76ba57 100644 --- a/Source/Horizon-OC-Monitor/lang/it.json +++ b/Source/Horizon-OC-Monitor/lang/it.json @@ -1,5 +1,5 @@ { - "Status Monitor": "Status Monitor", + "Horizon OC Monitor": "Horizon OC Monitor", "Modes": "Modalità", "Modes   Configure": "Modalità   Configura", "Full": "Completo", diff --git a/Source/Horizon-OC-Monitor/lang/ja.json b/Source/Horizon-OC-Monitor/lang/ja.json index a5473ec8..a4000d02 100644 --- a/Source/Horizon-OC-Monitor/lang/ja.json +++ b/Source/Horizon-OC-Monitor/lang/ja.json @@ -1,5 +1,5 @@ { - "Status Monitor": "Status Monitor", + "Horizon OC Monitor": "Horizon OC Monitor", "Modes": "モード", "Modes   Configure": "モード   設定", "Full": "フル", diff --git a/Source/Horizon-OC-Monitor/lang/ko.json b/Source/Horizon-OC-Monitor/lang/ko.json index cd041c34..a001d36d 100644 --- a/Source/Horizon-OC-Monitor/lang/ko.json +++ b/Source/Horizon-OC-Monitor/lang/ko.json @@ -1,5 +1,5 @@ { - "Status Monitor": "Status Monitor", + "Horizon OC Monitor": "Horizon OC Monitor", "Modes": "모드", "Modes   Configure": "모드   설정", "Full": "전체", diff --git a/Source/Horizon-OC-Monitor/lang/nl.json b/Source/Horizon-OC-Monitor/lang/nl.json index 1e7f7c1e..febfacdc 100644 --- a/Source/Horizon-OC-Monitor/lang/nl.json +++ b/Source/Horizon-OC-Monitor/lang/nl.json @@ -1,5 +1,5 @@ { - "Status Monitor": "Status Monitor", + "Horizon OC Monitor": "Horizon OC Monitor", "Modes": "Modi", "Modes   Configure": "Modi   Configureren", "Full": "Volledig", diff --git a/Source/Horizon-OC-Monitor/lang/pl.json b/Source/Horizon-OC-Monitor/lang/pl.json index 1be8bb36..e2dd49e5 100644 --- a/Source/Horizon-OC-Monitor/lang/pl.json +++ b/Source/Horizon-OC-Monitor/lang/pl.json @@ -1,5 +1,5 @@ { - "Status Monitor": "Status Monitor", + "Horizon OC Monitor": "Horizon OC Monitor", "Modes": "Tryby", "Modes   Configure": "Tryby   Konfiguruj", "Full": "Pełny", diff --git a/Source/Horizon-OC-Monitor/lang/pt.json b/Source/Horizon-OC-Monitor/lang/pt.json index 1971d64b..3805ce59 100644 --- a/Source/Horizon-OC-Monitor/lang/pt.json +++ b/Source/Horizon-OC-Monitor/lang/pt.json @@ -1,5 +1,5 @@ { - "Status Monitor": "Status Monitor", + "Horizon OC Monitor": "Horizon OC Monitor", "Modes": "Modos", "Modes   Configure": "Modos   Configurar", "Full": "Completo", diff --git a/Source/Horizon-OC-Monitor/lang/ru.json b/Source/Horizon-OC-Monitor/lang/ru.json index 37efa4ed..841b0b75 100644 --- a/Source/Horizon-OC-Monitor/lang/ru.json +++ b/Source/Horizon-OC-Monitor/lang/ru.json @@ -1,5 +1,5 @@ { - "Status Monitor": "Status Monitor", + "Horizon OC Monitor": "Horizon OC Monitor", "Modes": "Режимы", "Modes   Configure": "Режимы   Настроить", "Full": "Полный", diff --git a/Source/Horizon-OC-Monitor/lang/uk.json b/Source/Horizon-OC-Monitor/lang/uk.json index 8d40bab4..c41c1beb 100644 --- a/Source/Horizon-OC-Monitor/lang/uk.json +++ b/Source/Horizon-OC-Monitor/lang/uk.json @@ -1,5 +1,5 @@ { - "Status Monitor": "Status Monitor", + "Horizon OC Monitor": "Horizon OC Monitor", "Modes": "Режими", "Modes   Configure": "Режими   Налаштувати", "Full": "Повний", diff --git a/Source/Horizon-OC-Monitor/lang/zh-cn.json b/Source/Horizon-OC-Monitor/lang/zh-cn.json index 1079dbc9..df7d264a 100644 --- a/Source/Horizon-OC-Monitor/lang/zh-cn.json +++ b/Source/Horizon-OC-Monitor/lang/zh-cn.json @@ -1,5 +1,5 @@ { - "Status Monitor": "Status Monitor", + "Horizon OC Monitor": "Horizon OC Monitor", "Modes": "模式", "Modes   Configure": "模式   配置", "Full": "完整", diff --git a/Source/Horizon-OC-Monitor/lang/zh-tw.json b/Source/Horizon-OC-Monitor/lang/zh-tw.json index 82a1b474..ce8015e4 100644 --- a/Source/Horizon-OC-Monitor/lang/zh-tw.json +++ b/Source/Horizon-OC-Monitor/lang/zh-tw.json @@ -1,5 +1,5 @@ { - "Status Monitor": "Status Monitor", + "Horizon OC Monitor": "Horizon OC Monitor", "Modes": "模式", "Modes   Configure": "模式   設定", "Full": "完整", diff --git a/Source/Horizon-OC-Monitor/out/config/status-monitor/config.ini.template b/Source/Horizon-OC-Monitor/out/config/status-monitor/config.ini.template deleted file mode 100644 index a11d524b..00000000 --- a/Source/Horizon-OC-Monitor/out/config/status-monitor/config.ini.template +++ /dev/null @@ -1,127 +0,0 @@ -[status-monitor] -battery_avg_iir_filter=false -battery_time_left_refreshrate=60 -average_gpu_load=false -use_old_fps_average=false - -[full] -refresh_rate=1 -layer_width_align=left -show_real_freqs=true -show_deltas=true -show_target_freqs=true -show_fps=true -show_res=true -show_read_speed=true -use_dynamic_colors=true -disable_screenshots=false -separator_color=#888F -cat_color_1=#8FFF -cat_color_2=#8CFF -text_color=#FFFF - -[mini] -refresh_rate=1 -handheld_font_size=15 -docked_font_size=15 -spacing=8 -real_freqs=true -real_volts=true -show_full_cpu=false -show_full_res=true -show_fan_percentage=true -show_soc_voltage=false -use_dynamic_colors=true -show_vddq=false -show_vdd2=true -decimal_vdd2=false -show_dtc=true -use_dtc_symbol=true -dtc_format=%m-%d-%Y%H:%M:%S -show=DTC+BAT+CPU+GPU+RAM+TMP+FPS+RES -replace_MB_with_RAM_load=true -show_RAM_load_CPU_GPU=false -invert_battery_display=true -disable_screenshots=false -sleep_exit=false -frame_offset_x=10 -frame_offset_y=10 -frame_padding=10 -background_color=#0009 -focus_background_color=#000F -separator_color=#888F -cat_color=#2DFF -text_color=#FFFF - -[micro] -refresh_rate=1 -layer_height_align=top -handheld_font_size=15 -docked_font_size=15 -text_align=center -real_freqs=true -real_volts=true -show_full_cpu=false -show_full_res=false -show_soc_voltage=true -use_dynamic_colors=true -show_vddq=false -show_vdd2=true -decimal_vdd2=false -show_dtc=true -use_dtc_symbol=true -dtc_format=%H:%M:%S -show=FPS+CPU+GPU+RAM+SOC+BAT+DTC -replace_GB_with_RAM_load=true -invert_battery_display=false -disable_screenshots=false -sleep_exit=false -background_color=#0009 -separator_color=#888F -cat_color=#2DFF -text_color=#FFFF - -[fps-counter] -refresh_rate=30 -handheld_font_size=40 -docked_font_size=40 -use_integer_counter=false -disable_screenshots=false -frame_offset_x=10 -frame_offset_y=10 -frame_padding=10 -background_color=#0009 -focus_background_color=#000F -text_color=#8CFF - -[fps-graph] -refresh_rate=30 -show_info=false -use_dynamic_colors=true -disable_screenshots=false -frame_offset_x=10 -frame_offset_y=10 -frame_padding=10 -background_color=#0009 -focus_background_color=#000F -fps_counter_color=#888C -border_color=#2DFF -dashed_line_color=#8888 -main_line_color=#FFFF -rounded_line_color=#F0FF -perfect_line_color=#0C0F -max_fps_text_color=#FFFF -min_fps_text_color=#FFFF -text_color=#FFFF -cat_color=#0F0F - -[game_resolutions] -refresh_rate=10 -disable_screenshots=false -frame_offset_x=10 -frame_offset_y=10 -frame_padding=10 -background_color=#0009 -focus_background_color=#000F -cat_color=#8FFF -text_color=#FFFF diff --git a/Source/Horizon-OC-Monitor/source/Utils.hpp b/Source/Horizon-OC-Monitor/source/Utils.hpp index 9f1ce906..1db6b457 100644 --- a/Source/Horizon-OC-Monitor/source/Utils.hpp +++ b/Source/Horizon-OC-Monitor/source/Utils.hpp @@ -18,13 +18,14 @@ #include "rgltr_services.h" // for extern Service g_rgltrSrv, etc. -#include "../../sys-clk/common/include/sysclk/client/ipc.h" #if defined(__cplusplus) extern "C" { #endif +#include + #if defined(__cplusplus) } #endif @@ -221,10 +222,11 @@ uint64_t lastFrameNumber = 0; uint32_t realCPU_Hz = 0; uint32_t realGPU_Hz = 0; uint32_t realRAM_Hz = 0; -uint32_t ramLoad[SysClkPartLoad_EnumMax]; +uint32_t PartLoad[SysClkPartLoad_EnumMax]; uint32_t realCPU_mV = 0; uint32_t realGPU_mV = 0; -uint32_t realRAM_mV = 0; +uint32_t realVDD2_mV = 0; +uint32_t realVDDQ_mV = 0; uint32_t realSOC_mV = 0; uint8_t refreshRate = 0; @@ -515,9 +517,11 @@ std::string getVersionString() { bool usingEOS() { - return true; + const std::string versionString = getVersionString(); + return versionString.find("eos") != std::string::npos; } + // === ULTRA-FAST VOLTAGE READING === static constexpr PowerDomainId domains[] = { PcvPowerDomainId_Max77621_Cpu, // [0] CPU @@ -574,12 +578,13 @@ void Misc(void*) { realCPU_Hz = sysclkCTX.realFreqs[SysClkModule_CPU]; realGPU_Hz = sysclkCTX.realFreqs[SysClkModule_GPU]; realRAM_Hz = sysclkCTX.realFreqs[SysClkModule_MEM]; - ramLoad[SysClkPartLoad_EMC] = sysclkCTX.PartLoad[SysClkPartLoad_EMC]; - ramLoad[SysClkPartLoad_EMCCpu] = sysclkCTX.PartLoad[SysClkPartLoad_EMCCpu]; + PartLoad[SysClkPartLoad_EMC] = sysclkCTX.PartLoad[SysClkPartLoad_EMC]; + PartLoad[SysClkPartLoad_EMCCpu] = sysclkCTX.PartLoad[SysClkPartLoad_EMCCpu]; realCPU_mV = sysclkCTX.voltages[HocClkVoltage_CPU]; realGPU_mV = sysclkCTX.voltages[HocClkVoltage_GPU]; - realRAM_mV = sysclkCTX.voltages[HocClkVoltage_EMCVDDQ_MarikoOnly]; + realVDD2_mV = sysclkCTX.voltages[HocClkVoltage_EMCVDD2]; + realVDDQ_mV = sysclkCTX.voltages[HocClkVoltage_EMCVDDQ_MarikoOnly]; realSOC_mV = sysclkCTX.voltages[HocClkVoltage_SOC]; } } @@ -697,19 +702,18 @@ void Misc3(void*) { // Get sys-clk data if (R_SUCCEEDED(sysclkCheck)) { - SysClkContext sysclkCTX; - if (R_SUCCEEDED(sysclkIpcGetCurrentContext(&sysclkCTX))) { - ramLoad[SysClkPartLoad_EMC] = sysclkCTX.PartLoad[SysClkPartLoad_EMC]; - ramLoad[SysClkPartLoad_EMCCpu] = sysclkCTX.PartLoad[SysClkPartLoad_EMCCpu]; - - // Get voltages from sys-clk if using EOS + SysClkContext sysclkCTX; + if (R_SUCCEEDED(sysclkIpcGetCurrentContext(&sysclkCTX))) { + PartLoad[SysClkPartLoad_EMC] = sysclkCTX.PartLoad[SysClkPartLoad_EMC]; + PartLoad[SysClkPartLoad_EMCCpu] = sysclkCTX.PartLoad[SysClkPartLoad_EMCCpu]; + realCPU_mV = sysclkCTX.voltages[HocClkVoltage_CPU]; realGPU_mV = sysclkCTX.voltages[HocClkVoltage_GPU]; - realRAM_mV = sysclkCTX.voltages[HocClkVoltage_EMCVDDQ_MarikoOnly]; realSOC_mV = sysclkCTX.voltages[HocClkVoltage_SOC]; + realVDD2_mV = sysclkCTX.voltages[HocClkVoltage_EMCVDD2]; + realVDDQ_mV = sysclkCTX.voltages[HocClkVoltage_EMCVDDQ_MarikoOnly]; } } - // Temperatures if (R_SUCCEEDED(i2cCheck)) { Tmp451GetSocTemp(&SOC_temperatureF); diff --git a/Source/Horizon-OC-Monitor/source/main.cpp b/Source/Horizon-OC-Monitor/source/main.cpp index 2263213a..59fde40d 100644 --- a/Source/Horizon-OC-Monitor/source/main.cpp +++ b/Source/Horizon-OC-Monitor/source/main.cpp @@ -4,8 +4,6 @@ #include #include -#include "../../sys-clk/common/include/sysclk.h" - //static tsl::elm::HeaderOverlayFrame* rootFrame = nullptr; static bool skipMain = false; static std::string lastSelectedItem; @@ -53,7 +51,7 @@ static std::string lastSelectedItem; // }); // list->addItem(comFPSCounter); // -// tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Status Monitor", "Modes"); +// tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Horizon OC Monitor", "Modes"); // rootFrame->setContent(list); // // return rootFrame; @@ -378,7 +376,7 @@ public: //list->disableCaching(); - tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Status Monitor", APP_VERSION); + tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Horizon OC Monitor", APP_VERSION); rootFrame->setContent(list); return rootFrame; @@ -988,7 +986,7 @@ inline void setupMode(const std::string& modeType = "") { // This function gets called on startup to create a new Overlay object int main(int argc, char **argv) { - // load heap settings outside of loop (only Status Monitor directive) + // load heap settings outside of loop (only Horizon OC Monitor directive) ult::currentHeapSize = ult::getCurrentHeapSize(); ult::expandedMemory = ult::currentHeapSize >= ult::OverlayHeapSize::Size_8MB; ult::limitedMemory = ult::currentHeapSize == ult::OverlayHeapSize::Size_4MB; diff --git a/Source/Horizon-OC-Monitor/source/modes/Battery.hpp b/Source/Horizon-OC-Monitor/source/modes/Battery.hpp index f6e8d23c..685fc998 100644 --- a/Source/Horizon-OC-Monitor/source/modes/Battery.hpp +++ b/Source/Horizon-OC-Monitor/source/modes/Battery.hpp @@ -142,7 +142,7 @@ public: }); //tsl::elm::g_disableMenuCacheOnReturn.store(true, std::memory_order_release); - tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Status Monitor", APP_VERSION, true); + tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Horizon OC Monitor", APP_VERSION, true); rootFrame->setContent(Status); return rootFrame; diff --git a/Source/Horizon-OC-Monitor/source/modes/Configurator.hpp b/Source/Horizon-OC-Monitor/source/modes/Configurator.hpp index 03f275b9..c4060971 100644 --- a/Source/Horizon-OC-Monitor/source/modes/Configurator.hpp +++ b/Source/Horizon-OC-Monitor/source/modes/Configurator.hpp @@ -157,7 +157,7 @@ public: list->jumpToItem("", ult::CHECKMARK_SYMBOL, false); - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Status Monitor", "Alpha"); + tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", "Alpha"); rootFrame->setContent(list); return rootFrame; } @@ -262,7 +262,7 @@ public: // Jump to currently selected item list->jumpToItem("", ult::CHECKMARK_SYMBOL, false); - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Status Monitor", "DTC Format"); + tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", "DTC Format"); rootFrame->setContent(list); return rootFrame; } @@ -424,11 +424,11 @@ public: list->addItem(socVoltage); if (isMiniMode) { - auto* ramLoadCPUGPU = new tsl::elm::ToggleListItem("RAM Load CPU/GPU", getCurrentShowRAMLoadCPUGPU()); - ramLoadCPUGPU->setStateChangedListener([this, section](bool state) { + auto* PartLoadCPUGPU = new tsl::elm::ToggleListItem("RAM Load CPU/GPU", getCurrentShowRAMLoadCPUGPU()); + PartLoadCPUGPU->setStateChangedListener([this, section](bool state) { ult::setIniFileValue(configIniPath, section, "show_RAM_load_CPU_GPU", state ? "true" : "false"); }); - list->addItem(ramLoadCPUGPU); + list->addItem(PartLoadCPUGPU); } if (isMiniMode || isMicroMode) { @@ -494,7 +494,7 @@ public: jumpItemExactMatch = false; } - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Status Monitor", "Configuration"); + tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", "Configuration"); rootFrame->setContent(list); return rootFrame; } @@ -745,7 +745,7 @@ public: list->jumpToItem("", ult::CHECKMARK_SYMBOL, false); - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Status Monitor", "Configuration"); + tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", "Configuration"); rootFrame->setContent(list); return rootFrame; } @@ -808,7 +808,7 @@ public: list->jumpToItem("", ult::CHECKMARK_SYMBOL, false); - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Status Monitor", "Configuration"); + tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", "Configuration"); rootFrame->setContent(list); return rootFrame; } @@ -896,7 +896,7 @@ public: list->jumpToItem("", ult::CHECKMARK_SYMBOL, false); - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Status Monitor", "Font Sizes"); + tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", "Font Sizes"); rootFrame->setContent(list); return rootFrame; } @@ -969,7 +969,7 @@ public: }); list->addItem(dockedItem); - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Status Monitor", "Configuration"); + tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", "Configuration"); rootFrame->setContent(list); list->jumpToItem(jumpItemName, jumpItemValue, jumpItemExactMatch); { @@ -1181,7 +1181,7 @@ public: } list->jumpToItem("", _jumpItemValue, false); - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Status Monitor", "Colors"); + tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", "Colors"); rootFrame->setContent(list); return rootFrame; } @@ -1587,7 +1587,7 @@ public: } //list->disableCaching(); - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Status Monitor", "Configuration"); + tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", "Configuration"); rootFrame->setContent(list); return rootFrame; } @@ -1780,7 +1780,7 @@ public: jumpItemExactMatch = false; } - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Status Monitor", "Configuration"); + tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", "Configuration"); rootFrame->setContent(list); return rootFrame; } @@ -2022,7 +2022,7 @@ public: jumpItemExactMatch = false; } - tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Status Monitor", modeName); + tsl::elm::OverlayFrame* rootFrame = new tsl::elm::OverlayFrame("Horizon OC Monitor", modeName); rootFrame->setContent(list); return rootFrame; } diff --git a/Source/Horizon-OC-Monitor/source/modes/FPS_Graph.hpp b/Source/Horizon-OC-Monitor/source/modes/FPS_Graph.hpp index 6cbe4aa6..22a2da29 100644 --- a/Source/Horizon-OC-Monitor/source/modes/FPS_Graph.hpp +++ b/Source/Horizon-OC-Monitor/source/modes/FPS_Graph.hpp @@ -496,8 +496,8 @@ public: snprintf(CPU_Load_c, sizeof(CPU_Load_c), "%.1f%%", cpu_usageM); snprintf(GPU_Load_c, sizeof(GPU_Load_c), "%d.%d%%", GPU_Load_u / 10, GPU_Load_u % 10); snprintf(RAM_Load_c, sizeof(RAM_Load_c), "%hu.%hhu%%", - ramLoad[SysClkPartLoad_EMC] / 10, - ramLoad[SysClkPartLoad_EMC] % 10); + PartLoad[SysClkPartLoad_EMC] / 10, + PartLoad[SysClkPartLoad_EMC] % 10); mutexUnlock(&mutex_Misc); diff --git a/Source/Horizon-OC-Monitor/source/modes/Full.hpp b/Source/Horizon-OC-Monitor/source/modes/Full.hpp index 4cb02376..ed68710a 100644 --- a/Source/Horizon-OC-Monitor/source/modes/Full.hpp +++ b/Source/Horizon-OC-Monitor/source/modes/Full.hpp @@ -234,10 +234,10 @@ public: renderer->drawString(DeltaRAM_c, false, COMMON_MARGIN + deltaOffset, height_offset, 15, (settings.textColor)); } if (R_SUCCEEDED(sysclkCheck)) { - static std::vector ramLoadColoredChars = {"CPU", "GPU"}; + static std::vector PartLoadColoredChars = {"CPU", "GPU"}; //static auto loadLabelWidth = renderer->getTextDimensions("Load: ", false, 15).first; renderer->drawString("Load", false, COMMON_MARGIN, height_offset+15, 15, (settings.catColor2)); - renderer->drawStringWithColoredSections(RAM_load_c, false, ramLoadColoredChars, COMMON_MARGIN + valueOffset, height_offset+15, 15, (settings.textColor), settings.catColor2); + renderer->drawStringWithColoredSections(RAM_load_c, false, PartLoadColoredChars, COMMON_MARGIN + valueOffset, height_offset+15, 15, (settings.textColor), settings.catColor2); } } if (R_SUCCEEDED(Hinted)) { @@ -347,7 +347,7 @@ public: renderer->drawString(" to Exit", false, baseX + pressWidth + keyComboWidth, baseY, fontSize, (tsl::bottomTextColor)); }); - auto rootFrame = new tsl::elm::HeaderOverlayFrame("Status Monitor", APP_VERSION); + auto rootFrame = new tsl::elm::HeaderOverlayFrame("Horizon OC Monitor", APP_VERSION); rootFrame->setContent(Status); return rootFrame; @@ -446,11 +446,11 @@ public: ); if (R_SUCCEEDED(sysclkCheck)) { - const int RAM_GPU_Load = ramLoad[SysClkPartLoad_EMC] - ramLoad[SysClkPartLoad_EMCCpu]; + const int RAM_GPU_Load = PartLoad[SysClkPartLoad_EMC] - PartLoad[SysClkPartLoad_EMCCpu]; snprintf(RAM_load_c, sizeof RAM_load_c, "%u.%u%% CPU %u.%u%% GPU %u.%u%%", - ramLoad[SysClkPartLoad_EMC] / 10, ramLoad[SysClkPartLoad_EMC] % 10, - ramLoad[SysClkPartLoad_EMCCpu] / 10, ramLoad[SysClkPartLoad_EMCCpu] % 10, + PartLoad[SysClkPartLoad_EMC] / 10, PartLoad[SysClkPartLoad_EMC] % 10, + PartLoad[SysClkPartLoad_EMCCpu] / 10, PartLoad[SysClkPartLoad_EMCCpu] % 10, RAM_GPU_Load / 10, RAM_GPU_Load % 10); } ///Thermal diff --git a/Source/Horizon-OC-Monitor/source/modes/Micro.hpp b/Source/Horizon-OC-Monitor/source/modes/Micro.hpp index f3641959..22fe9855 100644 --- a/Source/Horizon-OC-Monitor/source/modes/Micro.hpp +++ b/Source/Horizon-OC-Monitor/source/modes/Micro.hpp @@ -821,13 +821,13 @@ public: if (R_SUCCEEDED(sysclkCheck)) { // Use sys-clk's RAM load if available snprintf(MICRO_RAM_all_c, sizeof(MICRO_RAM_all_c), "%hu%%", - ramLoad[SysClkPartLoad_EMC] / 10); + PartLoad[SysClkPartLoad_EMC] / 10); } else { // Calculate percentage manually when sys-clk isn't available const uint64_t RAM_Total_all = RAM_Total_application_u + RAM_Total_applet_u + RAM_Total_system_u + RAM_Total_systemunsafe_u; const uint64_t RAM_Used_all = RAM_Used_application_u + RAM_Used_applet_u + RAM_Used_system_u + RAM_Used_systemunsafe_u; - const unsigned ramLoadPercent = (RAM_Total_all > 0) ? (unsigned)((RAM_Used_all * 100) / RAM_Total_all) : 0; - snprintf(MICRO_RAM_all_c, sizeof(MICRO_RAM_all_c), "%u%%", ramLoadPercent); + const unsigned PartLoadPercent = (RAM_Total_all > 0) ? (unsigned)((RAM_Used_all * 100) / RAM_Total_all) : 0; + snprintf(MICRO_RAM_all_c, sizeof(MICRO_RAM_all_c), "%u%%", PartLoadPercent); } } @@ -857,8 +857,8 @@ public: if (settings.realVolts && (settings.showVDD2 || settings.showVDDQ)) { /* realRAM_mV packs VDD2 | VDDQ in 10-µV units * * → split, convert to mV */ - const float mv_vdd2 = (realRAM_mV / 10000) / 10.0f; // VDD2 - const uint32_t mv_vddq = (realRAM_mV % 10000) / 10; // VDDQ + const float mv_vdd2 = realVDD2_mV / 1000; // VDD2 + const uint32_t mv_vddq = realVDDQ_mV / 1000; // VDDQ // Build voltage string based on settings RAM_volt_c[0] = '\0'; // Start with empty string diff --git a/Source/Horizon-OC-Monitor/source/modes/Mini.hpp b/Source/Horizon-OC-Monitor/source/modes/Mini.hpp index 206fb455..3041850e 100644 --- a/Source/Horizon-OC-Monitor/source/modes/Mini.hpp +++ b/Source/Horizon-OC-Monitor/source/modes/Mini.hpp @@ -991,35 +991,35 @@ public: RAM_Hz / 1000000, (RAM_Hz / 100000) % 10); } } else { - unsigned ramLoadInt; + unsigned PartLoadInt; if (R_SUCCEEDED(sysclkCheck)) { - ramLoadInt = ramLoad[SysClkPartLoad_EMC] / 10; + PartLoadInt = PartLoad[SysClkPartLoad_EMC] / 10; if (settings.showRAMLoadCPUGPU) { - unsigned ramCpuLoadInt = ramLoad[SysClkPartLoad_EMCCpu] / 10; - int RAM_GPU_Load = ramLoad[SysClkPartLoad_EMC] - ramLoad[SysClkPartLoad_EMCCpu]; + unsigned ramCpuLoadInt = PartLoad[SysClkPartLoad_EMCCpu] / 10; + int RAM_GPU_Load = PartLoad[SysClkPartLoad_EMC] - PartLoad[SysClkPartLoad_EMCCpu]; unsigned ramGpuLoadInt = RAM_GPU_Load / 10; if (settings.realFrequencies && realRAM_Hz) { snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c), "%u%%[%u%%,%u%%]@%hu.%hhu", - ramLoadInt, ramCpuLoadInt, ramGpuLoadInt, + PartLoadInt, ramCpuLoadInt, ramGpuLoadInt, realRAM_Hz / 1000000, (realRAM_Hz / 100000) % 10); } else { snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c), "%u%%[%u%%,%u%%]@%hu.%hhu", - ramLoadInt, ramCpuLoadInt, ramGpuLoadInt, + PartLoadInt, ramCpuLoadInt, ramGpuLoadInt, RAM_Hz / 1000000, (RAM_Hz / 100000) % 10); } } else { if (settings.realFrequencies && realRAM_Hz) { snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c), - "%u%%@%hu.%hhu", ramLoadInt, + "%u%%@%hu.%hhu", PartLoadInt, realRAM_Hz / 1000000, (realRAM_Hz / 100000) % 10); } else { snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c), - "%u%%@%hu.%hhu", ramLoadInt, + "%u%%@%hu.%hhu", PartLoadInt, RAM_Hz / 1000000, (RAM_Hz / 100000) % 10); } } @@ -1028,24 +1028,24 @@ public: RAM_Total_system_u + RAM_Total_systemunsafe_u; const uint64_t RAM_Used_all = RAM_Used_application_u + RAM_Used_applet_u + RAM_Used_system_u + RAM_Used_systemunsafe_u; - ramLoadInt = (RAM_Total_all > 0) ? (unsigned)((RAM_Used_all * 100) / RAM_Total_all) : 0; + PartLoadInt = (RAM_Total_all > 0) ? (unsigned)((RAM_Used_all * 100) / RAM_Total_all) : 0; if (settings.realFrequencies && realRAM_Hz) { snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c), - "%u%%@%hu.%hhu", ramLoadInt, + "%u%%@%hu.%hhu", PartLoadInt, realRAM_Hz / 1000000, (realRAM_Hz / 100000) % 10); } else { snprintf(MINI_RAM_var_compressed_c, sizeof(MINI_RAM_var_compressed_c), - "%u%%@%hu.%hhu", ramLoadInt, + "%u%%@%hu.%hhu", PartLoadInt, RAM_Hz / 1000000, (RAM_Hz / 100000) % 10); } } } if (settings.realVolts) { - const float mv_vdd2_f = realRAM_mV / 100000.0f; - const uint32_t mv_vdd2_i = realRAM_mV / 100000; - const uint32_t mv_vddq = (realRAM_mV % 10000) / 10; + const float mv_vdd2_f = realVDD2_mV / 100000.0f; + const uint32_t mv_vdd2_i = realVDD2_mV / 1000; + const uint32_t mv_vddq = realVDDQ_mV / 1000; if (isMariko) { if (settings.showVDDQ && settings.showVDD2) { diff --git a/Source/Horizon-OC-Monitor/source/modes/Misc.hpp b/Source/Horizon-OC-Monitor/source/modes/Misc.hpp index 5cf955fd..fc2c1249 100644 --- a/Source/Horizon-OC-Monitor/source/modes/Misc.hpp +++ b/Source/Horizon-OC-Monitor/source/modes/Misc.hpp @@ -122,7 +122,7 @@ public: }); //tsl::elm::g_disableMenuCacheOnReturn.store(true, std::memory_order_release); - tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Status Monitor", APP_VERSION, true); + tsl::elm::HeaderOverlayFrame* rootFrame = new tsl::elm::HeaderOverlayFrame("Horizon OC Monitor", APP_VERSION, true); rootFrame->setContent(Status); return rootFrame; diff --git a/Source/Horizon-OC-Monitor/source/sysclk_ipc.c b/Source/Horizon-OC-Monitor/source/sysclk_ipc.c new file mode 100644 index 00000000..7c6e853c --- /dev/null +++ b/Source/Horizon-OC-Monitor/source/sysclk_ipc.c @@ -0,0 +1,128 @@ +/* + * -------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42): + * , , + * wrote this file. As long as you retain this notice you can do whatever you + * want with this stuff. If you meet any of us some day, and you think this + * stuff is worth it, you can buy us a beer in return. - The sys-clk authors + * -------------------------------------------------------------------------- + */ + +#define NX_SERVICE_ASSUME_NON_DOMAIN +#include +#include +#include +#include + +static Service g_sysclkSrv; +static atomic_size_t g_refCnt; + +bool sysclkIpcRunning() +{ + Handle handle; + const bool running = R_FAILED(smRegisterService(&handle, smEncodeName(SYSCLK_IPC_SERVICE_NAME), false, 1)); + + if (!running) + { + smUnregisterService(smEncodeName(SYSCLK_IPC_SERVICE_NAME)); + } + + return running; +} + +Result sysclkIpcInitialize(void) +{ + Result rc = 0; + + g_refCnt++; + + if (serviceIsActive(&g_sysclkSrv)) + return 0; + + rc = smGetService(&g_sysclkSrv, SYSCLK_IPC_SERVICE_NAME); + + if (R_FAILED(rc)) sysclkIpcExit(); + + return rc; +} + +void sysclkIpcExit(void) +{ + if (--g_refCnt == 0) + { + serviceClose(&g_sysclkSrv); + } +} + +Result sysclkIpcGetAPIVersion(u32* out_ver) +{ + return serviceDispatchOut(&g_sysclkSrv, SysClkIpcCmd_GetApiVersion, *out_ver); +} + +Result sysclkIpcGetVersionString(char* out, size_t len) +{ + return serviceDispatch(&g_sysclkSrv, SysClkIpcCmd_GetVersionString, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = {{out, len}}, + ); +} + +Result sysclkIpcGetCurrentContext(SysClkContext* out_context) +{ + return serviceDispatchOut(&g_sysclkSrv, SysClkIpcCmd_GetCurrentContext, *out_context); +} + +Result sysclkIpcGetProfileCount(u64 tid, u8* out_count) +{ + return serviceDispatchInOut(&g_sysclkSrv, SysClkIpcCmd_GetProfileCount, tid, *out_count); +} + +Result sysclkIpcSetEnabled(bool enabled) +{ + u8 enabledRaw = (u8)enabled; + return serviceDispatchIn(&g_sysclkSrv, SysClkIpcCmd_SetEnabled, enabledRaw); +} + +Result sysclkIpcSetOverride(SysClkModule module, u32 hz) +{ + SysClkIpc_SetOverride_Args args = { + .module = module, + .hz = hz + }; + return serviceDispatchIn(&g_sysclkSrv, SysClkIpcCmd_SetOverride, args); +} + +Result sysclkIpcGetProfiles(u64 tid, SysClkTitleProfileList* out_profiles) +{ + return serviceDispatchInOut(&g_sysclkSrv, SysClkIpcCmd_GetProfiles, tid, *out_profiles); +} + +Result sysclkIpcSetProfiles(u64 tid, SysClkTitleProfileList* profiles) +{ + SysClkIpc_SetProfiles_Args args; + args.tid = tid; + memcpy(&args.profiles, profiles, sizeof(SysClkTitleProfileList)); + return serviceDispatchIn(&g_sysclkSrv, SysClkIpcCmd_SetProfiles, args); +} + +Result sysclkIpcGetConfigValues(SysClkConfigValueList* out_configValues) +{ + return serviceDispatchOut(&g_sysclkSrv, SysClkIpcCmd_GetConfigValues, *out_configValues); +} + +Result sysclkIpcSetConfigValues(SysClkConfigValueList* configValues) +{ + return serviceDispatchIn(&g_sysclkSrv, SysClkIpcCmd_SetConfigValues, *configValues); +} + +Result sysclkIpcGetFreqList(SysClkModule module, u32* list, u32 maxCount, u32* outCount) +{ + SysClkIpc_GetFreqList_Args args = { + .module = module, + .maxCount = maxCount + }; + return serviceDispatchInOut(&g_sysclkSrv, SysClkIpcCmd_GetFreqList, args, *outCount, + .buffer_attrs = { SfBufferAttr_HipcAutoSelect | SfBufferAttr_Out }, + .buffers = {{list, maxCount * sizeof(u32)}}, + ); +} \ No newline at end of file