(3ds) dynarec: map the translation caches to specific addresses at

runtime, increases compatibility with loaders that can reloacate each
program section seperately.
move the svc enabling functions to the frontend.
This commit is contained in:
aliaspider 2015-11-04 15:46:27 +01:00
parent 6b8417143a
commit f1d14fbe7c
7 changed files with 89 additions and 83 deletions

View File

@ -1,24 +1,12 @@
#include "3ds.h"
#include "libkhax/khax.h"
static int ninjhax_version = 0;
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#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(
@ -36,22 +24,14 @@ static void ctr_flush_DCache_kernel(void)
}
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);
}
@ -61,32 +41,3 @@ 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)
{
if(hbInit() == 0)
{
/* ninjhax 1.0 */
ninjhax_version = 1;
hbExit();
khaxInit();
return 1;
}
ninjhax_version = 2;
return 0;
}
/* CFW */
ninjhax_version = 0;
ctr_enable_all_svc();
return 1;
}
void ctr_svchack_exit(void)
{
if (ninjhax_version == 1)
khaxExit();
}

View File

@ -3,10 +3,13 @@
void ctr_invalidate_ICache(void);
void ctr_flush_DCache(void);
void ctr_flush_invalidate_cache(void);
int ctr_svchack_init(void);
void ctr_svchack_exit(void);
extern __attribute((weak)) unsigned int __ctr_svchax;
void wait_for_input();
#define DEBUG_HOLD() do{printf("%s@%s:%d.\n",__FUNCTION__, __FILE__, __LINE__);fflush(stdout);wait_for_input();}while(0)
#define DEBUG_VAR(X) printf( "%-20s: 0x%08X\n", #X, (u32)(X))
#define DEBUG_VAR64(X) printf( #X"\r\t\t\t\t : 0x%016llX\n", (u64)(X))
#endif // _3DS_UTILS_H

View File

@ -211,7 +211,7 @@ else ifeq ($(platform), ctr)
CFLAGS += -fomit-frame-pointer -ffast-math
CXXFLAGS = $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
CPU_ARCH := arm
# dynarec unavailable on ninjhax 2.0
# dynarec unavailable with the HBL on FW > 9.2
HAVE_DYNAREC = 1
STATIC_LINKING = 1
@ -330,7 +330,7 @@ CODE_DEFINES =
COMMON_DEFINES += $(CODE_DEFINES) $(WARNINGS_DEFINES) -DNDEBUG=1 $(fpic)
CFLAGS += $(DEFINES) $(COMMON_DEFINES)
CFLAGS += $(DEFINES) $(COMMON_DEFINES) -Werror=implicit-function-declaration
ifeq ($(FRONTEND_SUPPORTS_RGB565), 1)
CFLAGS += -DFRONTEND_SUPPORTS_RGB565

9
cpu.h
View File

@ -135,10 +135,17 @@ s32 translate_block_thumb(u32 pc, translation_region_type translation_region,
#endif
#ifdef HAVE_MMAP
#if defined(HAVE_MMAP)
extern u8* rom_translation_cache;
extern u8* ram_translation_cache;
extern u8* bios_translation_cache;
#elif defined(_3DS)
#define rom_translation_cache ((u8*)0x02000000 - ROM_TRANSLATION_CACHE_SIZE)
#define ram_translation_cache (rom_translation_cache - RAM_TRANSLATION_CACHE_SIZE)
#define bios_translation_cache (ram_translation_cache - BIOS_TRANSLATION_CACHE_SIZE)
extern u8* rom_translation_cache_ptr;
extern u8* ram_translation_cache_ptr;
extern u8* bios_translation_cache_ptr;
#else
extern u8 rom_translation_cache[ROM_TRANSLATION_CACHE_SIZE];
extern u8 ram_translation_cache[RAM_TRANSLATION_CACHE_SIZE];

View File

@ -35,9 +35,9 @@ u8 *rom_translation_ptr;
u8 *ram_translation_ptr;
u8 *bios_translation_ptr;
#elif defined(_3DS)
u8 __attribute__((aligned(0x1000))) rom_translation_cache[ROM_TRANSLATION_CACHE_SIZE];
u8 __attribute__((aligned(0x1000))) ram_translation_cache[RAM_TRANSLATION_CACHE_SIZE];
u8 __attribute__((aligned(0x1000))) bios_translation_cache[BIOS_TRANSLATION_CACHE_SIZE];
u8* rom_translation_cache_ptr;
u8* ram_translation_cache_ptr;
u8* bios_translation_cache_ptr;
u8 *rom_translation_ptr = rom_translation_cache;
u8 *ram_translation_ptr = ram_translation_cache;
u8 *bios_translation_ptr = bios_translation_cache;

View File

@ -12,12 +12,15 @@
void* linearMemAlign(size_t size, size_t alignment);
void linearFree(void* mem);
#if defined(HAVE_DYNAREC)
#include <malloc.h>
#include "3ds/3ds_utils.h"
#define MEMOP_PROT 6
#define MEMOP_MAP 4
#define MEMOP_UNMAP 5
int32_t svcDuplicateHandle(uint32_t* out, uint32_t original);
int32_t svcCloseHandle(uint32_t handle);
int32_t svcControlProcessMemory(uint32_t process, void* addr0, void* addr1, uint32_t size, uint32_t type, uint32_t perm);
int ctr_has_full_svc_access;
static int translation_caches_inited = 0;
#endif
#endif
@ -115,30 +118,42 @@ void retro_get_system_av_info(struct retro_system_av_info* info)
void retro_init(void)
{
init_gamepak_buffer();
init_sound(1);
#if defined(_3DS) && defined(HAVE_DYNAREC)
ctr_has_full_svc_access = ctr_svchack_init();
if (ctr_has_full_svc_access)
if (__ctr_svchax && !translation_caches_inited)
{
uint32_t currentHandle;
svcDuplicateHandle(&currentHandle, 0xFFFF8001);
svcControlProcessMemory(currentHandle, rom_translation_cache, 0x0,
ROM_TRANSLATION_CACHE_SIZE, MEMOP_PROT, 0b111);
svcControlProcessMemory(currentHandle, ram_translation_cache, 0x0,
RAM_TRANSLATION_CACHE_SIZE, MEMOP_PROT, 0b111);
svcControlProcessMemory(currentHandle, bios_translation_cache, 0x0,
BIOS_TRANSLATION_CACHE_SIZE, MEMOP_PROT, 0b111);
svcCloseHandle(currentHandle);
rom_translation_cache_ptr = memalign(0x1000, ROM_TRANSLATION_CACHE_SIZE);
ram_translation_cache_ptr = memalign(0x1000, RAM_TRANSLATION_CACHE_SIZE);
bios_translation_cache_ptr = memalign(0x1000, BIOS_TRANSLATION_CACHE_SIZE);
svcDuplicateHandle(&currentHandle, 0xFFFF8001);
svcControlProcessMemory(currentHandle,
rom_translation_cache, rom_translation_cache_ptr,
ROM_TRANSLATION_CACHE_SIZE, MEMOP_MAP, 0b111);
svcControlProcessMemory(currentHandle,
ram_translation_cache, ram_translation_cache_ptr,
RAM_TRANSLATION_CACHE_SIZE, MEMOP_MAP, 0b111);
svcControlProcessMemory(currentHandle,
bios_translation_cache, bios_translation_cache_ptr,
BIOS_TRANSLATION_CACHE_SIZE, MEMOP_MAP, 0b111);
svcCloseHandle(currentHandle);
rom_translation_ptr = rom_translation_cache;
ram_translation_ptr = ram_translation_cache;
bios_translation_ptr = bios_translation_cache;
ctr_flush_invalidate_cache();
translation_caches_inited = 1;
}
#endif
if (!gamepak_rom)
init_gamepak_buffer();
init_sound(1);
if(!gba_screen_pixels)
#ifdef _3DS
gba_screen_pixels = (uint16_t*)linearMemAlign(GBA_SCREEN_PITCH * GBA_SCREEN_HEIGHT * sizeof(uint16_t), 128);
gba_screen_pixels = (uint16_t*)linearMemAlign(GBA_SCREEN_PITCH * GBA_SCREEN_HEIGHT * sizeof(uint16_t), 128);
#else
gba_screen_pixels = (uint16_t*)malloc(GBA_SCREEN_PITCH * GBA_SCREEN_HEIGHT * sizeof(uint16_t));
gba_screen_pixels = (uint16_t*)malloc(GBA_SCREEN_PITCH * GBA_SCREEN_HEIGHT * sizeof(uint16_t));
#endif
}
@ -154,13 +169,33 @@ void retro_deinit(void)
munmap(bios_translation_cache, BIOS_TRANSLATION_CACHE_SIZE);
#endif
#if defined(_3DS) && defined(HAVE_DYNAREC)
ctr_svchack_exit();
if (__ctr_svchax && translation_caches_inited)
{
uint32_t currentHandle;
svcDuplicateHandle(&currentHandle, 0xFFFF8001);
svcControlProcessMemory(currentHandle,
rom_translation_cache, rom_translation_cache_ptr,
ROM_TRANSLATION_CACHE_SIZE, MEMOP_UNMAP, 0b111);
svcControlProcessMemory(currentHandle,
ram_translation_cache, ram_translation_cache_ptr,
RAM_TRANSLATION_CACHE_SIZE, MEMOP_UNMAP, 0b111);
svcControlProcessMemory(currentHandle,
bios_translation_cache, bios_translation_cache_ptr,
BIOS_TRANSLATION_CACHE_SIZE, MEMOP_UNMAP, 0b111);
svcCloseHandle(currentHandle);
free(rom_translation_cache_ptr);
free(ram_translation_cache_ptr);
free(bios_translation_cache_ptr);
translation_caches_inited = 0;
}
#endif
#ifdef _3DS
linearFree(gba_screen_pixels);
#else
free(gba_screen_pixels);
#endif
gba_screen_pixels = NULL;
}
static retro_time_t retro_perf_dummy_get_time_usec() { return 0; }
@ -173,13 +208,21 @@ void retro_set_environment(retro_environment_t cb)
{
struct retro_log_callback log;
static const struct retro_variable vars[] = {
static struct retro_variable vars[] = {
#ifdef HAVE_DYNAREC
{ "gpsp_drc", "Dynamic recompiler (restart); enabled|disabled" },
#endif
{ NULL, NULL },
};
#if defined(_3DS) && (HAVE_DYNAREC)
if(!__ctr_svchax)
{
vars[0].key = 0;
vars[0].value = NULL;
}
#endif
environ_cb = cb;
if (environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log))
@ -338,8 +381,10 @@ bool retro_load_game(const struct retro_game_info* info)
ram_translation_ptr = ram_translation_cache;
bios_translation_ptr = bios_translation_cache;
#elif defined(_3DS)
if(!ctr_has_full_svc_access)
dynarec_enable = 0;
dynarec_enable = __ctr_svchax;
rom_translation_ptr = rom_translation_cache;
ram_translation_ptr = ram_translation_cache;
bios_translation_ptr = bios_translation_cache;
#endif
}
else

View File

@ -19,7 +19,7 @@
#include "common.h"
u16* gba_screen_pixels;
u16* gba_screen_pixels = NULL;
#define get_screen_pixels() gba_screen_pixels
#define get_screen_pitch() GBA_SCREEN_PITCH