diff --git a/exceptions/arm9/source/handlers.h b/exceptions/arm9/source/handlers.h index 7b4b219..0e4a49f 100644 --- a/exceptions/arm9/source/handlers.h +++ b/exceptions/arm9/source/handlers.h @@ -7,7 +7,6 @@ #pragma once -void setupStack(u32 mode, void *stack); void FIQHandler(void); void undefinedInstructionHandler(void); void dataAbortHandler(void); diff --git a/exceptions/arm9/source/handlers.s b/exceptions/arm9/source/handlers.s index cc6da60..af6e6eb 100644 --- a/exceptions/arm9/source/handlers.s +++ b/exceptions/arm9/source/handlers.s @@ -45,16 +45,3 @@ GEN_HANDLER FIQHandler GEN_HANDLER undefinedInstructionHandler GEN_HANDLER prefetchAbortHandler GEN_HANDLER dataAbortHandler - -.global setupStack -.type setupStack, %function -setupStack: - cmp r0, #0 - moveq r0, #0xf @ usr => sys - mrs r2, cpsr - bic r3, r2, #0xf - orr r3, r0 @ processor mode - msr cpsr_c, r3 @ change processor mode - mov sp, r1 - msr cpsr_c, r2 @ restore processor mode - bx lr diff --git a/exceptions/arm9/source/main.c b/exceptions/arm9/source/mainHandler.c similarity index 71% rename from exceptions/arm9/source/main.c rename to exceptions/arm9/source/mainHandler.c index a1a6f02..d201a0d 100644 --- a/exceptions/arm9/source/main.c +++ b/exceptions/arm9/source/mainHandler.c @@ -1,5 +1,5 @@ /* -* main.c +* mainHandler.c * by TuxSH * * This is part of Luma3DS, see LICENSE.txt for details @@ -10,8 +10,6 @@ #include "handlers.h" #define FINAL_BUFFER 0x25000000 -#define SP ((void *)0x02000000) //We make the (full descending) stack point to the end of ITCM for our exception handlers. - //It doesn't matter if we're overwriting stuff, since we're going to reboot. #define REG_DUMP_SIZE (4*17) #define CODE_DUMP_SIZE 48 @@ -70,22 +68,4 @@ void __attribute__((noreturn)) mainHandler(u32 regs[17], u32 type) i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 2); //Reboot while(1); -} - -void main(void) -{ - setupStack(1, SP); //FIQ - setupStack(7, SP); //Abort - setupStack(11, SP); //Undefined - - //IRQHandler is at 0x08000000, but we won't handle it for obvious reasons - *(vu32 *)0x08000008 = 0xE51FF004; - *(vu32 *)0x0800000C = (u32)FIQHandler; - //svcHandler is at 0x08000010, but we won't handle svc either - *(vu32 *)0x08000018 = 0xE51FF004; - *(vu32 *)0x0800001C = (u32)undefinedInstructionHandler; - *(vu32 *)0x08000020 = 0xE51FF004; - *(vu32 *)0x08000024 = (u32)prefetchAbortHandler; - *(vu32 *)0x08000028 = 0xE51FF004; - *(vu32 *)0x0800002C = (u32)dataAbortHandler; } \ No newline at end of file diff --git a/exceptions/arm9/source/start.s b/exceptions/arm9/source/start.s index 82107f4..0d0921f 100644 --- a/exceptions/arm9/source/start.s +++ b/exceptions/arm9/source/start.s @@ -2,4 +2,11 @@ .align 4 .global _start _start: - b main + add pc, r0, #(handlers - .) @ Dummy instruction to prevent compiler optimizations + +handlers: + .word FIQHandler + .word undefinedInstructionHandler + .word prefetchAbortHandler + .word dataAbortHandler + \ No newline at end of file diff --git a/source/exceptions.c b/source/exceptions.c index 99a2511..e0be517 100644 --- a/source/exceptions.c +++ b/source/exceptions.c @@ -12,12 +12,47 @@ #include "utils.h" #include "../build/arm9_exceptions.h" +#define _U __attribute__((unused)) //Silence "unused parameter" warnings +static void __attribute__((naked)) setupStack(_U u32 mode, _U void* SP) +{ + __asm__ volatile( + "cmp r0, #0 \n" + "moveq r0, #0xf @ usr => sys \n" + "mrs r2, cpsr \n" + "bic r3, r2, #0xf \n" + "orr r3, r0 @ processor mode \n" + "msr cpsr_c, r3 @ change processor mode \n" + "mov sp, r1 \n" + "msr cpsr_c, r2 @ restore processor mode \n" + "bx lr \n" + ); +} +#undef _U + void installArm9Handlers(void) { void *payloadAddress = (void *)0x01FF8000; - + u32 *handlers = (u32 *)payloadAddress + 1; + + void* SP = (void *)0x02000000; //We make the (full descending) stack point to the end of ITCM for our exception handlers. + //It doesn't matter if we're overwriting stuff, since we're going to reboot. + memcpy(payloadAddress, arm9_exceptions, arm9_exceptions_size); - ((void (*)())payloadAddress)(); + + setupStack(1, SP); //FIQ + setupStack(7, SP); //Abort + setupStack(11, SP); //Undefined + + const u32 offsets[] = {0x08, 0x18, 0x20, 0x28}; + + //IRQHandler is at 0x08000000, but we won't handle it for some reasons + //svcHandler is at 0x08000010, but we won't handle svc either + + for(u32 i = 0; i < 4; i++) + { + *(vu32 *)(0x08000000 + offsets[i]) = 0xE51FF004; + *(vu32 *)(0x08000000 + offsets[i] + 4) = handlers[i]; + } } static void hexItoa(u32 n, char *out)