mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 13:42:47 +00:00
- enable the VFP on the ARM11
- stopped using the ITCM as the interrupt vector table - removed dead Thumb code handler in interrupt handling - added basic memory protection flags
This commit is contained in:
parent
8b098fa91a
commit
ca7944ce04
@ -5,7 +5,7 @@ TARGET := $(shell basename $(CURDIR))
|
|||||||
SOURCE := source
|
SOURCE := source
|
||||||
BUILD := build
|
BUILD := build
|
||||||
|
|
||||||
SUBARCH := -D$(PROCESSOR) -mcpu=mpcore -mtune=mpcore -mfloat-abi=soft -marm
|
SUBARCH := -D$(PROCESSOR) -marm -march=armv6k -mtune=mpcore -mfloat-abi=hard -mfpu=vfpv2 -mtp=soft
|
||||||
INCDIRS := source
|
INCDIRS := source
|
||||||
INCLUDE := $(foreach dir,$(INCDIRS),-I"$(shell pwd)/$(dir)")
|
INCLUDE := $(foreach dir,$(INCDIRS),-I"$(shell pwd)/$(dir)")
|
||||||
|
|
||||||
|
@ -25,7 +25,8 @@
|
|||||||
|
|
||||||
.global __boot
|
.global __boot
|
||||||
__boot:
|
__boot:
|
||||||
cpsid aif, #SR_SVC_MODE
|
cpsid aif, #SR_SVC_MODE
|
||||||
|
clrex
|
||||||
|
|
||||||
@ Writeback and invalidate all DCache
|
@ Writeback and invalidate all DCache
|
||||||
@ Invalidate all caches
|
@ Invalidate all caches
|
||||||
@ -44,6 +45,18 @@ __boot:
|
|||||||
mcr p15, 0, r1, c1, c0, 1
|
mcr p15, 0, r1, c1, c0, 1
|
||||||
mcr p15, 0, r2, c1, c0, 2
|
mcr p15, 0, r2, c1, c0, 2
|
||||||
|
|
||||||
|
@ VFPv2 init
|
||||||
|
@ https://github.com/derrekr/fastboot3DS/blob/f63c967369451b1fd0078e649cf0010fe10a62fd/source/arm11/start.s#L195
|
||||||
|
mov r0, #0
|
||||||
|
mov r1, #0xF00000 @ Give full access to cp10/11 in user and privileged mode
|
||||||
|
mov r2, #0x40000000 @ Clear exception bits and enable VFP11
|
||||||
|
mov r3, #0x3C00000 @ Round towards zero (RZ) mode, flush-to-zero mode, default NaN mode
|
||||||
|
mcr p15, 0, r1, c1, c0, 2 @ Write Coprocessor Access Control Register
|
||||||
|
mcr p15, 0, r0, c7, c5, 4 @ Flush Prefetch Buffer
|
||||||
|
fmxr fpexc, r2 @ Write Floating-point exception register
|
||||||
|
fmxr fpscr, r3 @ Write Floating-Point Status and Control Register
|
||||||
|
|
||||||
|
|
||||||
@ Get CPU ID
|
@ Get CPU ID
|
||||||
mrc p15, 0, r12, c0, c0, 5
|
mrc p15, 0, r12, c0, c0, 5
|
||||||
ands r12, r12, #3
|
ands r12, r12, #3
|
||||||
|
@ -5,7 +5,7 @@ TARGET := $(shell basename $(CURDIR))
|
|||||||
SOURCE := source
|
SOURCE := source
|
||||||
BUILD := build
|
BUILD := build
|
||||||
|
|
||||||
SUBARCH := -D$(PROCESSOR) -mcpu=arm946e-s -mtune=arm946e-s -mfloat-abi=soft -mno-thumb-interwork -marm
|
SUBARCH := -D$(PROCESSOR) -marm -march=armv5te -mtune=arm946e-s -mfloat-abi=soft -mno-thumb-interwork
|
||||||
INCDIRS := source source/common source/filesys source/crypto source/fatfs source/nand source/virtual source/game source/gamecart source/lodepng source/qrcodegen source/system source/utils
|
INCDIRS := source source/common source/filesys source/crypto source/fatfs source/nand source/virtual source/game source/gamecart source/lodepng source/qrcodegen source/system source/utils
|
||||||
INCLUDE := $(foreach dir,$(INCDIRS),-I"$(shell pwd)/$(dir)")
|
INCLUDE := $(foreach dir,$(INCDIRS),-I"$(shell pwd)/$(dir)")
|
||||||
|
|
||||||
|
45
arm9/link.ld
45
arm9/link.ld
@ -2,19 +2,46 @@ OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
|||||||
OUTPUT_ARCH(arm)
|
OUTPUT_ARCH(arm)
|
||||||
ENTRY(_start)
|
ENTRY(_start)
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
AHBWRAM (RWX) : ORIGIN = 0x08006000, LENGTH = 512K
|
||||||
|
VECTORS (RX) : ORIGIN = 0x08000000, LENGTH = 64
|
||||||
|
}
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 0x08006000;
|
.vectors : ALIGN(4) {
|
||||||
__start__ = ABSOLUTE(.);
|
__vectors_lma = LOADADDR(.vectors);
|
||||||
|
__vectors_vma = ABSOLUTE(.);
|
||||||
|
KEEP(*(.vectors));
|
||||||
|
. = ALIGN(4);
|
||||||
|
__vectors_len = ABSOLUTE(.) - __vectors_vma;
|
||||||
|
} >VECTORS AT>AHBWRAM
|
||||||
|
|
||||||
.text.start : ALIGN(4) { *(.text.start) }
|
.text : ALIGN(4) {
|
||||||
.text : ALIGN(4) { *(.text*) }
|
__text_s = ABSOLUTE(.);
|
||||||
.rodata : ALIGN(4) { *(.rodata*) }
|
*(.text.start);
|
||||||
.data : ALIGN(4) { *(.data*) }
|
*(.text*);
|
||||||
.bss : ALIGN(4) { __bss_start = .; *(.bss* COMMON); __bss_end = .;}
|
. = ALIGN(4);
|
||||||
|
__text_e = ABSOLUTE(.);
|
||||||
|
} >AHBWRAM
|
||||||
|
|
||||||
. = ALIGN(4);
|
.rodata : ALIGN(4) {
|
||||||
|
*(.rodata*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >AHBWRAM
|
||||||
|
|
||||||
|
.data : ALIGN(4) {
|
||||||
|
*(.data*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >AHBWRAM
|
||||||
|
|
||||||
|
.bss : ALIGN(4) {
|
||||||
|
__bss_start = .;
|
||||||
|
*(.bss*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_end = .;
|
||||||
|
} >AHBWRAM
|
||||||
|
|
||||||
__end__ = ABSOLUTE(.);
|
__end__ = ABSOLUTE(.);
|
||||||
__code_size__ = __end__ - __start__;
|
|
||||||
}
|
}
|
||||||
|
@ -32,18 +32,18 @@ _start:
|
|||||||
ldr r0, =BRF_INVALIDATE_ICACHE
|
ldr r0, =BRF_INVALIDATE_ICACHE
|
||||||
blx r0 @ Invalidate Instruction Cache
|
blx r0 @ Invalidate Instruction Cache
|
||||||
|
|
||||||
@ Disable caches / DTCM / MPU
|
@ Disable caches / TCMs / MPU
|
||||||
ldr r1, =(CR_MPU | CR_CACHES | CR_DTCM | CR_TCM_LOAD)
|
ldr r1, =(CR_MPU | CR_CACHES | CR_DTCM | CR_ITCM | CR_TCM_LOAD)
|
||||||
ldr r2, =(CR_ITCM)
|
|
||||||
mrc p15, 0, r0, c1, c0, 0
|
mrc p15, 0, r0, c1, c0, 0
|
||||||
bic r0, r1
|
bic r0, r1
|
||||||
orr r0, r2
|
|
||||||
mcr p15, 0, r0, c1, c0, 0
|
mcr p15, 0, r0, c1, c0, 0
|
||||||
|
|
||||||
@ Give full access to defined memory regions
|
@ Set access permissions
|
||||||
ldr r0, =0x33333333
|
ldr r0, =0x11111115 @ RO data access for BootROM, RW otherwise
|
||||||
mcr p15, 0, r0, c5, c0, 2 @ write data access
|
ldr r1, =0x00505005 @ Can only execute code from ARM9 RAM, FCRAM and BootROM
|
||||||
mcr p15, 0, r0, c5, c0, 3 @ write instruction access
|
|
||||||
|
mcr p15, 0, r0, c5, c0, 2
|
||||||
|
mcr p15, 0, r1, c5, c0, 3
|
||||||
|
|
||||||
@ Set MPU regions and cache settings
|
@ Set MPU regions and cache settings
|
||||||
ldr r0, =__mpu_regions
|
ldr r0, =__mpu_regions
|
||||||
@ -64,15 +64,12 @@ _start:
|
|||||||
mcr p15, 0, r0, c2, c0, 0 @ Data cacheable
|
mcr p15, 0, r0, c2, c0, 0 @ Data cacheable
|
||||||
mcr p15, 0, r0, c2, c0, 1 @ Inst cacheable
|
mcr p15, 0, r0, c2, c0, 1 @ Inst cacheable
|
||||||
|
|
||||||
@ Enable DTCM
|
@ Configure TCMs
|
||||||
ldr r0, =0x3000800A
|
ldr r0, =0x3000800A
|
||||||
mcr p15, 0, r0, c9, c1, 0 @ set the DTCM Region Register
|
ldr r1, =0x00000024
|
||||||
|
mcr p15, 0, r0, c9, c1, 0 @ DTCM
|
||||||
|
mcr p15, 0, r1, c9, c1, 1 @ ITCM
|
||||||
|
|
||||||
@ Fix SDMC mounting
|
|
||||||
@ (this is done in sdmmc.c instead)
|
|
||||||
@ mov r0, #0x10000000
|
|
||||||
@ mov r1, #0x340
|
|
||||||
@ strh r1, [r0, #0x20]
|
|
||||||
|
|
||||||
@ Setup heap
|
@ Setup heap
|
||||||
ldr r0, =fake_heap_start
|
ldr r0, =fake_heap_start
|
||||||
@ -84,18 +81,18 @@ _start:
|
|||||||
str r1, [r0]
|
str r1, [r0]
|
||||||
|
|
||||||
@ Install exception handlers
|
@ Install exception handlers
|
||||||
ldr r0, =XRQ_Start
|
ldr r0, =__vectors_lma
|
||||||
ldr r1, =XRQ_End
|
ldr r1, =__vectors_len
|
||||||
ldr r2, =0x00000000
|
ldr r2, =XRQ_Start
|
||||||
|
add r1, r0, r1
|
||||||
.LXRQ_Install:
|
.LXRQ_Install:
|
||||||
cmp r0, r1
|
cmp r0, r1
|
||||||
ldrlo r3, [r0], #4
|
ldrlo r3, [r0], #4
|
||||||
strlo r3, [r2], #4
|
strlo r3, [r2], #4
|
||||||
blo .LXRQ_Install
|
blo .LXRQ_Install
|
||||||
|
|
||||||
@ Enable caches / DTCM / select low exception vectors
|
@ Enable caches / TCMs / select high exception vectors
|
||||||
ldr r1, =(CR_ALT_VECTORS | CR_V4TLD)
|
ldr r2, =(CR_MPU | CR_CACHES | CR_ITCM | CR_DTCM | CR_ALT_VECTORS)
|
||||||
ldr r2, =(CR_MPU | CR_CACHES | CR_DTCM)
|
|
||||||
mrc p15, 0, r0, c1, c0, 0
|
mrc p15, 0, r0, c1, c0, 0
|
||||||
bic r0, r1
|
bic r0, r1
|
||||||
orr r0, r2
|
orr r0, r2
|
||||||
@ -162,7 +159,7 @@ _start:
|
|||||||
__mpu_regions:
|
__mpu_regions:
|
||||||
.word 0xFFFF001F @ FFFF0000 64k | bootrom (unprotected / protected)
|
.word 0xFFFF001F @ FFFF0000 64k | bootrom (unprotected / protected)
|
||||||
.word 0x3000801B @ 30008000 16k | dtcm
|
.word 0x3000801B @ 30008000 16k | dtcm
|
||||||
.word 0x00000035 @ 00000000 128M | itcm (+ mirrors)
|
.word 0x01FF8035 @ 01FF8000 32k | itcm (+ mirrors)
|
||||||
.word 0x08000029 @ 08000000 2M | arm9 mem (O3DS / N3DS)
|
.word 0x08000029 @ 08000000 2M | arm9 mem (O3DS / N3DS)
|
||||||
.word 0x10000029 @ 10000000 2M | io mem (ARM9 / first 2MB)
|
.word 0x10000029 @ 10000000 2M | io mem (ARM9 / first 2MB)
|
||||||
.word 0x20000037 @ 20000000 256M | fcram (O3DS / N3DS)
|
.word 0x20000037 @ 20000000 256M | fcram (O3DS / N3DS)
|
||||||
|
@ -15,23 +15,45 @@
|
|||||||
|
|
||||||
#include <arm.h>
|
#include <arm.h>
|
||||||
|
|
||||||
#define PC_DUMPRAD (0x30)
|
#define PC_DUMPRAD (0x40)
|
||||||
#define SP_DUMPLEN (0x60)
|
#define SP_DUMPLEN (0x30)
|
||||||
|
extern u32 __text_s, __text_e;
|
||||||
|
|
||||||
|
static bool sp_dumpable(u32 sp, u32 *sp_lower, u32 *sp_upper)
|
||||||
|
{
|
||||||
|
if ((sp >= __STACK_TOP) || (sp < (__STACK_TOP - __STACK_LEN)))
|
||||||
|
return false;
|
||||||
|
*sp_lower = sp;
|
||||||
|
*sp_upper = min(sp + SP_DUMPLEN, __STACK_TOP);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool pc_dumpable(u32 pc, u32 *pc_lower, u32 *pc_upper)
|
||||||
|
{
|
||||||
|
u32 code_start = (u32)(&__text_s), code_end = (u32)(&__text_e);
|
||||||
|
|
||||||
|
if ((pc >= code_end) || (pc < code_start))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*pc_lower = max(pc - PC_DUMPRAD, code_start);
|
||||||
|
*pc_upper = min(pc + PC_DUMPRAD, code_end);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#define XRQ_DUMPDATAFUNC(type, size) \
|
#define XRQ_DUMPDATAFUNC(type, size) \
|
||||||
int XRQ_DumpData_##type(char *b, u32 s, u32 e) \
|
static unsigned XRQ_DumpData_##type(char *b, u32 s, u32 e) \
|
||||||
{ \
|
{ \
|
||||||
char *c = b; \
|
char *c = b; \
|
||||||
while(s<e) { \
|
while(s<e) { \
|
||||||
b+=sprintf(b, "%08lX: ",s); \
|
b+=sprintf(b, "%08lX: ",s); \
|
||||||
type *dl = (type*)s; \
|
type *dl = (type*)s; \
|
||||||
for (u32 i=0; i<(16/((size)/2)); i++) { \
|
for (u32 i = 0; i < (16 / sizeof(type)); i++) { \
|
||||||
b+=sprintf(b, "%0" #size "lX ", (u32)dl[i]); \
|
b+=sprintf(b, "%0" #size "lX ", (u32)dl[i]); \
|
||||||
} \
|
} \
|
||||||
b+=sprintf(b, "\n"); \
|
b+=sprintf(b, "\n"); \
|
||||||
s+=16; \
|
s+=16; \
|
||||||
} \
|
} \
|
||||||
return (int)(b-c); \
|
return (unsigned)(b-c); \
|
||||||
}
|
}
|
||||||
XRQ_DUMPDATAFUNC(u8, 2)
|
XRQ_DUMPDATAFUNC(u8, 2)
|
||||||
XRQ_DUMPDATAFUNC(u16, 4)
|
XRQ_DUMPDATAFUNC(u16, 4)
|
||||||
@ -46,7 +68,7 @@ const char *XRQ_Name[] = {
|
|||||||
|
|
||||||
void XRQ_DumpRegisters(u32 xrq, u32 *regs)
|
void XRQ_DumpRegisters(u32 xrq, u32 *regs)
|
||||||
{
|
{
|
||||||
u32 sp, st, pc;
|
u32 sp, sp_lower, sp_upper, pc, pc_lower, pc_upper;
|
||||||
char dumpstr[2048], *wstr = dumpstr;
|
char dumpstr[2048], *wstr = dumpstr;
|
||||||
|
|
||||||
DsTime dstime;
|
DsTime dstime;
|
||||||
@ -75,24 +97,25 @@ void XRQ_DumpRegisters(u32 xrq, u32 *regs)
|
|||||||
ClearScreen(MAIN_SCREEN, COLOR_STD_BG);
|
ClearScreen(MAIN_SCREEN, COLOR_STD_BG);
|
||||||
DrawStringF(MAIN_SCREEN, draw_x, draw_y, COLOR_STD_FONT, COLOR_STD_BG, dumpstr);
|
DrawStringF(MAIN_SCREEN, draw_x, draw_y, COLOR_STD_FONT, COLOR_STD_BG, dumpstr);
|
||||||
|
|
||||||
|
|
||||||
/* Dump STACK */
|
/* Dump STACK */
|
||||||
sp = regs[13] & ~0xF;
|
sp = regs[13] & ~0xF;
|
||||||
st = __STACK_TOP;
|
if (sp_dumpable(sp, &sp_lower, &sp_upper)) {
|
||||||
wstr += sprintf(wstr, "Stack dump:\n");
|
wstr += sprintf(wstr, "Stack:\n");
|
||||||
wstr += XRQ_DumpData_u8(wstr, sp, min(sp+SP_DUMPLEN, st));
|
wstr += XRQ_DumpData_u8(wstr, sp_lower, sp_upper);
|
||||||
wstr += sprintf(wstr, "\n");
|
wstr += sprintf(wstr, "\n");
|
||||||
|
|
||||||
|
|
||||||
/* Dump TEXT */
|
|
||||||
pc = regs[15] & ~0xF;
|
|
||||||
wstr += sprintf(wstr, "Code dump:\n");
|
|
||||||
if (regs[16] & SR_THUMB) {
|
|
||||||
wstr += XRQ_DumpData_u16(wstr, pc-PC_DUMPRAD, pc+PC_DUMPRAD);
|
|
||||||
} else {
|
|
||||||
wstr += XRQ_DumpData_u32(wstr, pc-PC_DUMPRAD, pc+PC_DUMPRAD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Dump CODE */
|
||||||
|
pc = regs[15] & ~0xF;
|
||||||
|
if (pc_dumpable(pc, &pc_lower, &pc_upper)) {
|
||||||
|
wstr += sprintf(wstr, "Code:\n");
|
||||||
|
wstr += XRQ_DumpData_u32(wstr, pc_lower, pc_upper);
|
||||||
|
/*if (regs[16] & SR_THUMB) { // no need to take Thumb code into account
|
||||||
|
wstr += XRQ_DumpData_u16(wstr, pc-PC_DUMPRAD, pc+PC_DUMPRAD);
|
||||||
|
} else {
|
||||||
|
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];
|
||||||
|
@ -3,125 +3,95 @@
|
|||||||
Read LICENSE for more details
|
Read LICENSE for more details
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.section .text.xrqh
|
|
||||||
.arm
|
.arm
|
||||||
|
|
||||||
#include <arm.h>
|
#include <arm.h>
|
||||||
#include <brf.h>
|
#include <brf.h>
|
||||||
#include "memmap.h"
|
#include "memmap.h"
|
||||||
|
|
||||||
.macro XRQ_FATAL id=0
|
.macro TRAP_ENTRY xrq_id
|
||||||
ldr sp, =__STACK_ABT_TOP
|
msr cpsr_f, #(\xrq_id << 29) @ preserve xrq id (idea grabbed from fb3ds)
|
||||||
sub sp, sp, #(18*4) @ Reserve space for registers
|
|
||||||
stmia sp, {r0-r12}
|
|
||||||
mov r11, #\id
|
|
||||||
b XRQ_MainHandler
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
.section .vectors, "ax"
|
||||||
.global XRQ_Start
|
.global XRQ_Start
|
||||||
XRQ_Start:
|
XRQ_Start:
|
||||||
XRQ_Vectors:
|
ldr pc, IRQ_Vector
|
||||||
b XRQ_Reset
|
IRQ_Vector: .word IRQ_Handler
|
||||||
b XRQ_Undefined
|
ldr pc, FIQ_Vector
|
||||||
b XRQ_SWI
|
FIQ_Vector: .word FIQ_Handler
|
||||||
b XRQ_PAbort
|
ldr pc, SVC_Vector
|
||||||
b XRQ_DAbort
|
SVC_Vector: .word SVC_Handler
|
||||||
b . @ Reserved exception vector
|
ldr pc, UND_Vector
|
||||||
subs pc, lr, #4 @ IRQs are unhandled
|
UND_Vector: .word UND_Handler
|
||||||
b . @ FIQs are unused (except for debug?)
|
ldr pc, PABT_Vector
|
||||||
|
PABT_Vector: .word PABT_Handler
|
||||||
|
ldr pc, DABT_Vector
|
||||||
|
DABT_Vector: .word DABT_Handler
|
||||||
|
.global XRQ_End
|
||||||
|
XRQ_End:
|
||||||
|
|
||||||
XRQ_Reset:
|
|
||||||
msr cpsr_c, #(SR_ABT_MODE | SR_NOINT)
|
|
||||||
XRQ_FATAL 0
|
|
||||||
|
|
||||||
XRQ_Undefined:
|
.section .text.xrqs
|
||||||
XRQ_FATAL 1
|
IRQ_Handler:
|
||||||
|
TRAP_ENTRY 6
|
||||||
|
b XRQ_Fatal
|
||||||
|
|
||||||
XRQ_SWI:
|
FIQ_Handler:
|
||||||
XRQ_FATAL 2
|
TRAP_ENTRY 7
|
||||||
|
b XRQ_Fatal
|
||||||
|
|
||||||
XRQ_PAbort:
|
SVC_Handler:
|
||||||
XRQ_FATAL 3
|
TRAP_ENTRY 2
|
||||||
|
b XRQ_Fatal
|
||||||
|
|
||||||
XRQ_DAbort:
|
UND_Handler:
|
||||||
XRQ_FATAL 4
|
TRAP_ENTRY 1
|
||||||
|
b XRQ_Fatal
|
||||||
|
|
||||||
@ r11 = exception number
|
PABT_Handler:
|
||||||
XRQ_MainHandler:
|
TRAP_ENTRY 3
|
||||||
mrs r10, cpsr
|
b XRQ_Fatal
|
||||||
mrs r9, spsr
|
|
||||||
mov r8, lr
|
|
||||||
|
|
||||||
@ Disable mpu / caches
|
DABT_Handler:
|
||||||
ldr r4, =BRF_WB_INV_DCACHE
|
sub lr, lr, #4 @ R14_abt = PC + 8, so it needs a small additional fixup
|
||||||
ldr r5, =BRF_INVALIDATE_ICACHE
|
TRAP_ENTRY 4
|
||||||
ldr r6, =BRF_RESETCP15
|
@b XRQ_Fatal
|
||||||
blx r4
|
|
||||||
blx r5
|
|
||||||
blx r6
|
|
||||||
|
|
||||||
@ Retrieve banked registers
|
XRQ_Fatal:
|
||||||
ands r0, r9, #(SR_PMODE_MASK & (0x0F))
|
sub lr, lr, #4 @ PC exception fixup
|
||||||
orreq r0, #(SR_SYS_MODE)
|
|
||||||
orr r0, #(0x10 | SR_NOINT)
|
|
||||||
|
|
||||||
msr cpsr_c, r0 @ Switch to previous mode
|
ldr sp, =(__STACK_ABT_TOP - 18*4) @ Set up abort stack, 8 byte aligned
|
||||||
mov r0, sp
|
stmia sp, {r0-r7} @ Preserve non-banked GPRs
|
||||||
mov r1, lr
|
|
||||||
msr cpsr_c, r10 @ Return to abort
|
|
||||||
|
|
||||||
add r2, sp, #(13*4)
|
mrs r1, cpsr
|
||||||
stmia r2, {r0, r1, r8, r9}
|
orr r0, r1, #SR_NOINT
|
||||||
|
msr cpsr_c, r0 @ Disable interrupts
|
||||||
|
|
||||||
@ Give read/write access to all the memory regions
|
lsr r0, r1, #29 @ Retrieve exception source
|
||||||
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
|
mrs r2, spsr
|
||||||
adr r0, __abt_mpu_regions
|
str lr, [sp, #15*4]
|
||||||
ldmia r0, {r1-r8}
|
str r2, [sp, #16*4] @ Preserve exception PC and CPSR
|
||||||
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
|
ands r2, r2, #SR_PMODE_MASK
|
||||||
ldr r1, =(CR_MPU | CR_CACHES | CR_DTCM)
|
orreq r2, r2, #SR_SYS_MODE @ Force a switch to system mode if
|
||||||
mrc p15, 0, r0, c1, c0, 0
|
@ the exception happened in user mode
|
||||||
orr r0, r0, r1
|
orr r2, r2, #(0x10 | SR_NOINT) @ With interrupts disabled
|
||||||
mcr p15, 0, r0, c1, c0, 0
|
|
||||||
|
add r3, sp, #8*4
|
||||||
|
msr cpsr_c, r2
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
stmia r3, {r8-r14} @ Preserve banked GPRs (R8-R12, SP_xrq, LR_xrq)
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
msr cpsr_c, r1
|
||||||
|
|
||||||
ldr r2, =XRQ_DumpRegisters @ void XRQ_DumpRegisters(u32 xrq_id, u32 *regs)
|
|
||||||
mov r1, sp
|
mov r1, sp
|
||||||
mov r0, r11
|
bl XRQ_DumpRegisters @ XRQ_DumpRegisters(exception_number, saved_regs);
|
||||||
blx r2
|
|
||||||
|
|
||||||
msr cpsr, #(SR_SVC_MODE | SR_NOINT)
|
|
||||||
mov r0, #0
|
mov r0, #0
|
||||||
1:
|
1:
|
||||||
mcr p15, 0, r0, c7, c0, 4
|
mcr p15, 0, r0, c7, c0, 4
|
||||||
b 1b
|
b 1b
|
||||||
|
|
||||||
.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:
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user