@ This file is part of Luma3DS @ Copyright (C) 2016-2017 Aurora Wright, TuxSH @ @ This program is free software: you can redistribute it and/or modify @ it under the terms of the GNU General Public License as published by @ the Free Software Foundation, either version 3 of the License, or @ (at your option) any later version. @ @ This program is distributed in the hope that it will be useful, @ but WITHOUT ANY WARRANTY; without even the implied warranty of @ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @ GNU General Public License for more details. @ @ You should have received a copy of the GNU General Public License @ along with this program. If not, see . @ @ Additional Terms 7.b and 7.c of GPLv3 apply to this file: @ * Requiring preservation of specified reasonable legal notices or @ author attributions in that material or in the Appropriate Legal @ Notices displayed by works containing it. @ * Prohibiting misrepresentation of the origin of that material, @ or requiring that modified versions of such material be marked in @ reasonable ways as different from the original version. .macro GEN_HANDLER name .global \name .type \name, %function \name: ldr sp, =#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 here, since we're going to reboot. stmfd sp!, {r0-r7} @ FIQ has its own r8-r14 regs ldr r1, =\@ @ macro expansion counter b _commonHandler .size \name, . - \name .endm .text .arm .align 4 .global _commonHandler .type _commonHandler, %function _commonHandler: mrs r2, spsr mov r6, sp mrs r3, cpsr orr r3, #0x1c0 @ disable Imprecise Aborts, IRQ and FIQ (equivalent to "cpsid aif" on arm11) msr cpsr_cx, r3 tst r2, #0x20 bne noSvcBreak cmp r1, #2 bne noSvcBreak sub r0, lr, #4 @ calling cannotAccessAddress cause more problems that it actually solves... (I've to save a lot of regs and that's a pain tbh) lsr r0, #20 @ we'll just do some address checks (to see if it's in ARM9 internal memory) cmp r0, #0x80 bne noSvcBreak ldr r4, [lr, #-4] ldr r5, =#0xe12fff7f cmp r4, r5 bne noSvcBreak bic r5, r3, #0xf orr r5, #0x3 msr cpsr_c, r5 @ switch to supervisor mode ldmfd sp, {r8-r11}^ ldr r2, [sp, #0x1c] @ implementation details of the official svc handler ldr r4, [sp, #0x18] msr cpsr_c, r3 @ restore processor mode tst r2, #0x20 addne lr, r4, #2 @ adjust address for later moveq lr, r4 noSvcBreak: ands r4, r2, #0xf @ get the mode that triggered the exception moveq r4, #0xf @ usr => sys bic r5, r3, #0xf orr r5, r4 msr cpsr_c, r5 @ change processor mode stmfd r6!, {r8-lr} msr cpsr_c, r3 @ restore processor mode mov sp, r6 stmfd sp!, {r2,lr} @ it's a bit of a mess, but we will fix that later @ order of saved regs now: cpsr, pc + (2/4/8), r8-r14, r0-r7 mov r0, sp b mainHandler GEN_HANDLER FIQHandler GEN_HANDLER undefinedInstructionHandler GEN_HANDLER prefetchAbortHandler GEN_HANDLER dataAbortHandler .global readMPUConfig .type readMPUConfig, %function readMPUConfig: stmfd sp!, {r4-r8, lr} mrc p15,0,r1,c6,c0,0 mrc p15,0,r2,c6,c1,0 mrc p15,0,r3,c6,c2,0 mrc p15,0,r4,c6,c3,0 mrc p15,0,r5,c6,c4,0 mrc p15,0,r6,c6,c5,0 mrc p15,0,r7,c6,c6,0 mrc p15,0,r8,c6,c7,0 stmia r0, {r1-r8} mrc p15,0,r0,c5,c0,2 @ read data access permission bits ldmfd sp!, {r4-r8, pc}