From d50c45ff23b8f449a5ff0ec931b476e8ce2f6080 Mon Sep 17 00:00:00 2001 From: Wolfvak Date: Mon, 18 Sep 2017 19:23:40 -0300 Subject: [PATCH] Enable MPU and caches on the exception handler An (uncachable) background region makes sure no bad accesses get caught --- link.ld | 4 +-- source/system/xrq.c | 10 +++---- source/system/xrq_handler.s | 59 +++++++++++++++++++++++++++++-------- 3 files changed, 53 insertions(+), 20 deletions(-) diff --git a/link.ld b/link.ld index 7abcdca..c8ea737 100644 --- a/link.ld +++ b/link.ld @@ -17,7 +17,7 @@ SECTIONS __end__ = ABSOLUTE(.); - __stack_top = __start__; - __stack_abt = 0x8000; + __stack_abt = __start__; + __stack_top = __start__ - 0x80000; __code_size__ = __end__ - __start__; } diff --git a/source/system/xrq.c b/source/system/xrq.c index 0c4524d..c95d586 100644 --- a/source/system/xrq.c +++ b/source/system/xrq.c @@ -48,14 +48,13 @@ void XRQ_DumpRegisters(u32 xrq, u32 *regs) { u32 sp, st, pc; char dumpstr[2048], *wstr = dumpstr; - + DsTime dstime; get_dstime(&dstime); - /* Dump registers */ wstr += sprintf(wstr, "Exception: %s (%lu)\n", XRQ_Name[xrq&7], xrq); - wstr += sprintf(wstr, "20%02lX-%02lX-%02lX %02lX:%02lX:%02lX\n \n", + wstr += sprintf(wstr, "20%02lX-%02lX-%02lX %02lX:%02lX:%02lX\n\n", (u32) dstime.bcd_Y, (u32) dstime.bcd_M, (u32) dstime.bcd_D, (u32) dstime.bcd_h, (u32) dstime.bcd_m, (u32) dstime.bcd_s); for (int i = 0; i < 8; i++) { @@ -65,7 +64,6 @@ void XRQ_DumpRegisters(u32 xrq, u32 *regs) } wstr += sprintf(wstr, "CPSR: %08lX\n\n", regs[16]); - /* Output registers to main screen */ u32 draw_width = GetDrawStringWidth(dumpstr); u32 draw_height = GetDrawStringHeight(dumpstr); @@ -93,8 +91,8 @@ void XRQ_DumpRegisters(u32 xrq, u32 *regs) } else { wstr += XRQ_DumpData_u32(wstr, pc-PC_DUMPRAD, pc+PC_DUMPRAD); } - - + + /* Draw QR Code */ u8 qrcode[qrcodegen_BUFFER_LEN_MAX]; u8 temp[qrcodegen_BUFFER_LEN_MAX]; diff --git a/source/system/xrq_handler.s b/source/system/xrq_handler.s index 9c33c27..71a3a66 100644 --- a/source/system/xrq_handler.s +++ b/source/system/xrq_handler.s @@ -10,8 +10,9 @@ #include .macro XRQ_FATAL id=0 - adr sp, XRQ_Registers - stmia sp!, {r0-r12} + ldr sp, =__stack_abt + sub sp, sp, #(18*4) @ Reserve space for registers + stmia sp, {r0-r12} mov r11, #\id b XRQ_MainHandler .endm @@ -28,10 +29,8 @@ XRQ_Vectors: subs pc, lr, #4 @ IRQs are unhandled b . @ FIQs are unused (except for debug?) -XRQ_Registers: - .space (17*4) - XRQ_Reset: + msr cpsr_c, #(SR_ABT_MODE | SR_IRQ | SR_FIQ) XRQ_FATAL 0 XRQ_Undefined: @@ -46,6 +45,7 @@ XRQ_PAbort: XRQ_DAbort: XRQ_FATAL 4 +@ r11 = exception number XRQ_MainHandler: mrs r10, cpsr mrs r9, spsr @@ -60,21 +60,47 @@ XRQ_MainHandler: blx r6 @ Retrieve banked registers - and r0, r9, #(SR_PMODE_MASK) - cmp r0, #(SR_USR_MODE) + ands r0, r9, #(SR_PMODE_MASK & (0x0F)) orreq r0, #(SR_SYS_MODE) - orr r0, #(SR_IRQ | SR_FIQ) + orr r0, #(0x10 | SR_IRQ | SR_FIQ) msr cpsr_c, r0 @ Switch to previous mode mov r0, sp mov r1, lr msr cpsr_c, r10 @ Return to abort - stmia sp!, {r0,r1,r8,r9} + add r2, sp, #(13*4) + stmia r2, {r0,r1,r8,r9} + + @ Give read/write access to all the memory regions + ldr r0, =0x33333333 + mcr p15, 0, r0, c5, c0, 2 @ write data access + mcr p15, 0, r0, c5, c0, 3 @ write instruction access + + @ Sets MPU regions and cache settings + adr r0, __abt_mpu_regions + ldmia r0, {r1-r8} + mov r0, #0b00110010 @ bootrom, arm9 mem and fcram are cacheable/bufferable + mcr p15, 0, r1, c6, c0, 0 + mcr p15, 0, r2, c6, c1, 0 + mcr p15, 0, r3, c6, c2, 0 + mcr p15, 0, r4, c6, c3, 0 + mcr p15, 0, r5, c6, c4, 0 + mcr p15, 0, r6, c6, c5, 0 + mcr p15, 0, r7, c6, c6, 0 + mcr p15, 0, r8, c6, c7, 0 + mcr p15, 0, r0, c3, c0, 0 @ Write bufferable 0, 2, 5 + mcr p15, 0, r0, c2, c0, 0 @ Data cacheable 0, 2, 5 + mcr p15, 0, r0, c2, c0, 1 @ Inst cacheable 0, 2, 5 + + @ Enable mpu/caches + ldr r1, =(CR_ENABLE_MPU | CR_ENABLE_DCACHE | CR_ENABLE_ICACHE | CR_ENABLE_DTCM) + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, r1 + mcr p15, 0, r0, c1, c0, 0 - ldr sp, =0x8000 ldr r2, =XRQ_DumpRegisters @ void XRQ_DumpRegisters(u32 xrq_id, u32 *regs) - adr r1, XRQ_Registers + mov r1, sp mov r0, r11 blx r2 @@ -86,6 +112,15 @@ XRQ_MainHandler: .pool +__abt_mpu_regions: + .word 0x0000003F @ 00000000 4G | background region (includes IO regs) + .word 0xFFFF001F @ FFFF0000 64k | bootrom (unprotected / protected) + .word 0x3000801B @ 30008000 16k | dtcm + .word 0x00000035 @ 00000000 128M | itcm + .word 0x08000029 @ 08000000 2M | arm9 mem (O3DS / N3DS) + .word 0x20000037 @ 20000000 256M | fcram (O3DS / N3DS) + .word 0x1FF00027 @ 1FF00000 1M | dsp / axi wram + .word 0x1800002D @ 18000000 8M | vram (+ 2MB) + .global XRQ_End XRQ_End: - .word 0