aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pk/elf.c2
-rw-r--r--pk/entry.S237
-rw-r--r--pk/fp.c2
-rw-r--r--pk/handlers.c39
-rw-r--r--pk/memset.c7
-rw-r--r--pk/pcr.h15
-rw-r--r--pk/pk.h15
7 files changed, 177 insertions, 140 deletions
diff --git a/pk/elf.c b/pk/elf.c
index 51debb3..ab56b58 100644
--- a/pk/elf.c
+++ b/pk/elf.c
@@ -9,7 +9,7 @@ long load_elf(const char* fn, int* user64)
{
sysret_t ret = file_open(fn, strlen(fn)+1, O_RDONLY, 0);
file_t* file = (file_t*)ret.result;
- if(file == NULL)
+ if(ret.result == -1)
panic("couldn't open %s!", fn);
char buf[2048]; // XXX
diff --git a/pk/entry.S b/pk/entry.S
index a9ddfc3..a0cdcbc 100644
--- a/pk/entry.S
+++ b/pk/entry.S
@@ -10,132 +10,135 @@
# define REGBYTES 4
#endif
- .text
- .ent save_tf
-save_tf: # write the trap frame onto the stack
+ .text
+ .ent save_tf
+save_tf: # write the trap frame onto the stack
- # save gprs
- STORE $x3,3*REGBYTES($x2)
- STORE $x4,4*REGBYTES($x2)
- STORE $x5,5*REGBYTES($x2)
- STORE $x6,6*REGBYTES($x2)
- STORE $x7,7*REGBYTES($x2)
- STORE $x8,8*REGBYTES($x2)
- STORE $x9,9*REGBYTES($x2)
- STORE $x10,10*REGBYTES($x2)
- STORE $x11,11*REGBYTES($x2)
- STORE $x12,12*REGBYTES($x2)
- STORE $x13,13*REGBYTES($x2)
- STORE $x14,14*REGBYTES($x2)
- STORE $x15,15*REGBYTES($x2)
- STORE $x16,16*REGBYTES($x2)
- STORE $x17,17*REGBYTES($x2)
- STORE $x18,18*REGBYTES($x2)
- STORE $x19,19*REGBYTES($x2)
- STORE $x20,20*REGBYTES($x2)
- STORE $x21,21*REGBYTES($x2)
- STORE $x22,22*REGBYTES($x2)
- STORE $x23,23*REGBYTES($x2)
- STORE $x24,24*REGBYTES($x2)
- STORE $x25,25*REGBYTES($x2)
- STORE $x26,26*REGBYTES($x2)
- STORE $x27,27*REGBYTES($x2)
- STORE $x28,28*REGBYTES($x2)
- STORE $x29,29*REGBYTES($x2)
- STORE $x30,30*REGBYTES($x2)
- STORE $x31,31*REGBYTES($x2)
+ # save gprs
+ STORE $x3,3*REGBYTES($x2)
+ STORE $x4,4*REGBYTES($x2)
+ STORE $x5,5*REGBYTES($x2)
+ STORE $x6,6*REGBYTES($x2)
+ STORE $x7,7*REGBYTES($x2)
+ STORE $x8,8*REGBYTES($x2)
+ STORE $x9,9*REGBYTES($x2)
+ STORE $x10,10*REGBYTES($x2)
+ STORE $x11,11*REGBYTES($x2)
+ STORE $x12,12*REGBYTES($x2)
+ STORE $x13,13*REGBYTES($x2)
+ STORE $x14,14*REGBYTES($x2)
+ STORE $x15,15*REGBYTES($x2)
+ STORE $x16,16*REGBYTES($x2)
+ STORE $x17,17*REGBYTES($x2)
+ STORE $x18,18*REGBYTES($x2)
+ STORE $x19,19*REGBYTES($x2)
+ STORE $x20,20*REGBYTES($x2)
+ STORE $x21,21*REGBYTES($x2)
+ STORE $x22,22*REGBYTES($x2)
+ STORE $x23,23*REGBYTES($x2)
+ STORE $x24,24*REGBYTES($x2)
+ STORE $x25,25*REGBYTES($x2)
+ STORE $x26,26*REGBYTES($x2)
+ STORE $x27,27*REGBYTES($x2)
+ STORE $x28,28*REGBYTES($x2)
+ STORE $x29,29*REGBYTES($x2)
+ STORE $x30,30*REGBYTES($x2)
+ STORE $x31,31*REGBYTES($x2)
- mfpcr $x3,ASM_CR(PCR_K0)
- STORE $x3,1*REGBYTES($x2) # $x1 is in $PCR_K0
- mfpcr $x3,ASM_CR(PCR_K1)
- STORE $x3,2*REGBYTES($x2) # $x2 is in $PCR_K1
+ mfpcr $x3,ASM_CR(PCR_K0)
+ STORE $x3,1*REGBYTES($x2) # $x1 is in $PCR_K0
+ mfpcr $x3,ASM_CR(PCR_K1)
+ STORE $x3,2*REGBYTES($x2) # $x2 is in $PCR_K1
- # get sr, epc, badvaddr, cause
- mfpcr $x3,ASM_CR(PCR_SR) # sr
- STORE $x3,32*REGBYTES($x2)
- mfpcr $x4,ASM_CR(PCR_EPC) # epc
- STORE $x4,33*REGBYTES($x2)
- mfpcr $x3,ASM_CR(PCR_BADVADDR) # badvaddr
- STORE $x3,34*REGBYTES($x2)
- mfpcr $x3,ASM_CR(PCR_CAUSE) # cause
- STORE $x3,35*REGBYTES($x2)
+ # get sr, epc, badvaddr, cause
+ mfpcr $x3,ASM_CR(PCR_SR) # sr
+ STORE $x3,32*REGBYTES($x2)
+ mfpcr $x4,ASM_CR(PCR_EPC) # epc
+ STORE $x4,33*REGBYTES($x2)
+ mfpcr $x3,ASM_CR(PCR_BADVADDR) # badvaddr
+ STORE $x3,34*REGBYTES($x2)
+ mfpcr $x3,ASM_CR(PCR_CAUSE) # cause
+ STORE $x3,35*REGBYTES($x2)
- # get insn
- and $x4,$x4,~1
- lh $x3,0($x4)
- lh $x4,2($x4)
- sh $x3, 36*REGBYTES($x2)
- sh $x4,2+36*REGBYTES($x2)
+ # get faulting insn, if it wasn't a fetch-related trap
+ li $x5, CAUSE_MISALIGNED_FETCH
+ li $x6, CAUSE_FAULT_FETCH
+ beq $x3, $x5, 1f
+ beq $x3, $x6, 1f
+ lh $x3,0($x4)
+ lh $x4,2($x4)
+ sh $x3, 36*REGBYTES($x2)
+ sh $x4,2+36*REGBYTES($x2)
+1:
+ ret
+ .end save_tf
- ret
- .end save_tf
+ .globl pop_tf
+ .ent pop_tf
+pop_tf: # write the trap frame onto the stack
+ # restore gprs
+ LOAD $t0,32*REGBYTES($a0) # restore sr (should disable interrupts)
+ mtpcr $t0,ASM_CR(PCR_SR)
- .globl pop_tf
- .ent pop_tf
-pop_tf: # write the trap frame onto the stack
- # restore gprs
- LOAD $t0,32*REGBYTES($a0) # restore sr (should disable interrupts)
- mtpcr $t0,ASM_CR(PCR_SR)
+ LOAD $x1,1*REGBYTES($a0)
+ mtpcr $x1,ASM_CR(PCR_K0)
+ LOAD $x1,2*REGBYTES($a0)
+ mtpcr $x1,ASM_CR(PCR_K1)
+ move $x1,$a0
+ LOAD $x3,3*REGBYTES($x1)
+ LOAD $x4,4*REGBYTES($x1)
+ LOAD $x5,5*REGBYTES($x1)
+ LOAD $x6,6*REGBYTES($x1)
+ LOAD $x7,7*REGBYTES($x1)
+ LOAD $x8,8*REGBYTES($x1)
+ LOAD $x9,9*REGBYTES($x1)
+ LOAD $x10,10*REGBYTES($x1)
+ LOAD $x11,11*REGBYTES($x1)
+ LOAD $x12,12*REGBYTES($x1)
+ LOAD $x13,13*REGBYTES($x1)
+ LOAD $x14,14*REGBYTES($x1)
+ LOAD $x15,15*REGBYTES($x1)
+ LOAD $x16,16*REGBYTES($x1)
+ LOAD $x17,17*REGBYTES($x1)
+ LOAD $x18,18*REGBYTES($x1)
+ LOAD $x19,19*REGBYTES($x1)
+ LOAD $x20,20*REGBYTES($x1)
+ LOAD $x21,21*REGBYTES($x1)
+ LOAD $x22,22*REGBYTES($x1)
+ LOAD $x23,23*REGBYTES($x1)
+ LOAD $x24,24*REGBYTES($x1)
+ LOAD $x25,25*REGBYTES($x1)
+ LOAD $x26,26*REGBYTES($x1)
+ LOAD $x27,27*REGBYTES($x1)
+ LOAD $x28,28*REGBYTES($x1)
+ LOAD $x29,29*REGBYTES($x1)
+ LOAD $x30,30*REGBYTES($x1)
+ LOAD $x31,31*REGBYTES($x1)
- LOAD $x1,1*REGBYTES($a0)
- mtpcr $x1,ASM_CR(PCR_K0)
- LOAD $x1,2*REGBYTES($a0)
- mtpcr $x1,ASM_CR(PCR_K1)
- move $x1,$a0
- LOAD $x3,3*REGBYTES($x1)
- LOAD $x4,4*REGBYTES($x1)
- LOAD $x5,5*REGBYTES($x1)
- LOAD $x6,6*REGBYTES($x1)
- LOAD $x7,7*REGBYTES($x1)
- LOAD $x8,8*REGBYTES($x1)
- LOAD $x9,9*REGBYTES($x1)
- LOAD $x10,10*REGBYTES($x1)
- LOAD $x11,11*REGBYTES($x1)
- LOAD $x12,12*REGBYTES($x1)
- LOAD $x13,13*REGBYTES($x1)
- LOAD $x14,14*REGBYTES($x1)
- LOAD $x15,15*REGBYTES($x1)
- LOAD $x16,16*REGBYTES($x1)
- LOAD $x17,17*REGBYTES($x1)
- LOAD $x18,18*REGBYTES($x1)
- LOAD $x19,19*REGBYTES($x1)
- LOAD $x20,20*REGBYTES($x1)
- LOAD $x21,21*REGBYTES($x1)
- LOAD $x22,22*REGBYTES($x1)
- LOAD $x23,23*REGBYTES($x1)
- LOAD $x24,24*REGBYTES($x1)
- LOAD $x25,25*REGBYTES($x1)
- LOAD $x26,26*REGBYTES($x1)
- LOAD $x27,27*REGBYTES($x1)
- LOAD $x28,28*REGBYTES($x1)
- LOAD $x29,29*REGBYTES($x1)
- LOAD $x30,30*REGBYTES($x1)
- LOAD $x31,31*REGBYTES($x1)
+ # gtfo!
+ LOAD $x2,33*REGBYTES($x1)
+ mtpcr $x2,ASM_CR(PCR_EPC)
+ mfpcr $x1,ASM_CR(PCR_K0)
+ mfpcr $x2,ASM_CR(PCR_K1)
+ eret
+ .end pop_tf
- # gtfo!
- LOAD $x2,33*REGBYTES($x1)
- mtpcr $x2,ASM_CR(PCR_EPC)
- mfpcr $x1,ASM_CR(PCR_K0)
- mfpcr $x2,ASM_CR(PCR_K1)
- eret
- .end pop_tf
-
- .global trap_entry
- .ent trap_entry
+ .global trap_entry
+ .ent trap_entry
trap_entry:
- mtpcr $ra,ASM_CR(PCR_K0)
- mtpcr $x2,ASM_CR(PCR_K1)
- la $x2,stack_top-320
- jal save_tf
- move $sp,$x2
- move $a0,$x2
- ei
- jal handle_trap
- .end trap_entry
+ mtpcr $ra,ASM_CR(PCR_K0)
+ mtpcr $x2,ASM_CR(PCR_K1)
+ la $x2,stack_top-320
+ jal save_tf
+ move $sp,$x2
+ move $a0,$x2
+ ei
+ jal handle_trap
+ .end trap_entry
- .bss
- .global stack_bot
- .global stack_top
+ .bss
+ .global stack_bot
+ .global stack_top
stack_bot:
- .skip 4096
+ .skip 4096
stack_top:
diff --git a/pk/fp.c b/pk/fp.c
index 153ba09..2d369d6 100644
--- a/pk/fp.c
+++ b/pk/fp.c
@@ -19,7 +19,7 @@ static inline void
validate_address(trapframe_t* tf, long addr, int size, int store)
{
if(addr & (size-1))
- handle_misaligned_ldst(tf);
+ store ? handle_misaligned_store(tf) : handle_misaligned_load(tf);
if(addr >= USER_MEM_SIZE)
store ? handle_fault_store(tf) : handle_fault_load(tf);
}
diff --git a/pk/handlers.c b/pk/handlers.c
index 1638a42..4d99578 100644
--- a/pk/handlers.c
+++ b/pk/handlers.c
@@ -59,10 +59,17 @@ static void handle_misaligned_fetch(trapframe_t* tf)
panic("Misaligned instruction access!");
}
-void handle_misaligned_ldst(trapframe_t* tf)
+void handle_misaligned_load(trapframe_t* tf)
{
+ // TODO emulate misaligned loads and stores
dump_tf(tf);
- panic("Misaligned data access!");
+ panic("Misaligned load!");
+}
+
+void handle_misaligned_store(trapframe_t* tf)
+{
+ dump_tf(tf);
+ panic("Misaligned store!");
}
static void handle_fault_fetch(trapframe_t* tf)
@@ -109,19 +116,21 @@ static void handle_interrupt(trapframe_t* tf)
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_interrupt,
- handle_syscall,
- handle_breakpoint,
- handle_misaligned_ldst,
- handle_fault_load,
- handle_fault_store,
- handle_vector_disabled,
+
+ const static trap_handler trap_handlers[NUM_CAUSES] = {
+ [CAUSE_MISALIGNED_FETCH] = handle_misaligned_fetch,
+ [CAUSE_FAULT_FETCH] = handle_fault_fetch,
+ [CAUSE_ILLEGAL_INSTRUCTION] = handle_illegal_instruction,
+ [CAUSE_PRIVILEGED_INSTRUCTION] = handle_privileged_instruction,
+ [CAUSE_FP_DISABLED] = handle_fp_disabled,
+ [CAUSE_INTERRUPT] = handle_interrupt,
+ [CAUSE_SYSCALL] = handle_syscall,
+ [CAUSE_BREAKPOINT] = handle_breakpoint,
+ [CAUSE_MISALIGNED_LOAD] = handle_misaligned_load,
+ [CAUSE_MISALIGNED_STORE] = handle_misaligned_store,
+ [CAUSE_FAULT_LOAD] = handle_fault_load,
+ [CAUSE_FAULT_STORE] = handle_fault_store,
+ [CAUSE_VECTOR_DISABLED] = handle_vector_disabled,
};
int exccode = (tf->cause & CAUSE_EXCCODE) >> CAUSE_EXCCODE_SHIFT;
diff --git a/pk/memset.c b/pk/memset.c
index c77c45c..53ecc85 100644
--- a/pk/memset.c
+++ b/pk/memset.c
@@ -7,8 +7,12 @@
void* memset(void* m, int ch, size_t s)
{
- size_t i;
+ size_t i = 0;
char* mem = (char*)m;
+
+ if(s < 8*sizeof(long))
+ goto small;
+
if((long)m & (sizeof(long)-1))
{
size_t n = sizeof(long) - ((long)m & (sizeof(long)-1));
@@ -39,6 +43,7 @@ void* memset(void* m, int ch, size_t s)
lmem[i+7] = l;
}
+small:
for( ; i < s/sizeof(long); i++)
lmem[i] = l;
diff --git a/pk/pcr.h b/pk/pcr.h
index 920defe..a8f0b4c 100644
--- a/pk/pcr.h
+++ b/pk/pcr.h
@@ -37,6 +37,21 @@
#define CAUSE_EXCCODE_SHIFT 0
#define CAUSE_IP_SHIFT 8
+#define CAUSE_MISALIGNED_FETCH 0
+#define CAUSE_FAULT_FETCH 1
+#define CAUSE_ILLEGAL_INSTRUCTION 2
+#define CAUSE_PRIVILEGED_INSTRUCTION 3
+#define CAUSE_FP_DISABLED 4
+#define CAUSE_INTERRUPT 5
+#define CAUSE_SYSCALL 6
+#define CAUSE_BREAKPOINT 7
+#define CAUSE_MISALIGNED_LOAD 8
+#define CAUSE_MISALIGNED_STORE 9
+#define CAUSE_FAULT_LOAD 10
+#define CAUSE_FAULT_STORE 11
+#define CAUSE_VECTOR_DISABLED 12
+#define NUM_CAUSES 13
+
#define ASM_CR(r) _ASM_CR(r)
#define _ASM_CR(r) $cr##r
diff --git a/pk/pk.h b/pk/pk.h
index 3def532..3887d84 100644
--- a/pk/pk.h
+++ b/pk/pk.h
@@ -1,6 +1,12 @@
#ifndef _PK_H
#define _PK_H
+#define USER_MEM_SIZE 0x70000000
+#define USER_MAINVARS_SIZE 0x1000
+#define USER_START 0x10000
+
+#ifndef __ASSEMBLER__
+
#include <stdint.h>
typedef struct
@@ -13,10 +19,6 @@ typedef struct
long insn;
} trapframe_t;
-#define USER_MEM_SIZE 0x70000000
-#define USER_MAINVARS_SIZE 0x1000
-#define USER_START 0x10000
-
#define panic(s,...) do { printk(s"\n", ##__VA_ARGS__); sys_exit(-1); } while(0)
#define kassert(cond) do { if(!(cond)) panic("assertion failed: "#cond); } while(0)
@@ -36,7 +38,8 @@ void dump_tf(trapframe_t*);
void unhandled_trap(trapframe_t*);
void handle_syscall(trapframe_t*);
-void handle_misaligned_ldst(trapframe_t*);
+void handle_misaligned_load(trapframe_t*);
+void handle_misaligned_store(trapframe_t*);
void handle_fault_load(trapframe_t*);
void handle_fault_store(trapframe_t*);
void boot();
@@ -55,3 +58,5 @@ static inline void advance_pc(trapframe_t* tf)
#endif
#endif
+
+#endif