From a6dae9f422fc86a6459d26b71672e1cb55a4fc22 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sun, 28 Feb 2016 23:15:22 -0800 Subject: WIP on priv spec v1.9 --- encoding.h | 170 +++++++++++++++++++++++++++----------------------------- p/link.ld | 2 +- p/riscv_test.h | 73 ++++++++++++------------ pt/riscv_test.h | 34 ++++-------- v/entry.S | 30 ++++------ v/vm.c | 16 +++--- 6 files changed, 147 insertions(+), 178 deletions(-) diff --git a/encoding.h b/encoding.h index 357cbb3..1127234 100644 --- a/encoding.h +++ b/encoding.h @@ -3,37 +3,42 @@ #ifndef RISCV_CSR_ENCODING_H #define RISCV_CSR_ENCODING_H -#define MSTATUS_IE 0x00000001 -#define MSTATUS_PRV 0x00000006 -#define MSTATUS_IE1 0x00000008 -#define MSTATUS_PRV1 0x00000030 -#define MSTATUS_IE2 0x00000040 -#define MSTATUS_PRV2 0x00000180 -#define MSTATUS_IE3 0x00000200 -#define MSTATUS_PRV3 0x00000C00 -#define MSTATUS_FS 0x00003000 -#define MSTATUS_XS 0x0000C000 -#define MSTATUS_MPRV 0x00010000 -#define MSTATUS_VM 0x003E0000 +#define MSTATUS_UIE 0x00000001 +#define MSTATUS_SIE 0x00000002 +#define MSTATUS_HIE 0x00000004 +#define MSTATUS_MIE 0x00000008 +#define MSTATUS_UPIE 0x00000010 +#define MSTATUS_SPIE 0x00000020 +#define MSTATUS_HPIE 0x00000040 +#define MSTATUS_MPIE 0x00000080 +#define MSTATUS_SPP 0x00000100 +#define MSTATUS_HPP 0x00000600 +#define MSTATUS_MPP 0x00001800 +#define MSTATUS_FS 0x00006000 +#define MSTATUS_XS 0x00018000 +#define MSTATUS_MPRV 0x00020000 +#define MSTATUS_PUM 0x00040000 +#define MSTATUS_VM 0x1F000000 #define MSTATUS32_SD 0x80000000 #define MSTATUS64_SD 0x8000000000000000 -#define SSTATUS_IE 0x00000001 -#define SSTATUS_PIE 0x00000008 -#define SSTATUS_PS 0x00000010 -#define SSTATUS_FS 0x00003000 -#define SSTATUS_XS 0x0000C000 -#define SSTATUS_MPRV 0x00010000 -#define SSTATUS_TIE 0x01000000 +#define SSTATUS_UIE 0x00000001 +#define SSTATUS_SIE 0x00000002 +#define SSTATUS_UPIE 0x00000010 +#define SSTATUS_SPIE 0x00000020 +#define SSTATUS_SPP 0x00000100 +#define SSTATUS_FS 0x00006000 +#define SSTATUS_XS 0x00018000 +#define SSTATUS_PUM 0x00040000 #define SSTATUS32_SD 0x80000000 #define SSTATUS64_SD 0x8000000000000000 -#define MIP_SSIP 0x00000002 -#define MIP_HSIP 0x00000004 -#define MIP_MSIP 0x00000008 -#define MIP_STIP 0x00000020 -#define MIP_HTIP 0x00000040 -#define MIP_MTIP 0x00000080 +#define MIP_SSIP (1 << IRQ_S_SOFT) +#define MIP_HSIP (1 << IRQ_H_SOFT) +#define MIP_MSIP (1 << IRQ_M_SOFT) +#define MIP_STIP (1 << IRQ_S_TIMER) +#define MIP_HTIP (1 << IRQ_H_TIMER) +#define MIP_MTIP (1 << IRQ_M_TIMER) #define SIP_SSIP MIP_SSIP #define SIP_STIP MIP_STIP @@ -50,18 +55,18 @@ #define VM_SV39 9 #define VM_SV48 10 -#define UA_RV32 0 -#define UA_RV64 4 -#define UA_RV128 8 +#define IRQ_S_SOFT 1 +#define IRQ_H_SOFT 2 +#define IRQ_M_SOFT 3 +#define IRQ_S_TIMER 5 +#define IRQ_H_TIMER 6 +#define IRQ_M_TIMER 7 +#define IRQ_COP 8 +#define IRQ_HOST 9 -#define IRQ_SOFT 0 -#define IRQ_TIMER 1 -#define IRQ_HOST 2 -#define IRQ_COP 3 - -#define IMPL_ROCKET 1 - -#define DEFAULT_MTVEC 0x100 +#define DEFAULT_RSTVEC 0x0 +#define DEFAULT_NMIVEC 0x4 +#define DEFAULT_MTVEC 0x8 // page table entry (PTE) fields #define PTE_V 0x001 // Valid @@ -335,18 +340,12 @@ #define MASK_SCALL 0xffffffff #define MATCH_SBREAK 0x100073 #define MASK_SBREAK 0xffffffff -#define MATCH_SRET 0x10000073 +#define MATCH_SRET 0x10200073 #define MASK_SRET 0xffffffff -#define MATCH_SFENCE_VM 0x10100073 +#define MATCH_SFENCE_VM 0x10400073 #define MASK_SFENCE_VM 0xfff07fff -#define MATCH_WFI 0x10200073 +#define MATCH_WFI 0x10500073 #define MASK_WFI 0xffffffff -#define MATCH_MRTH 0x30600073 -#define MASK_MRTH 0xffffffff -#define MATCH_MRTS 0x30500073 -#define MASK_MRTS 0xffffffff -#define MATCH_HRTS 0x20500073 -#define MASK_HRTS 0xffffffff #define MATCH_CSRRW 0x1073 #define MASK_CSRRW 0x707f #define MATCH_CSRRS 0x2073 @@ -639,48 +638,46 @@ #define CSR_UARCH14 0xcce #define CSR_UARCH15 0xccf #define CSR_SSTATUS 0x100 -#define CSR_STVEC 0x101 #define CSR_SIE 0x104 +#define CSR_STVEC 0x105 #define CSR_SSCRATCH 0x140 #define CSR_SEPC 0x141 +#define CSR_SCAUSE 0x142 +#define CSR_SBADADDR 0x143 #define CSR_SIP 0x144 #define CSR_SPTBR 0x180 #define CSR_SASID 0x181 -#define CSR_CYCLEW 0x900 -#define CSR_TIMEW 0x901 -#define CSR_INSTRETW 0x902 -#define CSR_STIME 0xd01 -#define CSR_SCAUSE 0xd42 -#define CSR_SBADADDR 0xd43 -#define CSR_STIMEW 0xa01 #define CSR_MSTATUS 0x300 -#define CSR_MTVEC 0x301 -#define CSR_MTDELEG 0x302 +#define CSR_MEDELEG 0x302 +#define CSR_MIDELEG 0x303 #define CSR_MIE 0x304 +#define CSR_MTVEC 0x305 #define CSR_MTIMECMP 0x321 #define CSR_MSCRATCH 0x340 #define CSR_MEPC 0x341 #define CSR_MCAUSE 0x342 #define CSR_MBADADDR 0x343 #define CSR_MIP 0x344 -#define CSR_MTIME 0x701 -#define CSR_MCPUID 0xf00 -#define CSR_MIMPID 0xf01 -#define CSR_MHARTID 0xf10 -#define CSR_MTOHOST 0x780 -#define CSR_MFROMHOST 0x781 -#define CSR_MRESET 0x782 -#define CSR_SEND_IPI 0x783 +#define CSR_MIPI 0x345 +#define CSR_MCYCLE 0xf00 +#define CSR_MTIME 0xf01 +#define CSR_MINSTRET 0xf02 +#define CSR_MISA 0xf10 +#define CSR_MVENDORID 0xf11 +#define CSR_MARCHID 0xf12 +#define CSR_MIMPID 0xf13 +#define CSR_MCFGADDR 0xf14 +#define CSR_MHARTID 0xf15 +#define CSR_MTOHOST 0x7c0 +#define CSR_MFROMHOST 0x7c1 +#define CSR_MRESET 0x7c2 #define CSR_CYCLEH 0xc80 #define CSR_TIMEH 0xc81 #define CSR_INSTRETH 0xc82 -#define CSR_CYCLEHW 0x980 -#define CSR_TIMEHW 0x981 -#define CSR_INSTRETHW 0x982 -#define CSR_STIMEH 0xd81 -#define CSR_STIMEHW 0xa81 #define CSR_MTIMECMPH 0x361 -#define CSR_MTIMEH 0x741 +#define CSR_MCYCLEH 0xf80 +#define CSR_MTIMEH 0xf81 +#define CSR_MINSTRETH 0xf82 #define CAUSE_MISALIGNED_FETCH 0x0 #define CAUSE_FAULT_FETCH 0x1 #define CAUSE_ILLEGAL_INSTRUCTION 0x2 @@ -786,9 +783,6 @@ DECLARE_INSN(sbreak, MATCH_SBREAK, MASK_SBREAK) DECLARE_INSN(sret, MATCH_SRET, MASK_SRET) DECLARE_INSN(sfence_vm, MATCH_SFENCE_VM, MASK_SFENCE_VM) DECLARE_INSN(wfi, MATCH_WFI, MASK_WFI) -DECLARE_INSN(mrth, MATCH_MRTH, MASK_MRTH) -DECLARE_INSN(mrts, MATCH_MRTS, MASK_MRTS) -DECLARE_INSN(hrts, MATCH_HRTS, MASK_HRTS) DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW) DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS) DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC) @@ -949,48 +943,46 @@ DECLARE_CSR(uarch13, CSR_UARCH13) DECLARE_CSR(uarch14, CSR_UARCH14) DECLARE_CSR(uarch15, CSR_UARCH15) DECLARE_CSR(sstatus, CSR_SSTATUS) -DECLARE_CSR(stvec, CSR_STVEC) DECLARE_CSR(sie, CSR_SIE) +DECLARE_CSR(stvec, CSR_STVEC) DECLARE_CSR(sscratch, CSR_SSCRATCH) DECLARE_CSR(sepc, CSR_SEPC) +DECLARE_CSR(scause, CSR_SCAUSE) +DECLARE_CSR(sbadaddr, CSR_SBADADDR) DECLARE_CSR(sip, CSR_SIP) DECLARE_CSR(sptbr, CSR_SPTBR) DECLARE_CSR(sasid, CSR_SASID) -DECLARE_CSR(cyclew, CSR_CYCLEW) -DECLARE_CSR(timew, CSR_TIMEW) -DECLARE_CSR(instretw, CSR_INSTRETW) -DECLARE_CSR(stime, CSR_STIME) -DECLARE_CSR(scause, CSR_SCAUSE) -DECLARE_CSR(sbadaddr, CSR_SBADADDR) -DECLARE_CSR(stimew, CSR_STIMEW) DECLARE_CSR(mstatus, CSR_MSTATUS) -DECLARE_CSR(mtvec, CSR_MTVEC) -DECLARE_CSR(mtdeleg, CSR_MTDELEG) +DECLARE_CSR(medeleg, CSR_MEDELEG) +DECLARE_CSR(mideleg, CSR_MIDELEG) DECLARE_CSR(mie, CSR_MIE) +DECLARE_CSR(mtvec, CSR_MTVEC) DECLARE_CSR(mtimecmp, CSR_MTIMECMP) DECLARE_CSR(mscratch, CSR_MSCRATCH) DECLARE_CSR(mepc, CSR_MEPC) DECLARE_CSR(mcause, CSR_MCAUSE) DECLARE_CSR(mbadaddr, CSR_MBADADDR) DECLARE_CSR(mip, CSR_MIP) +DECLARE_CSR(mipi, CSR_MIPI) +DECLARE_CSR(mcycle, CSR_MCYCLE) DECLARE_CSR(mtime, CSR_MTIME) -DECLARE_CSR(mcpuid, CSR_MCPUID) +DECLARE_CSR(minstret, CSR_MINSTRET) +DECLARE_CSR(misa, CSR_MISA) +DECLARE_CSR(mvendorid, CSR_MVENDORID) +DECLARE_CSR(marchid, CSR_MARCHID) DECLARE_CSR(mimpid, CSR_MIMPID) +DECLARE_CSR(mcfgaddr, CSR_MCFGADDR) DECLARE_CSR(mhartid, CSR_MHARTID) DECLARE_CSR(mtohost, CSR_MTOHOST) DECLARE_CSR(mfromhost, CSR_MFROMHOST) DECLARE_CSR(mreset, CSR_MRESET) -DECLARE_CSR(send_ipi, CSR_SEND_IPI) DECLARE_CSR(cycleh, CSR_CYCLEH) DECLARE_CSR(timeh, CSR_TIMEH) DECLARE_CSR(instreth, CSR_INSTRETH) -DECLARE_CSR(cyclehw, CSR_CYCLEHW) -DECLARE_CSR(timehw, CSR_TIMEHW) -DECLARE_CSR(instrethw, CSR_INSTRETHW) -DECLARE_CSR(stimeh, CSR_STIMEH) -DECLARE_CSR(stimehw, CSR_STIMEHW) DECLARE_CSR(mtimecmph, CSR_MTIMECMPH) +DECLARE_CSR(mcycleh, CSR_MCYCLEH) DECLARE_CSR(mtimeh, CSR_MTIMEH) +DECLARE_CSR(minstreth, CSR_MINSTRETH) #endif #ifdef DECLARE_CAUSE DECLARE_CAUSE("misaligned fetch", CAUSE_MISALIGNED_FETCH) diff --git a/p/link.ld b/p/link.ld index 0b2382e..eeb3730 100644 --- a/p/link.ld +++ b/p/link.ld @@ -2,7 +2,7 @@ OUTPUT_ARCH( "riscv" ) SECTIONS { - . = 0x100; + . = 0; .text.init : { *(.text.init) } .text : { *(.text) } .data ALIGN(0x1000) : { *(.data) } diff --git a/p/riscv_test.h b/p/riscv_test.h index 1cd0f4b..c4df61e 100644 --- a/p/riscv_test.h +++ b/p/riscv_test.h @@ -53,17 +53,17 @@ .endm #ifdef __riscv64 -# define CHECK_XLEN csrr a0, mcpuid; bltz a0, 1f; RVTEST_PASS; 1: +# define CHECK_XLEN csrr a0, misa; bltz a0, 1f; RVTEST_PASS; 1: #else -# define CHECK_XLEN csrr a0, mcpuid; bgez a0, 1f; RVTEST_PASS; 1: +# define CHECK_XLEN csrr a0, misa; bgez a0, 1f; RVTEST_PASS; 1: #endif #define RVTEST_ENABLE_SUPERVISOR \ - li a0, MSTATUS_PRV1 & (MSTATUS_PRV1 >> 1); \ + li a0, MSTATUS_MPP & (MSTATUS_MPP >> 1); \ csrs mstatus, a0; \ #define RVTEST_ENABLE_MACHINE \ - li a0, MSTATUS_PRV1; \ + li a0, MSTATUS_MPP; \ csrs mstatus, a0; \ #define RVTEST_FP_ENABLE \ @@ -76,67 +76,62 @@ 1: bnez a0, 1b #define EXTRA_TVEC_USER -#define EXTRA_TVEC_SUPERVISOR -#define EXTRA_TVEC_HYPERVISOR #define EXTRA_TVEC_MACHINE #define EXTRA_INIT #define EXTRA_INIT_TIMER +#define INTERRUPT_HANDLER j other_exception /* No interrupts should occur */ + #define RVTEST_CODE_BEGIN \ .text; \ .align 6; \ .weak stvec_handler; \ .weak mtvec_handler; \ -tvec_user: \ - EXTRA_TVEC_USER; \ + .globl _start; \ +_start: \ + /* reset vector */ \ + j reset_vector; \ + /* NMI vector */ \ + j other_exception; \ + /* trap vector */ \ /* test whether the test came from pass/fail */ \ la t5, ecall; \ csrr t6, mepc; \ beq t5, t6, write_tohost; \ - /* test whether the stvec_handler target exists */ \ - la t5, stvec_handler; \ - bnez t5, mrts_routine; \ - /* test whether the mtvec_handler target exists */ \ + /* if an mtvec_handler is defined, jump to it */ \ la t5, mtvec_handler; \ bnez t5, mtvec_handler; \ - /* some other exception occurred */ \ - j other_exception; \ - .align 6; \ -tvec_supervisor: \ - EXTRA_TVEC_SUPERVISOR; \ + /* was it an interrupt or an exception? */ \ csrr t5, mcause; \ - bgez t5, tvec_user; \ - mrts_routine: \ - mrts; \ - .align 6; \ -tvec_hypervisor: \ - EXTRA_TVEC_HYPERVISOR; \ - /* renting some space out here */ \ + bgez t5, handle_exception; \ + INTERRUPT_HANDLER; \ +handle_exception: \ + /* we don't know how to handle whatever the exception was */ \ other_exception: \ - 1: ori TESTNUM, TESTNUM, 1337; /* some other exception occurred */ \ + /* some unhandlable exception occurred */ \ + 1: ori TESTNUM, TESTNUM, 1337; \ write_tohost: \ csrw mtohost, TESTNUM; \ j write_tohost; \ - .align 6; \ -tvec_machine: \ - EXTRA_TVEC_MACHINE; \ - la t5, ecall; \ - csrr t6, mepc; \ - beq t5, t6, write_tohost; \ - la t5, mtvec_handler; \ - bnez t5, mtvec_handler; \ - j other_exception; \ - .align 6; \ - .globl _start; \ -_start: \ +reset_vector: \ RISCV_MULTICORE_DISABLE; \ CHECK_XLEN; \ li TESTNUM, 0; \ + /* if an stvec_handler is defined, delegate exceptions to it */ \ la t0, stvec_handler; \ beqz t0, 1f; \ csrw stvec, t0; \ -1: li t0, MSTATUS_PRV1 | MSTATUS_PRV2 | MSTATUS_IE1 | MSTATUS_IE2; \ - csrc mstatus, t0; \ + li t0, (1 << CAUSE_MISALIGNED_LOAD) | \ + (1 << CAUSE_MISALIGNED_STORE) | \ + (1 << CAUSE_MISALIGNED_FETCH) | \ + (1 << CAUSE_FAULT_LOAD) | \ + (1 << CAUSE_FAULT_STORE) | \ + (1 << CAUSE_FAULT_FETCH) | \ + (1 << CAUSE_ILLEGAL_INSTRUCTION) | \ + (1 << CAUSE_USER_ECALL) | \ + (1 << CAUSE_BREAKPOINT); \ + csrw medeleg, t0; \ +1: csrwi mstatus, 0; \ init; \ EXTRA_INIT; \ EXTRA_INIT_TIMER; \ diff --git a/pt/riscv_test.h b/pt/riscv_test.h index 8137782..7100a20 100644 --- a/pt/riscv_test.h +++ b/pt/riscv_test.h @@ -7,42 +7,28 @@ #define TIMER_INTERVAL 2 -#undef EXTRA_TVEC_USER -#define EXTRA_TVEC_USER \ - csrw mscratch, a0; \ - csrr a0, mcause; \ - bltz a0, _interrupt_handler; \ -_skip: \ - #undef EXTRA_INIT_TIMER #define EXTRA_INIT_TIMER \ - ENABLE_TIMER_INTERRUPT; \ - j _jump_around_interrupt_handler; \ - INTERRUPT_HANDLER; \ -_jump_around_interrupt_handler: \ - -#define ENABLE_TIMER_INTERRUPT \ li a0, MIP_MTIP; \ csrs mie, a0; \ csrr a0, mtime; \ addi a0, a0, TIMER_INTERVAL; \ csrw mtimecmp, a0; \ -#if SSTATUS_XS != 0xc000 +#if SSTATUS_XS != 0x18000 # error #endif -#define XS_SHIFT 14 +#define XS_SHIFT 15 +#undef INTERRUPT_HANDLER #define INTERRUPT_HANDLER \ -_interrupt_handler: \ - slli a0, a0, 1; \ - srli a0, a0, 1; \ - add a0, a0, -IRQ_TIMER; \ - bnez a0, _skip; \ - csrr a0, mtime; \ - addi a0, a0, TIMER_INTERVAL; \ - csrw mtimecmp, a0; \ - csrr a0, mscratch; \ + slli t5, t5, 1; \ + srli t5, t5, 1; \ + add t5, t5, -IRQ_M_TIMER; \ + bnez t5, other_exception; /* other interrups shouldn't happen */\ + csrr t5, mtime; \ + addi t5, t5, TIMER_INTERVAL; \ + csrw mtimecmp, t5; \ eret; \ //----------------------------------------------------------------------- diff --git a/v/entry.S b/v/entry.S index ea05e73..f503764 100644 --- a/v/entry.S +++ b/v/entry.S @@ -13,30 +13,25 @@ #define STACK_TOP (_end + 131072) .section ".text.init","ax",@progbits - .align 6 -entry_from_user: - mrts - .align 6 -entry_from_supervisor: - csrr t0, mcause - addi t0, t0, -CAUSE_SUPERVISOR_ECALL - beqz t0, handle_tohost - j wtf +reset_vector: + j handle_reset - .align 6 -entry_from_hypervisor: + /* NMI vector */ +nmi_vector: j wtf - .align 6 -entry_from_machine: +trap_vector: + # we can safely clobber caller-saved registers here, because we were + # either invoked via do_tohost or we are about to bail out csrr t0, mcause - addi t0, t0, -CAUSE_MACHINE_ECALL - beqz t0, handle_tohost + li t1, CAUSE_SUPERVISOR_ECALL + beq t0, t1, handle_tohost + li t1, CAUSE_MACHINE_ECALL + beq t0, t1, handle_tohost j wtf - .align 6 -power_on_reset: +handle_reset: la sp, STACK_TOP - SIZEOF_TRAPFRAME_T csrw mscratch, sp li a1, 1337 @@ -45,7 +40,6 @@ power_on_reset: .globl pop_tf pop_tf: - csrc sstatus, SSTATUS_IE LOAD t0,33*REGBYTES(a0) csrw sepc,t0 LOAD x1,1*REGBYTES(a0) diff --git a/v/vm.c b/v/vm.c index 7b5ba6c..561578e 100644 --- a/v/vm.c +++ b/v/vm.c @@ -182,17 +182,19 @@ void vm_boot(long test_addr, long seed) // map user to lowermost megapage l1pt[0] = ((pte_t)user_l2pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_TYPE_TABLE; user_l2pt[0] = ((pte_t)user_l3pt >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_TYPE_TABLE; - write_csr(sptbr, l1pt); + write_csr(sptbr, (uintptr_t)l1pt >> PGSHIFT); // set up supervisor trap handling write_csr(stvec, pa2kva(trap_entry)); write_csr(sscratch, pa2kva(read_csr(mscratch))); - // interrupts on; FPU on; accelerator on - set_csr(mstatus, MSTATUS_IE1 | MSTATUS_FS | MSTATUS_XS); - // virtual memory off; set user mode upon eret - clear_csr(mstatus, MSTATUS_VM | MSTATUS_PRV1); - // virtual memory to Sv39 - set_csr(mstatus, (long)VM_SV39 << __builtin_ctzl(MSTATUS_VM)); + write_csr(medeleg, + (1 << CAUSE_USER_ECALL) | + (1 << CAUSE_FAULT_FETCH) | + (1 << CAUSE_FAULT_LOAD) | + (1 << CAUSE_FAULT_STORE)); + // on ERET, user mode w/interrupts on; FPU on; accelerator on; VM on + write_csr(mstatus, MSTATUS_UIE | MSTATUS_FS | MSTATUS_XS | + (VM_SV39 * (MSTATUS_VM & ~(MSTATUS_VM<<1)))); seed = 1 + (seed % MAX_TEST_PAGES); freelist_head = pa2kva((void*)&freelist_nodes[0]); -- cgit v1.1