diff --git a/include/arm9/interrupt.h b/include/arm9/interrupt.h index 13a52a1..5d8d671 100644 --- a/include/arm9/interrupt.h +++ b/include/arm9/interrupt.h @@ -3,7 +3,7 @@ #include "io.h" -#define waitForIrq() __asm__ __volatile__("mcr p15, 0, %0, c7, c0, 4\n\t" : : "r" (0)) +#define waitForIrq() __asm__ __volatile__("mcr p15, 0, %0, c7, c0, 4" : : "r" (0)) typedef enum @@ -49,14 +49,14 @@ inline u32 enterCriticalSection(void) { u32 tmp; - __asm__ __volatile__("mrs %0, cpsr\n\t" : "=r" (tmp) : ); - __asm__ __volatile__("msr cpsr_c, %0\n\t" : : "r" (tmp | 0x80u)); + __asm__ __volatile__("mrs %0, cpsr" : "=r" (tmp) : ); + __asm__ __volatile__("msr cpsr_c, %0" : : "r" (tmp | 0x80u)); return tmp & 0x80u; } inline void leaveCriticalSection(u32 oldState) { u32 tmp; - __asm__ __volatile__("mrs %0, cpsr\n\t" : "=r" (tmp) : ); - __asm__ __volatile__("msr cpsr_c, %0\n\t" : : "r" ((tmp & ~(0x80u)) | oldState)); + __asm__ __volatile__("mrs %0, cpsr" : "=r" (tmp) : ); + __asm__ __volatile__("msr cpsr_c, %0" : : "r" ((tmp & ~(0x80u)) | oldState)); } diff --git a/source/arm9/cpu.s b/source/arm9/cpu.s index bcb35a4..45af328 100644 --- a/source/arm9/cpu.s +++ b/source/arm9/cpu.s @@ -232,7 +232,7 @@ deinitCpu: msr cpsr_cxsf, #0xDF - mov r4, lr + mov r3, lr @ Stub vectors to endless loops mov r0, #A9_RAM_BASE @@ -244,13 +244,13 @@ bne deinitCpu_lp bl flushDCache + mov r2, #0 mrc p15, 0, r0, c1, c0, 0 @ Read control register ldr r1, =0x1005 @ MPU, D-Cache and I-Cache bitmask bic r0, r0, r1 @ Disable MPU, D-Cache and I-Cache mcr p15, 0, r0, c1, c0, 0 @ Write control register - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ Invalidate I-Cache - mcr p15, 0, r0, c7, c6, 0 @ Invalidate D-Cache - bx r4 + mcr p15, 0, r2, c7, c5, 0 @ Invalidate I-Cache + mcr p15, 0, r2, c7, c6, 0 @ Invalidate D-Cache + bx r3 .pool diff --git a/source/arm9/exception.s b/source/arm9/exception.s index da2b7a2..e5970ca 100644 --- a/source/arm9/exception.s +++ b/source/arm9/exception.s @@ -34,16 +34,16 @@ exceptionHandler: mov sp, #A9_EXC_STACK_END stmfd sp!, {r0-r14}^ @ Save all user/system mode regs except pc - mrs r5, cpsr - lsr r5, r5, #29 @ Get back the exception type from cpsr + mrs r4, cpsr + lsr r4, r4, #29 @ Get back the exception type from cpsr mrs r1, spsr @ Get saved cpsr stmfd sp!, {r1, lr} @ Save spsr and lr (pc) on exception stack - mov r6, sp - msr cpsr_c, #0xDF @ Disable all interrupts, system mode + mov r5, sp + msr cpsr_cxsf, #0xDF @ Disable all interrupts, system mode bl deinitCpu - mov r0, r5 - mov sp, r6 - mov r1, r6 + mov r0, r4 + mov sp, r5 + mov r1, r5 b guruMeditation @ r0 = exception type, r1 = reg dump ptr {cpsr, pc (unmodified), r0-r14} .pool diff --git a/source/arm9/firm.c b/source/arm9/firm.c index c98e9c2..6d96805 100644 --- a/source/arm9/firm.c +++ b/source/arm9/firm.c @@ -64,12 +64,29 @@ if(section->size == 0) continue; - REG_NDMA_SRC_ADDR(i) = FIRM_LOAD_ADDR + section->offset; - REG_NDMA_DST_ADDR(i) = section->address; - REG_NDMA_WRITE_CNT(i) = section->size>>2; - REG_NDMA_BLOCK_CNT(i) = NDMA_BLOCK_SYS_FREQ; - REG_NDMA_CNT(i) = NDMA_DST_UPDATE_INC | NDMA_SRC_UPDATE_INC - | NDMA_STARTUP_IMMEDIATE | NDMA_ENABLE; + // If the section address is in ITCM use CPU copy + if(section->address < ITCM_BOOT9_MIRROR + ITCM_SIZE) + { + u32 *dst = (u32*)section->address; + u32 *src = (u32*)(FIRM_LOAD_ADDR + section->offset); + + for(u32 n = 0; n < section->size / 4; n += 4) + { + dst[n + 0] = src[n + 0]; + dst[n + 1] = src[n + 1]; + dst[n + 2] = src[n + 2]; + dst[n + 3] = src[n + 3]; + } + } + else + { + REG_NDMA_SRC_ADDR(i) = FIRM_LOAD_ADDR + section->offset; + REG_NDMA_DST_ADDR(i) = section->address; + REG_NDMA_WRITE_CNT(i) = section->size / 4; + REG_NDMA_BLOCK_CNT(i) = NDMA_BLOCK_SYS_FREQ; + REG_NDMA_CNT(i) = NDMA_DST_UPDATE_INC | NDMA_SRC_UPDATE_INC + | NDMA_STARTUP_IMMEDIATE | NDMA_ENABLE; + } } while(REG_NDMA0_CNT & NDMA_ENABLE || REG_NDMA1_CNT & NDMA_ENABLE @@ -91,7 +108,7 @@ REG_PXI_CNT9 = 0; // Disable PXI // go for it! - __asm__ __volatile__("mov lr, %0\n\tbx %1\n\t" : : "r" (ret), "r" (entry9) : "lr", "pc"); + __asm__ __volatile__("mov lr, %0\n\tbx %1" : : "r" (ret), "r" (entry9) : "lr", "pc"); } bool firm_verify(u32 fwSize)