mirror of
https://github.com/switchbrew/libnx.git
synced 2025-07-05 10:52:15 +02:00
hosversion: Attempt a non-tristate solution
This commit is contained in:
parent
371b164e79
commit
848a5c3ad9
@ -6,9 +6,14 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../types.h"
|
#include "../types.h"
|
||||||
|
#include "../runtime/hosversion.h"
|
||||||
|
|
||||||
|
/// Returns the lowest known kernel version that is compatible with observation.
|
||||||
|
u32 detectKernelVersion(void);
|
||||||
|
|
||||||
|
/// Returns the highest possible known kernel version that is compatible with observation.
|
||||||
|
u32 detectKernelVersionUpperBound(void);
|
||||||
|
|
||||||
/// Returns the kernel version that can be detected by checking kernel capabilities. This only goes from 1 (representing 1.0.0) up to 6 (representing 6.0.0 and above). Generally, \ref hosversionGet should be used instead of this function.
|
|
||||||
int detectKernelVersion(void);
|
|
||||||
/// Returns true if the process has a debugger attached.
|
/// Returns true if the process has a debugger attached.
|
||||||
bool detectDebugger(void);
|
bool detectDebugger(void);
|
||||||
/// Returns true if the kernel is patched to allow self-process-jit.
|
/// Returns true if the kernel is patched to allow self-process-jit.
|
||||||
@ -18,25 +23,25 @@ void detectIgnoreJitKernelPatch(void);
|
|||||||
|
|
||||||
/// Returns true if the kernel version is equal to or above 2.0.0. Generally, \ref hosversionAtLeast should be used instead of this function.
|
/// Returns true if the kernel version is equal to or above 2.0.0. Generally, \ref hosversionAtLeast should be used instead of this function.
|
||||||
static inline bool kernelAbove200(void) {
|
static inline bool kernelAbove200(void) {
|
||||||
return detectKernelVersion() >= 2;
|
return detectKernelVersion() >= MAKEHOSVERSION(2,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the kernel version is equal to or above 3.0.0. Generally, \ref hosversionAtLeast should be used instead of this function.
|
/// Returns true if the kernel version is equal to or above 3.0.0. Generally, \ref hosversionAtLeast should be used instead of this function.
|
||||||
static inline bool kernelAbove300(void) {
|
static inline bool kernelAbove300(void) {
|
||||||
return detectKernelVersion() >= 3;
|
return detectKernelVersion() >= MAKEHOSVERSION(3,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the kernel version is equal to or above 4.0.0. Generally, \ref hosversionAtLeast should be used instead of this function.
|
/// Returns true if the kernel version is equal to or above 4.0.0. Generally, \ref hosversionAtLeast should be used instead of this function.
|
||||||
static inline bool kernelAbove400(void) {
|
static inline bool kernelAbove400(void) {
|
||||||
return detectKernelVersion() >= 4;
|
return detectKernelVersion() >= MAKEHOSVERSION(4,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the kernel version is equal to or above 5.0.0. Generally, \ref hosversionAtLeast should be used instead of this function.
|
/// Returns true if the kernel version is equal to or above 5.0.0. Generally, \ref hosversionAtLeast should be used instead of this function.
|
||||||
static inline bool kernelAbove500(void) {
|
static inline bool kernelAbove500(void) {
|
||||||
return detectKernelVersion() >= 5;
|
return detectKernelVersion() >= MAKEHOSVERSION(5,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the kernel version is equal to or above 6.0.0. Generally, \ref hosversionAtLeast should be used instead of this function.
|
/// Returns true if the kernel version is equal to or above 6.0.0. Generally, \ref hosversionAtLeast should be used instead of this function.
|
||||||
static inline bool kernelAbove600(void) {
|
static inline bool kernelAbove600(void) {
|
||||||
return detectKernelVersion() >= 6;
|
return detectKernelVersion() >= MAKEHOSVERSION(6,0,0);
|
||||||
}
|
}
|
||||||
|
@ -19,24 +19,18 @@
|
|||||||
/// Extracts the micro number from a HOS version value.
|
/// Extracts the micro number from a HOS version value.
|
||||||
#define HOSVER_MICRO(_version) ( (_version) & 0xFF)
|
#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.
|
void hosversionSetup(void);
|
||||||
u32 hosversionGet(void);
|
|
||||||
|
|
||||||
/// Sets or overrides the current HOS version. This function is normally called automatically by libnx on startup.
|
/// Sets or overrides the current HOS version. This function is normally called automatically by libnx on startup.
|
||||||
void hosversionSet(u32 version);
|
void hosversionSet(u32 version);
|
||||||
|
|
||||||
/// Returns true if the current HOS version is equal to or above the specified major/minor/micro 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) {
|
bool hosversionAtLeast(u8 major, u8 minor, u8 micro);
|
||||||
return hosversionGet() >= MAKEHOSVERSION(major,minor,micro);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if the current HOS version is earlier than the specified major/minor/micro version.
|
/// 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) {
|
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).
|
/// 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) {
|
static inline bool hosversionBetween(u8 major1, u8 major2) {
|
||||||
u32 ver = hosversionGet();
|
return hosversionAtLeast(major1, 0, 0) && hosversionBefore(major2, 0, 0);
|
||||||
return ver >= MAKEHOSVERSION(major1,0,0) && ver < MAKEHOSVERSION(major2,0,0);
|
|
||||||
}
|
}
|
||||||
|
@ -51,14 +51,13 @@ static void _swkbdConfigClear(SwkbdConfig* c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void _swkbdInitVersion(u32* version) {
|
static void _swkbdInitVersion(u32* version) {
|
||||||
u32 hosver = hosversionGet();
|
if (hosversionAtLeast(5,0,0))
|
||||||
if (hosver >= MAKEHOSVERSION(5,0,0))
|
|
||||||
*version = 0x50009;
|
*version = 0x50009;
|
||||||
else if (hosver >= MAKEHOSVERSION(4,0,0))
|
else if (hosversionAtLeast(4,0,0))
|
||||||
*version = 0x40008;
|
*version = 0x40008;
|
||||||
else if (hosver >= MAKEHOSVERSION(3,0,0))
|
else if (hosversionAtLeast(3,0,0))
|
||||||
*version = 0x30007;
|
*version = 0x30007;
|
||||||
else if (hosver >= MAKEHOSVERSION(2,0,0))
|
else if (hosversionAtLeast(2,0,0))
|
||||||
*version = 0x10006;
|
*version = 0x10006;
|
||||||
else
|
else
|
||||||
*version=0x5;//1.0.0+ version
|
*version=0x5;//1.0.0+ version
|
||||||
|
@ -4,12 +4,23 @@
|
|||||||
#include "kernel/detect.h"
|
#include "kernel/detect.h"
|
||||||
#include "kernel/mutex.h"
|
#include "kernel/mutex.h"
|
||||||
#include "kernel/svc.h"
|
#include "kernel/svc.h"
|
||||||
|
#include "runtime/hosversion.h"
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
static bool g_VersionCached;
|
static bool g_VersionCached;
|
||||||
static Mutex g_VersionMutex;
|
static Mutex g_VersionMutex;
|
||||||
static int g_Version;
|
static int g_Version;
|
||||||
|
|
||||||
|
static u32 g_VersionBounds[] = {
|
||||||
|
MAKEHOSVERSION(1,0,0),
|
||||||
|
MAKEHOSVERSION(2,0,0),
|
||||||
|
MAKEHOSVERSION(3,0,0),
|
||||||
|
MAKEHOSVERSION(4,0,0),
|
||||||
|
MAKEHOSVERSION(5,0,0),
|
||||||
|
MAKEHOSVERSION(6,0,0),
|
||||||
|
UINT32_MAX
|
||||||
|
};
|
||||||
|
|
||||||
static bool g_JitKernelPatchCached;
|
static bool g_JitKernelPatchCached;
|
||||||
static Mutex g_JitKernelPatchMutex;
|
static Mutex g_JitKernelPatchMutex;
|
||||||
static bool g_JitKernelPatchDetected;
|
static bool g_JitKernelPatchDetected;
|
||||||
@ -27,17 +38,17 @@ static void _CacheVersion(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
u64 tmp;
|
u64 tmp;
|
||||||
g_Version = 1;
|
g_Version = 0;
|
||||||
if (R_VALUE(svcGetInfo(&tmp, 12, INVALID_HANDLE, 0)) != KERNELRESULT(InvalidEnumValue))
|
if (R_VALUE(svcGetInfo(&tmp, 12, INVALID_HANDLE, 0)) != KERNELRESULT(InvalidEnumValue))
|
||||||
g_Version = 2;
|
g_Version = 1;
|
||||||
if (R_VALUE(svcGetInfo(&tmp, 18, INVALID_HANDLE, 0)) != KERNELRESULT(InvalidEnumValue))
|
if (R_VALUE(svcGetInfo(&tmp, 18, INVALID_HANDLE, 0)) != KERNELRESULT(InvalidEnumValue))
|
||||||
g_Version = 3;
|
g_Version = 2;
|
||||||
if (R_VALUE(svcGetInfo(&tmp, 19, INVALID_HANDLE, 0)) != KERNELRESULT(InvalidEnumValue))
|
if (R_VALUE(svcGetInfo(&tmp, 19, INVALID_HANDLE, 0)) != KERNELRESULT(InvalidEnumValue))
|
||||||
g_Version = 4;
|
g_Version = 3;
|
||||||
if (R_VALUE(svcGetInfo(&tmp, 20, INVALID_HANDLE, 0)) != KERNELRESULT(InvalidEnumValue))
|
if (R_VALUE(svcGetInfo(&tmp, 20, INVALID_HANDLE, 0)) != KERNELRESULT(InvalidEnumValue))
|
||||||
g_Version = 5;
|
g_Version = 4;
|
||||||
if (R_VALUE(svcGetInfo(&tmp, 21, INVALID_HANDLE, 0)) != KERNELRESULT(InvalidEnumValue))
|
if (R_VALUE(svcGetInfo(&tmp, 21, INVALID_HANDLE, 0)) != KERNELRESULT(InvalidEnumValue))
|
||||||
g_Version = 6;
|
g_Version = 5;
|
||||||
|
|
||||||
__atomic_store_n(&g_VersionCached, true, __ATOMIC_SEQ_CST);
|
__atomic_store_n(&g_VersionCached, true, __ATOMIC_SEQ_CST);
|
||||||
|
|
||||||
@ -81,9 +92,14 @@ static void _CacheJitKernelPatch(void)
|
|||||||
mutexUnlock(&g_JitKernelPatchMutex);
|
mutexUnlock(&g_JitKernelPatchMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
int detectKernelVersion(void) {
|
u32 detectKernelVersion(void) {
|
||||||
_CacheVersion();
|
_CacheVersion();
|
||||||
return g_Version;
|
return g_VersionBounds[g_Version];
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 detectKernelVersionUpperBound(void) {
|
||||||
|
_CacheVersion();
|
||||||
|
return g_VersionBounds[g_Version + 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool detectDebugger(void) {
|
bool detectDebugger(void) {
|
||||||
|
@ -1,13 +1,47 @@
|
|||||||
#include "runtime/hosversion.h"
|
#include "runtime/hosversion.h"
|
||||||
|
#include "kernel/detect.h"
|
||||||
|
#include "services/fatal.h"
|
||||||
|
|
||||||
|
static u32 g_kernelLowerBound;
|
||||||
|
static u32 g_kernelUpperBound;
|
||||||
|
|
||||||
static u32 g_hosVersion;
|
static u32 g_hosVersion;
|
||||||
|
static bool g_hasHosVersion;
|
||||||
|
|
||||||
u32 hosversionGet(void)
|
void hosversionSetup(void)
|
||||||
{
|
{
|
||||||
return __atomic_load_n(&g_hosVersion, __ATOMIC_SEQ_CST);
|
g_kernelLowerBound = detectKernelVersion();
|
||||||
|
g_kernelUpperBound = detectKernelVersionUpperBound();
|
||||||
}
|
}
|
||||||
|
|
||||||
void hosversionSet(u32 version)
|
void hosversionSet(u32 version)
|
||||||
{
|
{
|
||||||
__atomic_store_n(&g_hosVersion, version, __ATOMIC_SEQ_CST);
|
g_hosVersion = version;
|
||||||
|
g_hasHosVersion = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hosversionAtLeast(u8 major, u8 minor, u8 micro)
|
||||||
|
{
|
||||||
|
u32 ver = MAKEHOSVERSION(major, minor, micro);
|
||||||
|
|
||||||
|
if (g_hasHosVersion)
|
||||||
|
return g_hosVersion >= ver;
|
||||||
|
|
||||||
|
if (g_kernelLowerBound >= ver)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
fatalSimple(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hosversionBefore(u8 major, u8 minor, u8 micro)
|
||||||
|
{
|
||||||
|
u32 ver = MAKEHOSVERSION(major, minor, micro);
|
||||||
|
|
||||||
|
if (g_hasHosVersion)
|
||||||
|
return g_hosVersion < ver;
|
||||||
|
|
||||||
|
if (g_kernelUpperBound < ver)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
fatalSimple(-1);
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,7 @@ void __attribute__((weak)) __libnx_init(void* ctx, Handle main_thread, void* sav
|
|||||||
|
|
||||||
// Libnx initialization goes here.
|
// Libnx initialization goes here.
|
||||||
envSetup(ctx, main_thread, saved_lr);
|
envSetup(ctx, main_thread, saved_lr);
|
||||||
hosversionSet(MAKEHOSVERSION(detectKernelVersion(), 0, 0));
|
hosversionSetup();
|
||||||
newlibSetup();
|
newlibSetup();
|
||||||
virtmemSetup();
|
virtmemSetup();
|
||||||
__libnx_initheap();
|
__libnx_initheap();
|
||||||
|
@ -56,16 +56,15 @@ Result audrenInitialize(const AudioRendererConfig* config)
|
|||||||
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||||
|
|
||||||
// Choose revision (i.e. if splitters are used then at least revision 2 must be used)
|
// 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;
|
g_audrenRevision = AUDREN_REVISION_6;
|
||||||
else if (hosver >= MAKEHOSVERSION(6,0,0))
|
else if (hosver >= MAKEHOSVERSION(6,0,0))
|
||||||
g_audrenRevision = AUDREN_REVISION_5;
|
g_audrenRevision = AUDREN_REVISION_5;
|
||||||
else*/ if (hosver >= MAKEHOSVERSION(4,0,0))
|
else*/ if (hosversionAtLeast(4,0,0))
|
||||||
g_audrenRevision = AUDREN_REVISION_4;
|
g_audrenRevision = AUDREN_REVISION_4;
|
||||||
else if (hosver >= MAKEHOSVERSION(3,0,0))
|
else if (hosversionAtLeast(3,0,0))
|
||||||
g_audrenRevision = AUDREN_REVISION_3;
|
g_audrenRevision = AUDREN_REVISION_3;
|
||||||
else if (hosver >= MAKEHOSVERSION(2,0,0))
|
else if (hosversionAtLeast(2,0,0))
|
||||||
g_audrenRevision = AUDREN_REVISION_2;
|
g_audrenRevision = AUDREN_REVISION_2;
|
||||||
else
|
else
|
||||||
g_audrenRevision = AUDREN_REVISION_1;
|
g_audrenRevision = AUDREN_REVISION_1;
|
||||||
|
Loading…
Reference in New Issue
Block a user