(ctr/3ds) optimize build, add support for 32x/svp dynamic recompilers.

This commit is contained in:
aliaspider 2015-09-30 23:43:20 +01:00
parent b44f946ce8
commit 0c73267625
4 changed files with 301 additions and 25 deletions

View File

@ -193,27 +193,31 @@ else ifeq ($(platform), ctr)
CXX = $(DEVKITARM)/bin/arm-none-eabi-g++$(EXE_EXT)
AR = $(DEVKITARM)/bin/arm-none-eabi-ar$(EXE_EXT)
CFLAGS += -DARM11 -D_3DS
CFLAGS += -march=armv6k -mtune=mpcore -mfloat-abi=hard
CFLAGS += -march=armv6k -mtune=mpcore -mfloat-abi=hard -marm -mfpu=vfp
CFLAGS += -Wall -mword-relocations
CFLAGS += -fomit-frame-pointer -ffast-math
CFLAGS += -D_3DS
PLATFORM_DEFINES := -D_3DS
STATIC_LINKING = 1
NO_MMAP = 1
DONT_COMPILE_IN_ZLIB = 1
ARCH = arm
ARM_ASM = 1
asm_memory = 0
asm_render = 0
asm_ym2612 = 0
asm_misc = 0
asm_cdpico = 0
asm_cdmemory = 0
asm_mix = 0
use_cyclone = 0
use_fame = 1
use_drz80 = 0
use_cz80 = 1
asm_memory = 1
asm_render = 1
asm_ym2612 = 1
asm_misc = 1
asm_cdpico = 1
asm_cdmemory = 1
asm_mix = 1
use_cyclone = 1
use_fame = 0
use_drz80 = 1
use_cz80 = 0
use_sh2drc = 1
use_svpdrc = 1
OBJS +=platform/libretro/3ds/3ds_utils.o
# Vita
else ifeq ($(platform), vita)

View File

@ -0,0 +1,78 @@
#include "3ds_utils.h"
typedef int (*ctr_callback_type)(void);
int srvGetServiceHandle(unsigned int* out, const char* name);
int svcCloseHandle(unsigned int handle);
int svcBackdoor(ctr_callback_type);
static void ctr_enable_all_svc_kernel(void)
{
__asm__ volatile("cpsid aif");
unsigned int* svc_access_control = *(*(unsigned int***)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;
}

View File

@ -0,0 +1,18 @@
#ifndef _3DS_UTILS_H
#define _3DS_UTILS_H
void ctr_invalidate_ICache(void);
void ctr_flush_DCache(void);
void ctr_flush_invalidate_cache(void);
int ctr_svchack_init(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);
#endif // _3DS_UTILS_H

View File

@ -24,6 +24,19 @@
#include <libkern/OSCacheControl.h>
#endif
#ifdef _3DS
#include "3ds/3ds_utils.h"
#define MEMOP_PROT 6
int svcDuplicateHandle(unsigned int* out, unsigned int original);
int svcCloseHandle(unsigned int handle);
int svcControlProcessMemory(unsigned int process, void* addr0, void* addr1,
unsigned int size, unsigned int type, unsigned int perm);
#define MEMOP_MAP 4
#define MEMOP_UNMAP 5
static int ctr_svchack_successful = 0;
#endif
#include <pico/pico_int.h>
#include <pico/state.h>
#include "../common/input_pico.h"
@ -67,8 +80,10 @@ void cache_flush_d_inval_i(void *start, void *end)
size_t len = (char *)end - (char *)start;
sys_dcache_flush(start, len);
sys_icache_invalidate(start, len);
#elif defined(_3DS)
ctr_flush_invalidate_cache();
#else
__clear_cache(start, end);
__clear_cache(start, end);
#endif
#endif
}
@ -190,7 +205,7 @@ void munmap(void *base_addr, size_t len)
int mprotect(void *addr, size_t len, int prot)
{
/* stub - not really needed at this point since this codepath has no dynarecs */
/* stub - not really needed at this point since this codepath has no dynarecs */
return 0;
}
@ -200,6 +215,134 @@ int mprotect(void *addr, size_t len, int prot)
#define MAP_ANONYMOUS MAP_ANON
#endif
#ifdef _3DS
typedef struct
{
unsigned int requested_map;
void* buffer;
}pico_mmap_t;
pico_mmap_t pico_mmaps[] = {
{0x02000000, 0},
{0x06000000, 0},
{NULL, 0}
};
void *plat_mmap(unsigned long addr, size_t size, int need_exec, int is_fixed)
{
(void)is_fixed;
if (ctr_svchack_successful)
{
pico_mmap_t* pico_mmap;
for (pico_mmap = pico_mmaps; pico_mmap->requested_map; pico_mmap++)
{
if ((pico_mmap->requested_map == addr))
{
unsigned int ptr_aligned, tmp;
unsigned int currentHandle;
unsigned int perm = 0b011;
if (need_exec)
perm = 0b111;
size = (size + 0xFFF) & ~0xFFF;
pico_mmap->buffer = malloc(size + 0x1000);
ptr_aligned = (((unsigned int)pico_mmap->buffer) + 0xFFF) & ~0xFFF;
svcDuplicateHandle(&currentHandle, 0xFFFF8001);
if(svcControlProcessMemory(currentHandle, pico_mmap->requested_map, ptr_aligned, size, MEMOP_MAP, perm) < 0)
{
if (log_cb)
log_cb(RETRO_LOG_ERROR, "could not map memory @0x%08X\n", pico_mmap->requested_map);
exit(1);
}
svcCloseHandle(currentHandle);
return (void*)pico_mmap->requested_map;
}
}
}
return malloc(size);
}
void *plat_mremap(void *ptr, size_t oldsize, size_t newsize)
{
if (ctr_svchack_successful)
{
pico_mmap_t* pico_mmap;
for (pico_mmap = pico_mmaps; pico_mmap->requested_map; pico_mmap++)
{
if ((pico_mmap->requested_map == (unsigned int)ptr))
{
unsigned int ptr_aligned;
unsigned int currentHandle;
void* tmp;
oldsize = (oldsize + 0xFFF) & ~0xFFF;
newsize = (newsize + 0xFFF) & ~0xFFF;
ptr_aligned = (((unsigned int)pico_mmap->buffer) + 0xFFF) & ~0xFFF;
svcDuplicateHandle(&currentHandle, 0xFFFF8001);
svcControlProcessMemory(currentHandle, pico_mmap->requested_map, ptr_aligned, oldsize, MEMOP_UNMAP, 0b011);
tmp = realloc(pico_mmap->buffer, newsize + 0x1000);
if(!tmp)
return NULL;
pico_mmap->buffer = tmp;
ptr_aligned = (((unsigned int)pico_mmap->buffer) + 0xFFF) & ~0xFFF;
svcControlProcessMemory(currentHandle, pico_mmap->requested_map, ptr_aligned, newsize, MEMOP_MAP, 0x3);
svcCloseHandle(currentHandle);
return ptr;
}
}
}
return realloc(ptr, newsize);
}
void plat_munmap(void *ptr, size_t size)
{
if (ctr_svchack_successful)
{
pico_mmap_t* pico_mmap;
for (pico_mmap = pico_mmaps; pico_mmap->requested_map; pico_mmap++)
{
if ((pico_mmap->requested_map == (unsigned int)ptr))
{
unsigned int ptr_aligned;
unsigned int currentHandle;
size = (size + 0xFFF) & ~0xFFF;
ptr_aligned = (((unsigned int)pico_mmap->buffer) + 0xFFF) & ~0xFFF;
svcDuplicateHandle(&currentHandle, 0xFFFF8001);
svcControlProcessMemory(currentHandle, (void*)pico_mmap->requested_map, (void*)ptr_aligned, size, MEMOP_UNMAP, 0b011);
svcCloseHandle(currentHandle);
free(pico_mmap->buffer);
pico_mmap->buffer = NULL;
return;
}
}
}
free(ptr);
}
#else
void *plat_mmap(unsigned long addr, size_t size, int need_exec, int is_fixed)
{
int flags = MAP_PRIVATE | MAP_ANONYMOUS;
@ -265,6 +408,7 @@ void plat_munmap(void *ptr, size_t size)
if (ptr != NULL)
munmap(ptr, size);
}
#endif
int plat_mem_set_exec(void *ptr, size_t size)
{
@ -272,6 +416,26 @@ int plat_mem_set_exec(void *ptr, size_t size)
int ret = VirtualProtect(ptr,size,PAGE_EXECUTE_READWRITE,0);
if (ret == 0 && log_cb)
log_cb(RETRO_LOG_ERROR, "mprotect(%p, %zd) failed: %d\n", ptr, size, 0);
#elif defined(_3DS)
int ret = -1;
if (ctr_svchack_successful)
{
unsigned int currentHandle;
svcDuplicateHandle(&currentHandle, 0xFFFF8001);
ret = svcControlProcessMemory(currentHandle, ptr, 0x0,
size, MEMOP_PROT, 0b111);
svcCloseHandle(currentHandle);
ctr_flush_invalidate_cache();
}
else
{
if (log_cb)
log_cb(RETRO_LOG_ERROR, "plat_mem_set_exec called with no svcControlProcessMemory access\n");
exit(1);
}
#else
int ret = mprotect(ptr, size, PROT_READ | PROT_WRITE | PROT_EXEC);
if (ret != 0 && log_cb)
@ -302,7 +466,8 @@ void lprintf(const char *fmt, ...)
vsprintf(buffer, fmt, ap);
/* TODO - add 'level' param for warning/error messages? */
if (log_cb)
log_cb(RETRO_LOG_INFO, "%s\n", fmt);
log_cb(RETRO_LOG_INFO, "%s\n", fmt, ap);
va_end(ap);
}
/* libretro */
@ -1001,6 +1166,10 @@ static void update_variables(void)
PicoOpt &= ~POPT_EN_DRC;
}
#endif
#ifdef _3DS
if(!ctr_svchack_successful)
PicoOpt &= ~POPT_EN_DRC;
#endif
}
void retro_run(void)
@ -1011,7 +1180,7 @@ void retro_run(void)
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
update_variables();
input_poll_cb();
input_poll_cb();
PicoPad[0] = PicoPad[1] = 0;
for (pad = 0; pad < 2; pad++)
@ -1047,29 +1216,36 @@ void retro_init(void)
environ_cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE, &disk_control);
#ifdef _3DS
ctr_svchack_successful = ctr_svchack_init();
#endif
PicoOpt = POPT_EN_STEREO|POPT_EN_FM|POPT_EN_PSG|POPT_EN_Z80
| POPT_EN_MCD_PCM|POPT_EN_MCD_CDDA|POPT_EN_MCD_GFX
| POPT_EN_32X|POPT_EN_PWM
| POPT_ACC_SPRITES|POPT_DIS_32C_BORDER;
#ifdef __arm__
PicoOpt |= POPT_EN_DRC;
#ifdef _3DS
if (ctr_svchack_successful)
#endif
PicoOpt |= POPT_EN_DRC;
#endif
PsndRate = 44100;
PicoAutoRgnOrder = 0x184; // US, EU, JP
vout_width = 320;
vout_height = 240;
vout_buf = malloc(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2);
vout_height = 240;
vout_buf = malloc(VOUT_MAX_WIDTH * VOUT_MAX_HEIGHT * 2);
PicoInit();
PicoDrawSetOutFormat(PDF_RGB555, 0);
PicoDrawSetOutBuf(vout_buf, vout_width * 2);
PicoInit();
PicoDrawSetOutFormat(PDF_RGB555, 0);
PicoDrawSetOutBuf(vout_buf, vout_width * 2);
//PicoMessage = plat_status_msg_busy_next;
PicoMCDopenTray = disk_tray_open;
PicoMCDcloseTray = disk_tray_close;
update_variables();
update_variables();
}
void retro_deinit(void)