From f72db18e0c39a5bf115f493767decc409e10f94a Mon Sep 17 00:00:00 2001 From: aliaspider Date: Sat, 16 Jan 2016 17:47:28 +0100 Subject: [PATCH] (3DS) - remove provileged services enabling code, it should be done by the frontend instead. - dynamically allocate the recompiler cache, this will allow using the recompiler even when the .bss section is relocated far from the .text section (for example when using the hombrew loader). --- Makefile.libretro | 11 +++--- frontend/3ds/3ds_utils.c | 74 ---------------------------------------- frontend/3ds/3ds_utils.h | 60 +++++++++++++++++++++++++++++--- frontend/3ds/pthread.h | 16 ++++----- frontend/3ds/sys/mman.h | 69 +++++++++++++++++++++++++++++-------- frontend/libretro.c | 15 ++++---- 6 files changed, 128 insertions(+), 117 deletions(-) delete mode 100644 frontend/3ds/3ds_utils.c diff --git a/Makefile.libretro b/Makefile.libretro index 2b2a362d..d4b3829d 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -142,20 +142,17 @@ else ifeq ($(platform), ctr) CC = $(DEVKITARM)/bin/arm-none-eabi-gcc$(EXE_EXT) CXX = $(DEVKITARM)/bin/arm-none-eabi-g++$(EXE_EXT) AR = $(DEVKITARM)/bin/arm-none-eabi-ar$(EXE_EXT) - CFLAGS += -DARM11 -D_3DS -DNO_OS -DNO_DYLIB - CFLAGS += -march=armv6k -mtune=mpcore -mfloat-abi=hard -marm -mfpu=vfp + CFLAGS += -DARM11 -D_3DS -DNO_OS -DNO_DYLIB -DNO_SOCKET + CFLAGS += -march=armv6k -mtune=mpcore -mfloat-abi=hard -marm -mfpu=vfp -mtp=soft CFLAGS += -Wall -mword-relocations CFLAGS += -fomit-frame-pointer -ffast-math - CFLAGS += -I$(CTRULIB)/include -I$(DEVKITPRO)/portlibs/armv6k/include -Ifrontend/3ds + CFLAGS += -Ifrontend/3ds CFLAGS += -Werror=implicit-function-declaration - OBJS += frontend/3ds/3ds_utils.o - - # CFLAGS += -DPCSX # BUILTIN_GPU = unai USE_DYNAREC = 1 - DRC_CACHE_BASE = 0 + DRC_CACHE_BASE = 1 ARCH = arm STATIC_LINKING = 1 diff --git a/frontend/3ds/3ds_utils.c b/frontend/3ds/3ds_utils.c deleted file mode 100644 index c415d375..00000000 --- a/frontend/3ds/3ds_utils.c +++ /dev/null @@ -1,74 +0,0 @@ - -#include "3ds.h" -#include "3ds_utils.h" - -typedef s32 (*ctr_callback_type)(void); - -static void ctr_enable_all_svc_kernel(void) -{ - __asm__ volatile("cpsid aif"); - - u32* svc_access_control = *(*(u32***)0xFFFF9000 + 0x22) - 0x6; - - svc_access_control[0]=0xFFFFFFFE; - svc_access_control[1]=0xFFFFFFFF; - svc_access_control[2]=0xFFFFFFFF; - svc_access_control[3]=0x3FFFFFFF; -} - - -static void ctr_invalidate_ICache_kernel(void) -{ - __asm__ volatile( - "cpsid aif\n\t" - "mov r0, #0\n\t" - "mcr p15, 0, r0, c7, c5, 0\n\t"); -} - -static void ctr_flush_DCache_kernel(void) -{ - __asm__ volatile( - "cpsid aif\n\t" - "mov r0, #0\n\t" - "mcr p15, 0, r0, c7, c10, 0\n\t"); - -} - - -static void ctr_enable_all_svc(void) -{ - svcBackdoor((ctr_callback_type)ctr_enable_all_svc_kernel); -} - -void ctr_invalidate_ICache(void) -{ -// __asm__ volatile("svc 0x2E\n\t"); - svcBackdoor((ctr_callback_type)ctr_invalidate_ICache_kernel); - -} - -void ctr_flush_DCache(void) -{ -// __asm__ volatile("svc 0x4B\n\t"); - svcBackdoor((ctr_callback_type)ctr_flush_DCache_kernel); -} - - -void ctr_flush_invalidate_cache(void) -{ - ctr_flush_DCache(); - ctr_invalidate_ICache(); -} - -int ctr_svchack_init(void) -{ - extern unsigned int __service_ptr; - - if(__service_ptr) - return 0; - - /* CFW */ - ctr_enable_all_svc(); - return 1; -} - diff --git a/frontend/3ds/3ds_utils.h b/frontend/3ds/3ds_utils.h index fe97985c..3d50a668 100644 --- a/frontend/3ds/3ds_utils.h +++ b/frontend/3ds/3ds_utils.h @@ -1,16 +1,66 @@ #ifndef _3DS_UTILS_H #define _3DS_UTILS_H -void ctr_invalidate_ICache(void); -void ctr_flush_DCache(void); +#include -void ctr_flush_invalidate_cache(void); +#define MEMOP_PROT 6 +#define MEMOP_MAP 4 +#define MEMOP_UNMAP 5 -int ctr_svchack_init(void); +void* linearMemAlign(size_t size, size_t alignment); +void linearFree(void* mem); + +int32_t svcDuplicateHandle(uint32_t* out, uint32_t original); +int32_t svcCloseHandle(uint32_t handle); +int32_t svcControlMemory(void* addr_out, void* addr0, void* addr1, uint32_t size, uint32_t op, uint32_t perm); +int32_t svcControlProcessMemory(uint32_t process, void* addr0, void* addr1, uint32_t size, uint32_t op, uint32_t perm); + +int32_t svcCreateThread(int32_t* thread, void *(*entrypoint)(void*), void* arg, void* stack_top, int32_t thread_priority, int32_t processor_id); +int32_t svcWaitSynchronization(int32_t handle, int64_t nanoseconds); +void svcExitThread(void) __attribute__((noreturn)); + +int32_t svcBackdoor(int32_t (*callback)(void)); -#include #define DEBUG_HOLD() do{printf("%s@%s:%d.\n",__FUNCTION__, __FILE__, __LINE__);fflush(stdout);wait_for_input();}while(0) void wait_for_input(void); +extern __attribute__((weak)) int __ctr_svchax; + +typedef int32_t (*ctr_callback_type)(void); + +static inline void ctr_invalidate_ICache_kernel(void) +{ + __asm__ volatile( + "cpsid aif\n\t" + "mov r0, #0\n\t" + "mcr p15, 0, r0, c7, c5, 0\n\t"); +} + +static inline void ctr_flush_DCache_kernel(void) +{ + __asm__ volatile( + "cpsid aif\n\t" + "mov r0, #0\n\t" + "mcr p15, 0, r0, c7, c10, 0\n\t"); +} + +static inline void ctr_invalidate_ICache(void) +{ + svcBackdoor((ctr_callback_type)ctr_invalidate_ICache_kernel); +} + +static inline void ctr_flush_DCache(void) +{ + svcBackdoor((ctr_callback_type)ctr_flush_DCache_kernel); +} + + +static inline void ctr_flush_invalidate_cache(void) +{ + ctr_flush_DCache(); + ctr_invalidate_ICache(); +} + + #endif // _3DS_UTILS_H diff --git a/frontend/3ds/pthread.h b/frontend/3ds/pthread.h index 56d90852..2c2bf6b1 100644 --- a/frontend/3ds/pthread.h +++ b/frontend/3ds/pthread.h @@ -2,18 +2,18 @@ #ifndef _3DS_PTHREAD_WRAP__ #define _3DS_PTHREAD_WRAP__ -#include "3ds.h" -#include "stdlib.h" -#include "string.h" -#include "stdio.h" +#include +#include +#include +#include "3ds_utils.h" #define CTR_PTHREAD_STACK_SIZE 0x10000 typedef struct { - Handle handle; - u32* stack; + int32_t handle; + uint32_t* stack; }pthread_t; typedef int pthread_attr_t; @@ -23,8 +23,8 @@ static inline int pthread_create(pthread_t *thread, thread->stack = linearMemAlign(CTR_PTHREAD_STACK_SIZE, 8); - svcCreateThread(&thread->handle, (ThreadFunc)start_routine,arg, - (u32*)((u32)thread->stack + CTR_PTHREAD_STACK_SIZE), + svcCreateThread(&thread->handle, start_routine, arg, + (uint32_t*)((uint32_t)thread->stack + CTR_PTHREAD_STACK_SIZE), 0x25, 1); return 1; diff --git a/frontend/3ds/sys/mman.h b/frontend/3ds/sys/mman.h index fae16245..e295b893 100644 --- a/frontend/3ds/sys/mman.h +++ b/frontend/3ds/sys/mman.h @@ -5,28 +5,58 @@ extern "C" { #endif -#include "3ds.h" -#include "stdlib.h" -#include "stdio.h" +#include +#include +#include +#include -#define PROT_READ MEMPERM_READ -#define PROT_WRITE MEMPERM_WRITE -#define PROT_EXEC MEMPERM_EXECUTE +#include "3ds_utils.h" + +#define PROT_READ 0b001 +#define PROT_WRITE 0b010 +#define PROT_EXEC 0b100 #define MAP_PRIVATE 2 +#define MAP_FIXED 0x10 #define MAP_ANONYMOUS 0x20 #define MAP_FAILED ((void *)-1) +static void* dynarec_cache = NULL; +static void* dynarec_cache_mapping = NULL; + static inline void* mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) { - (void)addr; - (void)prot; - (void)flags; (void)fd; (void)offset; void* addr_out; + if((prot == (PROT_READ | PROT_WRITE | PROT_EXEC)) && + (flags == (MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS))) + { + if(__ctr_svchax) + { + /* this hack works only for pcsx_rearmed */ + uint32_t currentHandle; + + if(!dynarec_cache) + dynarec_cache = memalign(0x1000, len); + + svcDuplicateHandle(¤tHandle, 0xFFFF8001); + svcControlProcessMemory(currentHandle, addr, dynarec_cache, + len, MEMOP_MAP, prot); + svcCloseHandle(currentHandle); + dynarec_cache_mapping = addr; + return addr; + } + else + { + printf("tried to mmap RWX pages without svcControlProcessMemory access !\n"); + return MAP_FAILED; + } + + } + addr_out = malloc(len); if(!addr_out) return MAP_FAILED; @@ -36,13 +66,11 @@ static inline void* mmap(void *addr, size_t len, int prot, int flags, int fd, of static inline int mprotect(void *addr, size_t len, int prot) { - extern int ctr_svchack_init_success; - - if(ctr_svchack_init_success) + if(__ctr_svchax) { uint32_t currentHandle; svcDuplicateHandle(¤tHandle, 0xFFFF8001); - svcControlProcessMemory(currentHandle, (u32)addr, 0x0, + svcControlProcessMemory(currentHandle, addr, NULL, len, MEMOP_PROT, prot); svcCloseHandle(currentHandle); return 0; @@ -54,7 +82,20 @@ static inline int mprotect(void *addr, size_t len, int prot) static inline int munmap(void *addr, size_t len) { - free(addr); + if((addr == dynarec_cache_mapping) && __ctr_svchax) + { + uint32_t currentHandle; + svcDuplicateHandle(¤tHandle, 0xFFFF8001); + svcControlProcessMemory(currentHandle, + dynarec_cache, dynarec_cache_mapping, + len, MEMOP_UNMAP, 0b111); + svcCloseHandle(currentHandle); + dynarec_cache_mapping = NULL; + + } + else + free(addr); + return 0; } diff --git a/frontend/libretro.c b/frontend/libretro.c index aaeb6242..a9b6e433 100644 --- a/frontend/libretro.c +++ b/frontend/libretro.c @@ -29,9 +29,7 @@ #include "libretro.h" #ifdef _3DS -#include "3ds.h" #include "3ds/3ds_utils.h" -int ctr_svchack_init_success = 0; #endif static retro_video_refresh_t video_cb; @@ -194,7 +192,7 @@ void* pl_3ds_mmap(unsigned long addr, size_t size, int is_fixed, (void)is_fixed; (void)addr; - if (ctr_svchack_init_success) + if (__ctr_svchax) { psx_map_t* custom_map = custom_psx_maps; @@ -207,7 +205,7 @@ void* pl_3ds_mmap(unsigned long addr, size_t size, int is_fixed, custom_map->buffer = malloc(size + 0x1000); ptr_aligned = (((u32)custom_map->buffer) + 0xFFF) & ~0xFFF; - if(svcControlMemory(&tmp, custom_map->target_map, ptr_aligned, size, MEMOP_MAP, 0x3) < 0) + if(svcControlMemory(&tmp, (void*)custom_map->target_map, (void*)ptr_aligned, size, MEMOP_MAP, 0x3) < 0) { SysPrintf("could not map memory @0x%08X\n", custom_map->target_map); exit(1); @@ -225,7 +223,7 @@ void pl_3ds_munmap(void *ptr, size_t size, enum psxMapTag tag) { (void)tag; - if (ctr_svchack_init_success) + if (__ctr_svchax) { psx_map_t* custom_map = custom_psx_maps; @@ -237,7 +235,7 @@ void pl_3ds_munmap(void *ptr, size_t size, enum psxMapTag tag) ptr_aligned = (((u32)custom_map->buffer) + 0xFFF) & ~0xFFF; - svcControlMemory(&tmp, custom_map->target_map, ptr_aligned, size, MEMOP_UNMAP, 0x3); + svcControlMemory(&tmp, (void*)custom_map->target_map, (void*)ptr_aligned, size, MEMOP_UNMAP, 0x3); free(custom_map->buffer); custom_map->buffer = NULL; @@ -1139,7 +1137,7 @@ static void update_variables(bool in_flight) R3000Acpu *prev_cpu = psxCpu; #ifdef _3DS - if(!ctr_svchack_init_success) + if(!__ctr_svchax) Config.Cpu = CPU_INTERPRETER; else #endif @@ -1385,14 +1383,13 @@ void retro_init(void) bool found_bios = false; #ifdef _3DS - ctr_svchack_init_success = ctr_svchack_init(); psxMapHook = pl_3ds_mmap; psxUnmapHook = pl_3ds_munmap; #endif ret = emu_core_preinit(); #ifdef _3DS /* emu_core_preinit sets the cpu to dynarec */ - if(!ctr_svchack_init_success) + if(!__ctr_svchax) Config.Cpu = CPU_INTERPRETER; #endif ret |= emu_core_init(); -- 2.39.5