Enable MPU and caches on the exception handler

An (uncachable) background region makes sure no bad accesses get caught
This commit is contained in:
Wolfvak 2017-09-18 19:23:40 -03:00 committed by d0k3
parent d249b647d6
commit d50c45ff23
3 changed files with 53 additions and 20 deletions

View File

@ -17,7 +17,7 @@ SECTIONS
__end__ = ABSOLUTE(.); __end__ = ABSOLUTE(.);
__stack_top = __start__; __stack_abt = __start__;
__stack_abt = 0x8000; __stack_top = __start__ - 0x80000;
__code_size__ = __end__ - __start__; __code_size__ = __end__ - __start__;
} }

View File

@ -48,14 +48,13 @@ void XRQ_DumpRegisters(u32 xrq, u32 *regs)
{ {
u32 sp, st, pc; u32 sp, st, pc;
char dumpstr[2048], *wstr = dumpstr; char dumpstr[2048], *wstr = dumpstr;
DsTime dstime; DsTime dstime;
get_dstime(&dstime); get_dstime(&dstime);
/* Dump registers */ /* Dump registers */
wstr += sprintf(wstr, "Exception: %s (%lu)\n", XRQ_Name[xrq&7], xrq); 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_Y, (u32) dstime.bcd_M, (u32) dstime.bcd_D,
(u32) dstime.bcd_h, (u32) dstime.bcd_m, (u32) dstime.bcd_s); (u32) dstime.bcd_h, (u32) dstime.bcd_m, (u32) dstime.bcd_s);
for (int i = 0; i < 8; i++) { 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]); wstr += sprintf(wstr, "CPSR: %08lX\n\n", regs[16]);
/* Output registers to main screen */ /* Output registers to main screen */
u32 draw_width = GetDrawStringWidth(dumpstr); u32 draw_width = GetDrawStringWidth(dumpstr);
u32 draw_height = GetDrawStringHeight(dumpstr); u32 draw_height = GetDrawStringHeight(dumpstr);
@ -93,8 +91,8 @@ void XRQ_DumpRegisters(u32 xrq, u32 *regs)
} else { } else {
wstr += XRQ_DumpData_u32(wstr, pc-PC_DUMPRAD, pc+PC_DUMPRAD); wstr += XRQ_DumpData_u32(wstr, pc-PC_DUMPRAD, pc+PC_DUMPRAD);
} }
/* Draw QR Code */ /* Draw QR Code */
u8 qrcode[qrcodegen_BUFFER_LEN_MAX]; u8 qrcode[qrcodegen_BUFFER_LEN_MAX];
u8 temp[qrcodegen_BUFFER_LEN_MAX]; u8 temp[qrcodegen_BUFFER_LEN_MAX];

View File

@ -10,8 +10,9 @@
#include <brf.h> #include <brf.h>
.macro XRQ_FATAL id=0 .macro XRQ_FATAL id=0
adr sp, XRQ_Registers ldr sp, =__stack_abt
stmia sp!, {r0-r12} sub sp, sp, #(18*4) @ Reserve space for registers
stmia sp, {r0-r12}
mov r11, #\id mov r11, #\id
b XRQ_MainHandler b XRQ_MainHandler
.endm .endm
@ -28,10 +29,8 @@ XRQ_Vectors:
subs pc, lr, #4 @ IRQs are unhandled subs pc, lr, #4 @ IRQs are unhandled
b . @ FIQs are unused (except for debug?) b . @ FIQs are unused (except for debug?)
XRQ_Registers:
.space (17*4)
XRQ_Reset: XRQ_Reset:
msr cpsr_c, #(SR_ABT_MODE | SR_IRQ | SR_FIQ)
XRQ_FATAL 0 XRQ_FATAL 0
XRQ_Undefined: XRQ_Undefined:
@ -46,6 +45,7 @@ XRQ_PAbort:
XRQ_DAbort: XRQ_DAbort:
XRQ_FATAL 4 XRQ_FATAL 4
@ r11 = exception number
XRQ_MainHandler: XRQ_MainHandler:
mrs r10, cpsr mrs r10, cpsr
mrs r9, spsr mrs r9, spsr
@ -60,21 +60,47 @@ XRQ_MainHandler:
blx r6 blx r6
@ Retrieve banked registers @ Retrieve banked registers
and r0, r9, #(SR_PMODE_MASK) ands r0, r9, #(SR_PMODE_MASK & (0x0F))
cmp r0, #(SR_USR_MODE)
orreq r0, #(SR_SYS_MODE) 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 msr cpsr_c, r0 @ Switch to previous mode
mov r0, sp mov r0, sp
mov r1, lr mov r1, lr
msr cpsr_c, r10 @ Return to abort 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) ldr r2, =XRQ_DumpRegisters @ void XRQ_DumpRegisters(u32 xrq_id, u32 *regs)
adr r1, XRQ_Registers mov r1, sp
mov r0, r11 mov r0, r11
blx r2 blx r2
@ -86,6 +112,15 @@ XRQ_MainHandler:
.pool .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 .global XRQ_End
XRQ_End: XRQ_End:
.word 0