From e9fa000e941398838490ebeda032b99a23d23c47 Mon Sep 17 00:00:00 2001 From: fincs Date: Sat, 1 Apr 2023 14:18:53 +0200 Subject: [PATCH 1/5] Implement dkA r60 threading syscalls (pthread, std::thread support) --- libctru/source/system/syscalls.c | 78 ++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/libctru/source/system/syscalls.c b/libctru/source/system/syscalls.c index 8921bb3..80ada5c 100644 --- a/libctru/source/system/syscalls.c +++ b/libctru/source/system/syscalls.c @@ -156,6 +156,84 @@ void __SYSCALL(exit)(int rc) { __ctru_exit(rc); } +int __SYSCALL(cond_signal)(_COND_T *cond) +{ + CondVar_Signal((CondVar*)cond); + return 0; +} + +int __SYSCALL(cond_broadcast)(_COND_T *cond) +{ + CondVar_Broadcast((CondVar*)cond); + return 0; +} + +int __SYSCALL(cond_wait)(_COND_T *cond, _LOCK_T *lock, uint64_t timeout_ns) +{ + return CondVar_WaitTimeout((CondVar*)cond, lock, timeout_ns) ? ETIMEDOUT : 0; +} + +int __SYSCALL(cond_wait_recursive)(_COND_T *cond, _LOCK_RECURSIVE_T *lock, uint64_t timeout_ns) +{ + uint32_t thread_tag_backup = 0; + if (lock->counter != 1) + return EBADF; + + thread_tag_backup = lock->thread_tag; + lock->thread_tag = 0; + lock->counter = 0; + + int err = CondVar_WaitTimeout((CondVar*)cond, &lock->lock, timeout_ns); + + lock->thread_tag = thread_tag_backup; + lock->counter = 1; + + return err ? ETIMEDOUT : 0; +} + +int __SYSCALL(thread_create)(struct __pthread_t **thread, void* (*func)(void*), void *arg, void *stack_addr, size_t stack_size) +{ + if (stack_addr) { + return EINVAL; + } + + if (!stack_size) { + stack_size = 32*1024; + } + + Thread t = threadCreate((ThreadFunc)func, arg, stack_size, 0x3F, 0, false); + if (t) { + *thread = (struct __pthread_t*)t; + return 0; + } + + return ENOMEM; +} + +void*__SYSCALL(thread_join)(struct __pthread_t *thread) +{ + threadJoin((Thread)thread, U64_MAX); + void* rc = (void*)threadGetExitCode((Thread)thread); + threadFree((Thread)thread); + return rc; +} + +int __SYSCALL(thread_detach)(struct __pthread_t *thread) +{ + threadDetach((Thread)thread); + return 0; +} + +void __SYSCALL(thread_exit)(void *value) +{ + threadExit((int)value); +} + +struct __pthread_t *__SYSCALL(thread_self)(void) +{ + return (struct __pthread_t*)threadGetCurrent(); +} + void initThreadVars(struct Thread_tag *thread) { ThreadVars* tv = getThreadVars(); From a4634c02905a824d01feae338d1c472ab5dae1eb Mon Sep 17 00:00:00 2001 From: oreo639 Date: Fri, 11 Aug 2023 17:26:42 -0700 Subject: [PATCH 2/5] Add GPU_DOT3_RGBA texture combiner function --- libctru/include/3ds/gpu/enums.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libctru/include/3ds/gpu/enums.h b/libctru/include/3ds/gpu/enums.h index 76ac488..45f8177 100644 --- a/libctru/include/3ds/gpu/enums.h +++ b/libctru/include/3ds/gpu/enums.h @@ -368,7 +368,8 @@ typedef enum GPU_ADD_SIGNED = 0x03, ///< Signed add. GPU_INTERPOLATE = 0x04, ///< Interpolate. GPU_SUBTRACT = 0x05, ///< Subtract. - GPU_DOT3_RGB = 0x06, ///< Dot3. RGB only. + GPU_DOT3_RGB = 0x06, ///< Dot3. Scalar result is written to RGB only. + GPU_DOT3_RGBA = 0x07, ///< Dot3. Scalar result is written to RGBA. GPU_MULTIPLY_ADD = 0x08, ///< Multiply then add. GPU_ADD_MULTIPLY = 0x09, ///< Add then multiply. } GPU_COMBINEFUNC; From 0f098853f2b1523efd045ccc915a1415718ec58e Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Fri, 15 Sep 2023 23:15:58 +0200 Subject: [PATCH 3/5] Add isb and prevent CPU from postponing threadOnException memory writes --- libctru/include/3ds/synchronization.h | 6 ++++++ libctru/include/3ds/thread.h | 3 +++ 2 files changed, 9 insertions(+) diff --git a/libctru/include/3ds/synchronization.h b/libctru/include/3ds/synchronization.h index d8edfdc..60cc2c8 100755 --- a/libctru/include/3ds/synchronization.h +++ b/libctru/include/3ds/synchronization.h @@ -42,6 +42,12 @@ static inline void __dmb(void) __asm__ __volatile__("mcr p15, 0, %[val], c7, c10, 5" :: [val] "r" (0) : "memory"); } +/// Performs an Instruction Synchronization Barrier (officially "flush prefetch buffer") operation. +static inline void __isb(void) +{ + __asm__ __volatile__("mcr p15, 0, %[val], c7, c5, 4" :: [val] "r" (0) : "memory"); +} + /// Performs a clrex operation. static inline void __clrex(void) { diff --git a/libctru/include/3ds/thread.h b/libctru/include/3ds/thread.h index 68c99eb..d37fdf3 100644 --- a/libctru/include/3ds/thread.h +++ b/libctru/include/3ds/thread.h @@ -117,4 +117,7 @@ static inline void threadOnException(ExceptionHandler handler, void* stack_top, *(u32*)(tls + 0x40) = (u32)handler; *(u32*)(tls + 0x44) = (u32)stack_top; *(u32*)(tls + 0x48) = (u32)exception_data; + + __dsb(); + __isb(); } From 5b2a9f6136e5f26b22e8113795732096cb445de8 Mon Sep 17 00:00:00 2001 From: TuxSH <1922548+TuxSH@users.noreply.github.com> Date: Sat, 16 Sep 2023 21:22:37 +0200 Subject: [PATCH 4/5] ac: add SSID-related ac:i functions ACI_LoadNetworkSetting and ACI_GetNetworkWirelessEssidSecuritySsid, plus acGetSessionHandle. --- libctru/include/3ds/services/ac.h | 15 ++++++++++++ libctru/source/services/ac.c | 39 +++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/libctru/include/3ds/services/ac.h b/libctru/include/3ds/services/ac.h index bc1ad79..a39f389 100644 --- a/libctru/include/3ds/services/ac.h +++ b/libctru/include/3ds/services/ac.h @@ -27,6 +27,9 @@ Result acInit(void); /// Exits AC. void acExit(void); +/// Gets the current AC session handle. +Handle *acGetSessionHandle(void); + /// Waits for the system to connect to the internet. Result acWaitInternetConnection(void); @@ -128,3 +131,15 @@ Result ACU_SetRequestEulaVersion(acuConfig* config); * @param connectionHandle Handle created with svcCreateEvent to wait on until the connection succeeds or fails. */ Result ACU_ConnectAsync(const acuConfig* config, Handle connectionHandle); + +/** + * @brief Selects the WiFi configuration slot for further ac:i operations. + * @param slot WiFi slot (0, 1 or 2). + */ +Result ACI_LoadNetworkSetting(u32 slot); + +/** + * @brief Fetches the SSID of the previously selected WiFi configuration slot. + * @param[out] ssid Pointer to the output buffer of size 32B the SSID will be stored in. + */ +Result ACI_GetNetworkWirelessEssidSecuritySsid(void *ssid); diff --git a/libctru/source/services/ac.c b/libctru/source/services/ac.c index 007a70c..db04f07 100644 --- a/libctru/source/services/ac.c +++ b/libctru/source/services/ac.c @@ -6,6 +6,7 @@ #include <3ds/synchronization.h> #include <3ds/services/ac.h> #include <3ds/ipc.h> +#include static Handle acHandle; static int acRefCount; @@ -30,6 +31,11 @@ void acExit(void) svcCloseHandle(acHandle); } +Handle *acGetSessionHandle(void) +{ + return &acHandle; +} + Result acWaitInternetConnection(void) { Result ret = 0; @@ -284,3 +290,36 @@ Result ACU_GetProxyUserName(char *username) return (Result)cmdbuf[1]; } + +Result ACI_LoadNetworkSetting(u32 slot) +{ + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x401,1,0); // 0x04010040 + cmdbuf[1] = slot; + + Result ret = 0; + if(R_FAILED(ret = svcSendSyncRequest(acHandle))) return ret; + + return (Result)cmdbuf[1]; +} + +Result ACI_GetNetworkWirelessEssidSecuritySsid(void *ssid) +{ + u32* cmdbuf = getThreadCommandBuffer(); + u32* staticbufs = getThreadStaticBuffers(); + + cmdbuf[0] = IPC_MakeHeader(0x40F,0,0); // 0x040F0000 + + u32 staticbufBackup[2]; + memcpy(staticbufBackup, staticbufs, 8); + + staticbufs[0] = IPC_Desc_StaticBuffer(0x20, 0); // at most 32 bytes + staticbufs[1] = (u32)ssid; + + Result ret = svcSendSyncRequest(acHandle); + + memcpy(staticbufs, staticbufBackup, 8); + + return R_SUCCEEDED(ret) ? (Result)cmdbuf[1] : ret; +} From 4de90c343605812b903aaa7b91b69254cfaecb80 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Mon, 25 Sep 2023 17:46:01 +0100 Subject: [PATCH 5/5] remove extra __libc_fini_array --- libctru/source/system/stack_adjust.s | 1 - 1 file changed, 1 deletion(-) diff --git a/libctru/source/system/stack_adjust.s b/libctru/source/system/stack_adjust.s index bc233b6..89ff9cf 100644 --- a/libctru/source/system/stack_adjust.s +++ b/libctru/source/system/stack_adjust.s @@ -26,7 +26,6 @@ BEGIN_ASM_FUNC initSystem, weak END_ASM_FUNC BEGIN_ASM_FUNC __ctru_exit, weak - bl __libc_fini_array bl __appExit ldr r2, =saved_stack