From 6720355dd10e862ea7b17a12aaa6fd159fbb0118 Mon Sep 17 00:00:00 2001 From: plutoo Date: Thu, 11 Jan 2018 22:59:29 +0100 Subject: [PATCH] Bringup loader config block parsing Not tested yet --- crt0/switch_crt0.s | 6 ++- nx/include/switch.h | 2 + nx/include/switch/runtime/env.h | 5 ++ nx/source/runtime/env.c | 91 +++++++++++++++++++++++++++++++++ nx/source/runtime/init.c | 7 +-- nx/source/runtime/newlib.c | 4 +- 6 files changed, 108 insertions(+), 7 deletions(-) create mode 100644 nx/include/switch/runtime/env.h create mode 100644 nx/source/runtime/env.c diff --git a/crt0/switch_crt0.s b/crt0/switch_crt0.s index 88a6061f..7a8fd932 100644 --- a/crt0/switch_crt0.s +++ b/crt0/switch_crt0.s @@ -12,7 +12,8 @@ startup: bl +4 sub x28, x30, #0x84 - // save main thread handle + // save context ptr and main thread handle + mov x26, x0 mov x27, x1 // clear .bss @@ -36,7 +37,8 @@ bss_loop: bl __nx_dynamic // initialize system - mov x0, x27 + mov x0, x26 + mov x1, x27 bl __libnx_init // call entrypoint diff --git a/nx/include/switch.h b/nx/include/switch.h index 01c01e27..b0face39 100644 --- a/nx/include/switch.h +++ b/nx/include/switch.h @@ -44,6 +44,8 @@ extern "C" { #include #include +#include + #include #include diff --git a/nx/include/switch/runtime/env.h b/nx/include/switch/runtime/env.h new file mode 100644 index 00000000..2af06ebc --- /dev/null +++ b/nx/include/switch/runtime/env.h @@ -0,0 +1,5 @@ +// Copyright 2018 plutoo + +void envParse(void* ctx, Handle main_thread); +Handle envGetMainThreadHandle(void); +bool envIsNso(void); diff --git a/nx/source/runtime/env.c b/nx/source/runtime/env.c new file mode 100644 index 00000000..70a5afa7 --- /dev/null +++ b/nx/source/runtime/env.c @@ -0,0 +1,91 @@ +// Copyright 2018 plutoo +#include + +static bool g_isNso = false; +static Handle g_mainThreadHandle = INVALID_HANDLE; +static void* g_loaderRetAddr = NULL; +static void* g_overrideHeapAddr = NULL; +static u64 g_overrideHeapSize = 0; + +typedef struct { + u32 Key; + u32 Flags; + u64 Value[2]; +} ConfigEntry; + +enum { + EntryType_EndOfList=0, + EntryType_MainThreadHandle=1, + EntryType_LoaderReturnAddr=2, + EntryType_OverrideHeap=3, + EntryType_OverrideService=4, + EntryType_Argv=5, + EntryType_SyscallAvailableHint=6, + EntryType_AppletType=7 +}; + +void envParse(void* ctx, Handle main_thread) +{ + if (main_thread != INVALID_HANDLE) + { + g_mainThreadHandle = main_thread; + g_isNso = true; + return; + } + + ConfigEntry* ent = ctx; + + while (ent->Key != EntryType_EndOfList) + { + switch (ent->Key) + { + case EntryType_MainThreadHandle: + g_mainThreadHandle = ent->Value[0]; + break; + + case EntryType_LoaderReturnAddr: + g_loaderRetAddr = (void*) ent->Value[0]; + break; + + case EntryType_OverrideHeap: + g_overrideHeapAddr = (void*) ent->Value[0]; + g_overrideHeapSize = ent->Value[1]; + break; + + case EntryType_OverrideService: + // TODO + break; + + case EntryType_Argv: + // TODO + break; + + case EntryType_SyscallAvailableHint: + // TODO + break; + + case EntryType_AppletType: + // TODO + break; + + default: + // TODO + break; + } + + ent++; + } + +} + +Handle envGetMainThreadHandle(void) { + if (g_mainThreadHandle != INVALID_HANDLE) { + return g_mainThreadHandle; + } + + fatalSimple(1); +} + +bool envIsNso(void) { + return g_isNso; +} diff --git a/nx/source/runtime/init.c b/nx/source/runtime/init.c index 5bb76df2..1ff19801 100644 --- a/nx/source/runtime/init.c +++ b/nx/source/runtime/init.c @@ -3,7 +3,7 @@ void __nx_exit(int rc); void virtmemSetup(void); -void newlibSetup(Handle main_thread); +void newlibSetup(void); void __system_initArgv(void); @@ -53,12 +53,13 @@ void __attribute__((weak)) __appExit(void) smExit(); } -void __attribute__((weak)) __libnx_init(Handle main_thread) +void __attribute__((weak)) __libnx_init(void* ctx, Handle main_thread) { // Called by crt0. // Libnx initialization goes here. - newlibSetup(main_thread); + envParse(ctx, main_thread); + newlibSetup(); virtmemSetup(); __libnx_initheap(); diff --git a/nx/source/runtime/newlib.c b/nx/source/runtime/newlib.c index bf1f05ab..d67541c5 100644 --- a/nx/source/runtime/newlib.c +++ b/nx/source/runtime/newlib.c @@ -18,7 +18,7 @@ static struct _reent* __libnx_get_reent(void) { return tv->reent; } -void newlibSetup(Handle main_thread) { +void newlibSetup() { // Register newlib syscalls __syscalls.exit = __libnx_exit; __syscalls.getreent = __libnx_get_reent; @@ -39,7 +39,7 @@ void newlibSetup(Handle main_thread) { tv->thread_ptr = NULL; tv->reent = _impure_ptr; tv->tls_tp = __tls_start-2*sizeof(void*); // subtract size of Thread Control Block (TCB) - tv->handle = main_thread; + tv->handle = envGetMainThreadHandle(); u32 tls_size = __tdata_lma_end - __tdata_lma; if (tls_size)