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).
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
+++ /dev/null
-
-#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;
-}
-
#ifndef _3DS_UTILS_H
#define _3DS_UTILS_H
-void ctr_invalidate_ICache(void);
-void ctr_flush_DCache(void);
+#include <stdio.h>
-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 <stdio.h>
#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
#ifndef _3DS_PTHREAD_WRAP__
#define _3DS_PTHREAD_WRAP__
-#include "3ds.h"
-#include "stdlib.h"
-#include "string.h"
-#include "stdio.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#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;
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;
extern "C" {
#endif
-#include "3ds.h"
-#include "stdlib.h"
-#include "stdio.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <malloc.h>
-#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;
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;
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;
}
#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;
(void)is_fixed;
(void)addr;
- if (ctr_svchack_init_success)
+ if (__ctr_svchax)
{
psx_map_t* custom_map = custom_psx_maps;
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);
{
(void)tag;
- if (ctr_svchack_init_success)
+ if (__ctr_svchax)
{
psx_map_t* custom_map = custom_psx_maps;
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;
R3000Acpu *prev_cpu = psxCpu;
#ifdef _3DS
- if(!ctr_svchack_init_success)
+ if(!__ctr_svchax)
Config.Cpu = CPU_INTERPRETER;
else
#endif
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();