aboutsummaryrefslogtreecommitdiff
path: root/pk/handlers.c
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2013-07-13 21:43:57 -0700
committerAndrew Waterman <waterman@cs.berkeley.edu>2013-07-13 21:44:16 -0700
commitcc72987e655578b0529b6c3c8084e810cf40b358 (patch)
treea7a99a9406dfef2d4103e85bc0976cb8d039d7e7 /pk/handlers.c
parent0bdb8c84092bf7c5eb4c981c620997a5893bfb70 (diff)
downloadriscv-pk-cc72987e655578b0529b6c3c8084e810cf40b358.zip
riscv-pk-cc72987e655578b0529b6c3c8084e810cf40b358.tar.gz
riscv-pk-cc72987e655578b0529b6c3c8084e810cf40b358.tar.bz2
Support Linux ABI and (optionally) virtual memory
Diffstat (limited to 'pk/handlers.c')
-rw-r--r--pk/handlers.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/pk/handlers.c b/pk/handlers.c
index 5caa29e..7493ac9 100644
--- a/pk/handlers.c
+++ b/pk/handlers.c
@@ -3,6 +3,8 @@
#include "pcr.h"
#include "pk.h"
#include "config.h"
+#include "syscall.h"
+#include "vm.h"
int have_fp = 1; // initialized to 1 because it can't be in the .bss section!
int have_vector = 1;
@@ -55,8 +57,6 @@ static void handle_illegal_instruction(trapframe_t* tf)
static void handle_fp_disabled(trapframe_t* tf)
{
- setpcr(PCR_SR, SR_ET);
-
if(have_fp && !(mfpcr(PCR_SR) & SR_EF))
init_fp(tf);
else
@@ -88,39 +88,46 @@ void handle_misaligned_store(trapframe_t* tf)
panic("Misaligned store!");
}
-static void handle_fault_fetch(trapframe_t* tf)
+static void segfault(trapframe_t* tf, uintptr_t addr, const char* type)
{
dump_tf(tf);
- panic("Faulting instruction access!");
+ const char* who = (tf->sr & SR_PS) ? "Kernel" : "User";
+ panic("%s %s segfault @ %p", who, type, addr);
+}
+
+static void handle_fault_fetch(trapframe_t* tf)
+{
+ if (handle_page_fault(tf->epc, PROT_EXEC) != 0)
+ segfault(tf, tf->epc, "fetch");
}
void handle_fault_load(trapframe_t* tf)
{
- dump_tf(tf);
- panic("Faulting load!");
+ if (handle_page_fault(tf->badvaddr, PROT_READ) != 0)
+ segfault(tf, tf->badvaddr, "load");
}
void handle_fault_store(trapframe_t* tf)
{
- dump_tf(tf);
- panic("Faulting store!");
+ if (handle_page_fault(tf->badvaddr, PROT_WRITE) != 0)
+ segfault(tf, tf->badvaddr, "store");
}
static void handle_syscall(trapframe_t* tf)
{
- setpcr(PCR_SR, SR_ET);
-
- long n = tf->gpr[16];
- sysret_t ret = syscall(tf->gpr[18], tf->gpr[19], tf->gpr[20], tf->gpr[21], n);
+ sysret_t ret = syscall(tf->gpr[18], tf->gpr[19], tf->gpr[20], tf->gpr[21],
+ tf->gpr[22], tf->gpr[23], tf->gpr[16]);
tf->gpr[16] = ret.result;
- tf->gpr[17] = ret.result == -1 ? ret.err : 0;
+ tf->gpr[21] = ret.err;
advance_pc(tf);
}
void handle_trap(trapframe_t* tf)
{
+ setpcr(PCR_SR, SR_ET);
+
typedef void (*trap_handler)(trapframe_t*);
const static trap_handler trap_handlers[] = {