diff --git a/bootloader/exception_handlers.S b/bootloader/exception_handlers.S
new file mode 100644
index 0000000..6b497a8
--- /dev/null
+++ b/bootloader/exception_handlers.S
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2019 CTCaer
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 .
+ */
+
+/*
+ * Armv7tdmi Status register.
+ *
+ * bit0: Mode 0.
+ * bit1: Mode 1.
+ * bit2: Mode 2.
+ * bit3: Mode 3.
+ * bit4: Mode 4.
+ * bit5: Thumb state.
+ * bit6: FIQ disable.
+ * bit7: IRQ disable.
+ * bit8-27: Reserved.
+ * bit28: Overflow condition.
+ * bit29: Carry/Borrow/Extend condition.
+ * bit30: Zero condition.
+ * bit31: Negative/Less than condition.
+ *
+ * M[4:0] | Mode | Visible Thumb-state registers | Visible ARM-state registers
+ * 10000 | USER | r0–r7, SP, LR, PC, CPSR | r0–r14, PC, CPSR
+ * 10001 | FIQ | r0–r7, SP_fiq, LR_fiq, PC, CPSR, SPSR_fiq | r0–r7, r8_fiq–r14_fiq, PC, CPSR, SPSR_fiq
+ * 10010 | IRQ | r0–r7, SP_irq, LR_irq, PC, CPSR, SPSR_irq | r0–r12, r13_irq, r14_irq, PC, CPSR, SPSR_irq
+ * 10011 | SVC | r0–r7, SP_svc, LR_svc, PC, CPSR, SPSR_svc | r0–r12, r13_svc, r14_svc, PC, CPSR, SPSR_svc
+ * 10111 | ABRT | r0–r7, SP_abt, LR_abt, PC, CPSR, SPSR_abt | r0–r12, r13_abt, r14_abt, PC, CPSR, SPSR_abt
+ * 11011 | UNDF | r0–r7, SP_und, LR_und, PC, CPSR, SPSR_und | r0–r12, r13_und, r14_und, PC, CPSR, SPSR_und
+ * 11111 | SYS | r0–r7, SP, LR, PC, CPSR | r0–r14, PC, CPSR
+ */
+
+#define EXCP_EN_ADDR 0x4003FFFC
+#define EXCP_TYPE_ADDR 0x4003FFF8
+#define EXCP_LR_ADDR 0x4003FFF4
+
+#define EXCP_VEC_BASE 0x6000F000
+#define EVP_COP_RESET_VECTOR 0x200
+#define EVP_COP_UNDEF_VECTOR 0x204
+#define EVP_COP_SWI_VECTOR 0x208
+#define EVP_COP_PREFETCH_ABORT_VECTOR 0x20C
+#define EVP_COP_DATA_ABORT_VECTOR 0x210
+#define EVP_COP_RSVD_VECTOR 0x214
+#define EVP_COP_IRQ_VECTOR 0x218
+#define EVP_COP_FIQ_VECTOR 0x21C
+
+#define MODE_USR 0x10
+#define MODE_FIQ 0x11
+#define MODE_IRQ 0x12
+#define MODE_SVC 0x13
+#define MODE_ABT 0x17
+#define MODE_UDF 0x1B
+#define MODE_SYS 0x1F
+#define MODE_MASK 0x1F
+
+#define FIQ 0x40
+#define IRQ 0x80
+
+.section .text._irq_setup
+.arm
+
+.extern ipl_main
+.type ipl_main, %function
+
+.extern svc_handler
+.type svc_handler, %function
+
+.extern irq_handler
+.type irq_handler, %function
+
+.extern fiq_setup
+.type fiq_setup, %function
+
+.extern fiq_handler
+.type fiq_handler, %function
+
+.globl _irq_setup
+.type _irq_setup, %function
+_irq_setup:
+ MRS R0, CPSR
+ BIC R0, R0, #MODE_MASK /* Clear mode bits */
+ ORR R0, R0, #(MODE_SVC | IRQ | FIQ) /* SUPERVISOR mode, IRQ/FIQ disabled */
+ MSR CPSR, R0
+
+ /* Setup IRQ stack pointer */
+ MSR CPSR, #(MODE_IRQ | IRQ | FIQ) /* IRQ mode, IRQ/FIQ disabled */
+ LDR SP, =0x40040000
+
+ /* Setup SYS stack pointer */
+ MSR CPSR, #(MODE_SYS | IRQ | FIQ) /* SYSTEM mode, IRQ/FIQ disabled */
+ LDR SP, =0x4003FF00 /* Will be changed later to DRAM */
+
+ MOV LR, PC
+ BL setup_vectors
+ /*BL fiq_setup*/
+
+ /* Enable interrupts */
+ BL irq_enable_cpu_irq_exceptions
+
+ B ipl_main
+ B .
+
+_reset:
+ LDR R0, =EXCP_EN_ADDR
+ LDR R1, =0x30505645 /* EVP0 */
+ STR R1, [R0] /* EVP0 in EXCP_EN_ADDR */
+ LDR R0, =EXCP_LR_ADDR
+ MOV R1, LR
+ STR R1, [R0] /* Save LR in EXCP_LR_ADDR */
+ LDR R0, =__bss_start
+ EOR R1, R1, R1
+ LDR R2, =__bss_end
+ SUB R2, R2, R0
+ BL memset
+ B _irq_setup
+
+_reset_handler:
+ LDR R0, =EXCP_TYPE_ADDR
+ LDR R1, =0x545352 /* RST */
+ STR R1, [R0] /* RST in EXCP_TYPE_ADDR */
+ B _reset
+
+_undefined_handler:
+ LDR R0, =EXCP_TYPE_ADDR
+ LDR R1, =0x464455 /* UDF */
+ STR R1, [R0] /* UDF in EXCP_TYPE_ADDR */
+ B _reset
+
+_prefetch_abort_handler:
+ LDR R0, =EXCP_TYPE_ADDR
+ LDR R1, =0x54424150 /* PABT */
+ STR R1, [R0] /* PABT in EXCP_TYPE_ADDR */
+ B _reset
+
+_data_abort_handler:
+ LDR R0, =EXCP_TYPE_ADDR
+ LDR R1, =0x54424144 /* DABT */
+ STR R1, [R0] /* DABT in EXCP_TYPE_ADDR */
+ B _reset
+
+.globl irq_enable_cpu_irq_exceptions
+.type irq_enable_cpu_irq_exceptions, %function
+irq_enable_cpu_irq_exceptions:
+ MRS R12, CPSR
+ BIC R12, R12, #(IRQ | FIQ) /* IRQ/FIQ enabled */
+ MSR CPSR, R12
+ BX LR
+
+.globl irq_disable_cpu_irq_exceptions
+.type irq_disable_cpu_irq_exceptions, %function
+irq_disable_cpu_irq_exceptions:
+ MRS R12, CPSR
+ ORR R12, R12, #(IRQ | FIQ) /* IRQ/FIQ disabled */
+ MSR CPSR, R12
+ BX LR
+
+_irq_handler:
+ MOV R13, R0 /* Save R0 in R13_IRQ */
+ SUB R0, LR, #4 /* Put return address in R0_SYS */
+ MOV LR, R1 /* Save R1 in R14_IRQ (LR) */
+ MRS R1, SPSR /* Put the SPSR in R1_SYS */
+
+ MSR CPSR_c, #(MODE_SYS | IRQ) /* SYSTEM mode, IRQ disabled */
+ STMFD SP!, {R0, R1} /* SPSR and PC */
+ STMFD SP!, {R2-R3, R12, LR} /* AAPCS-clobbered registers */
+ MOV R0, SP /* Make SP_SYS visible to IRQ mode */
+ SUB SP, SP, #8 /* Make room for stacking R0 and R1 */
+
+ MSR CPSR_c, #(MODE_IRQ | IRQ) /* IRQ mode, IRQ disabled */
+ STMFD R0!, {R13, R14} /* Finish saving the context (R0, R1) */
+
+ MSR CPSR_c, #(MODE_SYS | IRQ) /* SYSTEM mode, IRQ disabled */
+ LDR R12, =irq_handler
+ MOV LR, PC /* Copy the return address to link register */
+ BX R12 /* Call the C IRQ handler (ARM/THUMB) */
+
+ MSR CPSR_c, #(MODE_SYS | IRQ | FIQ) /* SYSTEM mode, IRQ/FIQ disabled */
+ MOV R0, SP /* Make SP_SYS visible to IRQ mode */
+ ADD SP, SP, #32 /* Fake unstacking 8 registers from SP_SYS */
+
+ MSR CPSR_c, #(MODE_IRQ | IRQ | FIQ) /* IRQ mode, IRQ/FIQ disabled */
+ MOV SP, R0 /* Copy SP_SYS to SP_IRQ */
+ LDR R0, [SP, #28] /* Load the saved SPSR from the stack */
+ MSR SPSR_cxsf, R0 /* Copy it into SPSR_IRQ */
+
+ LDMFD SP, {R0-R3, R12, LR}^ /* Unstack all saved USER/SYSTEM registers */
+ NOP /* Cant access barked registers immediately */
+ LDR LR, [SP, #24] /* Load return address from the SYS stack */
+ MOVS PC, LR /* Return restoring CPSR from SPSR */
+
+_fiq_handler:
+ BL fiq_handler
+
+setup_vectors:
+ /* Setup vectors */
+ LDR R0, =EXCP_VEC_BASE
+
+ LDR R1, =_reset_handler
+ STR R1, [R0, #EVP_COP_RESET_VECTOR]
+
+ LDR R1, =_undefined_handler
+ STR R1, [R0, #EVP_COP_UNDEF_VECTOR]
+
+ LDR R1, =_reset_handler
+ STR R1, [R0, #EVP_COP_SWI_VECTOR]
+
+ LDR R1, =_prefetch_abort_handler
+ STR R1, [R0, #EVP_COP_PREFETCH_ABORT_VECTOR]
+
+ LDR R1, =_data_abort_handler
+ STR R1, [R0, #EVP_COP_DATA_ABORT_VECTOR]
+
+ LDR R1, =_reset_handler
+ STR R1, [R0, #EVP_COP_RSVD_VECTOR]
+
+ LDR R1, =_irq_handler
+ STR R1, [R0, #EVP_COP_IRQ_VECTOR]
+
+ LDR R1, =_fiq_handler
+ STR R1, [R0, #EVP_COP_FIQ_VECTOR]
+
+ BX LR
diff --git a/bootloader/link.ld b/bootloader/link.ld
index 85568dd..cd8b8a1 100644
--- a/bootloader/link.ld
+++ b/bootloader/link.ld
@@ -7,6 +7,7 @@ SECTIONS {
*(.text._start);
*(._boot_cfg);
*(._ipl_version);
+ *(.text._irq_setup);
*(.text*);
}
.data : {
diff --git a/bootloader/main.c b/bootloader/main.c
index 6f4c263..054b97e 100644
--- a/bootloader/main.c
+++ b/bootloader/main.c
@@ -1182,8 +1182,24 @@ static void _patched_rcm_protection()
sdmmc_storage_end(&storage);
}
+#define EXCP_EN_ADDR 0x4003FFFC
+#define EXCP_MAGIC 0x30505645 // EVP0
+#define EXCP_TYPE_ADDR 0x4003FFF8
+#define EXCP_TYPE_RESET 0x545352 // RST
+#define EXCP_TYPE_UNDEF 0x464455 // UDF
+#define EXCP_TYPE_PABRT 0x54424150 // PABT
+#define EXCP_TYPE_DABRT 0x54424144 // DABT
+#define EXCP_LR_ADDR 0x4003FFF4
+
static void _show_errors()
{
+ u32 *excp_enabled = (u32 *)EXCP_EN_ADDR;
+ u32 *excp_type = (u32 *)EXCP_TYPE_ADDR;
+ u32 *excp_lr = (u32 *)EXCP_LR_ADDR;
+
+ if (*excp_enabled == EXCP_MAGIC)
+ h_cfg.errors |= ERR_EXCEPT_ENB;
+
if (h_cfg.errors)
{
gfx_clear_grey(0x1B);
@@ -1195,7 +1211,35 @@ static void _show_errors()
if (h_cfg.errors & ERR_SYSOLD_MTC)
WPRINTF("Missing or old Minerva library!\n");
- WPRINTF("\nUpdate your bootloader folder!\n\n");
+ if (h_cfg.errors & ~ERR_EXCEPT_ENB)
+ {
+ WPRINTF("\nUpdate your bootloader folder!\n\n");
+ }
+
+ if (h_cfg.errors & ERR_EXCEPT_ENB)
+ {
+ WPRINTFARGS("An exception happened (LR %08X):\n", *excp_lr);
+ switch (*excp_type)
+ {
+ case EXCP_TYPE_RESET:
+ WPRINTF("Reset");
+ break;
+ case EXCP_TYPE_UNDEF:
+ WPRINTF("Undefined instruction");
+ break;
+ case EXCP_TYPE_PABRT:
+ WPRINTF("Prefetch abort");
+ break;
+ case EXCP_TYPE_DABRT:
+ WPRINTF("Data abort");
+ break;
+ }
+ WPRINTF("\n");
+
+ // Clear the exception.
+ *excp_enabled = 0;
+ }
+
WPRINTF("Press any key...");
msleep(2000);
diff --git a/bootloader/start.S b/bootloader/start.S
index 534f963..269f2c7 100644
--- a/bootloader/start.S
+++ b/bootloader/start.S
@@ -23,8 +23,8 @@
.extern memset
.type memset, %function
-.extern ipl_main
-.type ipl_main, %function
+.extern _irq_setup
+.type _irq_setup, %function
.globl _start
.type _start, %function
@@ -67,7 +67,7 @@ _real_start:
LDR R2, =__bss_end
SUB R2, R2, R0
BL memset
- BL ipl_main
+ BL _irq_setup
B .
.globl pivot_stack
diff --git a/nyx/nyx_gui/exception_handlers.S b/nyx/nyx_gui/exception_handlers.S
new file mode 100644
index 0000000..6b497a8
--- /dev/null
+++ b/nyx/nyx_gui/exception_handlers.S
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2019 CTCaer
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 .
+ */
+
+/*
+ * Armv7tdmi Status register.
+ *
+ * bit0: Mode 0.
+ * bit1: Mode 1.
+ * bit2: Mode 2.
+ * bit3: Mode 3.
+ * bit4: Mode 4.
+ * bit5: Thumb state.
+ * bit6: FIQ disable.
+ * bit7: IRQ disable.
+ * bit8-27: Reserved.
+ * bit28: Overflow condition.
+ * bit29: Carry/Borrow/Extend condition.
+ * bit30: Zero condition.
+ * bit31: Negative/Less than condition.
+ *
+ * M[4:0] | Mode | Visible Thumb-state registers | Visible ARM-state registers
+ * 10000 | USER | r0–r7, SP, LR, PC, CPSR | r0–r14, PC, CPSR
+ * 10001 | FIQ | r0–r7, SP_fiq, LR_fiq, PC, CPSR, SPSR_fiq | r0–r7, r8_fiq–r14_fiq, PC, CPSR, SPSR_fiq
+ * 10010 | IRQ | r0–r7, SP_irq, LR_irq, PC, CPSR, SPSR_irq | r0–r12, r13_irq, r14_irq, PC, CPSR, SPSR_irq
+ * 10011 | SVC | r0–r7, SP_svc, LR_svc, PC, CPSR, SPSR_svc | r0–r12, r13_svc, r14_svc, PC, CPSR, SPSR_svc
+ * 10111 | ABRT | r0–r7, SP_abt, LR_abt, PC, CPSR, SPSR_abt | r0–r12, r13_abt, r14_abt, PC, CPSR, SPSR_abt
+ * 11011 | UNDF | r0–r7, SP_und, LR_und, PC, CPSR, SPSR_und | r0–r12, r13_und, r14_und, PC, CPSR, SPSR_und
+ * 11111 | SYS | r0–r7, SP, LR, PC, CPSR | r0–r14, PC, CPSR
+ */
+
+#define EXCP_EN_ADDR 0x4003FFFC
+#define EXCP_TYPE_ADDR 0x4003FFF8
+#define EXCP_LR_ADDR 0x4003FFF4
+
+#define EXCP_VEC_BASE 0x6000F000
+#define EVP_COP_RESET_VECTOR 0x200
+#define EVP_COP_UNDEF_VECTOR 0x204
+#define EVP_COP_SWI_VECTOR 0x208
+#define EVP_COP_PREFETCH_ABORT_VECTOR 0x20C
+#define EVP_COP_DATA_ABORT_VECTOR 0x210
+#define EVP_COP_RSVD_VECTOR 0x214
+#define EVP_COP_IRQ_VECTOR 0x218
+#define EVP_COP_FIQ_VECTOR 0x21C
+
+#define MODE_USR 0x10
+#define MODE_FIQ 0x11
+#define MODE_IRQ 0x12
+#define MODE_SVC 0x13
+#define MODE_ABT 0x17
+#define MODE_UDF 0x1B
+#define MODE_SYS 0x1F
+#define MODE_MASK 0x1F
+
+#define FIQ 0x40
+#define IRQ 0x80
+
+.section .text._irq_setup
+.arm
+
+.extern ipl_main
+.type ipl_main, %function
+
+.extern svc_handler
+.type svc_handler, %function
+
+.extern irq_handler
+.type irq_handler, %function
+
+.extern fiq_setup
+.type fiq_setup, %function
+
+.extern fiq_handler
+.type fiq_handler, %function
+
+.globl _irq_setup
+.type _irq_setup, %function
+_irq_setup:
+ MRS R0, CPSR
+ BIC R0, R0, #MODE_MASK /* Clear mode bits */
+ ORR R0, R0, #(MODE_SVC | IRQ | FIQ) /* SUPERVISOR mode, IRQ/FIQ disabled */
+ MSR CPSR, R0
+
+ /* Setup IRQ stack pointer */
+ MSR CPSR, #(MODE_IRQ | IRQ | FIQ) /* IRQ mode, IRQ/FIQ disabled */
+ LDR SP, =0x40040000
+
+ /* Setup SYS stack pointer */
+ MSR CPSR, #(MODE_SYS | IRQ | FIQ) /* SYSTEM mode, IRQ/FIQ disabled */
+ LDR SP, =0x4003FF00 /* Will be changed later to DRAM */
+
+ MOV LR, PC
+ BL setup_vectors
+ /*BL fiq_setup*/
+
+ /* Enable interrupts */
+ BL irq_enable_cpu_irq_exceptions
+
+ B ipl_main
+ B .
+
+_reset:
+ LDR R0, =EXCP_EN_ADDR
+ LDR R1, =0x30505645 /* EVP0 */
+ STR R1, [R0] /* EVP0 in EXCP_EN_ADDR */
+ LDR R0, =EXCP_LR_ADDR
+ MOV R1, LR
+ STR R1, [R0] /* Save LR in EXCP_LR_ADDR */
+ LDR R0, =__bss_start
+ EOR R1, R1, R1
+ LDR R2, =__bss_end
+ SUB R2, R2, R0
+ BL memset
+ B _irq_setup
+
+_reset_handler:
+ LDR R0, =EXCP_TYPE_ADDR
+ LDR R1, =0x545352 /* RST */
+ STR R1, [R0] /* RST in EXCP_TYPE_ADDR */
+ B _reset
+
+_undefined_handler:
+ LDR R0, =EXCP_TYPE_ADDR
+ LDR R1, =0x464455 /* UDF */
+ STR R1, [R0] /* UDF in EXCP_TYPE_ADDR */
+ B _reset
+
+_prefetch_abort_handler:
+ LDR R0, =EXCP_TYPE_ADDR
+ LDR R1, =0x54424150 /* PABT */
+ STR R1, [R0] /* PABT in EXCP_TYPE_ADDR */
+ B _reset
+
+_data_abort_handler:
+ LDR R0, =EXCP_TYPE_ADDR
+ LDR R1, =0x54424144 /* DABT */
+ STR R1, [R0] /* DABT in EXCP_TYPE_ADDR */
+ B _reset
+
+.globl irq_enable_cpu_irq_exceptions
+.type irq_enable_cpu_irq_exceptions, %function
+irq_enable_cpu_irq_exceptions:
+ MRS R12, CPSR
+ BIC R12, R12, #(IRQ | FIQ) /* IRQ/FIQ enabled */
+ MSR CPSR, R12
+ BX LR
+
+.globl irq_disable_cpu_irq_exceptions
+.type irq_disable_cpu_irq_exceptions, %function
+irq_disable_cpu_irq_exceptions:
+ MRS R12, CPSR
+ ORR R12, R12, #(IRQ | FIQ) /* IRQ/FIQ disabled */
+ MSR CPSR, R12
+ BX LR
+
+_irq_handler:
+ MOV R13, R0 /* Save R0 in R13_IRQ */
+ SUB R0, LR, #4 /* Put return address in R0_SYS */
+ MOV LR, R1 /* Save R1 in R14_IRQ (LR) */
+ MRS R1, SPSR /* Put the SPSR in R1_SYS */
+
+ MSR CPSR_c, #(MODE_SYS | IRQ) /* SYSTEM mode, IRQ disabled */
+ STMFD SP!, {R0, R1} /* SPSR and PC */
+ STMFD SP!, {R2-R3, R12, LR} /* AAPCS-clobbered registers */
+ MOV R0, SP /* Make SP_SYS visible to IRQ mode */
+ SUB SP, SP, #8 /* Make room for stacking R0 and R1 */
+
+ MSR CPSR_c, #(MODE_IRQ | IRQ) /* IRQ mode, IRQ disabled */
+ STMFD R0!, {R13, R14} /* Finish saving the context (R0, R1) */
+
+ MSR CPSR_c, #(MODE_SYS | IRQ) /* SYSTEM mode, IRQ disabled */
+ LDR R12, =irq_handler
+ MOV LR, PC /* Copy the return address to link register */
+ BX R12 /* Call the C IRQ handler (ARM/THUMB) */
+
+ MSR CPSR_c, #(MODE_SYS | IRQ | FIQ) /* SYSTEM mode, IRQ/FIQ disabled */
+ MOV R0, SP /* Make SP_SYS visible to IRQ mode */
+ ADD SP, SP, #32 /* Fake unstacking 8 registers from SP_SYS */
+
+ MSR CPSR_c, #(MODE_IRQ | IRQ | FIQ) /* IRQ mode, IRQ/FIQ disabled */
+ MOV SP, R0 /* Copy SP_SYS to SP_IRQ */
+ LDR R0, [SP, #28] /* Load the saved SPSR from the stack */
+ MSR SPSR_cxsf, R0 /* Copy it into SPSR_IRQ */
+
+ LDMFD SP, {R0-R3, R12, LR}^ /* Unstack all saved USER/SYSTEM registers */
+ NOP /* Cant access barked registers immediately */
+ LDR LR, [SP, #24] /* Load return address from the SYS stack */
+ MOVS PC, LR /* Return restoring CPSR from SPSR */
+
+_fiq_handler:
+ BL fiq_handler
+
+setup_vectors:
+ /* Setup vectors */
+ LDR R0, =EXCP_VEC_BASE
+
+ LDR R1, =_reset_handler
+ STR R1, [R0, #EVP_COP_RESET_VECTOR]
+
+ LDR R1, =_undefined_handler
+ STR R1, [R0, #EVP_COP_UNDEF_VECTOR]
+
+ LDR R1, =_reset_handler
+ STR R1, [R0, #EVP_COP_SWI_VECTOR]
+
+ LDR R1, =_prefetch_abort_handler
+ STR R1, [R0, #EVP_COP_PREFETCH_ABORT_VECTOR]
+
+ LDR R1, =_data_abort_handler
+ STR R1, [R0, #EVP_COP_DATA_ABORT_VECTOR]
+
+ LDR R1, =_reset_handler
+ STR R1, [R0, #EVP_COP_RSVD_VECTOR]
+
+ LDR R1, =_irq_handler
+ STR R1, [R0, #EVP_COP_IRQ_VECTOR]
+
+ LDR R1, =_fiq_handler
+ STR R1, [R0, #EVP_COP_FIQ_VECTOR]
+
+ BX LR
diff --git a/nyx/nyx_gui/link.ld b/nyx/nyx_gui/link.ld
index f0f01a0..bdf3dc0 100644
--- a/nyx/nyx_gui/link.ld
+++ b/nyx/nyx_gui/link.ld
@@ -6,6 +6,7 @@ SECTIONS {
.text : {
*(.text._start);
*(._ipl_version);
+ *(.text._irq_setup);
*(.text*);
}
.data : {
diff --git a/nyx/nyx_gui/nyx.c b/nyx/nyx_gui/nyx.c
index d7b0e60..b3970bd 100644
--- a/nyx/nyx_gui/nyx.c
+++ b/nyx/nyx_gui/nyx.c
@@ -367,6 +367,59 @@ void load_saved_configuration()
}
}
+#define EXCP_EN_ADDR 0x4003FFFC
+#define EXCP_MAGIC 0x30505645 // EVP0
+#define EXCP_TYPE_ADDR 0x4003FFF8
+#define EXCP_TYPE_RESET 0x545352 // RST
+#define EXCP_TYPE_UNDEF 0x464455 // UDF
+#define EXCP_TYPE_PABRT 0x54424150 // PABT
+#define EXCP_TYPE_DABRT 0x54424144 // DABT
+#define EXCP_LR_ADDR 0x4003FFF4
+
+static void _show_errors()
+{
+ u32 *excp_enabled = (u32 *)EXCP_EN_ADDR;
+ u32 *excp_type = (u32 *)EXCP_TYPE_ADDR;
+ u32 *excp_lr = (u32 *)EXCP_LR_ADDR;
+
+ if (*excp_enabled == EXCP_MAGIC)
+ {
+ gfx_clear_grey(0);
+ gfx_con_setpos(0, 0);
+ display_backlight_brightness(100, 1000);
+
+ WPRINTFARGS("An exception happened (LR %08X):\n", *excp_lr);
+ switch (*excp_type)
+ {
+ case EXCP_TYPE_RESET:
+ WPRINTF("Reset");
+ break;
+ case EXCP_TYPE_UNDEF:
+ WPRINTF("Undefined instruction");
+ break;
+ case EXCP_TYPE_PABRT:
+ WPRINTF("Prefetch abort");
+ break;
+ case EXCP_TYPE_DABRT:
+ WPRINTF("Data abort");
+ break;
+ }
+ WPRINTF("\n");
+
+ // Clear the exception.
+ *excp_lr = 0;
+ *excp_type = 0;
+ *excp_enabled = 0;
+
+ WPRINTF("Press any key...");
+
+ msleep(2000);
+ btn_wait();
+
+ reload_nyx();
+ }
+}
+
void nyx_init_load_res()
{
bpmp_mmu_enable();
diff --git a/nyx/nyx_gui/start.S b/nyx/nyx_gui/start.S
index c520ef1..20ff5cb 100644
--- a/nyx/nyx_gui/start.S
+++ b/nyx/nyx_gui/start.S
@@ -23,8 +23,8 @@
.extern memset
.type memset, %function
-.extern ipl_main
-.type ipl_main, %function
+.extern _irq_setup
+.type _irq_setup, %function
.globl _start
.type _start, %function
@@ -36,7 +36,7 @@ _start:
/* If we are not in the right location already, copy a relocator to upper IRAM. */
ADR R2, _reloc_ipl
- LDR R3, =0x4003FFE0
+ LDR R3, =0x4003FF00
MOV R4, #(_real_start - _reloc_ipl)
_copy_loop:
LDMIA R2!, {R5}
@@ -48,7 +48,7 @@ _copy_loop:
LDR R2, =__ipl_end
SUB R2, R2, R1
LDR R3, =_real_start
- LDR R4, =0x4003FFE0
+ LDR R4, =0x4003FF00
BX R4
_reloc_ipl:
@@ -67,7 +67,7 @@ _real_start:
LDR R2, =__bss_end
SUB R2, R2, R0
BL memset
- BL ipl_main
+ BL _irq_setup
B .
.globl pivot_stack