aboutsummaryrefslogtreecommitdiff
path: root/pk/handlers.c
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>2011-02-04 16:09:47 -0800
committerAndrew Waterman <waterman@s141.Millennium.Berkeley.EDU>2011-02-04 16:09:47 -0800
commit5c9d48945e6c62e77f22e32efcb963a56bf3dc74 (patch)
tree39008b7c01fc76ec86369c1d0b8d676896748bf9 /pk/handlers.c
parentaf2d471a4e6c2e4551238a2cc209f9c0d997c82f (diff)
downloadpk-5c9d48945e6c62e77f22e32efcb963a56bf3dc74.zip
pk-5c9d48945e6c62e77f22e32efcb963a56bf3dc74.tar.gz
pk-5c9d48945e6c62e77f22e32efcb963a56bf3dc74.tar.bz2
[sim,pk] added interrupt-pending field to cause reg
Diffstat (limited to 'pk/handlers.c')
-rw-r--r--pk/handlers.c66
1 files changed, 29 insertions, 37 deletions
diff --git a/pk/handlers.c b/pk/handlers.c
index cb580e6..430210d 100644
--- a/pk/handlers.c
+++ b/pk/handlers.c
@@ -1,16 +1,9 @@
#include "pcr.h"
#include "pk.h"
-int have_fp = 1;
+int have_fp = 1; // initialized to 1 because it can't be in the .bss section!
-void handle_breakpoint(trapframe_t* tf)
-{
- printk("Breakpoint\n");
- dump_tf(tf);
- tf->epc += 4;
-}
-
-void handle_fp_disabled(trapframe_t* tf)
+static void handle_fp_disabled(trapframe_t* tf)
{
if(have_fp)
init_fp();
@@ -28,19 +21,13 @@ void handle_fp_disabled(trapframe_t* tf)
}
}
-void handle_badtrap(trapframe_t* tf)
-{
- dump_tf(tf);
- panic("Bad trap vector!");
-}
-
-void handle_privileged_instruction(trapframe_t* tf)
+static void handle_privileged_instruction(trapframe_t* tf)
{
dump_tf(tf);
panic("A privileged instruction was executed!");
}
-void handle_illegal_instruction(trapframe_t* tf)
+static void handle_illegal_instruction(trapframe_t* tf)
{
#ifdef PK_ENABLE_FP_EMULATION
if(emulate_fp(tf) == 0)
@@ -51,7 +38,7 @@ void handle_illegal_instruction(trapframe_t* tf)
panic("An illegal instruction was executed!");
}
-void handle_misaligned_fetch(trapframe_t* tf)
+static void handle_misaligned_fetch(trapframe_t* tf)
{
dump_tf(tf);
panic("Misaligned instruction access!");
@@ -63,7 +50,7 @@ void handle_misaligned_ldst(trapframe_t* tf)
panic("Misaligned data access!");
}
-void handle_fault_fetch(trapframe_t* tf)
+static void handle_fault_fetch(trapframe_t* tf)
{
dump_tf(tf);
panic("Faulting instruction access!");
@@ -81,11 +68,29 @@ void handle_fault_store(trapframe_t* tf)
panic("Faulting store!");
}
-void handle_timer_interrupt(trapframe_t* tf)
+static void handle_bad_interrupt(trapframe_t* tf, int interrupt)
+{
+ panic("Bad interrupt %d!",interrupt);
+}
+
+static void handle_timer_interrupt(trapframe_t* tf)
{
mtpcr(mfpcr(PCR_COMPARE)+TIMER_PERIOD,PCR_COMPARE);
}
+static void handle_interrupt(trapframe_t* tf)
+{
+ int interrupts = (tf->cause & CAUSE_IP) >> CAUSE_IP_SHIFT;
+
+ for(int i = 0; interrupts; interrupts >>= 1, i++)
+ {
+ if(i == TIMER_IRQ)
+ handle_timer_interrupt(tf);
+ else
+ handle_bad_interrupt(tf,i);
+ }
+}
+
void handle_trap(trapframe_t* tf)
{
typedef void (*trap_handler)(trapframe_t*);
@@ -96,29 +101,16 @@ void handle_trap(trapframe_t* tf)
handle_privileged_instruction,
handle_fp_disabled,
handle_syscall,
- handle_breakpoint,
+ handle_interrupt,
handle_misaligned_ldst,
handle_fault_load,
handle_fault_store,
- handle_badtrap,
- handle_badtrap,
- handle_badtrap,
- handle_badtrap,
- handle_badtrap,
- handle_badtrap,
- handle_badtrap, /* irq 0 */
- handle_badtrap, /* irq 1 */
- handle_badtrap, /* irq 2 */
- handle_badtrap, /* irq 3 */
- handle_badtrap, /* irq 4 */
- handle_badtrap, /* irq 5 */
- handle_badtrap, /* irq 6 */
- handle_timer_interrupt, /* irq 7 */
};
- kassert(tf->cause < sizeof(trap_handlers)/sizeof(trap_handlers[0]));
+ int exccode = (tf->cause & CAUSE_EXCCODE) >> CAUSE_EXCCODE_SHIFT;
+ kassert(exccode < sizeof(trap_handlers)/sizeof(trap_handlers[0]));
- trap_handlers[tf->cause](tf);
+ trap_handlers[exccode](tf);
pop_tf(tf);
}