hoc-sys: add extra features to overlay

This commit is contained in:
souldbminersmwc
2025-11-22 15:53:21 -05:00
parent 39ae532108
commit 3bca6ba97d
26 changed files with 650 additions and 332 deletions

View File

@@ -31,6 +31,10 @@
#define HOSSVC_HAS_CLKRST (hosversionAtLeast(8,0,0))
#define HOSSVC_HAS_TC (hosversionAtLeast(5,0,0))
#define NVGPU_GPU_IOCTL_PMU_GET_GPU_LOAD 0x80044715
Result nvCheck = 1;
u32 fd = 0;
static SysClkSocType g_socType = SysClkSocType_Erista;
@@ -117,6 +121,11 @@ void Board::Initialize()
rc = tmp451Initialize();
ASSERT_RESULT_OK(rc, "tmp451Initialize");
// u32 fd = 0;
// if (R_SUCCEEDED(nvInitialize())) nvCheck = nvOpen(&fd, "/dev/nvhost-ctrl-gpu");
FetchHardwareInfos();
}
@@ -141,6 +150,7 @@ void Board::Exit()
max17050Exit();
tmp451Exit();
nvExit();
}
SysClkProfile Board::GetProfile()
@@ -463,16 +473,23 @@ std::int32_t Board::GetPowerMw(SysClkPowerSensor sensor)
return 0;
}
std::uint32_t Board::GetRamLoad(SysClkRamLoad loadSource)
std::uint32_t Board::GetPartLoad(SysClkPartLoad loadSource)
{
// u32 temp, GPU_Load_u = 0;
switch(loadSource)
{
case SysClkRamLoad_All:
case SysClkPartLoad_EMC:
return t210EmcLoadAll();
case SysClkRamLoad_Cpu:
case SysClkPartLoad_EMCCpu:
return t210EmcLoadCpu();
// case HocClkPartLoad_GPU:
// #define gpu_samples_average 10
// // nvIoctl(fd, NVGPU_GPU_IOCTL_PMU_GET_GPU_LOAD, &temp);
// GPU_Load_u = ((GPU_Load_u * (gpu_samples_average-1)) + temp) / gpu_samples_average;
// return GPU_Load_u / 10;
default:
ASSERT_ENUM_VALID(SysClkRamLoad, loadSource);
ASSERT_ENUM_VALID(SysClkPartLoad, loadSource);
}
return 0;
@@ -502,4 +519,4 @@ void Board::FetchHardwareInfos()
default:
g_socType = SysClkSocType_Erista;
}
}
}

View File

@@ -51,7 +51,7 @@ class Board
static void GetFreqList(SysClkModule module, std::uint32_t* outList, std::uint32_t maxCount, std::uint32_t* outCount);
static std::uint32_t GetTemperatureMilli(SysClkThermalSensor sensor);
static std::int32_t GetPowerMw(SysClkPowerSensor sensor);
static std::uint32_t GetRamLoad(SysClkRamLoad load);
static std::uint32_t GetPartLoad(SysClkPartLoad load);
static SysClkSocType GetSocType();
protected:

View File

@@ -24,6 +24,7 @@
* --------------------------------------------------------------------------
*/
#include "notification.h"
#include "clock_manager.h"
#include <cstring>
@@ -35,6 +36,10 @@
#define HOSPPC_HAS_BOOST (hosversionAtLeast(7,0,0))
bool HAS_TDP_BEEN_FIRED = false;
bool HAS_EBL_BEEN_FIRED = false;
bool HAS_TT_BEEN_FIRED = false;
ClockManager *ClockManager::instance = NULL;
ClockManager *ClockManager::GetInstance()
@@ -228,6 +233,7 @@ void ClockManager::RefreshFreqTableRow(SysClkModule module)
void ClockManager::Tick()
{
std::uint32_t mode = 0;
AppletOperationMode opMode = appletGetOperationMode();
Result rc = apmExtGetCurrentPerformanceConfiguration(&mode);
@@ -257,25 +263,47 @@ void ClockManager::Tick()
if(this->config->GetConfigValue(HocClkConfigValue_HandheldTDP) && opMode == AppletOperationMode_Handheld) {
if(Board::GetSocType() == SysClkSocType_MarikoLite) {
if(Board::GetPowerMw(SysClkPowerSensor_Avg) < -(int)this->config->GetConfigValue(HocClkConfigValue_LiteTDPLimit)) {
if(!HAS_TDP_BEEN_FIRED)
writeNotification("Horizon OC\nTDP has been activated");
HAS_TDP_BEEN_FIRED = true;
ResetToStockClocks();
return;
} else {
HAS_TDP_BEEN_FIRED = false;
}
} else {
if(Board::GetPowerMw(SysClkPowerSensor_Avg) < -(int)this->config->GetConfigValue(HocClkConfigValue_HandheldTDPLimit)) {
if(!HAS_TDP_BEEN_FIRED)
writeNotification("Horizon OC\nTDP has been activated");
HAS_TDP_BEEN_FIRED = true;
ResetToStockClocks();
return;
} else {
HAS_TDP_BEEN_FIRED = false;
}
}
} else if(opMode == AppletOperationMode_Console && this->config->GetConfigValue(HocClkConfigValue_EnforceBoardLimit)) {
if(Board::GetPowerMw(SysClkPowerSensor_Avg) < 0) {
if(!HAS_EBL_BEEN_FIRED)
writeNotification("Horizon OC\nBoard Limit has been exeeded");
HAS_EBL_BEEN_FIRED = true;
ResetToStockClocks();
return;
} else {
HAS_EBL_BEEN_FIRED = false;
}
}
if(((tmp451TempSoc() / 1000) > (int)this->config->GetConfigValue(HocClkConfigValue_ThermalThrottleThreshold)) && this->config->GetConfigValue(HocClkConfigValue_ThermalThrottle)) {
ResetToStockClocks();
return;
if(this->config->GetConfigValue(HocClkConfigValue_ThermalThrottle)) {
if(tmp451TempSoc() / 1000 > (int)this->config->GetConfigValue(HocClkConfigValue_ThermalThrottleThreshold)) {
if(!HAS_TT_BEEN_FIRED)
writeNotification("Horizon OC\nThermal Throttle has started");
HAS_TT_BEEN_FIRED = true;
ResetToStockClocks();
return;
} else {
HAS_TT_BEEN_FIRED = false;
}
}
std::scoped_lock lock{this->contextMutex};
@@ -454,9 +482,9 @@ bool ClockManager::RefreshContext()
}
// ram load do not and should not force a refresh, hasChanged untouched
for (unsigned int loadSource = 0; loadSource < SysClkRamLoad_EnumMax; loadSource++)
for (unsigned int loadSource = 0; loadSource < SysClkPartLoad_EnumMax; loadSource++)
{
this->context->ramLoad[loadSource] = Board::GetRamLoad((SysClkRamLoad)loadSource);
this->context->partLoad[loadSource] = Board::GetPartLoad((SysClkPartLoad)loadSource);
}
if (this->ConfigIntervalTimeout(SysClkConfigValue_CsvWriteIntervalMs, ns, &this->lastCsvWriteNs))
@@ -481,31 +509,29 @@ void ClockManager::set_sd1_voltage(uint32_t voltage_uv)
const u8 volt_addr = 0x17; // MAX77620_REG_SD1
const u8 volt_mask = 0x7F; // MAX77620_SD1_VOLT_MASK
// Validate input voltage
if (voltage_uv < uv_min || voltage_uv > uv_max)
return;
// Calculate voltage multiplier
u32 mult = (voltage_uv + uv_step - 1 - uv_min) / uv_step;
mult = mult & volt_mask;
// Open I2C session to MAX77620 PMIC
I2cSession session;
Result res = i2cOpenSession(&session, I2cDevice_Max77620Pmic);
if (R_FAILED(res)) {
return;
}
// Read current register value
u8 current_val = 0;
res = i2csessionSendAuto(&session, &volt_addr, 1, I2cTransactionOption_Start);
if (R_FAILED(res)) {
writeNotification("I2C write failed. This may be a hardware issue");
i2csessionClose(&session);
return;
}
res = i2csessionReceiveAuto(&session, &current_val, 1, I2cTransactionOption_Stop);
if (R_FAILED(res)) {
writeNotification("I2C write failed. This may be a hardware issue");
i2csessionClose(&session);
return;
}

View File

@@ -40,7 +40,7 @@
#include "fancontrol.h"
#include "emc_patcher.h"
#define INNER_HEAP_SIZE 0xFFFFF
#define INNER_HEAP_SIZE 0x50000
extern "C"
{
@@ -92,7 +92,7 @@ extern "C"
hosversionSet(MAKEHOSVERSION(fw.major, fw.minor, fw.micro));
setsysExit();
}
}
void __appExit(void)
@@ -124,7 +124,7 @@ int main(int argc, char** argv)
ClockManager* clockMgr = new ClockManager();
IpcService* ipcSrv = new IpcService(clockMgr);
FileUtils::LogLine("Starting Horizon OC Sysmodule");
clockMgr->SetRunning(true);

View File

@@ -0,0 +1,31 @@
#pragma once
#include <string>
#include <ctime>
#include <cstdio>
static void writeNotification(const std::string& message) {
const char* flagPath = "sdmc:/config/ultrahand/flags/NOTIFICATIONS.flag";
// Check if flag file exists
FILE* flagFile = fopen(flagPath, "r");
if (!flagFile) {
// Flag file does not exist, do nothing
return;
}
fclose(flagFile);
// Generate filename with timestamp
std::string filename = "Horzon OC -" + std::to_string(std::time(nullptr)) + ".notify";
std::string fullPath = "sdmc:/config/ultrahand/notifications/" + filename;
// Write JSON manually
FILE* file = fopen(fullPath.c_str(), "w");
if (file) {
fprintf(file, "{\n");
fprintf(file, " \"text\": \"%s\",\n", message.c_str());
fprintf(file, " \"fontSize\": 28\n");
fprintf(file, "}\n");
fclose(file);
}
}