diff --git a/Makefile.ctr b/Makefile.ctr index 1005e506420d..32b795953b37 100644 --- a/Makefile.ctr +++ b/Makefile.ctr @@ -28,6 +28,7 @@ OBJS += ctr/stack_adjust.o OBJS += ctr/ctr_system.o OBJS += ctr/ctr_memory.o OBJS += ctr/ctr_linear.o +OBJS += ctr/ctr_svchax.o ifeq ($(GRIFFIN_BUILD), 1) OBJS += griffin/griffin.o diff --git a/ctr/ctr_svchax.c b/ctr/ctr_svchax.c new file mode 100644 index 000000000000..c81d7875b8b1 --- /dev/null +++ b/ctr/ctr_svchax.c @@ -0,0 +1,145 @@ + +#include <3ds.h> +#include + +static void svchax_gspwn(u32 dst, u32 src, u32 size, u8* flush_buffer) +{ + extern Handle gspEvents[GSPEVENT_MAX]; + + memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000); + GSPGPU_InvalidateDataCache(dst, size); + GSPGPU_FlushDataCache(src, size); + memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000); + + svcClearEvent(gspEvents[GSPEVENT_PPF]); + GX_TextureCopy(src, 0, dst, 0, size, 8); + svcWaitSynchronization(gspEvents[GSPEVENT_PPF], U64_MAX); + + memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000); +} + +/* pseudo-code: + * if(val2) + * { + * *(u32*)val1 = val2; + * *(u32*)(val2 + 8) = (val1 - 4); + * } + * else + * *(u32*)val1 = 0x0; + */ + +// X-X--X-X +// X-XXXX-X + +static void memchunkhax_write_pair(u32 val1, u32 val2) +{ + u32 linear_buffer; + u8* flush_buffer; + u32 tmp; + + u32* next_ptr3; + u32* prev_ptr3; + + u32* next_ptr1; + u32* prev_ptr6; + + svcControlMemory(&linear_buffer, 0, 0, 0x10000, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE); + + flush_buffer = (u8*)(linear_buffer + 0x8000); + + svcControlMemory(&tmp, linear_buffer + 0x1000, 0, 0x1000, MEMOP_FREE, 0); + svcControlMemory(&tmp, linear_buffer + 0x3000, 0, 0x2000, MEMOP_FREE, 0); + svcControlMemory(&tmp, linear_buffer + 0x6000, 0, 0x1000, MEMOP_FREE, 0); + + next_ptr1 = (u32*)(linear_buffer + 0x0004); + svchax_gspwn(linear_buffer + 0x0000, linear_buffer + 0x1000, 16, flush_buffer); + + next_ptr3 = (u32*)(linear_buffer + 0x2004); + prev_ptr3 = (u32*)(linear_buffer + 0x2008); + svchax_gspwn(linear_buffer + 0x2000, linear_buffer + 0x3000, 16, flush_buffer); + + prev_ptr6 = (u32*)(linear_buffer + 0x5008); + svchax_gspwn(linear_buffer + 0x5000, linear_buffer + 0x6000, 16, flush_buffer); + + *next_ptr1 = *next_ptr3; + *prev_ptr6 = *prev_ptr3; + + *prev_ptr3 = val1 - 4; + *next_ptr3 = val2; + svchax_gspwn(linear_buffer + 0x3000, linear_buffer + 0x2000, 16, flush_buffer); + svcControlMemory(&tmp, 0, 0, 0x2000, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE); + + svchax_gspwn(linear_buffer + 0x1000, linear_buffer + 0x0000, 16, flush_buffer); + svchax_gspwn(linear_buffer + 0x6000, linear_buffer + 0x5000, 16, flush_buffer); + + svcControlMemory(&tmp, linear_buffer + 0x0000, 0, 0x1000, MEMOP_FREE, 0); + svcControlMemory(&tmp, linear_buffer + 0x2000, 0, 0x4000, MEMOP_FREE, 0); + svcControlMemory(&tmp, linear_buffer + 0x7000, 0, 0x9000, MEMOP_FREE, 0); + +} + + +static inline u32 get_7B_access_ctrl_ptr(void) +{ + register u32 r0 __asm__("r0"); + __asm__ volatile ( + "sub r0, sp, #8 \n\t" + "mov r1, #1 \n\t" + "mov r2, #0 \n\t" + "svc 0x2A \n\t" + "orr r0, r1, #0xF00 \n\t" + "bic r0, r0, #0x0FF \n\t" + "add r0, r0, #0x044 \n\t" + :::"r0","r1","r2"); + return r0; +} + +static u32 saved_vram_value; + +static s32 k_restore_vram_value(void) +{ + __asm__ volatile("cpsid aif \n\t"); + + *(u32*)0x1F000008 = saved_vram_value; + + return 0; +} + +static s32 k_enable_all_svc(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; + + return 0; +} + +u32 __ctr_svchax = 0; + +void svchax_init(void) +{ + extern u32 __service_ptr; + + if (__ctr_svchax) + return; + + if(__service_ptr) + { + if((*(u8*)0x1FF80002 > 0x2F) || (*(u8*)0x1FF80003 != 0x2)) + return; + + saved_vram_value = *(u32*)0x1F000008; + memchunkhax_write_pair(get_7B_access_ctrl_ptr(), 0x1F000000); + svcBackdoor(k_restore_vram_value); + } + + svcBackdoor(k_enable_all_svc); + + __ctr_svchax = 1; + +} diff --git a/frontend/drivers/platform_ctr.c b/frontend/drivers/platform_ctr.c index 9b93a19bf0bb..7e4b1714536e 100644 --- a/frontend/drivers/platform_ctr.c +++ b/frontend/drivers/platform_ctr.c @@ -213,6 +213,8 @@ static void ctr_check_dspfirm(void) } } +void svchax_init(void); + static void frontend_ctr_init(void *data) { #ifndef IS_SALAMANDER @@ -224,9 +226,13 @@ static void frontend_ctr_init(void *data) APT_SetAppCpuTimeLimit(NULL, 80); #endif osSetSpeedupEnable(true); - gfxInit(GSP_BGR8_OES,GSP_RGB565_OES,false); + gfxInit(GSP_BGR8_OES,GSP_RGB565_OES,false); gfxSet3D(false); consoleInit(GFX_BOTTOM, NULL); + + /* enable access to all service calls when possible. */ + svchax_init(); + audio_driver_t* dsp_audio_driver = &audio_ctr_dsp; if(csndInit() != 0) {