From 85696d04078eafcdc3f2f42c90a03a48936667a5 Mon Sep 17 00:00:00 2001 From: chaoskagami Date: Fri, 15 Jul 2016 03:48:04 -0400 Subject: [PATCH] Add interrupt handler --- source/interrupt.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++ source/interrupt.h | 6 +++++ source/main.c | 3 +++ 3 files changed, 71 insertions(+) create mode 100644 source/interrupt.c create mode 100644 source/interrupt.h diff --git a/source/interrupt.c b/source/interrupt.c new file mode 100644 index 0000000..49f0847 --- /dev/null +++ b/source/interrupt.c @@ -0,0 +1,62 @@ +#include "common.h" +#include + +void dump_state_printf(uint32_t* regs) { + fprintf(stderr, " cpsr:%x sp:%x lr:%x\n" + " r0:%x r1:%x r2:%x r3:%x\n" + " r4:%x r5:%x r6:%x r7:%x\n" + " r8:%x r9:%x r10:%x r11:%x\n" + " r12:%x\n", + (unsigned int)regs[0], (unsigned int)regs[1], (unsigned int)regs[2], + (unsigned int)regs[3], (unsigned int)regs[4], (unsigned int)regs[5], (unsigned int)regs[6], + (unsigned int)regs[7], (unsigned int)regs[8], (unsigned int)regs[9], (unsigned int)regs[10], + (unsigned int)regs[11], (unsigned int)regs[12], (unsigned int)regs[13], (unsigned int)regs[14], + (unsigned int)regs[15]); +} + +void reset_INT(_UNUSED uint32_t* regs) { + fprintf(stderr, "Reset called.\n"); +} + +void undef_INT(uint32_t* regs) { + fprintf(stderr, "Undefined instruction.\n"); + dump_state_printf(regs); + abort("Cannot continue. Halting.\n"); +} + +void swi_INT(_UNUSED uint32_t* regs) { + fprintf(stderr, "SWI called. Returning.\n"); +} + +void preabrt_INT(uint32_t* regs) { + fprintf(stderr, "Prefetch Abort.\n"); + dump_state_printf(regs); + abort("Cannot continue. Halting.\n"); +} + +void databrt_INT(uint32_t* regs) { + fprintf(stderr, "Data abort.\n"); + dump_state_printf(regs); + abort("Cannot continue. Halting.\n"); +} + +void irq_INT(_UNUSED uint32_t* regs) { + fprintf(stderr, "IRQ called. Returning.\n"); +} + +void fiq_INT(_UNUSED uint32_t* regs) { + fprintf(stderr, "FIQ called. Returning.\n"); +} + + +void install_interrupts() { + ctr_interrupt_prepare(); + + ctr_interrupt_set(CTR_INTERRUPT_RESET, reset_INT); + ctr_interrupt_set(CTR_INTERRUPT_UNDEF, undef_INT); + ctr_interrupt_set(CTR_INTERRUPT_SWI, swi_INT); + ctr_interrupt_set(CTR_INTERRUPT_PREABRT, preabrt_INT); + ctr_interrupt_set(CTR_INTERRUPT_DATABRT, databrt_INT); + ctr_interrupt_set(CTR_INTERRUPT_IRQ, irq_INT); + ctr_interrupt_set(CTR_INTERRUPT_FIQ, fiq_INT); +} diff --git a/source/interrupt.h b/source/interrupt.h new file mode 100644 index 0000000..9c48a72 --- /dev/null +++ b/source/interrupt.h @@ -0,0 +1,6 @@ +#ifndef __INTERRUPT_H +#define __INTERRUPT_H + +void install_interrupts(); + +#endif diff --git a/source/main.c b/source/main.c index 63572fb..994ab2d 100644 --- a/source/main.c +++ b/source/main.c @@ -6,6 +6,7 @@ #include "config.h" #include "screeninit.h" #include "std/abort.h" +#include "interrupt.h" int is_n3ds = 0; int doing_autoboot = 0; @@ -31,6 +32,8 @@ main(int argc, char** argv) set_font(PATH_BITS "/termfont.bin"); + install_interrupts(); // Get some free debug info. + if (c) { // Failed to mount SD. Bomb out. abort("Failed to mount SD card.\n"); -- 2.39.5