From 3a2ed4c0966add8f9730c3962a784cc423891663 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 12 Mar 2015 17:38:41 -0700 Subject: Update to new privileged spec --- encoding.h | 267 +++++++++++++++++++++++++++++++++++---------------------- p/link.ld | 2 +- p/riscv_test.h | 90 ++++++++++++++++--- pm/link.ld | 2 +- v/entry.S | 253 +++++++++++++++++++++++++----------------------------- v/link.ld | 7 +- v/vm.c | 60 +++++-------- 7 files changed, 381 insertions(+), 300 deletions(-) diff --git a/encoding.h b/encoding.h index 089a8a9..4b929d3 100644 --- a/encoding.h +++ b/encoding.h @@ -3,25 +3,61 @@ #ifndef RISCV_CSR_ENCODING_H #define RISCV_CSR_ENCODING_H -#define SR_S 0x00000001 -#define SR_PS 0x00000002 -#define SR_EI 0x00000004 -#define SR_PEI 0x00000008 -#define SR_EF 0x00000010 -#define SR_U64 0x00000020 -#define SR_S64 0x00000040 -#define SR_VM 0x00000080 -#define SR_EA 0x00000100 -#define SR_IM 0x00FF0000 -#define SR_IP 0xFF000000 -#define SR_ZERO ~(SR_S|SR_PS|SR_EI|SR_PEI|SR_EF|SR_U64|SR_S64|SR_VM|SR_EA|SR_IM|SR_IP) -#define SR_IM_SHIFT 16 -#define SR_IP_SHIFT 24 +#define MSTATUS_SSIP 0x00000002 +#define MSTATUS_HSIP 0x00000004 +#define MSTATUS_MSIP 0x00000008 +#define MSTATUS_IE 0x00000010 +#define MSTATUS_PRV 0x00000060 +#define MSTATUS_IE1 0x00000080 +#define MSTATUS_PRV1 0x00000300 +#define MSTATUS_IE2 0x00000400 +#define MSTATUS_PRV2 0x00001800 +#define MSTATUS_IE3 0x00002000 +#define MSTATUS_PRV3 0x0000C000 +#define MSTATUS_MPRV 0x00030000 +#define MSTATUS_VM 0x00780000 +#define MSTATUS_STIE 0x01000000 +#define MSTATUS_HTIE 0x02000000 +#define MSTATUS_MTIE 0x04000000 +#define MSTATUS_FS 0x18000000 +#define MSTATUS_XS 0x60000000 +#define MSTATUS32_SD 0x80000000 +#define MSTATUS64_UA 0x0000000F00000000 +#define MSTATUS64_SA 0x000000F000000000 +#define MSTATUS64_HA 0x00000F0000000000 +#define MSTATUS64_SD 0x8000000000000000 -#define IRQ_COP 2 -#define IRQ_IPI 5 -#define IRQ_HOST 6 -#define IRQ_TIMER 7 +#define SSTATUS_SIP 0x00000002 +#define SSTATUS_IE 0x00000010 +#define SSTATUS_PIE 0x00000080 +#define SSTATUS_PS 0x00000100 +#define SSTATUS_UA 0x000F0000 +#define SSTATUS_TIE 0x01000000 +#define SSTATUS_TIP 0x04000000 +#define SSTATUS_FS 0x18000000 +#define SSTATUS_XS 0x60000000 +#define SSTATUS32_SD 0x80000000 +#define SSTATUS64_SD 0x8000000000000000 + +#define PRV_U 0 +#define PRV_S 1 +#define PRV_H 2 +#define PRV_M 3 + +#define VM_MBARE 0 +#define VM_MBB 1 +#define VM_MBBID 2 +#define VM_SV32 4 +#define VM_SV43 5 + +#define UA_RV32 0 +#define UA_RV64 4 +#define UA_RV128 8 + +#define IRQ_TIMER 0 +#define IRQ_IPI 1 +#define IRQ_HOST 2 +#define IRQ_COP 3 #define IMPL_SPIKE 1 #define IMPL_ROCKET 2 @@ -41,9 +77,16 @@ #ifdef __riscv #ifdef __riscv64 +# define MSTATUS_UA MSTATUS64_UA +# define MSTATUS_SA MSTATUS64_SA +# define MSTATUS_HA MSTATUS64_HA +# define MSTATUS_SD MSTATUS64_SD +# define SSTATUS_SD SSTATUS64_SD # define RISCV_PGLEVELS 3 # define RISCV_PGSHIFT 13 #else +# define MSTATUS_SD MSTATUS32_SD +# define SSTATUS_SD SSTATUS32_SD # define RISCV_PGLEVELS 2 # define RISCV_PGSHIFT 12 #endif @@ -52,7 +95,9 @@ #ifndef __ASSEMBLER__ -#define read_csr(reg) ({ long __tmp; \ +#ifdef __GNUC__ + +#define read_csr(reg) ({ unsigned long __tmp; \ asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ __tmp; }) @@ -63,31 +108,25 @@ asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \ __tmp; }) -#define set_csr(reg, bit) ({ long __tmp; \ +#define set_csr(reg, bit) ({ unsigned long __tmp; \ if (__builtin_constant_p(bit) && (bit) < 32) \ asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \ else \ asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \ __tmp; }) -#define clear_csr(reg, bit) ({ long __tmp; \ +#define clear_csr(reg, bit) ({ unsigned long __tmp; \ if (__builtin_constant_p(bit) && (bit) < 32) \ asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \ else \ asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \ __tmp; }) -#define rdtime() ({ unsigned long __tmp; \ - asm volatile ("rdtime %0" : "=r"(__tmp)); \ - __tmp; }) - -#define rdcycle() ({ unsigned long __tmp; \ - asm volatile ("rdcycle %0" : "=r"(__tmp)); \ - __tmp; }) +#define rdtime() read_csr(time) +#define rdcycle() read_csr(cycle) +#define rdinstret() read_csr(instret) -#define rdinstret() ({ unsigned long __tmp; \ - asm volatile ("rdinstret %0" : "=r"(__tmp)); \ - __tmp; }) +#endif #endif @@ -113,6 +152,8 @@ #define MASK_FSGNJN_D 0xfe00707f #define MATCH_FMIN_S 0x28000053 #define MASK_FMIN_S 0xfe00707f +#define MATCH_MRET 0x30200073 +#define MASK_MRET 0xffffffff #define MATCH_CSRRW 0x1073 #define MASK_CSRRW 0x707f #define MATCH_SLLIW 0x101b @@ -201,6 +242,8 @@ #define MASK_SCALL 0xffffffff #define MATCH_FCLASS_S 0xe0001053 #define MASK_FCLASS_S 0xfff0707f +#define MATCH_SFENCE_VM 0x10400073 +#define MASK_SFENCE_VM 0xfff07fff #define MATCH_SC_W 0x1800202f #define MASK_SC_W 0xf800707f #define MATCH_REM 0x2006033 @@ -217,6 +260,8 @@ #define MASK_MULH 0xfe00707f #define MATCH_FMUL_S 0x10000053 #define MASK_FMUL_S 0xfe00007f +#define MATCH_MCALL 0x20000073 +#define MASK_MCALL 0xffffffff #define MATCH_CSRRSI 0x6073 #define MASK_CSRRSI 0x707f #define MATCH_SRAI 0x40005013 @@ -257,6 +302,8 @@ #define MASK_FSUB_D 0xfe00007f #define MATCH_FSGNJX_S 0x20002053 #define MASK_FSGNJX_S 0xfe00707f +#define MATCH_MRTS 0x30900073 +#define MASK_MRTS 0xffffffff #define MATCH_FEQ_D 0xa2002053 #define MASK_FEQ_D 0xfe00707f #define MATCH_FCVT_D_WU 0xd2100053 @@ -283,7 +330,7 @@ #define MASK_ANDI 0x707f #define MATCH_FMV_X_S 0xe0000053 #define MASK_FMV_X_S 0xfff0707f -#define MATCH_SRET 0x80000073 +#define MATCH_SRET 0x10200073 #define MASK_SRET 0xffffffff #define MATCH_FNMADD_S 0x4f #define MASK_FNMADD_S 0x600007f @@ -414,29 +461,10 @@ #define CSR_FFLAGS 0x1 #define CSR_FRM 0x2 #define CSR_FCSR 0x3 -#define CSR_STATS 0xc0 -#define CSR_SUP0 0x500 -#define CSR_SUP1 0x501 -#define CSR_EPC 0x502 -#define CSR_BADVADDR 0x503 -#define CSR_PTBR 0x504 -#define CSR_ASID 0x505 -#define CSR_COUNT 0x506 -#define CSR_COMPARE 0x507 -#define CSR_EVEC 0x508 -#define CSR_CAUSE 0x509 -#define CSR_STATUS 0x50a -#define CSR_HARTID 0x50b -#define CSR_IMPL 0x50c -#define CSR_FATC 0x50d -#define CSR_SEND_IPI 0x50e -#define CSR_CLEAR_IPI 0x50f -#define CSR_RESET 0x51d -#define CSR_TOHOST 0x51e -#define CSR_FROMHOST 0x51f #define CSR_CYCLE 0xc00 #define CSR_TIME 0xc01 #define CSR_INSTRET 0xc02 +#define CSR_STATS 0xc0 #define CSR_UARCH0 0xcc0 #define CSR_UARCH1 0xcc1 #define CSR_UARCH2 0xcc2 @@ -453,22 +481,45 @@ #define CSR_UARCH13 0xccd #define CSR_UARCH14 0xcce #define CSR_UARCH15 0xccf -#define CSR_COUNTH 0x586 +#define CSR_SSTATUS 0x100 +#define CSR_STVEC 0x101 +#define CSR_STIMECMP 0x121 +#define CSR_SSCRATCH 0x140 +#define CSR_SEPC 0x141 +#define CSR_SPTBR 0x188 +#define CSR_SASID 0x189 +#define CSR_SCYCLE 0x900 +#define CSR_STIME 0x901 +#define CSR_SINSTRET 0x902 +#define CSR_SCAUSE 0xd40 +#define CSR_SBADADDR 0xd41 +#define CSR_MSTATUS 0x300 +#define CSR_MSCRATCH 0x340 +#define CSR_MEPC 0x341 +#define CSR_MCAUSE 0x342 +#define CSR_MBADADDR 0x343 +#define CSR_RESET 0x780 +#define CSR_TOHOST 0x781 +#define CSR_FROMHOST 0x782 +#define CSR_SEND_IPI 0x783 +#define CSR_HARTID 0xfc0 #define CSR_CYCLEH 0xc80 #define CSR_TIMEH 0xc81 #define CSR_INSTRETH 0xc82 +#define CSR_SCYCLEH 0x980 +#define CSR_STIMEH 0x981 +#define CSR_SINSTRETH 0x982 #define CAUSE_MISALIGNED_FETCH 0x0 #define CAUSE_FAULT_FETCH 0x1 #define CAUSE_ILLEGAL_INSTRUCTION 0x2 -#define CAUSE_PRIVILEGED_INSTRUCTION 0x3 -#define CAUSE_FP_DISABLED 0x4 -#define CAUSE_SYSCALL 0x6 +#define CAUSE_SCALL 0x4 +#define CAUSE_HCALL 0x5 +#define CAUSE_MCALL 0x6 #define CAUSE_BREAKPOINT 0x7 #define CAUSE_MISALIGNED_LOAD 0x8 -#define CAUSE_MISALIGNED_STORE 0x9 -#define CAUSE_FAULT_LOAD 0xa +#define CAUSE_FAULT_LOAD 0x9 +#define CAUSE_MISALIGNED_STORE 0xa #define CAUSE_FAULT_STORE 0xb -#define CAUSE_ACCELERATOR_DISABLED 0xc #endif #ifdef DECLARE_INSN DECLARE_INSN(fmv_s_x, MATCH_FMV_S_X, MASK_FMV_S_X) @@ -479,6 +530,7 @@ DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D) DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU) DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D) DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S) +DECLARE_INSN(mret, MATCH_MRET, MASK_MRET) DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW) DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW) DECLARE_INSN(lb, MATCH_LB, MASK_LB) @@ -523,6 +575,7 @@ DECLARE_INSN(sub, MATCH_SUB, MASK_SUB) DECLARE_INSN(blt, MATCH_BLT, MASK_BLT) DECLARE_INSN(scall, MATCH_SCALL, MASK_SCALL) DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S) +DECLARE_INSN(sfence_vm, MATCH_SFENCE_VM, MASK_SFENCE_VM) DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W) DECLARE_INSN(rem, MATCH_REM, MASK_REM) DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW) @@ -531,6 +584,7 @@ DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI) DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI) DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH) DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S) +DECLARE_INSN(mcall, MATCH_MCALL, MASK_MCALL) DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI) DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI) DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D) @@ -551,6 +605,7 @@ DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW) DECLARE_INSN(srl, MATCH_SRL, MASK_SRL) DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D) DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S) +DECLARE_INSN(mrts, MATCH_MRTS, MASK_MRTS) DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D) DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU) DECLARE_INSN(or, MATCH_OR, MASK_OR) @@ -633,29 +688,10 @@ DECLARE_INSN(sd, MATCH_SD, MASK_SD) DECLARE_CSR(fflags, CSR_FFLAGS) DECLARE_CSR(frm, CSR_FRM) DECLARE_CSR(fcsr, CSR_FCSR) -DECLARE_CSR(stats, CSR_STATS) -DECLARE_CSR(sup0, CSR_SUP0) -DECLARE_CSR(sup1, CSR_SUP1) -DECLARE_CSR(epc, CSR_EPC) -DECLARE_CSR(badvaddr, CSR_BADVADDR) -DECLARE_CSR(ptbr, CSR_PTBR) -DECLARE_CSR(asid, CSR_ASID) -DECLARE_CSR(count, CSR_COUNT) -DECLARE_CSR(compare, CSR_COMPARE) -DECLARE_CSR(evec, CSR_EVEC) -DECLARE_CSR(cause, CSR_CAUSE) -DECLARE_CSR(status, CSR_STATUS) -DECLARE_CSR(hartid, CSR_HARTID) -DECLARE_CSR(impl, CSR_IMPL) -DECLARE_CSR(fatc, CSR_FATC) -DECLARE_CSR(send_ipi, CSR_SEND_IPI) -DECLARE_CSR(clear_ipi, CSR_CLEAR_IPI) -DECLARE_CSR(reset, CSR_RESET) -DECLARE_CSR(tohost, CSR_TOHOST) -DECLARE_CSR(fromhost, CSR_FROMHOST) DECLARE_CSR(cycle, CSR_CYCLE) DECLARE_CSR(time, CSR_TIME) DECLARE_CSR(instret, CSR_INSTRET) +DECLARE_CSR(stats, CSR_STATS) DECLARE_CSR(uarch0, CSR_UARCH0) DECLARE_CSR(uarch1, CSR_UARCH1) DECLARE_CSR(uarch2, CSR_UARCH2) @@ -672,38 +708,43 @@ DECLARE_CSR(uarch12, CSR_UARCH12) DECLARE_CSR(uarch13, CSR_UARCH13) DECLARE_CSR(uarch14, CSR_UARCH14) DECLARE_CSR(uarch15, CSR_UARCH15) -DECLARE_CSR(counth, CSR_COUNTH) +DECLARE_CSR(sstatus, CSR_SSTATUS) +DECLARE_CSR(stvec, CSR_STVEC) +DECLARE_CSR(stimecmp, CSR_STIMECMP) +DECLARE_CSR(sscratch, CSR_SSCRATCH) +DECLARE_CSR(sepc, CSR_SEPC) +DECLARE_CSR(sptbr, CSR_SPTBR) +DECLARE_CSR(sasid, CSR_SASID) +DECLARE_CSR(scycle, CSR_SCYCLE) +DECLARE_CSR(stime, CSR_STIME) +DECLARE_CSR(sinstret, CSR_SINSTRET) +DECLARE_CSR(scause, CSR_SCAUSE) +DECLARE_CSR(sbadaddr, CSR_SBADADDR) +DECLARE_CSR(mstatus, CSR_MSTATUS) +DECLARE_CSR(mscratch, CSR_MSCRATCH) +DECLARE_CSR(mepc, CSR_MEPC) +DECLARE_CSR(mcause, CSR_MCAUSE) +DECLARE_CSR(mbadaddr, CSR_MBADADDR) +DECLARE_CSR(reset, CSR_RESET) +DECLARE_CSR(tohost, CSR_TOHOST) +DECLARE_CSR(fromhost, CSR_FROMHOST) +DECLARE_CSR(send_ipi, CSR_SEND_IPI) +DECLARE_CSR(hartid, CSR_HARTID) DECLARE_CSR(cycleh, CSR_CYCLEH) DECLARE_CSR(timeh, CSR_TIMEH) DECLARE_CSR(instreth, CSR_INSTRETH) +DECLARE_CSR(scycleh, CSR_SCYCLEH) +DECLARE_CSR(stimeh, CSR_STIMEH) +DECLARE_CSR(sinstreth, CSR_SINSTRETH) #endif #ifdef DECLARE_CAUSE DECLARE_CAUSE("fflags", CAUSE_FFLAGS) DECLARE_CAUSE("frm", CAUSE_FRM) DECLARE_CAUSE("fcsr", CAUSE_FCSR) -DECLARE_CAUSE("stats", CAUSE_STATS) -DECLARE_CAUSE("sup0", CAUSE_SUP0) -DECLARE_CAUSE("sup1", CAUSE_SUP1) -DECLARE_CAUSE("epc", CAUSE_EPC) -DECLARE_CAUSE("badvaddr", CAUSE_BADVADDR) -DECLARE_CAUSE("ptbr", CAUSE_PTBR) -DECLARE_CAUSE("asid", CAUSE_ASID) -DECLARE_CAUSE("count", CAUSE_COUNT) -DECLARE_CAUSE("compare", CAUSE_COMPARE) -DECLARE_CAUSE("evec", CAUSE_EVEC) -DECLARE_CAUSE("cause", CAUSE_CAUSE) -DECLARE_CAUSE("status", CAUSE_STATUS) -DECLARE_CAUSE("hartid", CAUSE_HARTID) -DECLARE_CAUSE("impl", CAUSE_IMPL) -DECLARE_CAUSE("fatc", CAUSE_FATC) -DECLARE_CAUSE("send_ipi", CAUSE_SEND_IPI) -DECLARE_CAUSE("clear_ipi", CAUSE_CLEAR_IPI) -DECLARE_CAUSE("reset", CAUSE_RESET) -DECLARE_CAUSE("tohost", CAUSE_TOHOST) -DECLARE_CAUSE("fromhost", CAUSE_FROMHOST) DECLARE_CAUSE("cycle", CAUSE_CYCLE) DECLARE_CAUSE("time", CAUSE_TIME) DECLARE_CAUSE("instret", CAUSE_INSTRET) +DECLARE_CAUSE("stats", CAUSE_STATS) DECLARE_CAUSE("uarch0", CAUSE_UARCH0) DECLARE_CAUSE("uarch1", CAUSE_UARCH1) DECLARE_CAUSE("uarch2", CAUSE_UARCH2) @@ -720,8 +761,32 @@ DECLARE_CAUSE("uarch12", CAUSE_UARCH12) DECLARE_CAUSE("uarch13", CAUSE_UARCH13) DECLARE_CAUSE("uarch14", CAUSE_UARCH14) DECLARE_CAUSE("uarch15", CAUSE_UARCH15) -DECLARE_CAUSE("counth", CAUSE_COUNTH) +DECLARE_CAUSE("sstatus", CAUSE_SSTATUS) +DECLARE_CAUSE("stvec", CAUSE_STVEC) +DECLARE_CAUSE("stimecmp", CAUSE_STIMECMP) +DECLARE_CAUSE("sscratch", CAUSE_SSCRATCH) +DECLARE_CAUSE("sepc", CAUSE_SEPC) +DECLARE_CAUSE("sptbr", CAUSE_SPTBR) +DECLARE_CAUSE("sasid", CAUSE_SASID) +DECLARE_CAUSE("scycle", CAUSE_SCYCLE) +DECLARE_CAUSE("stime", CAUSE_STIME) +DECLARE_CAUSE("sinstret", CAUSE_SINSTRET) +DECLARE_CAUSE("scause", CAUSE_SCAUSE) +DECLARE_CAUSE("sbadaddr", CAUSE_SBADADDR) +DECLARE_CAUSE("mstatus", CAUSE_MSTATUS) +DECLARE_CAUSE("mscratch", CAUSE_MSCRATCH) +DECLARE_CAUSE("mepc", CAUSE_MEPC) +DECLARE_CAUSE("mcause", CAUSE_MCAUSE) +DECLARE_CAUSE("mbadaddr", CAUSE_MBADADDR) +DECLARE_CAUSE("reset", CAUSE_RESET) +DECLARE_CAUSE("tohost", CAUSE_TOHOST) +DECLARE_CAUSE("fromhost", CAUSE_FROMHOST) +DECLARE_CAUSE("send_ipi", CAUSE_SEND_IPI) +DECLARE_CAUSE("hartid", CAUSE_HARTID) DECLARE_CAUSE("cycleh", CAUSE_CYCLEH) DECLARE_CAUSE("timeh", CAUSE_TIMEH) DECLARE_CAUSE("instreth", CAUSE_INSTRETH) +DECLARE_CAUSE("scycleh", CAUSE_SCYCLEH) +DECLARE_CAUSE("stimeh", CAUSE_STIMEH) +DECLARE_CAUSE("sinstreth", CAUSE_SINSTRETH) #endif diff --git a/p/link.ld b/p/link.ld index 6b19389..694e906 100644 --- a/p/link.ld +++ b/p/link.ld @@ -26,7 +26,7 @@ SECTIONS { /* text: test code section */ - . = 0x00002000; + . = 0; .text : { *(.text) diff --git a/p/riscv_test.h b/p/riscv_test.h index ad9bfdc..36d723d 100644 --- a/p/riscv_test.h +++ b/p/riscv_test.h @@ -43,30 +43,55 @@ RVTEST_VEC_ENABLE; \ .endm +#define RVTEST_RV64M \ + .macro init; \ + RVTEST_ENABLE_MACHINE; \ + .endm + #define RVTEST_RV64S \ .macro init; \ + RVTEST_ENABLE_SUPERVISOR; \ + .endm + +#define RVTEST_RV32M \ + .macro init; \ + RVTEST_ENABLE_MACHINE; \ + RVTEST_32_ENABLE; \ .endm #define RVTEST_RV32S \ .macro init; \ + RVTEST_ENABLE_SUPERVISOR; \ RVTEST_32_ENABLE; \ .endm #define RVTEST_32_ENABLE \ - li a0, SR_S64; \ - csrc status, a0; \ + li a0, MSTATUS64_UA >> 31; \ + slli a0, a0, 31; \ + csrc mstatus, a0; \ + li a0, MSTATUS64_SA >> 31; \ + slli a0, a0, 31; \ + csrc mstatus, a0; \ + +#define RVTEST_ENABLE_SUPERVISOR \ + li a0, MSTATUS_PRV1 & (MSTATUS_PRV1 >> 1); \ + csrs mstatus, a0; \ + +#define RVTEST_ENABLE_MACHINE \ + li a0, MSTATUS_PRV1; \ + csrs mstatus, a0; \ #define RVTEST_FP_ENABLE \ - li a0, SR_EF; \ - csrs status, a0; \ - csrr a1, status; \ + li a0, SSTATUS_FS & (SSTATUS_FS >> 1); \ + csrs sstatus, a0; \ + csrr a1, sstatus; \ and a0, a0, a1; \ bnez a0, 2f; \ RVTEST_PASS; \ 2:fssr x0; \ #define RVTEST_VEC_ENABLE \ - li a0, SR_EA; \ + li a0, SSSTATUS_XS & (SSTATUS_XS >> 1); \ csrs status, a0; \ csrr a1, status; \ and a0, a0, a1; \ @@ -76,26 +101,64 @@ #define RISCV_MULTICORE_DISABLE \ csrr a0, hartid; \ - 1: bnez a0, 1b; \ + 1: bnez a0, 1b #define EXTRA_INIT #define EXTRA_INIT_TIMER #define RVTEST_CODE_BEGIN \ .text; \ - .align 4; \ - .global _start; \ + .align 6; \ +tvec_user: \ + la t5, mcall; \ + csrr t6, mepc; \ + beq t5, t6, write_tohost; \ + li t5, 0xbadbad0; \ + csrr t6, stvec; \ + bne t5, t6, 2f; \ + ori TESTNUM, TESTNUM, 1337; /* some other exception occurred */ \ + write_tohost: csrw tohost, TESTNUM; \ + j write_tohost; \ + 2: mrts; \ + .align 6; \ +tvec_supervisor: \ + csrr t5, mcause; \ + bgez t5, tvec_user; \ + mrts; \ + .align 6; \ +tvec_hypervisor: \ + RVTEST_FAIL; /* no hypervisor */ \ + .align 6; \ +tvec_machine: \ + .weak mtvec; \ + la t5, mcall; \ + csrr t6, mepc; \ + beq t5, t6, write_tohost; \ + la t5, mtvec; \ +1: beqz t5, 1b; \ + j mtvec; \ + .align 6; \ + .globl _start; \ _start: \ RISCV_MULTICORE_DISABLE; \ + li t0, 0xbadbad0; csrw stvec, t0; \ + li t0, MSTATUS_PRV1; csrc mstatus, t0; \ init; \ EXTRA_INIT; \ EXTRA_INIT_TIMER; \ + la t0, 1f; \ + csrw mepc, t0; \ + csrr a0, hartid; \ + mret; \ +1: //----------------------------------------------------------------------- // End Macro //----------------------------------------------------------------------- #define RVTEST_CODE_END \ +mcall: mcall; \ + j mcall //----------------------------------------------------------------------- // Pass/Fail Macro @@ -103,17 +166,16 @@ _start: \ #define RVTEST_PASS \ fence; \ - csrw tohost, 1; \ -1: j 1b; \ + li TESTNUM, 1; \ + j mcall #define TESTNUM x28 #define RVTEST_FAIL \ fence; \ - beqz TESTNUM, 1f; \ +1: beqz TESTNUM, 1b; \ sll TESTNUM, TESTNUM, 1; \ or TESTNUM, TESTNUM, 1; \ - csrw tohost, TESTNUM; \ -1: j 1b; \ + j mcall //----------------------------------------------------------------------- // Data Section Macro diff --git a/pm/link.ld b/pm/link.ld index 6b19389..694e906 100644 --- a/pm/link.ld +++ b/pm/link.ld @@ -26,7 +26,7 @@ SECTIONS { /* text: test code section */ - . = 0x00002000; + . = 0; .text : { *(.text) diff --git a/v/entry.S b/v/entry.S index 96f0ca5..68c0f0a 100644 --- a/v/entry.S +++ b/v/entry.S @@ -13,166 +13,143 @@ #define STACK_TOP (_end + 131072) .text - .global _start -_start: - la sp, STACK_TOP + .align 6 +entry_from_user: + j trap_entry + + .align 6 +entry_from_supervisor: + j double_fault + + .align 6 +entry_from_hypervisor: + j double_fault + + .align 6 +entry_from_machine: + j double_fault + + .align 6 +power_on_reset: + la sp, STACK_TOP - SIZEOF_TRAPFRAME_T + csrw mscratch, sp li a1, 1337 la a0, userstart j vm_boot -save_tf: # write the trap frame onto the stack + .globl pop_tf +pop_tf: + csrc mstatus, MSTATUS_IE + LOAD t0,33*REGBYTES(a0) + csrw mepc,t0 + LOAD x1,1*REGBYTES(a0) + LOAD x2,2*REGBYTES(a0) + LOAD x3,3*REGBYTES(a0) + LOAD x4,4*REGBYTES(a0) + LOAD x5,5*REGBYTES(a0) + LOAD x6,6*REGBYTES(a0) + LOAD x7,7*REGBYTES(a0) + LOAD x8,8*REGBYTES(a0) + LOAD x9,9*REGBYTES(a0) + LOAD x11,11*REGBYTES(a0) + LOAD x12,12*REGBYTES(a0) + LOAD x13,13*REGBYTES(a0) + LOAD x14,14*REGBYTES(a0) + LOAD x15,15*REGBYTES(a0) + LOAD x16,16*REGBYTES(a0) + LOAD x17,17*REGBYTES(a0) + LOAD x18,18*REGBYTES(a0) + LOAD x19,19*REGBYTES(a0) + LOAD x20,20*REGBYTES(a0) + LOAD x21,21*REGBYTES(a0) + LOAD x22,22*REGBYTES(a0) + LOAD x23,23*REGBYTES(a0) + LOAD x24,24*REGBYTES(a0) + LOAD x25,25*REGBYTES(a0) + LOAD x26,26*REGBYTES(a0) + LOAD x27,27*REGBYTES(a0) + LOAD x28,28*REGBYTES(a0) + LOAD x29,29*REGBYTES(a0) + LOAD x30,30*REGBYTES(a0) + LOAD x31,31*REGBYTES(a0) + LOAD a0,10*REGBYTES(a0) + mret + + .global trap_entry +trap_entry: + csrrw sp, mscratch, sp # 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) - - csrr x3,sup0 - STORE x3,1*REGBYTES(x2) # x1 is in sup0 - csrr x3,sup1 - STORE x3,2*REGBYTES(x2) # x2 is in sup1 + STORE x1,1*REGBYTES(sp) + STORE x3,3*REGBYTES(sp) + STORE x4,4*REGBYTES(sp) + STORE x5,5*REGBYTES(sp) + STORE x6,6*REGBYTES(sp) + STORE x7,7*REGBYTES(sp) + STORE x8,8*REGBYTES(sp) + STORE x9,9*REGBYTES(sp) + STORE x10,10*REGBYTES(sp) + STORE x11,11*REGBYTES(sp) + STORE x12,12*REGBYTES(sp) + STORE x13,13*REGBYTES(sp) + STORE x14,14*REGBYTES(sp) + STORE x15,15*REGBYTES(sp) + STORE x16,16*REGBYTES(sp) + STORE x17,17*REGBYTES(sp) + STORE x18,18*REGBYTES(sp) + STORE x19,19*REGBYTES(sp) + STORE x20,20*REGBYTES(sp) + STORE x21,21*REGBYTES(sp) + STORE x22,22*REGBYTES(sp) + STORE x23,23*REGBYTES(sp) + STORE x24,24*REGBYTES(sp) + STORE x25,25*REGBYTES(sp) + STORE x26,26*REGBYTES(sp) + STORE x27,27*REGBYTES(sp) + STORE x28,28*REGBYTES(sp) + STORE x29,29*REGBYTES(sp) + STORE x30,30*REGBYTES(sp) + STORE x31,31*REGBYTES(sp) + + csrrw t0,mscratch,sp + STORE t0,2*REGBYTES(sp) # get sr, epc, badvaddr, cause - csrr x3,status # sr - STORE x3,32*REGBYTES(x2) - csrr x4,epc # epc - STORE x4,33*REGBYTES(x2) - csrr x3,badvaddr # badvaddr - STORE x3,34*REGBYTES(x2) - csrr x3,cause # cause - STORE x3,35*REGBYTES(x2) + csrr t0,mstatus + STORE t0,32*REGBYTES(sp) + csrr t0,mepc + STORE t0,33*REGBYTES(sp) + csrr t0,mbadaddr + STORE t0,34*REGBYTES(sp) + csrr t0,mcause + STORE t0,35*REGBYTES(sp) # get hwacha cause if IRQ_COP # vxcptcause clears hwacha interrupt bit - bge x3,x0,1f - slli x3,x3,1 # clearing MSB of cause - srli x3,x3,1 # clearing MSB of cause - li x4,IRQ_COP - bne x3,x4,1f - vxcptcause x3 - STORE x3,36*REGBYTES(x2) + bgez t0,1f + slli t0,t0,1 # clearing MSB of cause + srli t0,t0,1 # clearing MSB of cause + li t1,IRQ_COP + bne t0,t1,1f + vxcptcause t0 + STORE t0,36*REGBYTES(sp) 1: - jr x1 - - .globl pop_tf -pop_tf: # write the trap frame onto the stack - # restore gprs - LOAD a1,32*REGBYTES(a0) # restore sr (should disable interrupts) - csrw status,a1 - - LOAD x1,1*REGBYTES(a0) - LOAD x2,2*REGBYTES(a0) - csrw sup0,x1 - csrw sup1,x2 - 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) - csrw epc,x2 - csrr x1,sup0 - csrr x2,sup1 - sret - - .global trap_entry -trap_entry: - csrw sup0,x1 - csrw sup1,x2 - - # coming from kernel? - csrr x1,status - and x1,x1,SR_PS - bnez x1, 1f - - # no, so start at the top of the stack - la x2,STACK_TOP-SIZEOF_TRAPFRAME_T - jal x1, save_tf - move sp,x2 - csrs status,SR_EI move a0,sp - csrr t0,status - and t0,t0,SR_EA + csrr t0,mstatus + li t1, MSTATUS_XS + and t0,t0,t1 beqz t0,2f + + # disable saving vector state for now addi t0,sp,SIZEOF_TRAPFRAME_T_SCALAR # rocket currently doesn't support vxcptsave/vxcptrestore natively - csrr x3,impl - li x4,IMPL_ROCKET - bne x3,x4,3f vgetcfg x4 STORE x4,0*REGBYTES(t0) vgetvl x4 STORE x4,1*REGBYTES(t0) addi t0,t0,2*REGBYTES vxcptevac t0 - j 2f - - # native vxcptsave -3:vxcptsave t0 -2:jal handle_trap - - # when coming from kernel, continue below its stack - # we assume vector unit wasn't used in kernel -1:addi x2,sp,-SIZEOF_TRAPFRAME_T_SCALAR - jal x1, save_tf - move sp,x2 - csrs status,SR_EI - move a0,sp - jal handle_trap - unimp +2:j handle_trap diff --git a/v/link.ld b/v/link.ld index 4efeaaa..3ae9717 100644 --- a/v/link.ld +++ b/v/link.ld @@ -13,11 +13,6 @@ OUTPUT_ARCH( "riscv" ) -/* The ENTRY command specifies the entry point (ie. first instruction - to execute). The symbol _start should be defined in each test. */ - -ENTRY( _start ) - /*----------------------------------------------------------------------*/ /* Sections */ /*----------------------------------------------------------------------*/ @@ -26,7 +21,7 @@ SECTIONS { /* text: test code section */ - . = 0x00002000; + . = 0; .text : { *(.text) diff --git a/v/vm.c b/v/vm.c index a57a136..10fc0cd 100644 --- a/v/vm.c +++ b/v/vm.c @@ -12,13 +12,13 @@ void pop_tf(trapframe_t*); static void cputchar(int x) { while (swap_csr(tohost, 0x0101000000000000 | (unsigned char)x)); + while (swap_csr(fromhost, 0) == 0); } static void cputstring(const char* s) { while(*s) cputchar(*s++); - cputchar('\n'); } static void terminate(int code) @@ -31,12 +31,10 @@ static void terminate(int code) #define stringify(x) stringify1(x) #define assert(x) do { \ if (x) break; \ - cputstring("Assertion failed: " stringify(x)); \ + cputstring("Assertion failed: " stringify(x) "\n"); \ terminate(3); \ } while(0) -#define RELOC(x) ((typeof(x))((char*)(x) + (PGSIZE*MAX_TEST_PAGES))) - typedef struct { pte_t addr; void* next; } freelist_t; pte_t l1pt[PTES_PER_PT] __attribute__((aligned(PGSIZE))); @@ -61,13 +59,13 @@ void printhex(uint64_t x) void evict(unsigned long addr) { - assert(addr >= PGSIZE && addr < RELOC(0L)); + assert(addr >= PGSIZE && addr < MAX_TEST_PAGES * PGSIZE); addr = addr/PGSIZE*PGSIZE; freelist_t* node = &user_mapping[addr/PGSIZE]; if (node->addr) { - memcpy((void*)RELOC(addr), (void*)addr, PGSIZE); + memcpy((void*)addr, (void*)node->addr, PGSIZE); user_mapping[addr/PGSIZE].addr = 0; if (freelist_tail == 0) @@ -82,7 +80,7 @@ void evict(unsigned long addr) void handle_fault(unsigned long addr) { - assert(addr >= PGSIZE && addr < RELOC(0L)); + assert(addr >= PGSIZE && addr < MAX_TEST_PAGES * PGSIZE); addr = addr/PGSIZE*PGSIZE; freelist_t* node = freelist_head; @@ -92,11 +90,11 @@ void handle_fault(unsigned long addr) freelist_tail = 0; l3pt[addr/PGSIZE] = node->addr | PTE_UW | PTE_UR | PTE_UX | PTE_SW | PTE_SR | PTE_SX | PTE_V; - write_csr(fatc, 0); + asm volatile ("sfence.vm"); assert(user_mapping[addr/PGSIZE].addr == 0); user_mapping[addr/PGSIZE] = *node; - memcpy((void*)addr, (void*)RELOC(addr), PGSIZE); + memcpy((void*)node->addr, (void*)addr, PGSIZE); __builtin___clear_cache(0,0); } @@ -151,15 +149,12 @@ static void do_vxcptrestore(long* where) static void restore_vector(trapframe_t* tf) { - if (read_csr(impl) == IMPL_ROCKET) - do_vxcptrestore(tf->hwacha_opaque); - else - vxcptrestore(tf->hwacha_opaque); + do_vxcptrestore(tf->hwacha_opaque); } void handle_trap(trapframe_t* tf) { - if (tf->cause == CAUSE_SYSCALL) + if (tf->cause == CAUSE_SCALL) { int n = tf->gpr[10]; @@ -201,10 +196,8 @@ void handle_trap(trapframe_t* tf) assert(!"unexpected exception"); out: - if (!(tf->sr & SR_PS) && (tf->sr & SR_EA)) { + if (!(tf->sr & MSTATUS_PRV1) && (tf->sr & MSTATUS_XS)) restore_vector(tf); - tf->sr |= SR_PEI; - } pop_tf(tf); } @@ -214,34 +207,20 @@ void vm_boot(long test_addr, long seed) assert(SIZEOF_TRAPFRAME_T == sizeof(trapframe_t)); - assert(MAX_TEST_PAGES*2 < PTES_PER_PT); l1pt[0] = (pte_t)l2pt | PTE_V | PTE_T; l2pt[0] = (pte_t)l3pt | PTE_V | PTE_T; - for (long i = 0; i < MAX_TEST_PAGES; i++) - l3pt[i] = l3pt[i+MAX_TEST_PAGES] = (i*PGSIZE) | PTE_SW | PTE_SR | PTE_SX | PTE_V; - - write_csr(ptbr, l1pt); - write_csr(status, read_csr(status) | SR_VM | SR_EF); - - // relocate - long adjustment = RELOC(0L), tmp; - write_csr(evec, (char*)&trap_entry + adjustment); - asm volatile ("add sp, sp, %1\n" - "jal %0, 1f\n" - "1: add %0, %0, %1\n" - "jr %0, 8" - : "=&r"(tmp) - : "r"(adjustment)); - - memset(l3pt, 0, MAX_TEST_PAGES*sizeof(pte_t)); - write_csr(fatc, 0); + write_csr(sptbr, l1pt); + set_csr(mstatus, MSTATUS_IE1 | MSTATUS_FS /* | MSTATUS_XS */ | MSTATUS_MPRV); + clear_csr(mstatus, MSTATUS_VM | MSTATUS_UA | MSTATUS_PRV1); + set_csr(mstatus, (long)VM_SV43 << __builtin_ctzl(MSTATUS_VM)); + set_csr(mstatus, (long)UA_RV64 << __builtin_ctzl(MSTATUS_UA)); seed = 1 + (seed % MAX_TEST_PAGES); freelist_head = &freelist_nodes[0]; freelist_tail = &freelist_nodes[MAX_TEST_PAGES-1]; for (long i = 0; i < MAX_TEST_PAGES; i++) { - freelist_nodes[i].addr = (MAX_TEST_PAGES+i)*PGSIZE; + freelist_nodes[i].addr = (MAX_TEST_PAGES + seed)*PGSIZE; freelist_nodes[i].next = &freelist_nodes[i+1]; seed = LFSR_NEXT(seed); } @@ -249,8 +228,11 @@ void vm_boot(long test_addr, long seed) trapframe_t tf; memset(&tf, 0, sizeof(tf)); - tf.sr = SR_PEI | ((1 << IRQ_COP) << SR_IM_SHIFT) | SR_EF | SR_EA | SR_S | SR_U64 | SR_S64 | SR_VM; tf.epc = test_addr; - pop_tf(&tf); } + +void double_fault() +{ + assert(!"double fault!"); +} -- cgit v1.1