c++ bindings for libnx

This commit is contained in:
souldbminersmwc committed 2026-10-05 19:15:19 -04:00
1 parent b144c8d633
commit 018325747d
26 files changed
+33869 -41

No files matched your search

File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+2
View File
@@ -71,6 +71,8 @@ CFLAGS += -DUI_OVERRIDE_PATH="\"$(UI_OVERRIDE_PATH)\""
CXXFLAGS := $(CFLAGS) -fno-exceptions -std=gnu++23
switch.o: CXXFLAGS += -fno-lto
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map),-wrap,__cxa_throw -Wl,-wrap,_Unwind_Resume -Wl,-wrap,__gxx_personality_v0
+2 -2
View File
@@ -26,14 +26,14 @@
#pragma once
#include <hocclk.h>
#if defined(__cplusplus)
#include "cpp_util.hpp"
extern "C" {
#endif
#include <hocclk.h>
#include <hocclk/client/ipc.h>
#if defined(__cplusplus)
+1 -1
View File
@@ -22,7 +22,7 @@ CONFIG_DIR := horizon-oc
BUILD := build
OUTDIR := out
RESOURCES := res
SOURCES := src src/hos src/i2c src/ipc src/board src/display src/tsensor src/mgr src/file src/soc src/mapping src/pwr src/util
SOURCES := src src/hos src/i2c src/ipc src/board src/display src/tsensor src/mgr src/file src/soc src/mapping src/pwr src/util ../common/src
DATA := data
INCLUDES := ../common/include src/hos src/soc src/i2c src/util src/pwr src/ipc
EXEFS_SRC := exefs_src
@@ -28,7 +28,7 @@
#include <i2c.h>
#include <max17050.h>
#include <switch.h>
#include <t210.h>
#include <t210.hpp>
#include <tmp451.h>
#include "../display/display_refresh_rate.hpp"
@@ -42,6 +42,7 @@
#include "board_name.hpp"
#include <ipc_server.h>
#include <lockable_mutex.h>
#include <switch.hpp>
namespace board {
static u32 currentInjectedHz = 0;
@@ -67,18 +68,18 @@ namespace board {
PcvModuleId GetPcvModuleId(HocClkModule hocclkModule) {
PcvModuleId pcvModuleId;
Result rc = pcvGetModuleId(&pcvModuleId, GetPcvModule(hocclkModule));
Result rc = nx::pcv::GetModuleId(&pcvModuleId, GetPcvModule(hocclkModule));
ASSERT_RESULT_OK(rc, "pcvGetModuleId");
return pcvModuleId;
}
void ClkrstSetHz(ClkrstSession &session, u32 hz) {
ASSERT_RESULT_OK(clkrstSetClockRate(&session, hz), "clkrstSetClockRate");
ASSERT_RESULT_OK(nx::clkrst::SetClockRate(&session, hz), "clkrstSetClockRate");
}
void PcvSetHz(PcvModule moduleID, u32 hz) {
ASSERT_RESULT_OK(pcvSetClockRate(moduleID, hz), "pcvSetClockRate");
ASSERT_RESULT_OK(nx::pcv::SetClockRate(moduleID, hz), "pcvSetClockRate");
}
void HandleCpuUv() {
@@ -112,22 +113,22 @@ namespace board {
if (HOSSVC_HAS_CLKRST) {
ClkrstSession session = {};
rc = clkrstOpenSession(&session, GetPcvModuleId(module), 3);
rc = nx::clkrst::OpenSession(&session, GetPcvModuleId(module), 3);
ASSERT_RESULT_OK(rc, "clkrstOpenSession");
ClkrstSetHz(session, pcvHz);
/* Voltage bug workaround. */
if (module == HocClkModule_CPU) {
svcSleepThread(300'000);
nx::svc::SleepThread(300'000);
ClkrstSetHz(session, pcvHz);
}
clkrstCloseSession(&session);
nx::clkrst::CloseSession(&session);
} else {
PcvSetHz(GetPcvModule(module), pcvHz);
if (module == HocClkModule_CPU) {
svcSleepThread(300'000);
nx::svc::SleepThread(300'000);
PcvSetHz(GetPcvModule(module), pcvHz);
}
}
@@ -33,8 +33,9 @@
#include <minIni.h>
#include <numeric>
#include <switch.h>
#include <t210.h>
#include <t210.hpp>
#include <tmp451.h>
#include <switch.hpp>
#include "../hos/apm_ext.h"
#include "board.hpp"
@@ -74,7 +75,7 @@ namespace board {
gpu_load_array[i++ % gpu_samples_average] = temp;
gpuLoad = std::accumulate(&gpu_load_array[0], &gpu_load_array[gpu_samples_average], 0) / gpu_samples_average;
}
svcSleepThread(16'666'000); // wait a bit (this is the perfect amount of time to keep the reading accurate)
nx::svc::SleepThread(16'666'000); // wait a bit (this is the perfect amount of time to keep the reading accurate)
} while (true);
}
@@ -27,6 +27,8 @@
#include <cmath>
#include <pwm.h>
#include <switch.h>
#include <hocclk.h>
#include <switch.hpp>
namespace board {
@@ -50,7 +52,7 @@ namespace board {
}
fanLevel = static_cast<u8>(rotationDuty);
svcSleepThread(300'000'000);
nx::svc::SleepThread(300'000'000);
}
}
@@ -53,7 +53,7 @@ namespace board {
u32 gDramMr4Tick = DramMr4PollDivisor;
s32 gDramMr4Millis = 30000; /* 4x refresh default */
s32 PollDramMr4TempMilli() {
[[maybe_unused]] s32 PollDramMr4TempMilli() {
u8 mr4 = 0;
if (!soc::ReadRamMr4(&mr4))
return 0; /* stock exosphere */
@@ -657,7 +657,7 @@ namespace board {
constexpr u32 KNOWN_GOOD_WAR_FREQUENCY = 1'785'000'000;
u32 hz = board::GetHz(HocClkModule_CPU);
board::SetHz(HocClkModule_CPU, KNOWN_GOOD_WAR_FREQUENCY);
svcSleepThread(5'000'000);
nx::svc::SleepThread(5'000'000);
board::SetHz(HocClkModule_CPU, hz);
}
@@ -19,6 +19,7 @@
#include "aula.hpp"
#include "common.hpp"
#include <switch.hpp>
// I *think* HOS changes this in some ways, so look into it more
@@ -31,7 +32,7 @@ namespace display {
DSI(DSI_TRIGGER) = DSI_TRIGGER_HOST;
if (wait)
svcSleepThread(wait * 1000); // usleep-equivalant
nx::svc::SleepThread(wait * 1000); // usleep-equivalant
}
void SetDisplayColorMode(AulaColorMode mode) {
@@ -15,6 +15,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <switch.hpp>
#ifndef _DI_H_
#define _DI_H_
@@ -19,8 +19,9 @@
#include <stdarg.h>
#include <string.h>
#include <switch.h>
#include <hocclk.h>
#include "display_refresh_rate.hpp"
#include <switch.hpp>
namespace display {
#define DSI_CLOCK_HZ 234000000llu
@@ -142,7 +143,7 @@ namespace display {
#define MIPI_DCS_PRIV_SM_SET_ELVSS 0xB1
dsi[DSI_VIDEO_MODE_CONTROL] = true;
svcSleepThread(20000000);
nx::svc::SleepThread(20000000);
dsi[DSI_WR_DATA] = MIPI_DSI_DCS_LONG_WRITE | (5 << 8);
dsi[DSI_WR_DATA] = 0x5A5A5AE2;
@@ -162,7 +163,7 @@ namespace display {
dsi[DSI_TRIGGER] = 0;
dsi[DSI_VIDEO_MODE_CONTROL] = false;
svcSleepThread(20000000);
nx::svc::SleepThread(20000000);
}
void SetDockedState(bool isDocked) {
g_config.isDocked = isDocked;
@@ -493,11 +494,11 @@ namespace display {
if (!g_config.displaySync) {
g_wasRetroSuperTurnedOff = false;
} else if (g_wasRetroSuperTurnedOff) {
svcSleepThread(2000000000);
nx::svc::SleepThread(2000000000);
g_wasRetroSuperTurnedOff = false;
}
svcSleepThread(1000000000);
nx::svc::SleepThread(1000000000);
uint32_t fd = 0;
if (nvOpen(&fd, "/dev/nvdisp-disp0")) {
@@ -693,7 +694,7 @@ namespace display {
_getDockedHighestRefreshRate(0);
g_canChangeRefreshRateDocked = true;
} else {
svcSleepThread(1000000000);
nx::svc::SleepThread(1000000000);
return false;
}
} else {
@@ -33,6 +33,7 @@
#include <switch.h>
#include <time.h>
#include <vector>
#include <switch.hpp>
#define FILE_CONFIG_DIR "/config/" CONFIG_DIR
#define FILE_CONTEXT_CSV_PATH FILE_CONFIG_DIR "/context.csv"
@@ -0,0 +1,53 @@
/*
* Copyright (c) Souldbminer, Lightos_ 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 <http://www.gnu.org/licenses/>.
*
*/
#include "clkrst_ext.hpp"
namespace hos::clkrst {
/// @brief Sets the minimum voltage for a session's module to the one required for @param hz. Does not work with cpu module
/// @param session A ClkrstSession pointer
/// @param hz The hz to set the vmin for
/// @return Result code
Result SetMinimumVoltageClockRate(ClkrstSession *session, u32 hz) {
return serviceDispatchIn(&session->s, 9, hz);
}
Result GetDvfsTable(ClkrstSession *session, u32 *out_rate_table, s32 in_rate_count, u32 *out_voltage_table, s32 in_voltage_count, s32 *out_count) {
const struct {
s32 rate_count;
s32 voltage_count;
} in = { in_rate_count, in_voltage_count };
s32 out = 0;
Result rc = serviceDispatchInOut(&session->s, 11, in, out,
.buffer_attrs = {
SfBufferAttr_Out | SfBufferAttr_HipcAutoSelect,
SfBufferAttr_Out | SfBufferAttr_HipcAutoSelect,
},
.buffers = {
{ out_rate_table, in_rate_count * sizeof(u32) },
{ out_voltage_table, in_voltage_count * sizeof(u32) },
},
);
if (R_SUCCEEDED(rc) && out_count) {
*out_count = out;
}
return rc;
}
} // namespace hos::clkrst
@@ -0,0 +1,24 @@
/*
* Copyright (c) Souldbminer, Lightos_ 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 <http://www.gnu.org/licenses/>.
*
*/
#include <hocclk.h>
#include <switch.h>
namespace hos::clkrst {
Result SetMinimumVoltageClockRate(ClkrstSession *session, u32 hz);
Result GetDvfsTable(ClkrstSession *session, u32 *out_rate_table, s32 in_rate_count, u32 *out_voltage_table, s32 in_voltage_count, s32 *out_count);
} // namespace hos::clkrst
@@ -20,6 +20,7 @@
#include "integrations.hpp"
#include "process_management.hpp"
#include <sys/stat.h>
#include <switch.hpp>
namespace hos {
@@ -41,7 +42,7 @@ namespace hos {
}
if (i == 66)
return false;
svcSleepThread(1'000'000);
nx::svc::SleepThread(1'000'000);
}
for (int i = 0; i < 67; i++) {
@@ -49,7 +50,7 @@ namespace hos {
svcCloseHandle(saltysd);
return true;
}
svcSleepThread(1'000'000);
nx::svc::SleepThread(1'000'000);
}
return false;
@@ -62,7 +62,7 @@ namespace hos {
u64 pid = 0;
do {
rc = pmdmntGetProcessId(&pid, Qlaunch);
svcSleepThread(50 * 1000000ULL); // 50ms
nx::svc::SleepThread(50 * 1000000ULL); // 50ms
} while (R_FAILED(rc));
}
+4 -3
View File
@@ -15,6 +15,7 @@
*
*/
#include "i2cDrv.h"
#include <switch.hpp>
Result I2cSet_U8(I2cDevice dev, u8 reg, u8 val) {
// ams::fatal::srv::StopSoundTask::StopSound()
@@ -133,7 +134,7 @@ u32 I2c_BuckConverter_GetMvOut(const I2c_BuckConverter_Domain *domain) {
return 0u;
// Wait 1us
svcSleepThread(1E3);
nx::svc::SleepThread(1E3);
if (!domain->por_val || val != domain->por_val)
break;
@@ -149,7 +150,7 @@ u32 I2c_BuckConverter_GetUvOut(const I2c_BuckConverter_Domain *domain) {
return 0u;
// Wait 1us
svcSleepThread(1E3);
nx::svc::SleepThread(1E3);
if (!domain->por_val || val != domain->por_val)
break;
@@ -172,7 +173,7 @@ Result I2c_BuckConverter_SetMvOut(const I2c_BuckConverter_Domain *domain, u32 mv
return res;
// 5ms Ramp delay
svcSleepThread(5E6);
nx::svc::SleepThread(5E6);
u8 new_val;
res = I2cRead_OutU8(domain->device, domain->reg, &new_val);
if (R_FAILED(res))
+1 -1
View File
@@ -6,7 +6,7 @@
#pragma once
#include <switch.h>
#include <hocclk.h>
// To use i2c service, sm and i2c should be intialized via smInitialize() and i2cInitialize().
Result I2cSet_U8(I2cDevice dev, u8 reg, u8 val);
+2 -2
View File
@@ -28,7 +28,7 @@
#include <cstring>
#include <malloc.h>
#include <switch.h>
#include <switch.hpp>
#include "board/board.hpp"
#include "file/config.hpp"
#include "file/errors.hpp"
@@ -156,7 +156,7 @@ int main(int argc, char **argv) {
board::Exit();
file::config::Exit();
file::utils::LogLine("Exiting hoc-clk");
svcSleepThread(1000000ULL);
nx::svc::SleepThread(1000000ULL);
file::utils::Exit();
return 0;
@@ -45,7 +45,8 @@
#include "clock_manager.hpp"
#include "governor.hpp"
#include "../i2c/max77620_wdt.hpp"
#include "../hos/clkrst_ext.hpp"
#include <switch.hpp>
#define HOSPPC_HAS_BOOST (hosversionAtLeast(7, 0, 0))
@@ -868,6 +869,7 @@ namespace mgr {
}
mgr::StartThreads();
}
void Exit() {
@@ -914,6 +916,6 @@ namespace mgr {
void WaitForNextTick() {
i2c::wdt::Pet();
svcSleepThread(file::config::GetConfigValue(HocClkConfigValue_PollingIntervalMs) * 1000000ULL);
nx::svc::SleepThread(file::config::GetConfigValue(HocClkConfigValue_PollingIntervalMs) * 1000000ULL);
}
} // namespace mgr
@@ -140,7 +140,7 @@ namespace mgr {
cpuLastHz = 0;
gpuDownHoldRemaining = 0;
gpuLastHz = 0;
svcSleepThread(pollNs);
nx::svc::SleepThread(pollNs);
continue;
}
@@ -302,14 +302,14 @@ namespace mgr {
if (++vrrTick > 50) {
vrrTick = 0;
board::SetHz(HocClkModule_Display, maxDisplay);
svcSleepThread(50'000'000);
nx::svc::SleepThread(50'000'000);
}
}
}
}
}
svcSleepThread(pollNs);
nx::svc::SleepThread(pollNs);
}
}
@@ -17,11 +17,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "t210.h"
#include "t210.hpp"
#include <hocclk.h>
#include <switch.hpp>
#define WAIT_NS 1000000000UL
#define usleep(x) svcSleepThread(1000UL * x)
#define usleep(x) (nx::svc::SleepThread(1000UL * x))
#define GPU_TRIM_SYS_GPCPLL_COEFF 0x4
#define GPU_TRIM_SYS_GPCPLL(x) (*(volatile u32 *)(g_gpu_base + 0x137000ul + (x)))
@@ -505,7 +505,7 @@ namespace tsensor {
}
/* Wait for HW recalibration */
svcSleepThread(25'000);
nx::svc::SleepThread(25'000);
temps.cpu = TranslateTemp(ReadReg(socthermVa, SENSOR_TEMP1) >> 16);
temps.gpu = TranslateTemp(ReadReg(socthermVa, SENSOR_TEMP1) & SENSOR_TEMP1_GPU_TEMP_MASK);
@@ -528,7 +528,7 @@ namespace tsensor {
WriteReg(carVa, CAR_CLK_SOURCE_TSENSOR, CAR_CLK_SOURCE_TSENSOR_VAL);
SetBits(carVa, CAR_CLK_OUT_ENB_V, 0x10);
svcSleepThread(2000);
nx::svc::SleepThread(2000);
TSensorSharedCalib sharedCal = {};
CalcSharedCal(&tfuse, &sharedCal, fuseVa);