hoc-clk: add reversenx sync
This commit is contained in:
36
Source/sys-clk/common/include/cpp_util.hpp
Normal file
36
Source/sys-clk/common/include/cpp_util.hpp
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
class ScopeGuard {
|
||||||
|
public:
|
||||||
|
ScopeGuard(F&& f)
|
||||||
|
: f(f), engaged(true) {};
|
||||||
|
|
||||||
|
~ScopeGuard() {
|
||||||
|
if (engaged)
|
||||||
|
f();
|
||||||
|
};
|
||||||
|
|
||||||
|
ScopeGuard(ScopeGuard&& rhs)
|
||||||
|
: f(std::move(rhs.f)) {};
|
||||||
|
|
||||||
|
void dismiss() { engaged = false; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
F f;
|
||||||
|
bool engaged;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MakeScopeExit {
|
||||||
|
template<typename F>
|
||||||
|
ScopeGuard<F> operator+=(F&& f) {
|
||||||
|
return ScopeGuard<F>(std::move(f));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#define STRING_CAT2(x, y) x##y
|
||||||
|
#define STRING_CAT(x, y) STRING_CAT2(x, y)
|
||||||
|
#define SCOPE_GUARD MakeScopeExit() += [&]() __attribute__((always_inline))
|
||||||
|
#define SCOPE_EXIT auto STRING_CAT(scope_exit_, __LINE__) = SCOPE_GUARD
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
#include "cpp_util.hpp"
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,15 @@ typedef enum
|
|||||||
SysClkRamLoad_EnumMax
|
SysClkRamLoad_EnumMax
|
||||||
} SysClkRamLoad;
|
} SysClkRamLoad;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ReverseNX_NotFound = 0,
|
||||||
|
ReverseNX_SystemDefault = 0,
|
||||||
|
ReverseNX_Handheld,
|
||||||
|
ReverseNX_Docked,
|
||||||
|
} ReverseNXMode;
|
||||||
|
|
||||||
|
|
||||||
#define SYSCLK_ENUM_VALID(n, v) ((v) < n##_EnumMax)
|
#define SYSCLK_ENUM_VALID(n, v) ((v) < n##_EnumMax)
|
||||||
|
|
||||||
static inline const char* sysclkFormatModule(SysClkModule module, bool pretty)
|
static inline const char* sysclkFormatModule(SysClkModule module, bool pretty)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ Result sysclkIpcSetProfiles(u64 tid, SysClkTitleProfileList* profiles);
|
|||||||
Result sysclkIpcGetConfigValues(SysClkConfigValueList* out_configValues);
|
Result sysclkIpcGetConfigValues(SysClkConfigValueList* out_configValues);
|
||||||
Result sysclkIpcSetConfigValues(SysClkConfigValueList* configValues);
|
Result sysclkIpcSetConfigValues(SysClkConfigValueList* configValues);
|
||||||
Result sysclkIpcGetFreqList(SysClkModule module, u32* list, u32 maxCount, u32* outCount);
|
Result sysclkIpcGetFreqList(SysClkModule module, u32* list, u32 maxCount, u32* outCount);
|
||||||
|
Result sysclkIpcSetReverseNXRTMode(ReverseNXMode mode);
|
||||||
|
|
||||||
static inline Result sysclkIpcRemoveOverride(SysClkModule module)
|
static inline Result sysclkIpcRemoveOverride(SysClkModule module)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ typedef enum {
|
|||||||
SysClkConfigValue_CsvWriteIntervalMs,
|
SysClkConfigValue_CsvWriteIntervalMs,
|
||||||
HocClkConfigValue_UncappedClocks,
|
HocClkConfigValue_UncappedClocks,
|
||||||
HocClkConfigValue_OverwriteBoostMode,
|
HocClkConfigValue_OverwriteBoostMode,
|
||||||
|
HocClkConfigValue_SyncReverseNXMode,
|
||||||
SysClkConfigValue_EnumMax,
|
SysClkConfigValue_EnumMax,
|
||||||
} SysClkConfigValue;
|
} SysClkConfigValue;
|
||||||
|
|
||||||
@@ -46,6 +47,8 @@ static inline const char* sysclkFormatConfigValue(SysClkConfigValue val, bool pr
|
|||||||
return pretty ? "Uncapped Clocks" : "uncapped_clocks";
|
return pretty ? "Uncapped Clocks" : "uncapped_clocks";
|
||||||
case HocClkConfigValue_OverwriteBoostMode:
|
case HocClkConfigValue_OverwriteBoostMode:
|
||||||
return pretty ? "Overwrite Boost Mode" : "ow_boost";
|
return pretty ? "Overwrite Boost Mode" : "ow_boost";
|
||||||
|
case HocClkConfigValue_SyncReverseNXMode:
|
||||||
|
return pretty ? "ReverseNX Sync" : "rnx_sync";
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -63,6 +66,7 @@ static inline uint64_t sysclkDefaultConfigValue(SysClkConfigValue val)
|
|||||||
case SysClkConfigValue_CsvWriteIntervalMs:
|
case SysClkConfigValue_CsvWriteIntervalMs:
|
||||||
case HocClkConfigValue_UncappedClocks:
|
case HocClkConfigValue_UncappedClocks:
|
||||||
case HocClkConfigValue_OverwriteBoostMode:
|
case HocClkConfigValue_OverwriteBoostMode:
|
||||||
|
case HocClkConfigValue_SyncReverseNXMode:
|
||||||
return 0ULL;
|
return 0ULL;
|
||||||
default:
|
default:
|
||||||
return 0ULL;
|
return 0ULL;
|
||||||
@@ -82,6 +86,7 @@ static inline uint64_t sysclkValidConfigValue(SysClkConfigValue val, uint64_t in
|
|||||||
return input >= 0;
|
return input >= 0;
|
||||||
case HocClkConfigValue_OverwriteBoostMode:
|
case HocClkConfigValue_OverwriteBoostMode:
|
||||||
case HocClkConfigValue_UncappedClocks:
|
case HocClkConfigValue_UncappedClocks:
|
||||||
|
case HocClkConfigValue_SyncReverseNXMode:
|
||||||
return (input & 0x1) == input;
|
return (input & 0x1) == input;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ enum SysClkIpcCmd
|
|||||||
SysClkIpcCmd_GetConfigValues = 9,
|
SysClkIpcCmd_GetConfigValues = 9,
|
||||||
SysClkIpcCmd_SetConfigValues = 10,
|
SysClkIpcCmd_SetConfigValues = 10,
|
||||||
SysClkIpcCmd_GetFreqList = 11,
|
SysClkIpcCmd_GetFreqList = 11,
|
||||||
|
SysClkIpcCmd_SetReverseNXRTMode = 12,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -126,3 +126,8 @@ Result sysclkIpcGetFreqList(SysClkModule module, u32* list, u32 maxCount, u32* o
|
|||||||
.buffers = {{list, maxCount * sizeof(u32)}},
|
.buffers = {{list, maxCount * sizeof(u32)}},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result sysclkIpcSetReverseNXRTMode(ReverseNXMode mode)
|
||||||
|
{
|
||||||
|
return serviceDispatchIn(&g_sysclkSrv, SysClkIpcCmd_SetReverseNXRTMode, mode);
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "ipc.h"
|
#include "ipc.h"
|
||||||
|
|
||||||
#if defined(__SWITCH__) && defined(__cplusplus)
|
#if defined(__SWITCH__) && defined(__cplusplus)
|
||||||
|
#include "cpp_util.hpp"
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
|
#include "cpp_util.hpp"
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ void MiscGui::listUI()
|
|||||||
this->listElement->addItem(new tsl::elm::CategoryHeader("Config"));
|
this->listElement->addItem(new tsl::elm::CategoryHeader("Config"));
|
||||||
addConfigToggle(HocClkConfigValue_UncappedClocks);
|
addConfigToggle(HocClkConfigValue_UncappedClocks);
|
||||||
addConfigToggle(HocClkConfigValue_OverwriteBoostMode);
|
addConfigToggle(HocClkConfigValue_OverwriteBoostMode);
|
||||||
|
addConfigToggle(HocClkConfigValue_SyncReverseNXMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MiscGui::refresh() {
|
void MiscGui::refresh() {
|
||||||
|
|||||||
@@ -15,6 +15,30 @@
|
|||||||
#include "process_management.h"
|
#include "process_management.h"
|
||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
#include "ipc_service.h"
|
#include "ipc_service.h"
|
||||||
|
|
||||||
|
ClockManager* ClockManager::instance = NULL;
|
||||||
|
|
||||||
|
ClockManager* ClockManager::GetInstance()
|
||||||
|
{
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClockManager::Exit()
|
||||||
|
{
|
||||||
|
if(instance)
|
||||||
|
{
|
||||||
|
delete instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClockManager::Initialize()
|
||||||
|
{
|
||||||
|
if(!instance)
|
||||||
|
{
|
||||||
|
instance = new ClockManager();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ClockManager::ClockManager()
|
ClockManager::ClockManager()
|
||||||
{
|
{
|
||||||
this->config = Config::CreateDefault();
|
this->config = Config::CreateDefault();
|
||||||
@@ -34,6 +58,9 @@ ClockManager::ClockManager()
|
|||||||
this->running = false;
|
this->running = false;
|
||||||
this->lastTempLogNs = 0;
|
this->lastTempLogNs = 0;
|
||||||
this->lastCsvWriteNs = 0;
|
this->lastCsvWriteNs = 0;
|
||||||
|
|
||||||
|
this->rnxSync = new ReverseNXSync;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ClockManager::~ClockManager()
|
ClockManager::~ClockManager()
|
||||||
@@ -237,6 +264,8 @@ bool ClockManager::RefreshContext()
|
|||||||
FileUtils::LogLine("[mgr] TitleID change: %016lX", applicationId);
|
FileUtils::LogLine("[mgr] TitleID change: %016lX", applicationId);
|
||||||
this->context->applicationId = applicationId;
|
this->context->applicationId = applicationId;
|
||||||
hasChanged = true;
|
hasChanged = true;
|
||||||
|
this->rnxSync->Reset(applicationId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SysClkProfile profile = Board::GetProfile();
|
SysClkProfile profile = Board::GetProfile();
|
||||||
@@ -250,6 +279,7 @@ bool ClockManager::RefreshContext()
|
|||||||
// restore clocks to stock values on app or profile change
|
// restore clocks to stock values on app or profile change
|
||||||
if (hasChanged)
|
if (hasChanged)
|
||||||
{
|
{
|
||||||
|
this->rnxSync->ToggleSync(this->GetConfig()->GetConfigValue(HocClkConfigValue_SyncReverseNXMode));
|
||||||
Board::ResetToStock();
|
Board::ResetToStock();
|
||||||
this->WaitForNextTick();
|
this->WaitForNextTick();
|
||||||
}
|
}
|
||||||
@@ -347,3 +377,7 @@ bool ClockManager::RefreshContext()
|
|||||||
|
|
||||||
return hasChanged;
|
return hasChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClockManager::SetRNXRTMode(ReverseNXMode mode) {
|
||||||
|
this->rnxSync->SetRTMode(mode);
|
||||||
|
}
|
||||||
@@ -16,10 +16,18 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include <nxExt/cpp/lockable_mutex.h>
|
#include <nxExt/cpp/lockable_mutex.h>
|
||||||
|
#include "integrations.h"
|
||||||
|
|
||||||
|
class ReverseNXSync;
|
||||||
|
|
||||||
class ClockManager
|
class ClockManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static ClockManager* GetInstance();
|
||||||
|
static void Initialize();
|
||||||
|
static void Exit();
|
||||||
|
|
||||||
|
|
||||||
ClockManager();
|
ClockManager();
|
||||||
virtual ~ClockManager();
|
virtual ~ClockManager();
|
||||||
|
|
||||||
@@ -30,6 +38,7 @@ class ClockManager
|
|||||||
void GetFreqList(SysClkModule module, std::uint32_t* list, std::uint32_t maxCount, std::uint32_t* outCount);
|
void GetFreqList(SysClkModule module, std::uint32_t* list, std::uint32_t maxCount, std::uint32_t* outCount);
|
||||||
void Tick();
|
void Tick();
|
||||||
void WaitForNextTick();
|
void WaitForNextTick();
|
||||||
|
void SetRNXRTMode(ReverseNXMode mode);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool IsAssignableHz(SysClkModule module, std::uint32_t hz);
|
bool IsAssignableHz(SysClkModule module, std::uint32_t hz);
|
||||||
@@ -39,6 +48,8 @@ class ClockManager
|
|||||||
void RefreshFreqTableRow(SysClkModule module);
|
void RefreshFreqTableRow(SysClkModule module);
|
||||||
bool RefreshContext();
|
bool RefreshContext();
|
||||||
|
|
||||||
|
static ClockManager *instance;
|
||||||
|
|
||||||
std::atomic_bool running;
|
std::atomic_bool running;
|
||||||
LockableMutex contextMutex;
|
LockableMutex contextMutex;
|
||||||
struct {
|
struct {
|
||||||
@@ -51,4 +62,5 @@ class ClockManager
|
|||||||
std::uint64_t lastFreqLogNs;
|
std::uint64_t lastFreqLogNs;
|
||||||
std::uint64_t lastPowerLogNs;
|
std::uint64_t lastPowerLogNs;
|
||||||
std::uint64_t lastCsvWriteNs;
|
std::uint64_t lastCsvWriteNs;
|
||||||
|
ReverseNXSync *rnxSync;
|
||||||
};
|
};
|
||||||
|
|||||||
66
Source/sys-clk/sysmodule/src/integrations.cpp
Normal file
66
Source/sys-clk/sysmodule/src/integrations.cpp
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#include "integrations.h"
|
||||||
|
|
||||||
|
ReverseNXSync::ReverseNXSync()
|
||||||
|
: m_rt_mode(ReverseNX_NotFound), m_tool_mode(ReverseNX_NotFound) {
|
||||||
|
FILE *fp = fopen("/atmosphere/contents/0000000000534C56/flags/boot2.flag", "r");
|
||||||
|
m_tool_enabled = fp ? true : false;
|
||||||
|
if (fp)
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
SysClkProfile ReverseNXSync::GetProfile(SysClkProfile real) {
|
||||||
|
switch (this->GetMode()) {
|
||||||
|
case ReverseNX_Docked:
|
||||||
|
return SysClkProfile_Docked;
|
||||||
|
case ReverseNX_Handheld:
|
||||||
|
if (real == SysClkProfile_Docked)
|
||||||
|
return SysClkProfile_HandheldChargingOfficial;
|
||||||
|
default:
|
||||||
|
return real;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReverseNXMode ReverseNXSync::GetMode() {
|
||||||
|
if (!this->m_sync_enabled)
|
||||||
|
return ReverseNX_NotFound;
|
||||||
|
if (this->m_rt_mode)
|
||||||
|
return this->m_rt_mode;
|
||||||
|
return this->m_tool_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReverseNXMode ReverseNXSync::GetToolModeFromPatch(const char* patch_path) {
|
||||||
|
constexpr uint32_t DOCKED_MAGIC = 0x320003E0;
|
||||||
|
constexpr uint32_t HANDHELD_MAGIC = 0x52A00000;
|
||||||
|
FILE *fp = fopen(patch_path, "rb");
|
||||||
|
if (fp) {
|
||||||
|
uint32_t buf = 0;
|
||||||
|
fread(&buf, sizeof(buf), 1, fp);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
if (buf == DOCKED_MAGIC)
|
||||||
|
return ReverseNX_Docked;
|
||||||
|
if (buf == HANDHELD_MAGIC)
|
||||||
|
return ReverseNX_Handheld;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ReverseNX_NotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReverseNXMode ReverseNXSync::RecheckToolMode() {
|
||||||
|
ReverseNXMode mode = ReverseNX_NotFound;
|
||||||
|
if (this->m_tool_enabled) {
|
||||||
|
const char* fileName = "_ZN2nn2oe18GetPerformanceModeEv.asm64"; // or _ZN2nn2oe18GetPerformanceModeEv.asm64
|
||||||
|
const char* filePath = new char[72];
|
||||||
|
SCOPE_EXIT { delete[] filePath; };
|
||||||
|
/* Check per-game patch */
|
||||||
|
snprintf((char*)filePath, 72, "/SaltySD/patches/%016lX/%s", this->m_app_id, fileName);
|
||||||
|
mode = this->GetToolModeFromPatch(filePath);
|
||||||
|
if (!mode) {
|
||||||
|
/* Check global patch */
|
||||||
|
snprintf((char*)filePath, 72, "/SaltySD/patches/%s", fileName);
|
||||||
|
mode = this->GetToolModeFromPatch(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
33
Source/sys-clk/sysmodule/src/integrations.h
Normal file
33
Source/sys-clk/sysmodule/src/integrations.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <atomic>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <nxExt.h>
|
||||||
|
#include <sysclk.h>
|
||||||
|
#include <switch.h>
|
||||||
|
#include "errors.h"
|
||||||
|
#include "file_utils.h"
|
||||||
|
|
||||||
|
class ReverseNXSync {
|
||||||
|
public:
|
||||||
|
ReverseNXSync ();
|
||||||
|
|
||||||
|
void ToggleSync(bool enable) { m_sync_enabled = enable; };
|
||||||
|
void Reset(uint64_t app_id) { m_app_id = app_id; SetRTMode(ReverseNX_NotFound); GetToolMode(); }
|
||||||
|
ReverseNXMode GetRTMode() { return m_rt_mode; };
|
||||||
|
void SetRTMode(ReverseNXMode mode) { m_rt_mode = mode; };
|
||||||
|
ReverseNXMode GetToolMode() { return m_tool_mode = RecheckToolMode(); };
|
||||||
|
SysClkProfile GetProfile(SysClkProfile real);
|
||||||
|
ReverseNXMode GetMode();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::atomic<ReverseNXMode> m_rt_mode;
|
||||||
|
ReverseNXMode m_tool_mode;
|
||||||
|
uint64_t m_app_id = 0;
|
||||||
|
bool m_tool_enabled;
|
||||||
|
bool m_sync_enabled;
|
||||||
|
|
||||||
|
ReverseNXMode GetToolModeFromPatch(const char* patch_path);
|
||||||
|
ReverseNXMode RecheckToolMode();
|
||||||
|
};
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include "file_utils.h"
|
#include "file_utils.h"
|
||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
|
#include "clock_manager.h"
|
||||||
IpcService::IpcService(ClockManager* clockMgr)
|
IpcService::IpcService(ClockManager* clockMgr)
|
||||||
{
|
{
|
||||||
std::int32_t priority;
|
std::int32_t priority;
|
||||||
@@ -166,7 +166,12 @@ Result IpcService::ServiceHandlerFunc(void* arg, const IpcServerRequest* r, u8*
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SysClkIpcCmd_SetReverseNXRTMode:
|
||||||
|
if (r->data.size >= sizeof(ReverseNXMode)) {
|
||||||
|
ReverseNXMode mode = *((ReverseNXMode*)r->data.ptr);
|
||||||
|
return ipcSrv->SetReverseNXRTMode(mode);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SYSCLK_ERROR(Generic);
|
return SYSCLK_ERROR(Generic);
|
||||||
@@ -317,4 +322,9 @@ Result IpcService::GetFreqList(SysClkIpc_GetFreqList_Args* args, std::uint32_t*
|
|||||||
this->clockMgr->GetFreqList(args->module, out_list, args->maxCount, out_count);
|
this->clockMgr->GetFreqList(args->module, out_list, args->maxCount, out_count);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result IpcService::SetReverseNXRTMode(ReverseNXMode mode) {
|
||||||
|
ClockManager::GetInstance()->SetRNXRTMode(mode);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ class IpcService
|
|||||||
Result GetConfigValues(SysClkConfigValueList* out_configValues);
|
Result GetConfigValues(SysClkConfigValueList* out_configValues);
|
||||||
Result SetConfigValues(SysClkConfigValueList* configValues);
|
Result SetConfigValues(SysClkConfigValueList* configValues);
|
||||||
Result GetFreqList(SysClkIpc_GetFreqList_Args* args, std::uint32_t* out_list, std::size_t size, std::uint32_t* out_count);
|
Result GetFreqList(SysClkIpc_GetFreqList_Args* args, std::uint32_t* out_list, std::size_t size, std::uint32_t* out_count);
|
||||||
|
Result SetReverseNXRTMode(ReverseNXMode mode);
|
||||||
|
|
||||||
bool running;
|
bool running;
|
||||||
Thread thread;
|
Thread thread;
|
||||||
|
|||||||
Reference in New Issue
Block a user