mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-22 13:02:38 +02:00
Merge branch 'master' of https://gitlab.com/yellows8/libnx
This commit is contained in:
commit
4fd0989bf3
@ -1,5 +1,5 @@
|
|||||||
.section ".crt0","ax"
|
.section ".crt0","ax"
|
||||||
.global _start, _sysexit, main
|
.global _start
|
||||||
|
|
||||||
_start:
|
_start:
|
||||||
bl startup
|
bl startup
|
||||||
@ -40,7 +40,8 @@ got_loop:
|
|||||||
subs x1, x1, #8
|
subs x1, x1, #8
|
||||||
bne got_loop
|
bne got_loop
|
||||||
|
|
||||||
ldr x3, =heapSetup
|
mov x0, x28
|
||||||
|
ldr x3, =initSystem
|
||||||
add x3, x3, x28
|
add x3, x3, x28
|
||||||
blr x3
|
blr x3
|
||||||
|
|
||||||
@ -49,7 +50,8 @@ got_loop:
|
|||||||
|
|
||||||
ldr x3, =main
|
ldr x3, =main
|
||||||
add x3, x3, x28
|
add x3, x3, x28
|
||||||
blr x3
|
ldr x2, =__nx_exit
|
||||||
|
add x2, x2, x28
|
||||||
|
mov x30, x2
|
||||||
|
br x3
|
||||||
|
|
||||||
_sysexit:
|
|
||||||
svc 0x7
|
|
||||||
|
@ -24,7 +24,7 @@ VERSION := $(LIBNX_MAJOR).$(LIBNX_MINOR).$(LIBNX_PATCH)
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
TARGET := nx
|
TARGET := nx
|
||||||
#BUILD := build
|
#BUILD := build
|
||||||
SOURCES := source/kernel source/services source/heap
|
SOURCES := source/system source/kernel source/services source/heap
|
||||||
|
|
||||||
DATA := data
|
DATA := data
|
||||||
INCLUDES := include
|
INCLUDES := include
|
||||||
|
@ -18,16 +18,37 @@ static inline void* armGetTls(void) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _regs_t
|
||||||
|
{
|
||||||
|
u64 X0;
|
||||||
|
u64 X1;
|
||||||
|
u64 X2;
|
||||||
|
u64 X3;
|
||||||
|
u64 X4;
|
||||||
|
u64 X5;
|
||||||
|
u64 X6;
|
||||||
|
u64 X7;
|
||||||
|
} __attribute__((packed)) regs_t;
|
||||||
|
|
||||||
Result svcSetHeapSize(void** out_addr, u64 size);
|
Result svcSetHeapSize(void** out_addr, u64 size);
|
||||||
Result svcQueryMemory(u32 *meminfo_ptr, u32 *pageinfo, u64 addr);
|
Result svcQueryMemory(u32 *meminfo_ptr, u32 *pageinfo, u64 addr);
|
||||||
|
void svcExitProcess() __attribute__((noreturn));
|
||||||
|
Result svcSleepThread(u64 nano);
|
||||||
Result svcCloseHandle(Handle handle);
|
Result svcCloseHandle(Handle handle);
|
||||||
Result svcCreateTransferMemory(Handle* out, void* addr, size_t size, u32 perm);
|
Result svcCreateTransferMemory(Handle* out, void* addr, size_t size, u32 perm);
|
||||||
Result svcWaitSynchronization(s32* index, const Handle* handles, s32 handleCount, u64 timeout);
|
Result svcWaitSynchronization(s32* index, const Handle* handles, s32 handleCount, u64 timeout);
|
||||||
Result svcConnectToNamedPort(Handle* session, const char* name);
|
Result svcConnectToNamedPort(Handle* session, const char* name);
|
||||||
Result svcSendSyncRequest(Handle session);
|
Result svcSendSyncRequest(Handle session);
|
||||||
Result svcBreak(u32 breakReason, u64 inval1, u64 inval2);
|
Result svcBreak(u32 breakReason, u64 inval1, u64 inval2);
|
||||||
|
Result svcGetInfo(u64* out, u64 id0, Handle handle, u64 id1);
|
||||||
Result svcAcceptSession(Handle *session_handle, Handle port_handle);
|
Result svcAcceptSession(Handle *session_handle, Handle port_handle);
|
||||||
Result svcReplyAndReceive(s32* index, const Handle* handles, s32 handleCount, Handle replyTarget, u64 timeout);
|
Result svcReplyAndReceive(s32* index, const Handle* handles, s32 handleCount, Handle replyTarget, u64 timeout);
|
||||||
Result svcQueryPhysicalAddress(u64 out[3], u64 virtaddr);
|
Result svcQueryPhysicalAddress(u64 out[3], u64 virtaddr);
|
||||||
Result svcQueryIoMapping(u64* virtaddr, u64 physaddr, u64 size);
|
Result svcQueryIoMapping(u64* virtaddr, u64 physaddr, u64 size);
|
||||||
|
Result svcCreateDeviceAddressSpace(Handle *handle, u64 dev_addr, u64 dev_size);
|
||||||
|
Result svcAttachDeviceAddressSpace(u64 device, Handle handle);
|
||||||
|
Result svcDetachDeviceAddressSpace(u64 device, Handle handle);
|
||||||
|
Result svcMapDeviceAddressSpaceAligned(Handle handle, Handle proc_handle, u64 dev_addr, u64 dev_size, u64 map_addr, u64 perm);
|
||||||
|
Result svcUnmapDeviceAddressSpace(Handle handle, Handle proc_handle, u64 map_addr, u64 map_size, u64 perm);
|
||||||
|
u64 svcCallSecureMonitor(regs_t *regs);
|
||||||
Result svcManageNamedPort(Handle* portServer, const char* name, s32 maxSessions);
|
Result svcManageNamedPort(Handle* portServer, const char* name, s32 maxSessions);
|
||||||
|
@ -32,16 +32,18 @@ void heapInit(void* base, size_t size) {
|
|||||||
|
|
||||||
void heapSetup() {
|
void heapSetup() {
|
||||||
// Called by crt0.
|
// Called by crt0.
|
||||||
|
#define INNER_HEAP_SIZE 0x20000
|
||||||
|
#define OUTER_HEAP_SIZE (0x2000000*4)
|
||||||
|
|
||||||
void* addr;
|
void* addr;
|
||||||
Result rc = svcSetHeapSize(&addr, 0x2000000);
|
Result rc = svcSetHeapSize(&addr, OUTER_HEAP_SIZE);
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
heapInit(addr, 0x2000000);
|
heapInit(addr, OUTER_HEAP_SIZE);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#define HEAP_SIZE 0x20000
|
static u8 g_Heap[INNER_HEAP_SIZE];
|
||||||
static u8 g_Heap[HEAP_SIZE];
|
heapInit(&g_Heap[0], INNER_HEAP_SIZE);
|
||||||
heapInit(&g_Heap[0], HEAP_SIZE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
SVC_BEGIN svcSetHeapSize
|
SVC_BEGIN svcSetHeapSize
|
||||||
str x0, [sp, #-16]!
|
str x0, [sp, #-16]!
|
||||||
svc 1
|
svc 0x1
|
||||||
ldr x2, [sp], #16
|
ldr x2, [sp], #16
|
||||||
str x1, [x2]
|
str x1, [x2]
|
||||||
ret
|
ret
|
||||||
@ -27,6 +27,16 @@ SVC_BEGIN svcQueryMemory
|
|||||||
ret
|
ret
|
||||||
SVC_END
|
SVC_END
|
||||||
|
|
||||||
|
SVC_BEGIN svcExitProcess
|
||||||
|
svc 0x7
|
||||||
|
ret
|
||||||
|
SVC_END
|
||||||
|
|
||||||
|
SVC_BEGIN svcSleepThread
|
||||||
|
svc 0xB
|
||||||
|
ret
|
||||||
|
SVC_END
|
||||||
|
|
||||||
SVC_BEGIN svcCloseHandle
|
SVC_BEGIN svcCloseHandle
|
||||||
svc 0x16
|
svc 0x16
|
||||||
ret
|
ret
|
||||||
@ -50,7 +60,7 @@ SVC_END
|
|||||||
|
|
||||||
SVC_BEGIN svcConnectToNamedPort
|
SVC_BEGIN svcConnectToNamedPort
|
||||||
str x0, [sp, #-16]!
|
str x0, [sp, #-16]!
|
||||||
svc 0x1f
|
svc 0x1F
|
||||||
ldr x2, [sp], #16
|
ldr x2, [sp], #16
|
||||||
str w1, [x2]
|
str w1, [x2]
|
||||||
ret
|
ret
|
||||||
@ -66,6 +76,14 @@ SVC_BEGIN svcBreak
|
|||||||
ret
|
ret
|
||||||
SVC_END
|
SVC_END
|
||||||
|
|
||||||
|
SVC_BEGIN svcGetInfo
|
||||||
|
str x0, [sp, #-16]!
|
||||||
|
svc 0x29
|
||||||
|
ldr x2, [sp], #16
|
||||||
|
str x1, [x2]
|
||||||
|
ret
|
||||||
|
SVC_END
|
||||||
|
|
||||||
SVC_BEGIN svcAcceptSession
|
SVC_BEGIN svcAcceptSession
|
||||||
str x0, [sp, #-16]!
|
str x0, [sp, #-16]!
|
||||||
svc 0x41
|
svc 0x41
|
||||||
@ -100,6 +118,35 @@ SVC_BEGIN svcQueryIoMapping
|
|||||||
ret
|
ret
|
||||||
SVC_END
|
SVC_END
|
||||||
|
|
||||||
|
SVC_BEGIN svcCreateDeviceAddressSpace
|
||||||
|
str x0, [sp, #-16]!
|
||||||
|
svc 0x56
|
||||||
|
ldr x2, [sp]
|
||||||
|
str w1, [x2]
|
||||||
|
add sp, sp, #0x10
|
||||||
|
ret
|
||||||
|
SVC_END
|
||||||
|
|
||||||
|
SVC_BEGIN svcAttachDeviceAddressSpace
|
||||||
|
svc 0x57
|
||||||
|
ret
|
||||||
|
SVC_END
|
||||||
|
|
||||||
|
SVC_BEGIN svcDetachDeviceAddressSpace
|
||||||
|
svc 0x58
|
||||||
|
ret
|
||||||
|
SVC_END
|
||||||
|
|
||||||
|
SVC_BEGIN svcMapDeviceAddressSpaceAligned
|
||||||
|
svc 0x5A
|
||||||
|
ret
|
||||||
|
SVC_END
|
||||||
|
|
||||||
|
SVC_BEGIN svcUnmapDeviceAddressSpace
|
||||||
|
svc 0x5C
|
||||||
|
ret
|
||||||
|
SVC_END
|
||||||
|
|
||||||
SVC_BEGIN svcManageNamedPort
|
SVC_BEGIN svcManageNamedPort
|
||||||
str x0, [sp, #-16]!
|
str x0, [sp, #-16]!
|
||||||
svc 0x71
|
svc 0x71
|
||||||
@ -107,3 +154,21 @@ SVC_BEGIN svcManageNamedPort
|
|||||||
str w1, [x2]
|
str w1, [x2]
|
||||||
ret
|
ret
|
||||||
SVC_END
|
SVC_END
|
||||||
|
|
||||||
|
SVC_BEGIN svcCallSecureMonitor
|
||||||
|
str x0, [sp, #-16]!
|
||||||
|
mov x8, x0
|
||||||
|
ldp x0, x1, [x8]
|
||||||
|
ldp x2, x3, [x8, #0x10]
|
||||||
|
ldp x4, x5, [x8, #0x20]
|
||||||
|
ldp x6, x7, [x8, #0x30]
|
||||||
|
svc 0x7F
|
||||||
|
ldr x8, [SP]
|
||||||
|
stp x0, x1, [x8]
|
||||||
|
stp x2, x3, [x8, #0x10]
|
||||||
|
stp x4, x5, [x8, #0x20]
|
||||||
|
stp x6, x7, [x8, #0x30]
|
||||||
|
add sp, sp, #0x10
|
||||||
|
ret
|
||||||
|
SVC_END
|
||||||
|
|
||||||
|
5
nx/source/system/appExit.c
Normal file
5
nx/source/system/appExit.c
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include <switch/types.h>
|
||||||
|
|
||||||
|
void __attribute__((weak)) __appExit(void) {
|
||||||
|
// Initialize services
|
||||||
|
}
|
5
nx/source/system/appInit.c
Normal file
5
nx/source/system/appInit.c
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include <switch/types.h>
|
||||||
|
|
||||||
|
void __attribute__((weak)) __appInit(void) {
|
||||||
|
// Initialize services
|
||||||
|
}
|
18
nx/source/system/initSystem.c
Normal file
18
nx/source/system/initSystem.c
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#include <sys/iosupport.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <switch/types.h>
|
||||||
|
#include <switch/svc.h>
|
||||||
|
|
||||||
|
void __system_initSyscalls(void);
|
||||||
|
|
||||||
|
void heapSetup();
|
||||||
|
|
||||||
|
void __attribute__((weak)) __libnx_init(void)
|
||||||
|
{
|
||||||
|
// Initialize newlib support system calls
|
||||||
|
__system_initSyscalls();
|
||||||
|
|
||||||
|
heapSetup();
|
||||||
|
}
|
7
nx/source/system/nx_exit.c
Normal file
7
nx/source/system/nx_exit.c
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include <switch/types.h>
|
||||||
|
#include <switch/svc.h>
|
||||||
|
|
||||||
|
void __attribute__((weak)) __attribute__((noreturn)) __libnx_exit(int rc)
|
||||||
|
{
|
||||||
|
svcExitProcess();
|
||||||
|
}
|
46
nx/source/system/syscalls.c
Normal file
46
nx/source/system/syscalls.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include <sys/iosupport.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/lock.h>
|
||||||
|
#include <sys/reent.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <switch/types.h>
|
||||||
|
#include <switch/svc.h>
|
||||||
|
|
||||||
|
void __nx_exit(int rc);
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
/*extern const u8 __tdata_lma[];
|
||||||
|
extern const u8 __tdata_lma_end[];
|
||||||
|
extern u8 __tls_start[];
|
||||||
|
|
||||||
|
static struct _reent* __nx_get_reent()
|
||||||
|
{
|
||||||
|
ThreadVars* tv = getThreadVars();
|
||||||
|
if (tv->magic != THREADVARS_MAGIC)
|
||||||
|
{
|
||||||
|
svcBreak(USERBREAK_PANIC);
|
||||||
|
for (;;);
|
||||||
|
}
|
||||||
|
return tv->reent;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void __system_initSyscalls(void)
|
||||||
|
{
|
||||||
|
// Register newlib syscalls
|
||||||
|
__syscalls.exit = __nx_exit;
|
||||||
|
//__syscalls.getreent = __nx_get_reent;
|
||||||
|
|
||||||
|
// Initialize thread vars for the main thread (TODO)
|
||||||
|
/*ThreadVars* tv = getThreadVars();
|
||||||
|
tv->magic = THREADVARS_MAGIC;
|
||||||
|
tv->reent = _impure_ptr;
|
||||||
|
tv->thread_ptr = NULL;
|
||||||
|
tv->tls_tp = __tls_start-8; // ARM ELF TLS ABI mandates an 8-byte header
|
||||||
|
|
||||||
|
u32 tls_size = __tdata_lma_end - __tdata_lma;
|
||||||
|
if (tls_size)
|
||||||
|
memcpy(__tls_start, __tdata_lma, tls_size);*/
|
||||||
|
}
|
||||||
|
|
99
nx/source/system/sysinit.s
Normal file
99
nx/source/system/sysinit.s
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
.text
|
||||||
|
.global initSystem
|
||||||
|
.type initSystem, %function
|
||||||
|
|
||||||
|
initSystem:
|
||||||
|
stp x29, x30, [sp, #-16]!
|
||||||
|
adr x1, __nx_binarybase
|
||||||
|
str x0, [x1]
|
||||||
|
bl __libnx_init
|
||||||
|
|
||||||
|
bl __appInit
|
||||||
|
bl __nx_libc_init_array
|
||||||
|
ldp x29, x30, [sp], #16
|
||||||
|
ret
|
||||||
|
|
||||||
|
.global __nx_exit
|
||||||
|
.type __nx_exit, %function
|
||||||
|
|
||||||
|
__nx_exit:
|
||||||
|
bl __nx_libc_fini_array
|
||||||
|
bl __appExit
|
||||||
|
|
||||||
|
b __libnx_exit
|
||||||
|
|
||||||
|
__nx_libc_init_array:
|
||||||
|
stp x29, x30, [sp, #-16]!
|
||||||
|
stp x21, x22, [sp, #-16]!
|
||||||
|
stp x19, x20, [sp, #-16]!
|
||||||
|
adr x3, __nx_binarybase
|
||||||
|
ldr x20, [x3]
|
||||||
|
|
||||||
|
ldr x0, =__preinit_array_start
|
||||||
|
ldr x1, =__preinit_array_end
|
||||||
|
sub x1, x1, x0
|
||||||
|
add x21, x0, x20
|
||||||
|
lsr x19, x1, #3
|
||||||
|
cbz x19, __nx_libc_init_array_end0
|
||||||
|
|
||||||
|
__nx_libc_init_array_lp0:
|
||||||
|
ldr x3, [x21], #8
|
||||||
|
sub x19, x19, #1
|
||||||
|
add x3, x3, x20
|
||||||
|
blr x3
|
||||||
|
cbnz x19, __nx_libc_init_array_lp0
|
||||||
|
|
||||||
|
__nx_libc_init_array_end0:
|
||||||
|
bl _init
|
||||||
|
|
||||||
|
ldr x0, =__init_array_start
|
||||||
|
ldr x1, =__init_array_end
|
||||||
|
sub x1, x1, x0
|
||||||
|
add x21, x0, x20
|
||||||
|
lsr x19, x1, #3
|
||||||
|
cbz x19, __nx_libc_init_array_end1
|
||||||
|
|
||||||
|
__nx_libc_init_array_lp1:
|
||||||
|
ldr x3, [x21], #8
|
||||||
|
sub x19, x19, #1
|
||||||
|
add x3, x3, x20
|
||||||
|
blr x3
|
||||||
|
cbnz x19, __nx_libc_init_array_lp1
|
||||||
|
|
||||||
|
__nx_libc_init_array_end1:
|
||||||
|
ldp x19, x20, [sp], #16
|
||||||
|
ldp x21, x22, [sp], #16
|
||||||
|
ldp x29, x30, [sp], #16
|
||||||
|
ret
|
||||||
|
|
||||||
|
__nx_libc_fini_array:
|
||||||
|
stp x29, x30, [sp, #-16]!
|
||||||
|
stp x21, x22, [sp, #-16]!
|
||||||
|
stp x19, x20, [sp, #-16]!
|
||||||
|
adr x3, __nx_binarybase
|
||||||
|
ldr x20, [x3]
|
||||||
|
|
||||||
|
ldr x0, =__fini_array_start
|
||||||
|
ldr x1, =__fini_array_end
|
||||||
|
sub x1, x1, x0
|
||||||
|
add x21, x0, x20
|
||||||
|
lsr x19, x1, #3
|
||||||
|
cbz x19, __nx_libc_fini_array_end
|
||||||
|
|
||||||
|
__nx_libc_fini_array_lp:
|
||||||
|
sub x19, x19, #1
|
||||||
|
ldr x3, [x21, x19, lsl #3]
|
||||||
|
add x3, x3, x20
|
||||||
|
blr x3
|
||||||
|
cbnz x19, __nx_libc_fini_array_lp
|
||||||
|
|
||||||
|
__nx_libc_fini_array_end:
|
||||||
|
ldp x19, x20, [sp], #16
|
||||||
|
ldp x21, x22, [sp], #16
|
||||||
|
ldp x29, x30, [sp], #16
|
||||||
|
ret
|
||||||
|
|
||||||
|
.data
|
||||||
|
__nx_binarybase:
|
||||||
|
.dword 0
|
||||||
|
|
Loading…
Reference in New Issue
Block a user