diff --git a/include/arm.h b/include/arm.h new file mode 100644 index 0000000..9bffb08 --- /dev/null +++ b/include/arm.h @@ -0,0 +1,43 @@ +#pragma once + +/* + * This file is part of fastboot 3DS + * Copyright (C) 2017 derrek, profi200 + * + * 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 . + */ + + +// Program status register (CPSR/SPSR) +#define PSR_USER_MODE (16) +#define PSR_FIQ_MODE (17) +#define PSR_IRQ_MODE (18) +#define PSR_SVC_MODE (19) +#define PSR_ABORT_MODE (23) +#define PSR_UNDEF_MODE (27) +#define PSR_SYS_MODE (31) +#define PSR_MODE_MASK (PSR_SYS_MODE) + +#define PSR_T (1<<5) // Thumb mode +#define PSR_F (1<<6) // Interrupts (FIQ) disable flag +#define PSR_I (1<<7) // Interrupts (IRQ) disable flag +#define PSR_A (1<<8) // Imprecise aborts disable flag +#define PSR_E (1<<9) // Big endian +#define PSR_J (1<<24) // Jazelle mode +#define PSR_Q (1<<27) +#define PSR_V (1<<28) // Overflow flag +#define PSR_C (1<<29) // Carry flag +#define PSR_Z (1<<30) // Zero flag +#define PSR_N (1<<31) // Negative flag +#define PSR_INT_OFF (PSR_I | PSR_F) // IRQ and FIQ disabled flags diff --git a/include/arm11/hardware/interrupt.h b/include/arm11/hardware/interrupt.h index 9264fba..d712fa6 100644 --- a/include/arm11/hardware/interrupt.h +++ b/include/arm11/hardware/interrupt.h @@ -18,6 +18,7 @@ * along with this program. If not, see . */ +#include "arm.h" #include "types.h" @@ -135,12 +136,12 @@ u32 tmp; __asm__("mrs %0, cpsr" : "=r" (tmp) : ); __asm__ volatile("cpsid i" : : : "memory"); - return tmp & 0x80; + return tmp & PSR_I; } static inline void leaveCriticalSection(u32 oldState) { u32 tmp; __asm__ volatile("mrs %0, cpsr" : "=r" (tmp) : ); - __asm__ volatile("msr cpsr_c, %0" : : "r" ((tmp & ~0x80u) | oldState) : "memory"); + __asm__ volatile("msr cpsr_c, %0" : : "r" ((tmp & ~PSR_I) | oldState) : "memory"); } diff --git a/include/arm9/hardware/interrupt.h b/include/arm9/hardware/interrupt.h index 99e438a..2ce4a6a 100644 --- a/include/arm9/hardware/interrupt.h +++ b/include/arm9/hardware/interrupt.h @@ -18,6 +18,7 @@ * along with this program. If not, see . */ +#include "arm.h" #include "types.h" @@ -92,13 +93,13 @@ { u32 tmp; __asm__ volatile("mrs %0, cpsr" : "=r" (tmp) : ); - __asm__ volatile("msr cpsr_c, %0" : : "r" (tmp | 0x80) : "memory"); - return tmp & 0x80; + __asm__ volatile("msr cpsr_c, %0" : : "r" (tmp | PSR_I) : "memory"); + return tmp & PSR_I; } static inline void leaveCriticalSection(u32 oldState) { u32 tmp; __asm__ volatile("mrs %0, cpsr" : "=r" (tmp) : ); - __asm__ volatile("msr cpsr_c, %0" : : "r" ((tmp & ~0x80u) | oldState) : "memory"); + __asm__ volatile("msr cpsr_c, %0" : : "r" ((tmp & ~PSR_I) | oldState) : "memory"); } diff --git a/source/arm11/hardware/exception.s b/source/arm11/hardware/exception.s index 50a9652..645eb98 100644 --- a/source/arm11/hardware/exception.s +++ b/source/arm11/hardware/exception.s @@ -16,7 +16,9 @@ * along with this program. If not, see . */ +#include "arm.h" #include "asmfunc.h" +#include "mem_map.h" .arm .cpu mpcore @@ -29,21 +31,21 @@ ASM_FUNC undefInstrHandler - msr cpsr_f, #(0<<29) @ Abuse conditional flags in cpsr for temporary exception type storage + msr cpsr_f, #0<<29 @ Abuse conditional flags in cpsr for temporary exception type storage b exceptionHandler ASM_FUNC prefetchAbortHandler - msr cpsr_f, #(1<<29) + msr cpsr_f, #1<<29 b exceptionHandler ASM_FUNC dataAbortHandler - msr cpsr_f, #(2<<29) + msr cpsr_f, #2<<29 ASM_FUNC exceptionHandler sub sp, #68 stmia sp, {r0-r14}^ @ Save all user/system mode regs except pc mrs r2, spsr @ Get saved cpsr mrs r3, cpsr lsr r0, r3, #29 @ Get back the exception type from cpsr - and r1, r2, #0x1F - cmp r1, #0x10 @ User mode + and r1, r2, #PSR_MODE_MASK + cmp r1, #PSR_USER_MODE beq exceptionHandler_skip_other_mode add r4, sp, #32 msr cpsr_c, r2 @@ -63,10 +65,10 @@ ASM_FUNC irqHandler sub lr, lr, #4 - srsfd sp!, #31 @ Store lr and spsr on system mode stack - cps #31 @ Switch to system mode + srsfd sp!, #PSR_SYS_MODE @ Store lr and spsr on system mode stack + cps #PSR_SYS_MODE stmfd sp!, {r0-r3, r12, lr} - ldr r12, =0x17E00000 + ldr r12, =MPCORE_PRIV_REG_BASE ldr r0, [r12, #0x10C] @ REG_CPU_II_AKN and r1, r0, #0x7F cmp r1, #32 @@ -82,7 +84,7 @@ str r0, [sp, #-4]! @ A single ldr/str can't be interrupted blx r3 ldr r0, [sp], #4 - ldr r12, =0x17E00000 + ldr r12, =MPCORE_PRIV_REG_BASE cpsid i irqHandler_skip_processing: str r0, [r12, #0x110] @ REG_CPU_II_EOI diff --git a/source/arm11/start.s b/source/arm11/start.s index 304e310..b918581 100644 --- a/source/arm11/start.s +++ b/source/arm11/start.s @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +#include "arm.h" #include "mem_map.h" .arm @@ -74,7 +75,7 @@ _start: - cpsid aif, #19 @ Disable all interrupts, SVC mode + cpsid aif, #PSR_SVC_MODE @ Control register: @ [29] Force AP functionality : disabled @@ -105,15 +106,16 @@ bleq stubExceptionVectors @ Stub the vectors in AXIWRAM bootrom vectors jump to mov sp, #0 @ unused SVC mode sp - cps #23 @ Abort mode - ldr sp, =A11_EXC_STACK_END - cps #27 @ Undefined mode - ldr sp, =A11_EXC_STACK_END - cps #17 @ FIQ mode + cps #PSR_FIQ_MODE mov sp, #0 @ Unused - cps #18 @ IRQ mode + cps #PSR_IRQ_MODE mov sp, #0 @ not needed - cps #31 @ System mode + cps #PSR_ABORT_MODE + ldr r0, =A11_EXC_STACK_END + mov sp, r0 + cps #PSR_UNDEF_MODE + mov sp, r0 + cps #PSR_SYS_MODE adr r2, _sysmode_stacks ldr sp, [r2, r4, lsl #2] @@ -216,7 +218,7 @@ deinitCpu: mov r3, lr - cpsid aif, #31 @ System mode + cpsid aif, #PSR_SYS_MODE bl stubExceptionVectors bl flushDCache mov r2, #0 diff --git a/source/arm9/hardware/exception.s b/source/arm9/hardware/exception.s index 02f9dda..fe74bf0 100644 --- a/source/arm9/hardware/exception.s +++ b/source/arm9/hardware/exception.s @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +#include "arm.h" #include "asmfunc.h" #include "mem_map.h" @@ -30,21 +31,21 @@ ASM_FUNC undefInstrHandler - msr cpsr_f, #(0<<29) @ Abuse conditional flags in cpsr for temporary exception type storage + msr cpsr_f, #0<<29 @ Abuse conditional flags in cpsr for temporary exception type storage b exceptionHandler ASM_FUNC prefetchAbortHandler - msr cpsr_f, #(1<<29) + msr cpsr_f, #1<<29 b exceptionHandler ASM_FUNC dataAbortHandler - msr cpsr_f, #(2<<29) + msr cpsr_f, #2<<29 ASM_FUNC exceptionHandler sub sp, #68 stmia sp, {r0-r14}^ @ Save all user/system mode regs except pc mrs r2, spsr @ Get saved cpsr mrs r3, cpsr lsr r0, r3, #29 @ Get back the exception type from cpsr - and r1, r2, #0x1F - cmp r1, #0x10 @ User mode + and r1, r2, #PSR_MODE_MASK + cmp r1, #PSR_USER_MODE beq exceptionHandler_skip_other_mode add r4, sp, #32 msr cpsr_c, r2 @@ -65,7 +66,7 @@ ASM_FUNC irqHandler sub lr, lr, #4 stmfd sp!, {r0-r3, r12, lr} - ldr r12, =0x10001000 @ REG_IRQ_IE + ldr r12, =IO_MEM_ARM9_ONLY + 0x1000 @ REG_IRQ_IE ldrd r0, r1, [r12] and r1, r0, r1 mov r3, #0x80000000 @@ -82,11 +83,11 @@ beq irqHandler_skip_processing mrs r3, spsr str r3, [sp, #-4]! - msr cpsr_c, #0x5F @ System mode, IRQ enabled + msr cpsr_c, #PSR_F | PSR_SYS_MODE str lr, [sp, #-4]! @ A single ldr/str can't be interrupted blx r2 ldr lr, [sp], #4 - msr cpsr_c, #0xD2 @ IRQ mode, IRQ disabled + msr cpsr_c, #PSR_INT_OFF | PSR_IRQ_MODE ldr r0, [sp], #4 msr spsr_cxsf, r0 irqHandler_skip_processing: diff --git a/source/arm9/start.s b/source/arm9/start.s index e89e0db..6ae93f2 100644 --- a/source/arm9/start.s +++ b/source/arm9/start.s @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +#include "arm.h" #include "mem_map.h" .arm @@ -57,7 +58,7 @@ .word (VERS_MAJOR<<16 | VERS_MINOR) _start: - msr cpsr_cxsf, #0xD3 @ Disable all interrupts, SVC mode + msr cpsr_cxsf, #PSR_INT_OFF | PSR_SVC_MODE @ Control register: @ [19] ITCM load mode : disabled @@ -82,13 +83,13 @@ bl setupTcms @ Setup and enable DTCM and ITCM mov sp, #0 @ unused SVC mode sp - msr cpsr_cxsf, #0xD7 @ Abort mode - mov sp, #A9_EXC_STACK_END - msr cpsr_cxsf, #0xDB @ Undefined mode - mov sp, #A9_EXC_STACK_END - msr cpsr_cxsf, #0xD2 @ IRQ mode + msr cpsr_cxsf, #PSR_INT_OFF | PSR_IRQ_MODE ldr sp, =A9_IRQ_STACK_END - msr cpsr_cxsf, #0xDF @ System mode + msr cpsr_cxsf, #PSR_INT_OFF | PSR_ABORT_MODE + mov sp, #A9_EXC_STACK_END + msr cpsr_cxsf, #PSR_INT_OFF | PSR_UNDEF_MODE + mov sp, #A9_EXC_STACK_END + msr cpsr_cxsf, #PSR_INT_OFF | PSR_SYS_MODE ldr sp, =A9_STACK_END bl setupMpu @@ -283,7 +284,7 @@ deinitCpu: mov r3, lr - msr cpsr_cxsf, #0xDF @ System mode + msr cpsr_cxsf, #PSR_INT_OFF | PSR_SYS_MODE @ Stub vectors to endless loops mov r0, #A9_RAM_BASE mov r1, #6