From af67b4adb12f69027bd4532a46f97959fb2ab1cd Mon Sep 17 00:00:00 2001 From: plutooo Date: Sun, 17 Feb 2019 15:17:33 +0100 Subject: [PATCH] hosversion: Suggestion for tristate properly handle error scenarios --- nx/include/switch/runtime/hosversion.h | 37 +++++++++++++++----------- nx/source/applets/swkbd.c | 3 ++- nx/source/runtime/hosversion.c | 34 ++++++++++++++++++----- nx/source/runtime/init.c | 2 +- nx/source/services/audren.c | 7 ++--- 5 files changed, 56 insertions(+), 27 deletions(-) diff --git a/nx/include/switch/runtime/hosversion.h b/nx/include/switch/runtime/hosversion.h index f426ade8..8860a07c 100644 --- a/nx/include/switch/runtime/hosversion.h +++ b/nx/include/switch/runtime/hosversion.h @@ -19,24 +19,31 @@ /// Extracts the micro number from a HOS version value. #define HOSVER_MICRO(_version) ( (_version) & 0xFF) -/// Returns the current HOS version. Normally, this matches the version returned by \ref setsysGetFirmwareVersion or, if set:sys is not available, the version detected by \ref detectKernelVersion. -u32 hosversionGet(void); - -/// Sets or overrides the current HOS version. This function is normally called automatically by libnx on startup. +void hosversionSetup(void); void hosversionSet(u32 version); -/// Returns true if the current HOS version is equal to or above the specified major/minor/micro version. -static inline bool hosversionAtLeast(u8 major, u8 minor, u8 micro) { - return hosversionGet() >= MAKEHOSVERSION(major,minor,micro); +typedef enum { + CompareResult_False, + CompareResult_True, + CompareResult_Unknown +} CompareResult; + +CompareResult cmpresNot(CompareResult in) { + // Does a not-operation. True maps to False, False maps to True. Unknown maps to Unknown. + switch (in) { + case CompareResult_False: + return CompareResult_True; + case CompareResult_True: + return CompareResult_False; + default: + return CompareResult_Unknown; + } } +/// Returns true if the current HOS version is equal to or above the specified major/minor/micro version. +CompareResult hosversionAtLeast(u8 major, u8 minor, u8 micro); + /// Returns true if the current HOS version is earlier than the specified major/minor/micro version. -static inline bool hosversionBefore(u8 major, u8 minor, u8 micro) { - return !hosversionAtLeast(major, minor, micro); -} - -/// Returns true if the current HOS version is between the two specified major versions, i.e. [major1, major2). -static inline bool hosversionBetween(u8 major1, u8 major2) { - u32 ver = hosversionGet(); - return ver >= MAKEHOSVERSION(major1,0,0) && ver < MAKEHOSVERSION(major2,0,0); +static inline CompareResult hosversionBefore(u8 major, u8 minor, u8 micro) { + return cmpresNot(hosversionAtLeast(major, minor, micro)); } diff --git a/nx/source/applets/swkbd.c b/nx/source/applets/swkbd.c index 7088e82f..827eb765 100644 --- a/nx/source/applets/swkbd.c +++ b/nx/source/applets/swkbd.c @@ -51,6 +51,7 @@ static void _swkbdConfigClear(SwkbdConfig* c) { } static void _swkbdInitVersion(u32* version) { + /* u32 hosver = hosversionGet(); if (hosver >= MAKEHOSVERSION(5,0,0)) *version = 0x50009; @@ -60,7 +61,7 @@ static void _swkbdInitVersion(u32* version) { *version = 0x30007; else if (hosver >= MAKEHOSVERSION(2,0,0)) *version = 0x10006; - else + else*/ *version=0x5;//1.0.0+ version } diff --git a/nx/source/runtime/hosversion.c b/nx/source/runtime/hosversion.c index 5bffb725..b393fb2c 100644 --- a/nx/source/runtime/hosversion.c +++ b/nx/source/runtime/hosversion.c @@ -1,13 +1,33 @@ #include "runtime/hosversion.h" +#include "kernel/detect.h" -static u32 g_hosVersion; +static u32 g_hosVersionKernelLowerBound; +static bool g_hasKernelLowerBound; -u32 hosversionGet(void) -{ - return __atomic_load_n(&g_hosVersion, __ATOMIC_SEQ_CST); +static u32 g_hosVersionExact; +static bool g_hasExact; + + +void hosversionSetup(void) { + g_hosVersionKernelLowerBound = MAKEHOSVERSION(detectKernelVersion(), 0, 0); + g_hasKernelLowerBound = true; } -void hosversionSet(u32 version) -{ - __atomic_store_n(&g_hosVersion, version, __ATOMIC_SEQ_CST); +void hosversionSet(u32 version) { + g_hosVersionExact = version; + g_hasExact = true; +} + +CompareResult hosversionAtLeast(u8 major, u8 minor, u8 micro) +{ + if (g_hasExact) { + return (MAKEHOSVERSION(major, minor, micro) <= g_hosVersionExact) ? CompareResult_True : CompareResult_False; + } + + if (g_hasKernelLowerBound) { + if (MAKEHOSVERSION(major, minor, micro) <= g_hosVersionKernelLowerBound) + return CompareResult_True; + } + + return CompareResult_Unknown; } diff --git a/nx/source/runtime/init.c b/nx/source/runtime/init.c index b8cb9cc7..276ca260 100644 --- a/nx/source/runtime/init.c +++ b/nx/source/runtime/init.c @@ -168,7 +168,7 @@ void __attribute__((weak)) __libnx_init(void* ctx, Handle main_thread, void* sav // Libnx initialization goes here. envSetup(ctx, main_thread, saved_lr); - hosversionSet(MAKEHOSVERSION(detectKernelVersion(), 0, 0)); + hosversionSetup(); newlibSetup(); virtmemSetup(); __libnx_initheap(); diff --git a/nx/source/services/audren.c b/nx/source/services/audren.c index a03f8124..82818a0b 100644 --- a/nx/source/services/audren.c +++ b/nx/source/services/audren.c @@ -56,12 +56,13 @@ Result audrenInitialize(const AudioRendererConfig* config) return MAKERESULT(Module_Libnx, LibnxError_BadInput); // Choose revision (i.e. if splitters are used then at least revision 2 must be used) + /* u32 hosver = hosversionGet(); - /*if (hosver >= MAKEHOSVERSION(6,1,0)) + if (hosver >= MAKEHOSVERSION(6,1,0)) g_audrenRevision = AUDREN_REVISION_6; else if (hosver >= MAKEHOSVERSION(6,0,0)) g_audrenRevision = AUDREN_REVISION_5; - else*/ if (hosver >= MAKEHOSVERSION(4,0,0)) + else if (hosver >= MAKEHOSVERSION(4,0,0)) g_audrenRevision = AUDREN_REVISION_4; else if (hosver >= MAKEHOSVERSION(3,0,0)) g_audrenRevision = AUDREN_REVISION_3; @@ -69,7 +70,7 @@ Result audrenInitialize(const AudioRendererConfig* config) g_audrenRevision = AUDREN_REVISION_2; else g_audrenRevision = AUDREN_REVISION_1; - +*/ // Prepare parameter structure AudioRendererParameter param = {0}; param.sample_rate = config->output_rate == AudioRendererOutputRate_32kHz ? 32000 : 48000;