summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arm9/asm/OS_exception.s172
-rw-r--r--arm9/lib/include/OS_exception.h26
-rw-r--r--arm9/lib/include/OS_init.h1
-rw-r--r--arm9/lib/include/mmap.h2
-rw-r--r--arm9/lib/src/OS_exception.c158
-rw-r--r--arm9/lib/src/OS_init.c1
6 files changed, 187 insertions, 173 deletions
diff --git a/arm9/asm/OS_exception.s b/arm9/asm/OS_exception.s
deleted file mode 100644
index 85b378d4..00000000
--- a/arm9/asm/OS_exception.s
+++ /dev/null
@@ -1,172 +0,0 @@
- .include "asm/macros.inc"
- .include "global.inc"
-
- .section .bss
-
- .global OSi_UserExceptionHandler
-OSi_UserExceptionHandler: ; 0x021D371C
- .space 0x4
-
- .global OSi_UserExceptionHandlerArg
-OSi_UserExceptionHandlerArg: ; 0x021D3720
- .space 0x4
-
- .global OSi_DebuggerHandler
-OSi_DebuggerHandler: ; 0x021D3724
- .space 0x4
-
- .global OSi_ExContext
-OSi_ExContext: ; 0x021D3728
- .space 0x80
-
- .text
-
- arm_func_start OSi_ExceptionHandler
-OSi_ExceptionHandler: ; 0x020CC9FC
- ldr ip, _020CCA68 ; =OSi_DebuggerHandler
- ldr r12, [r12, #0x0]
- cmp r12, #0x0
- movne lr, pc
- bxne r12
- ldr ip, _020CCA6C ; =0x02000000
- stmdb r12!, {r0-r3,sp-lr}
- and r0, sp, #0x1
- mov sp, r12
- mrs r1, cpsr
- and r1, r1, #0x1f
- teq r1, #0x17
- bne _020CCA38
- bl OSi_GetAndDisplayContext
- b _020CCA44
-_020CCA38:
- teq r1, #0x1b
- bne _020CCA44
- bl OSi_GetAndDisplayContext
-_020CCA44:
- ldr ip, _020CCA68 ; =OSi_DebuggerHandler
- ldr r12, [r12, #0x0]
- cmp r12, #0x0
-_020CCA50:
- beq _020CCA50
-_020CCA54:
- mov r0, r0
- b _020CCA54
-_020CCA5C:
- ldmia sp!, {r0-r3,ip,lr}
- mov sp, ip
- bx lr
-_020CCA68: .word OSi_DebuggerHandler
-_020CCA6C: .word 0x02000000
-
- arm_func_start OSi_GetAndDisplayContext
-OSi_GetAndDisplayContext: ; 0x020CCA70
- stmdb sp!, {r0,lr}
- bl OSi_SetExContext
- bl OSi_DisplayExContext
- ldmia sp!, {r0,lr}
- bx lr
-
- arm_func_start OSi_SetExContext
-OSi_SetExContext: ; 0x020CCA84
- ldr r1, _020CCB10 ; =OSi_ExContext
- mrs r2, cpsr
- str r2, [r1, #0x74]
- str r0, [r1, #0x6c]
- ldr r0, [r12, #0x0]
- str r0, [r1, #0x4]
- ldr r0, [r12, #0x4]
- str r0, [r1, #0x8]
- ldr r0, [r12, #0x8]
- str r0, [r1, #0xc]
- ldr r0, [r12, #0xc]
- str r0, [r1, #0x10]
- ldr r2, [r12, #0x10]
- bic r2, r2, #0x1
- add r0, r1, #0x14
- stmia r0, {r4-r11}
- str r12, [r1, #0x70]
- ldr r0, [r2, #0x0]
- str r0, [r1, #0x64]
- ldr r3, [r2, #0x4]
- str r3, [r1, #0x0]
- ldr r0, [r2, #0x8]
- str r0, [r1, #0x34]
- ldr r0, [r2, #0xc]
- str r0, [r1, #0x40]
- mrs r0, cpsr
- orr r3, r3, #0x80
- bic r3, r3, #0x20
- msr cpsr_fsxc, r3
- str sp, [r1, #0x38]
- str lr, [r1, #0x3c]
- mrs r2, spsr
- str r2, [r1, #0x7c]
- msr cpsr_fsxc, r0
- bx lr
- .balign 4
-_020CCB10: .word OSi_ExContext
-
- arm_func_start OSi_DisplayExContext
-OSi_DisplayExContext: ; 0x020CCB14
- stmdb sp!, {lr}
- sub sp, sp, #0x4
- ldr r0, _020CCB70 ; =OSi_UserExceptionHandler
- ldr r0, [r0, #0x0]
- cmp r0, #0x0
- addeq sp, sp, #0x4
- ldmeqia sp!, {lr}
- bxeq lr
- mov r0, sp
- ldr r1, _020CCB74 ; =0x0000009F
- msr cpsr_fsxc, r1
- mov sp, r0
- bl OS_EnableProtectionUnit
- ldr r1, _020CCB78 ; =OSi_UserExceptionHandlerArg
- ldr r0, _020CCB70 ; =OSi_UserExceptionHandler
- ldr r1, [r1, #0x0]
- ldr r2, [r0, #0x0]
- ldr r0, _020CCB7C ; =OSi_ExContext
- blx r2
- bl OS_DisableProtectionUnit
- add sp, sp, #0x4
- ldmia sp!, {lr}
- bx lr
- .balign 4
-_020CCB70: .word OSi_UserExceptionHandler
-_020CCB74: .word 0x0000009F
-_020CCB78: .word OSi_UserExceptionHandlerArg
-_020CCB7C: .word OSi_ExContext
-
- arm_func_start OS_InitException
-OS_InitException: ; 0x020CCB80
- ldr r0, _020CCBDC ; =0x027FFD9C
- ldr r1, [r0, #0x0]
- cmp r1, #0x2600000
- blo _020CCBA0
- cmp r1, #0x2800000
- ldrlo r0, _020CCBE0 ; =OSi_DebuggerHandler
- strcc r1, [r0, #0x0]
- blo _020CCBAC
-_020CCBA0:
- ldr r0, _020CCBE0 ; =OSi_DebuggerHandler
- mov r1, #0x0
- str r1, [r0, #0x0]
-_020CCBAC:
- ldr r0, _020CCBE0 ; =OSi_DebuggerHandler
- ldr r0, [r0, #0x0]
- cmp r0, #0x0
- ldreq r2, _020CCBE4 ; =OSi_ExceptionHandler
- ldreq r1, _020CCBDC ; =0x027FFD9C
- ldreq r0, _020CCBE8 ; =0x027E3000
- streq r2, [r1, #0x0]
- streq r2, [r0, #0xfdc]
- ldr r0, _020CCBEC ; =OSi_UserExceptionHandler
- mov r1, #0x0
- str r1, [r0, #0x0]
- bx lr
- .balign 4
-_020CCBDC: .word 0x027FFD9C
-_020CCBE0: .word OSi_DebuggerHandler
-_020CCBE4: .word OSi_ExceptionHandler
-_020CCBE8: .word 0x027E3000
-_020CCBEC: .word OSi_UserExceptionHandler
diff --git a/arm9/lib/include/OS_exception.h b/arm9/lib/include/OS_exception.h
new file mode 100644
index 00000000..68caf856
--- /dev/null
+++ b/arm9/lib/include/OS_exception.h
@@ -0,0 +1,26 @@
+#ifndef POKEDIAMOND_OS_EXCEPTION_H
+#define POKEDIAMOND_OS_EXCEPTION_H
+
+#include "consts.h"
+#include "OS_context.h"
+
+typedef struct
+{
+ OSContext context;
+ u32 cp15;
+ u32 spsr;
+ u32 exinfo;
+ u32 debug[4];
+} OSiExContext;
+
+typedef void (*OSExceptionHandler) (u32, void *);
+
+static void OSi_ExceptionHandler(void);
+
+void OS_InitException(void);
+void OSi_ExceptionHandler(void);
+static void OSi_GetAndDisplayContext(void);
+static void OSi_SetExContext(void);
+static void OSi_DisplayExContext(void);
+
+#endif //POKEDIAMOND_OS_EXCEPTION_H
diff --git a/arm9/lib/include/OS_init.h b/arm9/lib/include/OS_init.h
index 7cf21709..499c9f6c 100644
--- a/arm9/lib/include/OS_init.h
+++ b/arm9/lib/include/OS_init.h
@@ -23,6 +23,7 @@
#include "OS_irqTable.h"
#include "OS_interrupt.h"
#include "OS_reset.h"
+#include "OS_exception.h"
void OS_Init(void);
diff --git a/arm9/lib/include/mmap.h b/arm9/lib/include/mmap.h
index 12823fa0..143b609b 100644
--- a/arm9/lib/include/mmap.h
+++ b/arm9/lib/include/mmap.h
@@ -19,6 +19,8 @@ extern u32 SDK_AUTOLOAD_DTCM_START[];
#define HW_DTCM_SYSRV (HW_DTCM + 0x00003fc0)
#define HW_INTR_CHECK_BUF (HW_DTCM_SYSRV + 0x38)
+#define HW_EXCP_VECTOR_BUF (HW_DTCM_SYSRV + 0x1C)
+
#define HW_CARD_ROM_HEADER_SIZE 0x00000160
#define HW_DOWNLOAD_PARAMETER_SIZE 0x00000020
diff --git a/arm9/lib/src/OS_exception.c b/arm9/lib/src/OS_exception.c
new file mode 100644
index 00000000..5a66b2c4
--- /dev/null
+++ b/arm9/lib/src/OS_exception.c
@@ -0,0 +1,158 @@
+#include "OS_exception.h"
+#include "function_target.h"
+#include "OS_protectionUnit.h"
+
+static OSiExContext OSi_ExContext;
+
+static OSExceptionHandler OSi_UserExceptionHandler;
+static void *OSi_UserExceptionHandlerArg;
+
+static void *OSi_DebuggerHandler = NULL;
+
+#define HW_EXCEP_VECTOR_BUF_FOR_DEBUGGER 0x027ffd9c
+
+ARM_FUNC void OS_InitException(void)
+{
+ if (0x2600000 <= *(u32 *)HW_EXCEP_VECTOR_BUF_FOR_DEBUGGER
+ && *(u32 *)HW_EXCEP_VECTOR_BUF_FOR_DEBUGGER < 0x2800000)
+ {
+ OSi_DebuggerHandler = *(void **)HW_EXCEP_VECTOR_BUF_FOR_DEBUGGER;
+ }
+ else
+ {
+ OSi_DebuggerHandler = NULL;
+ }
+
+ if (!OSi_DebuggerHandler)
+ {
+ *(u32 *)(HW_EXCEP_VECTOR_BUF_FOR_DEBUGGER) = (u32)OSi_ExceptionHandler;
+
+ *(u32 *)(HW_EXCP_VECTOR_BUF) = (u32)OSi_ExceptionHandler;
+ }
+
+ OSi_UserExceptionHandler = NULL;
+}
+
+ARM_FUNC asm void OSi_ExceptionHandler(void)
+{
+ ldr r12, =OSi_DebuggerHandler
+ ldr r12, [r12]
+ cmp r12, #0
+ movne lr, pc
+ bxne r12
+
+ ldr r12, =HW_ITCM_END
+ stmfd r12!, {r0-r3, sp, lr}
+
+ and r0, sp, #1
+ mov sp, r12
+
+ mrs r1, cpsr
+ and r1, r1, #0x1f
+
+ teq r1, #0x17
+ bne _020CCA38
+ bl OSi_GetAndDisplayContext
+ b _020CCA44
+
+_020CCA38:
+ teq r1, #0x1b
+ bne _020CCA44
+ bl OSi_GetAndDisplayContext
+
+_020CCA44:
+ ldr r12, =OSi_DebuggerHandler
+ ldr r12, [r12]
+ cmp r12, #0
+
+_020CCA50:
+ beq _020CCA50
+
+_020CCA54:
+ mov r0, r0
+ b _020CCA54
+
+ ldmfd sp!, {r0-r3, r12, lr}
+ mov sp, r12
+ bx lr
+}
+
+ARM_FUNC static asm void OSi_GetAndDisplayContext(void)
+{
+ stmfd sp!, {r0, lr}
+
+ bl OSi_SetExContext
+ bl OSi_DisplayExContext
+
+ ldmfd sp!, {r0, lr}
+ bx lr
+}
+
+ARM_FUNC static asm void OSi_SetExContext(void)
+{
+ ldr r1, =OSi_ExContext;
+
+ mrs r2, cpsr
+ str r2, [r1, #OSiExContext.debug[1]]
+
+ str r0, [r1, #OSiExContext.exinfo]
+
+ ldr r0, [r12, #0]
+ str r0, [r1, #4]
+ ldr r0, [r12, #4]
+ str r0, [r1, #8]
+ ldr r0, [r12, #8]
+ str r0, [r1, #12]
+ ldr r0, [r12, #12]
+ str r0, [r1, #16]
+ ldr r2, [r12, #16]
+ bic r2, r2, #1
+
+ add r0, r1, #20
+ stmia r0, {r4-r11}
+
+ str r12, [r1, #OSiExContext.debug[0]]
+
+ ldr r0, [r2, #0]
+ str r0, [r1, #OSiExContext.cp15]
+ ldr r3, [r2, #4]
+ str r3, [r1, #0]
+ ldr r0, [r2, #8]
+ str r0, [r1, #52]
+ ldr r0, [r2, #12]
+ str r0, [r1, #64]
+
+ mrs r0, cpsr
+ orr r3, r3, #0x80
+ bic r3, r3, #0x20
+ msr cpsr_cxsf, r3
+
+ str sp, [r1, #56]
+ str lr, [r1, #60]
+ mrs r2, spsr
+
+ str r2, [r1, #OSiExContext.debug[3]]
+
+ msr cpsr_cxsf, r0
+ bx lr
+}
+
+ARM_FUNC static void OSi_DisplayExContext(void)
+{
+ if (OSi_UserExceptionHandler)
+ {
+ asm
+ {
+ mov r0, sp
+ ldr r1, =0x9f
+ msr CPSR_cxsf, r1
+ mov sp, r0
+ }
+
+ OS_EnableProtectionUnit();
+
+ ((void (*)(u32, void *))OSi_UserExceptionHandler)((u32)&OSi_ExContext, OSi_UserExceptionHandlerArg);
+
+ OS_DisableProtectionUnit();
+ }
+}
diff --git a/arm9/lib/src/OS_init.c b/arm9/lib/src/OS_init.c
index a8f36f00..c93b1584 100644
--- a/arm9/lib/src/OS_init.c
+++ b/arm9/lib/src/OS_init.c
@@ -2,7 +2,6 @@
#include "OS_init.h"
extern void PXI_Init(void);
-extern void OS_InitException(void);
extern void MI_Init(void);
extern void OS_InitVAlarm(void);
extern void OSi_InitVramExclusive(void);