aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pk/entry.S73
-rw-r--r--pk/handlers.c44
-rw-r--r--pk/pcr.h3
-rw-r--r--pk/pk.h1
-rw-r--r--pk/riscv-pk.c6
5 files changed, 65 insertions, 62 deletions
diff --git a/pk/entry.S b/pk/entry.S
index 4d44993..67fb025 100644
--- a/pk/entry.S
+++ b/pk/entry.S
@@ -49,15 +49,17 @@ save_tf: # write the trap frame onto the stack
mfpcr $x2,ASM_CR(PCR_K0)
STORE $x2,31*REGBYTES($x1) # $ra is actually in $PCR_K0
- # get sr, epc, badvaddr, cr29 (tid)
+ # get sr, epc, badvaddr, cause, cr29 (tid)
mfpcr $x2,ASM_CR(PCR_SR) # sr
STORE $x2,32*REGBYTES($x1)
mfpcr $x2,ASM_CR(PCR_EPC) # epc
STORE $x2,33*REGBYTES($x1)
- mfpcr $x2,ASM_CR(PCR_BADVADDR) # badvaddr
+ mfpcr $x2,ASM_CR(PCR_BADVADDR) # badvaddr
STORE $x2,34*REGBYTES($x1)
- mfcr $x2,ASM_CR(29) # cr29 (tid)
+ mfpcr $x2,ASM_CR(PCR_CAUSE) # cause
STORE $x2,35*REGBYTES($x1)
+ mfcr $x2,ASM_CR(29) # cr29 (tid)
+ STORE $x2,36*REGBYTES($x1)
jr $ra
.end save_tf
@@ -115,60 +117,19 @@ pop_tf: # write the trap frame onto the stack
eret
.end pop_tf
- #define TIMER_IRQ_HANDLER \
- .align 7; \
- mtpcr $x2,ASM_CR(PCR_K0); \
- mtpcr $x1,ASM_CR(PCR_K1); \
- mfpcr $x1,ASM_CR(PCR_COMPARE); \
- liw $x2,TIMER_PERIOD; \
- addw $x1,$x1,$x2; \
- mtpcr $x1,ASM_CR(PCR_COMPARE); \
- mfpcr $x1,ASM_CR(PCR_K1); \
- mfpcr $x2,ASM_CR(PCR_K0); \
- eret
-
- #define TRAP_TABLE_ENTRY(x) \
- .align 7; \
- mtpcr $ra,ASM_CR(PCR_K0); \
- mtpcr $x1,ASM_CR(PCR_K1); \
- law $x1,stack_top-320; \
- jal save_tf; \
- move $sp,$x1; \
- move $a0,$x1; \
- ei; \
- jal x; \
+ .global trap_entry
+ .ent trap_entry
+trap_entry:
+ mtpcr $ra,ASM_CR(PCR_K0)
+ mtpcr $x1,ASM_CR(PCR_K1)
+ law $x1,stack_top-320
+ jal save_tf
+ move $sp,$x1
+ move $a0,$x1
+ ei
+ jal handle_trap
unimp
-
- .align 12
- .global trap_table
- .ent trap_table
-trap_table:
- TRAP_TABLE_ENTRY(handle_misaligned_fetch)
- TRAP_TABLE_ENTRY(handle_fault_fetch)
- TRAP_TABLE_ENTRY(handle_illegal_instruction)
- TRAP_TABLE_ENTRY(handle_privileged_instruction)
- TRAP_TABLE_ENTRY(handle_fp_disabled)
- TRAP_TABLE_ENTRY(handle_syscall)
- TRAP_TABLE_ENTRY(handle_breakpoint)
- TRAP_TABLE_ENTRY(handle_misaligned_ldst)
- TRAP_TABLE_ENTRY(handle_fault_load)
- TRAP_TABLE_ENTRY(handle_fault_store)
- TRAP_TABLE_ENTRY(handle_badtrap)
- TRAP_TABLE_ENTRY(handle_badtrap)
- TRAP_TABLE_ENTRY(handle_badtrap)
- TRAP_TABLE_ENTRY(handle_badtrap)
- TRAP_TABLE_ENTRY(handle_badtrap)
- TRAP_TABLE_ENTRY(handle_badtrap)
- TRAP_TABLE_ENTRY(handle_badtrap)
- TRAP_TABLE_ENTRY(handle_badtrap)
- TRAP_TABLE_ENTRY(handle_badtrap)
- TRAP_TABLE_ENTRY(handle_badtrap)
- TRAP_TABLE_ENTRY(handle_badtrap)
- TRAP_TABLE_ENTRY(handle_badtrap)
- TRAP_TABLE_ENTRY(handle_badtrap)
- TIMER_IRQ_HANDLER
- .align 12
- .end trap_table
+ .end trap_entry
.bss
.global stack_bot
diff --git a/pk/handlers.c b/pk/handlers.c
index 59338e5..38745bf 100644
--- a/pk/handlers.c
+++ b/pk/handlers.c
@@ -6,13 +6,11 @@ void handle_breakpoint(trapframe_t* tf)
printk("Breakpoint\n");
dump_tf(tf);
tf->epc += 4;
- pop_tf(tf);
}
void handle_fp_disabled(trapframe_t* tf)
{
tf->sr |= SR_EF;
- pop_tf(tf);
}
void handle_badtrap(trapframe_t* tf)
@@ -62,3 +60,45 @@ void handle_fault_store(trapframe_t* tf)
dump_tf(tf);
panic("Faulting store!");
}
+
+void handle_timer_interrupt(trapframe_t* tf)
+{
+ mtpcr(mfpcr(PCR_COMPARE)+TIMER_PERIOD,PCR_COMPARE);
+}
+
+void handle_trap(trapframe_t* tf)
+{
+ typedef void (*trap_handler)(trapframe_t*);
+ const static trap_handler trap_handlers[] = {
+ handle_misaligned_fetch,
+ handle_fault_fetch,
+ handle_illegal_instruction,
+ handle_privileged_instruction,
+ handle_fp_disabled,
+ handle_syscall,
+ handle_breakpoint,
+ 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]));
+
+ trap_handlers[tf->cause](tf);
+
+ pop_tf(tf);
+}
diff --git a/pk/pcr.h b/pk/pcr.h
index 9d6ca57..0834c2d 100644
--- a/pk/pcr.h
+++ b/pk/pcr.h
@@ -14,9 +14,10 @@
#define PCR_SR 0
#define PCR_EPC 1
#define PCR_BADVADDR 2
-#define PCR_TBR 3
+#define PCR_EVEC 3
#define PCR_COUNT 4
#define PCR_COMPARE 5
+#define PCR_CAUSE 6
#define PCR_TOHOST 16
#define PCR_FROMHOST 17
#define PCR_K0 24
diff --git a/pk/pk.h b/pk/pk.h
index c164306..501010e 100644
--- a/pk/pk.h
+++ b/pk/pk.h
@@ -7,6 +7,7 @@ typedef struct
long sr;
long epc;
long badvaddr;
+ long cause;
long cr29;
} trapframe_t;
diff --git a/pk/riscv-pk.c b/pk/riscv-pk.c
index efe4239..3e4c76f 100644
--- a/pk/riscv-pk.c
+++ b/pk/riscv-pk.c
@@ -5,9 +5,9 @@ void __attribute__((section(".boottext"))) __start()
extern char stack_top;
asm("move $sp,%0" : : "r"(&stack_top-64));
- extern char trap_table;
- register void* tt = &trap_table;
- mtpcr(tt,PCR_TBR);
+ extern char trap_entry;
+ register void* te = &trap_entry;
+ mtpcr(te,PCR_EVEC);
mtpcr(0,PCR_COUNT);
mtpcr(0,PCR_COMPARE);