diff options
-rw-r--r-- | pk/elf.c | 2 | ||||
-rw-r--r-- | pk/entry.S | 237 | ||||
-rw-r--r-- | pk/fp.c | 2 | ||||
-rw-r--r-- | pk/handlers.c | 39 | ||||
-rw-r--r-- | pk/memset.c | 7 | ||||
-rw-r--r-- | pk/pcr.h | 15 | ||||
-rw-r--r-- | pk/pk.h | 15 |
7 files changed, 177 insertions, 140 deletions
@@ -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 @@ -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: @@ -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; @@ -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 @@ -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 |