From: Andrew Waterman Date: Mon, 25 Nov 2013 12:42:03 +0000 (-0800) Subject: Update to new privileged ISA X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=aedcd67ac8133ea71de7ff37b772c1533b038c93;p=riscv-isa-sim.git Update to new privileged ISA --- diff --git a/hwacha/hwacha.mk.in b/hwacha/hwacha.mk.in index bf16b6f..f2a0178 100644 --- a/hwacha/hwacha.mk.in +++ b/hwacha/hwacha.mk.in @@ -1,6 +1,3 @@ -get_insn_list = $(shell cat $(1) | sed 's/DECLARE_INSN(\(.*\),.*,.*)/\1/') -get_opcode = $(shell grep \\\<$(2)\\\> $(1) | sed 's/DECLARE_INSN(.*,\(.*\),.*)/\1/') - hwacha_subproject_deps = \ riscv \ softfloat \ diff --git a/riscv/decode.h b/riscv/decode.h index 3fc2be7..2229afb 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -10,7 +10,7 @@ #define __STDC_LIMIT_MACROS #include #include -#include "pcr.h" +#include "encoding.h" #include "config.h" #include "common.h" #include @@ -48,8 +48,6 @@ const int NFPR = 32; #define FSR_NXA (FPEXC_NX << FSR_AEXC_SHIFT) #define FSR_AEXC (FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA) -#define FSR_ZERO ~(FSR_RD | FSR_AEXC) - class insn_t { public: @@ -131,7 +129,7 @@ private: #define BRANCH_TARGET (pc + insn.sb_imm()) #define JUMP_TARGET (pc + insn.uj_imm()) #define RM ({ int rm = insn.rm(); \ - if(rm == 7) rm = (p->get_state()->fsr & FSR_RD) >> FSR_RD_SHIFT; \ + if(rm == 7) rm = p->get_state()->frm; \ if(rm > 4) throw trap_illegal_instruction(); \ rm; }) @@ -148,8 +146,7 @@ private: #define require_accelerator if(unlikely(!(p->get_state()->sr & SR_EA))) throw trap_accelerator_disabled() #define cmp_trunc(reg) (reg_t(reg) << (64-xprlen)) -#define set_fp_exceptions ({ p->set_fsr(p->get_state()->fsr | \ - (softfloat_exceptionFlags << FSR_AEXC_SHIFT)); \ +#define set_fp_exceptions ({ p->get_state()->fflags |= softfloat_exceptionFlags; \ softfloat_exceptionFlags = 0; }) #define sext32(x) ((sreg_t)(int32_t)(x)) @@ -169,4 +166,10 @@ private: npc = (x); \ } while(0) +#define validate_csr(which, write) ({ \ + int read_priv = ((which) >> 10) & 3; \ + int write_priv = ((which) >> 8) & 3; \ + if (read_priv > 0 || (write_priv > 0 && (write))) require_supervisor; \ + (which); }) + #endif diff --git a/riscv/disasm.cc b/riscv/disasm.cc index 436aea3..7d5a8e2 100644 --- a/riscv/disasm.cc +++ b/riscv/disasm.cc @@ -83,9 +83,15 @@ struct : public arg_t { struct : public arg_t { std::string to_string(insn_t insn) const { - return std::string("pcr") + xpr[insn.rs1()]; + switch (insn.i_imm()) + { + #define DECLARE_CSR(name, num) case num: return #name; + #include "encoding.h" + #undef DECLARE_CSR + default: return "unknown"; + } } -} pcr; +} csr; struct : public arg_t { std::string to_string(insn_t insn) const { @@ -101,6 +107,12 @@ struct : public arg_t { } } bigimm; +struct : public arg_t { + std::string to_string(insn_t insn) const { + return std::to_string(insn.rs1()); + } +} zimm5; + struct : public arg_t { std::string to_string(insn_t insn) const { std::stringstream s; @@ -139,7 +151,7 @@ disassembler_t::disassembler_t() #define DECLARE_INSN(code, match, mask) \ const uint32_t match_##code = match; \ const uint32_t mask_##code = mask; - #include "opcodes.h" + #include "encoding.h" #undef DECLARE_INSN // explicit per-instruction disassembly @@ -147,7 +159,6 @@ disassembler_t::disassembler_t() add_insn(new disasm_insn_t(name, match_##code, mask_##code | (extra), __VA_ARGS__)); #define DEFINE_NOARG(code) \ add_insn(new disasm_insn_t(#code, match_##code, mask_##code, {})); - #define DEFINE_DTYPE(code) DISASM_INSN(#code, code, 0, {&xrd}) #define DEFINE_RTYPE(code) DISASM_INSN(#code, code, 0, {&xrd, &xrs1, &xrs2}) #define DEFINE_ITYPE(code) DISASM_INSN(#code, code, 0, {&xrd, &xrs1, &imm}) #define DEFINE_I0TYPE(name, code) DISASM_INSN(name, code, mask_rs1, {&xrd, &imm}) @@ -279,21 +290,20 @@ disassembler_t::disassembler_t() DEFINE_RTYPE(remw); DEFINE_RTYPE(remuw); - DEFINE_NOARG(syscall); - DEFINE_NOARG(break); + DEFINE_NOARG(scall); + DEFINE_NOARG(sbreak); DEFINE_NOARG(fence); DEFINE_NOARG(fence_i); - DEFINE_DTYPE(rdcycle); - DEFINE_DTYPE(rdtime); - DEFINE_DTYPE(rdinstret); - - add_insn(new disasm_insn_t("mtpcr", match_mtpcr, mask_mtpcr | mask_rd, {&xrs2, &pcr})); - add_insn(new disasm_insn_t("mtpcr", match_mtpcr, mask_mtpcr, {&xrd, &xrs2, &pcr})); - add_insn(new disasm_insn_t("mfpcr", match_mfpcr, mask_mfpcr, {&xrd, &pcr})); - add_insn(new disasm_insn_t("setpcr", match_setpcr, mask_setpcr, {&xrd, &pcr, &imm})); - add_insn(new disasm_insn_t("clearpcr", match_clearpcr, mask_clearpcr, {&xrd, &pcr, &imm})); - DEFINE_NOARG(eret) + add_insn(new disasm_insn_t("csrr", match_csrrs, mask_csrrs | mask_rs1, {&xrd, &csr})); + add_insn(new disasm_insn_t("csrw", match_csrrw, mask_csrrw | mask_rd, {&xrs1, &csr})); + add_insn(new disasm_insn_t("csrrw", match_csrrw, mask_csrrw, {&xrd, &xrs1, &csr})); + add_insn(new disasm_insn_t("csrrs", match_csrrs, mask_csrrs, {&xrd, &xrs1, &csr})); + add_insn(new disasm_insn_t("csrrc", match_csrrc, mask_csrrc, {&xrd, &xrs1, &csr})); + add_insn(new disasm_insn_t("csrrwi", match_csrrwi, mask_csrrwi, {&xrd, &zimm5, &csr})); + add_insn(new disasm_insn_t("csrrsi", match_csrrsi, mask_csrrsi, {&xrd, &zimm5, &csr})); + add_insn(new disasm_insn_t("csrrci", match_csrrci, mask_csrrci, {&xrd, &zimm5, &csr})); + DEFINE_NOARG(sret) DEFINE_FRTYPE(fadd_s); DEFINE_FRTYPE(fsub_s); @@ -355,14 +365,10 @@ disassembler_t::disassembler_t() DEFINE_FXTYPE(flt_d); DEFINE_FXTYPE(fle_d); - add_insn(new disasm_insn_t("fssr", match_fssr, mask_fssr | mask_rd, {&xrs1})); - add_insn(new disasm_insn_t("fssr", match_fssr, mask_fssr, {&xrd, &xrs1})); - DEFINE_DTYPE(frsr); - // provide a default disassembly for all instructions as a fallback #define DECLARE_INSN(code, match, mask) \ add_insn(new disasm_insn_t(#code " (args unknown)", match, mask, {})); - #include "opcodes.h" + #include "encoding.h" #undef DECLARE_INSN } diff --git a/riscv/encoding.h b/riscv/encoding.h new file mode 100644 index 0000000..92accfe --- /dev/null +++ b/riscv/encoding.h @@ -0,0 +1,626 @@ +// See LICENSE for license details. + +#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 IRQ_COP 2 +#define IRQ_IPI 5 +#define IRQ_HOST 6 +#define IRQ_TIMER 7 + +#define IMPL_SPIKE 1 +#define IMPL_ROCKET 2 + +#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_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_ACCELERATOR_DISABLED 12 + +// page table entry (PTE) fields +#define PTE_V 0x001 // Entry is a page Table descriptor +#define PTE_T 0x002 // Entry is a page Table, not a terminal node +#define PTE_G 0x004 // Global +#define PTE_UR 0x008 // User Write permission +#define PTE_UW 0x010 // User Read permission +#define PTE_UX 0x020 // User eXecute permission +#define PTE_SR 0x040 // Supervisor Read permission +#define PTE_SW 0x080 // Supervisor Write permission +#define PTE_SX 0x100 // Supervisor eXecute permission +#define PTE_PERM (PTE_SR | PTE_SW | PTE_SX | PTE_UR | PTE_UW | PTE_UX) + +#ifdef __riscv + +#ifdef __riscv64 +# define RISCV_PGLEVELS 3 +# define RISCV_PGSHIFT 13 +#else +# define RISCV_PGLEVELS 2 +# define RISCV_PGSHIFT 12 +#endif +#define RISCV_PGLEVEL_BITS 10 +#define RISCV_PGSIZE (1 << RISCV_PGSHIFT) + +#ifndef __ASSEMBLER__ + +#define read_csr(reg) ({ long __tmp; \ + asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ + __tmp; }) + +#define write_csr(reg, val) \ + asm volatile ("csrw " #reg ", %0" :: "r"(val)) + +#define swap_csr(reg, val) ({ long __tmp; \ + asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \ + __tmp; }) + +#define set_csr(reg, bit) ({ 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; \ + 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 rdcycle() ({ unsigned long __tmp; \ + asm volatile ("rdcycle %0" : "=r"(__tmp)); \ + __tmp; }) + +#endif + +#endif + +#endif +/* Automatically generated by parse-opcodes */ +#ifndef RISCV_ENCODING_H +#define RISCV_ENCODING_H +#define MATCH_FMV_S_X 0xf0000053 +#define MASK_FMV_S_X 0xfff0707f +#define MATCH_AMOXOR_W 0x2000202f +#define MASK_AMOXOR_W 0xf800707f +#define MATCH_REMUW 0x200703b +#define MASK_REMUW 0xfe00707f +#define MATCH_FMIN_D 0xc2000053 +#define MASK_FMIN_D 0xfe00707f +#define MATCH_AMOMAX_D 0xa000302f +#define MASK_AMOMAX_D 0xf800707f +#define MATCH_BLTU 0x6063 +#define MASK_BLTU 0x707f +#define MATCH_FSGNJN_D 0x32000053 +#define MASK_FSGNJN_D 0xfe00707f +#define MATCH_FMIN_S 0xc0000053 +#define MASK_FMIN_S 0xfe00707f +#define MATCH_CSRRW 0x1073 +#define MASK_CSRRW 0x707f +#define MATCH_SLLIW 0x101b +#define MASK_SLLIW 0xfe00707f +#define MATCH_LB 0x3 +#define MASK_LB 0x707f +#define MATCH_FCVT_D_L 0x62000053 +#define MASK_FCVT_D_L 0xfff0007f +#define MATCH_LH 0x1003 +#define MASK_LH 0x707f +#define MATCH_FCVT_D_W 0x72000053 +#define MASK_FCVT_D_W 0xfff0007f +#define MATCH_LW 0x2003 +#define MASK_LW 0x707f +#define MATCH_ADD 0x33 +#define MASK_ADD 0xfe00707f +#define MATCH_CSRRC 0x3073 +#define MASK_CSRRC 0x707f +#define MATCH_FMAX_D 0xca000053 +#define MASK_FMAX_D 0xfe00707f +#define MATCH_BNE 0x1063 +#define MASK_BNE 0x707f +#define MATCH_FCVT_S_D 0x88000053 +#define MASK_FCVT_S_D 0xfff0007f +#define MATCH_BGEU 0x7063 +#define MASK_BGEU 0x707f +#define MATCH_FADD_D 0x2000053 +#define MASK_FADD_D 0xfe00007f +#define MATCH_SLTIU 0x3013 +#define MASK_SLTIU 0x707f +#define MATCH_FADD_S 0x53 +#define MASK_FADD_S 0xfe00007f +#define MATCH_FCVT_S_W 0x70000053 +#define MASK_FCVT_S_W 0xfff0007f +#define MATCH_MUL 0x2000033 +#define MASK_MUL 0xfe00707f +#define MATCH_AMOMINU_D 0xc000302f +#define MASK_AMOMINU_D 0xf800707f +#define MATCH_FCVT_S_LU 0x68000053 +#define MASK_FCVT_S_LU 0xfff0007f +#define MATCH_SRLI 0x5013 +#define MASK_SRLI 0xfc00707f +#define MATCH_AMOMINU_W 0xc000202f +#define MASK_AMOMINU_W 0xf800707f +#define MATCH_DIVUW 0x200503b +#define MASK_DIVUW 0xfe00707f +#define MATCH_MULW 0x200003b +#define MASK_MULW 0xfe00707f +#define MATCH_SRLW 0x503b +#define MASK_SRLW 0xfe00707f +#define MATCH_DIV 0x2004033 +#define MASK_DIV 0xfe00707f +#define MATCH_FDIV_D 0x1a000053 +#define MASK_FDIV_D 0xfe00007f +#define MATCH_FENCE 0xf +#define MASK_FENCE 0x707f +#define MATCH_FNMSUB_S 0x4b +#define MASK_FNMSUB_S 0x600007f +#define MATCH_FCVT_L_S 0x40000053 +#define MASK_FCVT_L_S 0xfff0007f +#define MATCH_SBREAK 0x100073 +#define MASK_SBREAK 0xffffffff +#define MATCH_FLE_S 0xb8000053 +#define MASK_FLE_S 0xfe00707f +#define MATCH_FDIV_S 0x18000053 +#define MASK_FDIV_S 0xfe00007f +#define MATCH_FLE_D 0xba000053 +#define MASK_FLE_D 0xfe00707f +#define MATCH_FENCE_I 0x100f +#define MASK_FENCE_I 0x707f +#define MATCH_FNMSUB_D 0x200004b +#define MASK_FNMSUB_D 0x600007f +#define MATCH_ADDW 0x3b +#define MASK_ADDW 0xfe00707f +#define MATCH_SLL 0x1033 +#define MASK_SLL 0xfe00707f +#define MATCH_XOR 0x4033 +#define MASK_XOR 0xfe00707f +#define MATCH_SUB 0x40000033 +#define MASK_SUB 0xfe00707f +#define MATCH_BLT 0x4063 +#define MASK_BLT 0x707f +#define MATCH_SCALL 0x73 +#define MASK_SCALL 0xffffffff +#define MATCH_SC_W 0x1800202f +#define MASK_SC_W 0xf800707f +#define MATCH_REM 0x2006033 +#define MASK_REM 0xfe00707f +#define MATCH_SRLIW 0x501b +#define MASK_SRLIW 0xfe00707f +#define MATCH_LUI 0x37 +#define MASK_LUI 0x7f +#define MATCH_CSRRCI 0x7073 +#define MASK_CSRRCI 0x707f +#define MATCH_ADDI 0x13 +#define MASK_ADDI 0x707f +#define MATCH_MULH 0x2001033 +#define MASK_MULH 0xfe00707f +#define MATCH_FMUL_S 0x10000053 +#define MASK_FMUL_S 0xfe00007f +#define MATCH_CSRRSI 0x6073 +#define MASK_CSRRSI 0x707f +#define MATCH_SRAI 0x40005013 +#define MASK_SRAI 0xfc00707f +#define MATCH_AMOAND_D 0x6000302f +#define MASK_AMOAND_D 0xf800707f +#define MATCH_FLT_D 0xb2000053 +#define MASK_FLT_D 0xfe00707f +#define MATCH_SRAW 0x4000503b +#define MASK_SRAW 0xfe00707f +#define MATCH_FMUL_D 0x12000053 +#define MASK_FMUL_D 0xfe00007f +#define MATCH_LD 0x3003 +#define MASK_LD 0x707f +#define MATCH_ORI 0x6013 +#define MASK_ORI 0x707f +#define MATCH_CSRRS 0x2073 +#define MASK_CSRRS 0x707f +#define MATCH_FLT_S 0xb0000053 +#define MASK_FLT_S 0xfe00707f +#define MATCH_ADDIW 0x1b +#define MASK_ADDIW 0x707f +#define MATCH_AMOAND_W 0x6000202f +#define MASK_AMOAND_W 0xf800707f +#define MATCH_FEQ_S 0xa8000053 +#define MASK_FEQ_S 0xfe00707f +#define MATCH_FSGNJX_D 0x3a000053 +#define MASK_FSGNJX_D 0xfe00707f +#define MATCH_SRA 0x40005033 +#define MASK_SRA 0xfe00707f +#define MATCH_BGE 0x5063 +#define MASK_BGE 0x707f +#define MATCH_SRAIW 0x4000501b +#define MASK_SRAIW 0xfe00707f +#define MATCH_SRL 0x5033 +#define MASK_SRL 0xfe00707f +#define MATCH_FSUB_D 0xa000053 +#define MASK_FSUB_D 0xfe00007f +#define MATCH_FSGNJX_S 0x38000053 +#define MASK_FSGNJX_S 0xfe00707f +#define MATCH_FEQ_D 0xaa000053 +#define MASK_FEQ_D 0xfe00707f +#define MATCH_FCVT_D_WU 0x7a000053 +#define MASK_FCVT_D_WU 0xfff0007f +#define MATCH_OR 0x6033 +#define MASK_OR 0xfe00707f +#define MATCH_FCVT_WU_D 0x5a000053 +#define MASK_FCVT_WU_D 0xfff0007f +#define MATCH_SUBW 0x4000003b +#define MASK_SUBW 0xfe00707f +#define MATCH_FMAX_S 0xc8000053 +#define MASK_FMAX_S 0xfe00707f +#define MATCH_AMOMAXU_D 0xe000302f +#define MASK_AMOMAXU_D 0xf800707f +#define MATCH_XORI 0x4013 +#define MASK_XORI 0x707f +#define MATCH_AMOXOR_D 0x2000302f +#define MASK_AMOXOR_D 0xf800707f +#define MATCH_AMOMAXU_W 0xe000202f +#define MASK_AMOMAXU_W 0xf800707f +#define MATCH_FCVT_WU_S 0x58000053 +#define MASK_FCVT_WU_S 0xfff0007f +#define MATCH_ANDI 0x7013 +#define MASK_ANDI 0x707f +#define MATCH_FMV_X_S 0xe0000053 +#define MASK_FMV_X_S 0xfff0707f +#define MATCH_SRET 0x80000073 +#define MASK_SRET 0xffffffff +#define MATCH_FNMADD_S 0x4f +#define MASK_FNMADD_S 0x600007f +#define MATCH_JAL 0x67 +#define MASK_JAL 0x7f +#define MATCH_LWU 0x6003 +#define MASK_LWU 0x707f +#define MATCH_FMV_X_D 0xe2000053 +#define MASK_FMV_X_D 0xfff0707f +#define MATCH_FCVT_D_S 0x82000053 +#define MASK_FCVT_D_S 0xfff0007f +#define MATCH_FNMADD_D 0x200004f +#define MASK_FNMADD_D 0x600007f +#define MATCH_AMOADD_D 0x302f +#define MASK_AMOADD_D 0xf800707f +#define MATCH_LR_D 0x1000302f +#define MASK_LR_D 0xf9f0707f +#define MATCH_FCVT_W_S 0x50000053 +#define MASK_FCVT_W_S 0xfff0007f +#define MATCH_MULHSU 0x2002033 +#define MASK_MULHSU 0xfe00707f +#define MATCH_AMOADD_W 0x202f +#define MASK_AMOADD_W 0xf800707f +#define MATCH_FCVT_D_LU 0x6a000053 +#define MASK_FCVT_D_LU 0xfff0007f +#define MATCH_LR_W 0x1000202f +#define MASK_LR_W 0xf9f0707f +#define MATCH_FCVT_W_D 0x52000053 +#define MASK_FCVT_W_D 0xfff0007f +#define MATCH_SLT 0x2033 +#define MASK_SLT 0xfe00707f +#define MATCH_SLLW 0x103b +#define MASK_SLLW 0xfe00707f +#define MATCH_AMOOR_D 0x4000302f +#define MASK_AMOOR_D 0xf800707f +#define MATCH_SLTI 0x2013 +#define MASK_SLTI 0x707f +#define MATCH_REMU 0x2007033 +#define MASK_REMU 0xfe00707f +#define MATCH_FLW 0x2007 +#define MASK_FLW 0x707f +#define MATCH_REMW 0x200603b +#define MASK_REMW 0xfe00707f +#define MATCH_SLTU 0x3033 +#define MASK_SLTU 0xfe00707f +#define MATCH_SLLI 0x1013 +#define MASK_SLLI 0xfc00707f +#define MATCH_AMOOR_W 0x4000202f +#define MASK_AMOOR_W 0xf800707f +#define MATCH_BEQ 0x63 +#define MASK_BEQ 0x707f +#define MATCH_FLD 0x3007 +#define MASK_FLD 0x707f +#define MATCH_FSUB_S 0x8000053 +#define MASK_FSUB_S 0xfe00007f +#define MATCH_AND 0x7033 +#define MASK_AND 0xfe00707f +#define MATCH_FMV_D_X 0xf2000053 +#define MASK_FMV_D_X 0xfff0707f +#define MATCH_LBU 0x4003 +#define MASK_LBU 0x707f +#define MATCH_FSGNJ_S 0x28000053 +#define MASK_FSGNJ_S 0xfe00707f +#define MATCH_AMOMAX_W 0xa000202f +#define MASK_AMOMAX_W 0xf800707f +#define MATCH_FSGNJ_D 0x2a000053 +#define MASK_FSGNJ_D 0xfe00707f +#define MATCH_MULHU 0x2003033 +#define MASK_MULHU 0xfe00707f +#define MATCH_FCVT_L_D 0x42000053 +#define MASK_FCVT_L_D 0xfff0007f +#define MATCH_FCVT_S_WU 0x78000053 +#define MASK_FCVT_S_WU 0xfff0007f +#define MATCH_FCVT_LU_S 0x48000053 +#define MASK_FCVT_LU_S 0xfff0007f +#define MATCH_FCVT_S_L 0x60000053 +#define MASK_FCVT_S_L 0xfff0007f +#define MATCH_AUIPC 0x17 +#define MASK_AUIPC 0x7f +#define MATCH_FCVT_LU_D 0x4a000053 +#define MASK_FCVT_LU_D 0xfff0007f +#define MATCH_CSRRWI 0x5073 +#define MASK_CSRRWI 0x707f +#define MATCH_SC_D 0x1800302f +#define MASK_SC_D 0xf800707f +#define MATCH_FMADD_S 0x43 +#define MASK_FMADD_S 0x600007f +#define MATCH_FSQRT_S 0x20000053 +#define MASK_FSQRT_S 0xfff0007f +#define MATCH_AMOMIN_W 0x8000202f +#define MASK_AMOMIN_W 0xf800707f +#define MATCH_FSGNJN_S 0x30000053 +#define MASK_FSGNJN_S 0xfe00707f +#define MATCH_AMOSWAP_D 0x800302f +#define MASK_AMOSWAP_D 0xf800707f +#define MATCH_FSQRT_D 0x22000053 +#define MASK_FSQRT_D 0xfff0007f +#define MATCH_FMADD_D 0x2000043 +#define MASK_FMADD_D 0x600007f +#define MATCH_DIVW 0x200403b +#define MASK_DIVW 0xfe00707f +#define MATCH_AMOMIN_D 0x8000302f +#define MASK_AMOMIN_D 0xf800707f +#define MATCH_DIVU 0x2005033 +#define MASK_DIVU 0xfe00707f +#define MATCH_AMOSWAP_W 0x800202f +#define MASK_AMOSWAP_W 0xf800707f +#define MATCH_JALR 0x6f +#define MASK_JALR 0x707f +#define MATCH_FSD 0x3027 +#define MASK_FSD 0x707f +#define MATCH_SW 0x2023 +#define MASK_SW 0x707f +#define MATCH_FMSUB_S 0x47 +#define MASK_FMSUB_S 0x600007f +#define MATCH_LHU 0x5003 +#define MASK_LHU 0x707f +#define MATCH_SH 0x1023 +#define MASK_SH 0x707f +#define MATCH_FSW 0x2027 +#define MASK_FSW 0x707f +#define MATCH_SB 0x23 +#define MASK_SB 0x707f +#define MATCH_FMSUB_D 0x2000047 +#define MASK_FMSUB_D 0x600007f +#define MATCH_SD 0x3023 +#define MASK_SD 0x707f +#define CSR_SUP0 0x500 +#define CSR_FFLAGS 0x1 +#define CSR_FRM 0x2 +#define CSR_FCSR 0x3 +#define CSR_CYCLE 0x4 +#define CSR_TIME 0x5 +#define CSR_INSTRET 0x6 +#define CSR_SUP1 0x501 +#define CSR_EVEC 0x508 +#define CSR_CAUSE 0x509 +#define CSR_STATUS 0x50a +#define CSR_HARTID 0x50b +#define CSR_IMPL 0x50c +#define CSR_EPC 0x502 +#define CSR_SEND_IPI 0x50e +#define CSR_CLEAR_IPI 0x50f +#define CSR_BADVADDR 0x503 +#define CSR_PTBR 0x504 +#define CSR_STATS 0x51c +#define CSR_RESET 0x51d +#define CSR_TOHOST 0x51e +#define CSR_ASID 0x505 +#define CSR_COUNT 0x506 +#define CSR_COMPARE 0x507 +#define CSR_FROMHOST 0x51f +#define CSR_FATC 0x50d +#endif +#ifdef DECLARE_INSN +DECLARE_INSN(fmv_s_x, MATCH_FMV_S_X, MASK_FMV_S_X) +DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W) +DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW) +DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D) +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(csrrw, MATCH_CSRRW, MASK_CSRRW) +DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW) +DECLARE_INSN(lb, MATCH_LB, MASK_LB) +DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L) +DECLARE_INSN(lh, MATCH_LH, MASK_LH) +DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W) +DECLARE_INSN(lw, MATCH_LW, MASK_LW) +DECLARE_INSN(add, MATCH_ADD, MASK_ADD) +DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC) +DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D) +DECLARE_INSN(bne, MATCH_BNE, MASK_BNE) +DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D) +DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU) +DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D) +DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU) +DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S) +DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W) +DECLARE_INSN(mul, MATCH_MUL, MASK_MUL) +DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D) +DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU) +DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI) +DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W) +DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW) +DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW) +DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW) +DECLARE_INSN(div, MATCH_DIV, MASK_DIV) +DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D) +DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE) +DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S) +DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S) +DECLARE_INSN(sbreak, MATCH_SBREAK, MASK_SBREAK) +DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S) +DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S) +DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D) +DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I) +DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D) +DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW) +DECLARE_INSN(sll, MATCH_SLL, MASK_SLL) +DECLARE_INSN(xor, MATCH_XOR, MASK_XOR) +DECLARE_INSN(sub, MATCH_SUB, MASK_SUB) +DECLARE_INSN(blt, MATCH_BLT, MASK_BLT) +DECLARE_INSN(scall, MATCH_SCALL, MASK_SCALL) +DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W) +DECLARE_INSN(rem, MATCH_REM, MASK_REM) +DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW) +DECLARE_INSN(lui, MATCH_LUI, MASK_LUI) +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(csrrsi, MATCH_CSRRSI, MASK_CSRRSI) +DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI) +DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D) +DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D) +DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW) +DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D) +DECLARE_INSN(ld, MATCH_LD, MASK_LD) +DECLARE_INSN(ori, MATCH_ORI, MASK_ORI) +DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS) +DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S) +DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW) +DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W) +DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S) +DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D) +DECLARE_INSN(sra, MATCH_SRA, MASK_SRA) +DECLARE_INSN(bge, MATCH_BGE, MASK_BGE) +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(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) +DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D) +DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW) +DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S) +DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D) +DECLARE_INSN(xori, MATCH_XORI, MASK_XORI) +DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D) +DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W) +DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S) +DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI) +DECLARE_INSN(fmv_x_s, MATCH_FMV_X_S, MASK_FMV_X_S) +DECLARE_INSN(sret, MATCH_SRET, MASK_SRET) +DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S) +DECLARE_INSN(jal, MATCH_JAL, MASK_JAL) +DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU) +DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D) +DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S) +DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D) +DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D) +DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D) +DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S) +DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU) +DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W) +DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU) +DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W) +DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D) +DECLARE_INSN(slt, MATCH_SLT, MASK_SLT) +DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW) +DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D) +DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI) +DECLARE_INSN(remu, MATCH_REMU, MASK_REMU) +DECLARE_INSN(flw, MATCH_FLW, MASK_FLW) +DECLARE_INSN(remw, MATCH_REMW, MASK_REMW) +DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU) +DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI) +DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W) +DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ) +DECLARE_INSN(fld, MATCH_FLD, MASK_FLD) +DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S) +DECLARE_INSN(and, MATCH_AND, MASK_AND) +DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X) +DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU) +DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S) +DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W) +DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D) +DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU) +DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D) +DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU) +DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S) +DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L) +DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC) +DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D) +DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI) +DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D) +DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S) +DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S) +DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W) +DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S) +DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D) +DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D) +DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D) +DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW) +DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D) +DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU) +DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W) +DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR) +DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD) +DECLARE_INSN(sw, MATCH_SW, MASK_SW) +DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S) +DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU) +DECLARE_INSN(sh, MATCH_SH, MASK_SH) +DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW) +DECLARE_INSN(sb, MATCH_SB, MASK_SB) +DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D) +DECLARE_INSN(sd, MATCH_SD, MASK_SD) +#endif +#ifdef DECLARE_CSR +DECLARE_CSR(sup0, CSR_SUP0) +DECLARE_CSR(fflags, CSR_FFLAGS) +DECLARE_CSR(frm, CSR_FRM) +DECLARE_CSR(fcsr, CSR_FCSR) +DECLARE_CSR(cycle, CSR_CYCLE) +DECLARE_CSR(time, CSR_TIME) +DECLARE_CSR(instret, CSR_INSTRET) +DECLARE_CSR(sup1, CSR_SUP1) +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(epc, CSR_EPC) +DECLARE_CSR(send_ipi, CSR_SEND_IPI) +DECLARE_CSR(clear_ipi, CSR_CLEAR_IPI) +DECLARE_CSR(badvaddr, CSR_BADVADDR) +DECLARE_CSR(ptbr, CSR_PTBR) +DECLARE_CSR(stats, CSR_STATS) +DECLARE_CSR(reset, CSR_RESET) +DECLARE_CSR(tohost, CSR_TOHOST) +DECLARE_CSR(asid, CSR_ASID) +DECLARE_CSR(count, CSR_COUNT) +DECLARE_CSR(compare, CSR_COMPARE) +DECLARE_CSR(fromhost, CSR_FROMHOST) +DECLARE_CSR(fatc, CSR_FATC) +#endif diff --git a/riscv/htif.cc b/riscv/htif.cc index d7b9f63..af26faa 100644 --- a/riscv/htif.cc +++ b/riscv/htif.cc @@ -2,6 +2,7 @@ #include "htif.h" #include "sim.h" +#include "encoding.h" #include #include #include @@ -63,9 +64,10 @@ void htif_isasim_t::tick_once() case HTIF_CMD_READ_CONTROL_REG: case HTIF_CMD_WRITE_CONTROL_REG: { + assert(hdr.data_size == 1); reg_t coreid = hdr.addr >> 20; reg_t regno = hdr.addr & ((1<<20)-1); - assert(hdr.data_size == 1); + uint64_t old_val, new_val = 0 /* shut up gcc */; packet_header_t ack(HTIF_CMD_ACK, seqno, 1, 0); send(&ack, sizeof(ack)); @@ -77,28 +79,40 @@ void htif_isasim_t::tick_once() break; } - assert(coreid < sim->num_cores()); - uint64_t old_val = sim->procs[coreid]->get_pcr(regno); - send(&old_val, sizeof(old_val)); - - if (regno == PCR_TOHOST) - sim->procs[coreid]->state.tohost = 0; + processor_t* proc = sim->get_core(coreid); + bool write = hdr.cmd == HTIF_CMD_WRITE_CONTROL_REG; + if (write) + memcpy(&new_val, p.get_payload(), sizeof(new_val)); - if (hdr.cmd == HTIF_CMD_WRITE_CONTROL_REG) + // TODO mapping HTIF regno to CSR[4:0] is arbitrary; consider alternative + switch (regno) { - uint64_t new_val; - memcpy(&new_val, p.get_payload(), sizeof(new_val)); - if (regno == PCR_RESET) - { - if (reset && !(new_val & 1)) - reset = false; - sim->procs[coreid]->reset(new_val & 1); - } - else if (regno == PCR_FROMHOST && old_val != 0) - ; // ignore host writes to fromhost if target hasn't yet consumed - else - sim->procs[coreid]->set_pcr(regno, new_val); + case CSR_HARTID & 0x1f: + old_val = coreid; + break; + case CSR_TOHOST & 0x1f: + old_val = proc->state.tohost; + if (write) + proc->state.tohost = new_val; + break; + case CSR_FROMHOST & 0x1f: + old_val = proc->state.fromhost; + if (write && old_val == 0) + proc->state.fromhost = new_val; + break; + case CSR_RESET & 0x1f: + old_val = !proc->running(); + if (write) + { + reset = reset & (new_val & 1); + proc->reset(new_val & 1); + } + break; + default: + abort(); } + + send(&old_val, sizeof(old_val)); break; } default: diff --git a/riscv/insns/break.h b/riscv/insns/break.h deleted file mode 100644 index c22776c..0000000 --- a/riscv/insns/break.h +++ /dev/null @@ -1 +0,0 @@ -throw trap_breakpoint(); diff --git a/riscv/insns/clearpcr.h b/riscv/insns/clearpcr.h deleted file mode 100644 index ac64687..0000000 --- a/riscv/insns/clearpcr.h +++ /dev/null @@ -1,2 +0,0 @@ -require_supervisor; -WRITE_RD(p->set_pcr(insn.rs1(), p->get_pcr(insn.rs1()) & ~insn.i_imm())); diff --git a/riscv/insns/csrrc.h b/riscv/insns/csrrc.h new file mode 100644 index 0000000..636c3f8 --- /dev/null +++ b/riscv/insns/csrrc.h @@ -0,0 +1,2 @@ +int csr = validate_csr(insn.i_imm(), true); +WRITE_RD(p->set_pcr(csr, p->get_pcr(csr) & ~RS1)); diff --git a/riscv/insns/csrrci.h b/riscv/insns/csrrci.h new file mode 100644 index 0000000..d671f3b --- /dev/null +++ b/riscv/insns/csrrci.h @@ -0,0 +1,2 @@ +int csr = validate_csr(insn.i_imm(), true); +WRITE_RD(p->set_pcr(csr, p->get_pcr(csr) & ~(reg_t)insn.rs1())); diff --git a/riscv/insns/csrrs.h b/riscv/insns/csrrs.h new file mode 100644 index 0000000..fff9f23 --- /dev/null +++ b/riscv/insns/csrrs.h @@ -0,0 +1,2 @@ +int csr = validate_csr(insn.i_imm(), insn.rs1() != 0); +WRITE_RD(p->set_pcr(csr, p->get_pcr(csr) | RS1)); diff --git a/riscv/insns/csrrsi.h b/riscv/insns/csrrsi.h new file mode 100644 index 0000000..99d323b --- /dev/null +++ b/riscv/insns/csrrsi.h @@ -0,0 +1,2 @@ +int csr = validate_csr(insn.i_imm(), true); +WRITE_RD(p->set_pcr(csr, p->get_pcr(csr) | insn.rs1())); diff --git a/riscv/insns/csrrw.h b/riscv/insns/csrrw.h new file mode 100644 index 0000000..fbccb77 --- /dev/null +++ b/riscv/insns/csrrw.h @@ -0,0 +1,2 @@ +int csr = validate_csr(insn.i_imm(), true); +WRITE_RD(p->set_pcr(csr, RS1)); diff --git a/riscv/insns/csrrwi.h b/riscv/insns/csrrwi.h new file mode 100644 index 0000000..840150e --- /dev/null +++ b/riscv/insns/csrrwi.h @@ -0,0 +1,2 @@ +int csr = validate_csr(insn.i_imm(), true); +WRITE_RD(p->set_pcr(csr, insn.rs1())); diff --git a/riscv/insns/eret.h b/riscv/insns/eret.h deleted file mode 100644 index d4517ee..0000000 --- a/riscv/insns/eret.h +++ /dev/null @@ -1,5 +0,0 @@ -require_supervisor; -p->set_pcr(PCR_SR, ((p->get_state()->sr & ~(SR_S | SR_EI)) | - ((p->get_state()->sr & SR_PS) ? SR_S : 0)) | - ((p->get_state()->sr & SR_PEI) ? SR_EI : 0)); -set_pc(p->get_state()->epc); diff --git a/riscv/insns/frsr.h b/riscv/insns/frsr.h deleted file mode 100644 index 4d80769..0000000 --- a/riscv/insns/frsr.h +++ /dev/null @@ -1,2 +0,0 @@ -require_fp; -WRITE_RD(p->get_fsr()); diff --git a/riscv/insns/fssr.h b/riscv/insns/fssr.h deleted file mode 100644 index 5695d8c..0000000 --- a/riscv/insns/fssr.h +++ /dev/null @@ -1,2 +0,0 @@ -require_fp; -WRITE_RD(p->set_fsr(RS1)); diff --git a/riscv/insns/mfpcr.h b/riscv/insns/mfpcr.h deleted file mode 100644 index a539115..0000000 --- a/riscv/insns/mfpcr.h +++ /dev/null @@ -1,2 +0,0 @@ -require_supervisor; -WRITE_RD(p->get_pcr(insn.rs1())); diff --git a/riscv/insns/mtpcr.h b/riscv/insns/mtpcr.h deleted file mode 100644 index ca22db1..0000000 --- a/riscv/insns/mtpcr.h +++ /dev/null @@ -1,2 +0,0 @@ -require_supervisor; -WRITE_RD(p->set_pcr(insn.rs1(), RS2)); diff --git a/riscv/insns/rdcycle.h b/riscv/insns/rdcycle.h deleted file mode 100644 index 5467f8a..0000000 --- a/riscv/insns/rdcycle.h +++ /dev/null @@ -1 +0,0 @@ -WRITE_RD(sext_xprlen(p->get_state()->cycle)); diff --git a/riscv/insns/rdinstret.h b/riscv/insns/rdinstret.h deleted file mode 100644 index df56cb7..0000000 --- a/riscv/insns/rdinstret.h +++ /dev/null @@ -1 +0,0 @@ -#include "insns/rdcycle.h" diff --git a/riscv/insns/rdtime.h b/riscv/insns/rdtime.h deleted file mode 100644 index df56cb7..0000000 --- a/riscv/insns/rdtime.h +++ /dev/null @@ -1 +0,0 @@ -#include "insns/rdcycle.h" diff --git a/riscv/insns/sbreak.h b/riscv/insns/sbreak.h new file mode 100644 index 0000000..c22776c --- /dev/null +++ b/riscv/insns/sbreak.h @@ -0,0 +1 @@ +throw trap_breakpoint(); diff --git a/riscv/insns/scall.h b/riscv/insns/scall.h new file mode 100644 index 0000000..b31b7e6 --- /dev/null +++ b/riscv/insns/scall.h @@ -0,0 +1 @@ +throw trap_syscall(); diff --git a/riscv/insns/setpcr.h b/riscv/insns/setpcr.h deleted file mode 100644 index f001827..0000000 --- a/riscv/insns/setpcr.h +++ /dev/null @@ -1,2 +0,0 @@ -require_supervisor; -WRITE_RD(p->set_pcr(insn.rs1(), p->get_pcr(insn.rs1()) | insn.i_imm())); diff --git a/riscv/insns/sret.h b/riscv/insns/sret.h new file mode 100644 index 0000000..442b00b --- /dev/null +++ b/riscv/insns/sret.h @@ -0,0 +1,5 @@ +require_supervisor; +p->set_pcr(CSR_STATUS, ((p->get_state()->sr & ~(SR_S | SR_EI)) | + ((p->get_state()->sr & SR_PS) ? SR_S : 0)) | + ((p->get_state()->sr & SR_PEI) ? SR_EI : 0)); +set_pc(p->get_state()->epc); diff --git a/riscv/insns/syscall.h b/riscv/insns/syscall.h deleted file mode 100644 index b31b7e6..0000000 --- a/riscv/insns/syscall.h +++ /dev/null @@ -1 +0,0 @@ -throw trap_syscall(); diff --git a/riscv/opcodes.h b/riscv/opcodes.h deleted file mode 100644 index aa2a38c..0000000 --- a/riscv/opcodes.h +++ /dev/null @@ -1,158 +0,0 @@ -DECLARE_INSN(fmv_s_x, 0xf0000053, 0xfff0707f) -DECLARE_INSN(amoxor_w, 0x2000202f, 0xf800707f) -DECLARE_INSN(remuw, 0x200703b, 0xfe00707f) -DECLARE_INSN(fmin_d, 0xc2000053, 0xfe00707f) -DECLARE_INSN(amomax_d, 0xa000302f, 0xf800707f) -DECLARE_INSN(bltu, 0x6063, 0x707f) -DECLARE_INSN(fmin_s, 0xc0000053, 0xfe00707f) -DECLARE_INSN(slliw, 0x101b, 0xfe00707f) -DECLARE_INSN(lb, 0x3, 0x707f) -DECLARE_INSN(fcvt_s_wu, 0x78000053, 0xfff0007f) -DECLARE_INSN(fcvt_d_l, 0x62000053, 0xfff0007f) -DECLARE_INSN(lh, 0x1003, 0x707f) -DECLARE_INSN(frsr, 0xe8000053, 0xfffff07f) -DECLARE_INSN(fcvt_d_w, 0x72000053, 0xfff0007f) -DECLARE_INSN(lw, 0x2003, 0x707f) -DECLARE_INSN(add, 0x33, 0xfe00707f) -DECLARE_INSN(fcvt_d_s, 0x82000053, 0xfff0007f) -DECLARE_INSN(mfpcr, 0x1073, 0xfff0707f) -DECLARE_INSN(fmax_d, 0xca000053, 0xfe00707f) -DECLARE_INSN(bne, 0x1063, 0x707f) -DECLARE_INSN(rdcycle, 0x4077, 0xfffff07f) -DECLARE_INSN(fcvt_s_d, 0x88000053, 0xfff0007f) -DECLARE_INSN(bgeu, 0x7063, 0x707f) -DECLARE_INSN(fadd_d, 0x2000053, 0xfe00007f) -DECLARE_INSN(sltiu, 0x3013, 0x707f) -DECLARE_INSN(mtpcr, 0x73, 0xfe00707f) -DECLARE_INSN(break, 0x1077, 0xffffffff) -DECLARE_INSN(fcvt_s_w, 0x70000053, 0xfff0007f) -DECLARE_INSN(mul, 0x2000033, 0xfe00707f) -DECLARE_INSN(amominu_d, 0xc000302f, 0xf800707f) -DECLARE_INSN(srli, 0x5013, 0xfc00707f) -DECLARE_INSN(amominu_w, 0xc000202f, 0xf800707f) -DECLARE_INSN(divuw, 0x200503b, 0xfe00707f) -DECLARE_INSN(mulw, 0x200003b, 0xfe00707f) -DECLARE_INSN(srlw, 0x503b, 0xfe00707f) -DECLARE_INSN(div, 0x2004033, 0xfe00707f) -DECLARE_INSN(fdiv_d, 0x1a000053, 0xfe00007f) -DECLARE_INSN(fence, 0xf, 0x707f) -DECLARE_INSN(fnmsub_s, 0x4b, 0x600007f) -DECLARE_INSN(fcvt_l_s, 0x40000053, 0xfff0007f) -DECLARE_INSN(fle_s, 0xb8000053, 0xfe00707f) -DECLARE_INSN(fdiv_s, 0x18000053, 0xfe00007f) -DECLARE_INSN(fle_d, 0xba000053, 0xfe00707f) -DECLARE_INSN(fence_i, 0x100f, 0x707f) -DECLARE_INSN(fnmsub_d, 0x200004b, 0x600007f) -DECLARE_INSN(addw, 0x3b, 0xfe00707f) -DECLARE_INSN(sll, 0x1033, 0xfe00707f) -DECLARE_INSN(xor, 0x4033, 0xfe00707f) -DECLARE_INSN(sub, 0x40000033, 0xfe00707f) -DECLARE_INSN(eret, 0x4073, 0xffffffff) -DECLARE_INSN(blt, 0x4063, 0x707f) -DECLARE_INSN(sc_w, 0x1800202f, 0xf800707f) -DECLARE_INSN(rem, 0x2006033, 0xfe00707f) -DECLARE_INSN(srliw, 0x501b, 0xfe00707f) -DECLARE_INSN(lui, 0x37, 0x7f) -DECLARE_INSN(fcvt_s_lu, 0x68000053, 0xfff0007f) -DECLARE_INSN(addi, 0x13, 0x707f) -DECLARE_INSN(mulh, 0x2001033, 0xfe00707f) -DECLARE_INSN(fmul_s, 0x10000053, 0xfe00007f) -DECLARE_INSN(srai, 0x40005013, 0xfc00707f) -DECLARE_INSN(amoand_d, 0x6000302f, 0xf800707f) -DECLARE_INSN(flt_d, 0xb2000053, 0xfe00707f) -DECLARE_INSN(sraw, 0x4000503b, 0xfe00707f) -DECLARE_INSN(fmul_d, 0x12000053, 0xfe00007f) -DECLARE_INSN(ld, 0x3003, 0x707f) -DECLARE_INSN(ori, 0x6013, 0x707f) -DECLARE_INSN(flt_s, 0xb0000053, 0xfe00707f) -DECLARE_INSN(addiw, 0x1b, 0x707f) -DECLARE_INSN(amoand_w, 0x6000202f, 0xf800707f) -DECLARE_INSN(feq_s, 0xa8000053, 0xfe00707f) -DECLARE_INSN(fsgnjx_d, 0x3a000053, 0xfe00707f) -DECLARE_INSN(sra, 0x40005033, 0xfe00707f) -DECLARE_INSN(bge, 0x5063, 0x707f) -DECLARE_INSN(sraiw, 0x4000501b, 0xfe00707f) -DECLARE_INSN(srl, 0x5033, 0xfe00707f) -DECLARE_INSN(fsub_d, 0xa000053, 0xfe00007f) -DECLARE_INSN(fsgnjx_s, 0x38000053, 0xfe00707f) -DECLARE_INSN(feq_d, 0xaa000053, 0xfe00707f) -DECLARE_INSN(fcvt_d_wu, 0x7a000053, 0xfff0007f) -DECLARE_INSN(or, 0x6033, 0xfe00707f) -DECLARE_INSN(rdinstret, 0x4004077, 0xfffff07f) -DECLARE_INSN(fcvt_wu_d, 0x5a000053, 0xfff0007f) -DECLARE_INSN(subw, 0x4000003b, 0xfe00707f) -DECLARE_INSN(fmax_s, 0xc8000053, 0xfe00707f) -DECLARE_INSN(amomaxu_d, 0xe000302f, 0xf800707f) -DECLARE_INSN(xori, 0x4013, 0x707f) -DECLARE_INSN(amoxor_d, 0x2000302f, 0xf800707f) -DECLARE_INSN(amomaxu_w, 0xe000202f, 0xf800707f) -DECLARE_INSN(fcvt_wu_s, 0x58000053, 0xfff0007f) -DECLARE_INSN(rdtime, 0x2004077, 0xfffff07f) -DECLARE_INSN(andi, 0x7013, 0x707f) -DECLARE_INSN(clearpcr, 0x3073, 0x707f) -DECLARE_INSN(fmv_x_s, 0xe0000053, 0xfff0707f) -DECLARE_INSN(fsgnjn_d, 0x32000053, 0xfe00707f) -DECLARE_INSN(fnmadd_s, 0x4f, 0x600007f) -DECLARE_INSN(jal, 0x67, 0x7f) -DECLARE_INSN(lwu, 0x6003, 0x707f) -DECLARE_INSN(fmv_x_d, 0xe2000053, 0xfff0707f) -DECLARE_INSN(fnmadd_d, 0x200004f, 0x600007f) -DECLARE_INSN(amoadd_d, 0x302f, 0xf800707f) -DECLARE_INSN(lr_d, 0x1000302f, 0xf9f0707f) -DECLARE_INSN(fcvt_w_s, 0x50000053, 0xfff0007f) -DECLARE_INSN(mulhsu, 0x2002033, 0xfe00707f) -DECLARE_INSN(amoadd_w, 0x202f, 0xf800707f) -DECLARE_INSN(fcvt_d_lu, 0x6a000053, 0xfff0007f) -DECLARE_INSN(lr_w, 0x1000202f, 0xf9f0707f) -DECLARE_INSN(fcvt_w_d, 0x52000053, 0xfff0007f) -DECLARE_INSN(slt, 0x2033, 0xfe00707f) -DECLARE_INSN(sllw, 0x103b, 0xfe00707f) -DECLARE_INSN(amoor_d, 0x4000302f, 0xf800707f) -DECLARE_INSN(slti, 0x2013, 0x707f) -DECLARE_INSN(remu, 0x2007033, 0xfe00707f) -DECLARE_INSN(flw, 0x2007, 0x707f) -DECLARE_INSN(remw, 0x200603b, 0xfe00707f) -DECLARE_INSN(sltu, 0x3033, 0xfe00707f) -DECLARE_INSN(slli, 0x1013, 0xfc00707f) -DECLARE_INSN(amoor_w, 0x4000202f, 0xf800707f) -DECLARE_INSN(beq, 0x63, 0x707f) -DECLARE_INSN(fld, 0x3007, 0x707f) -DECLARE_INSN(fsub_s, 0x8000053, 0xfe00007f) -DECLARE_INSN(and, 0x7033, 0xfe00707f) -DECLARE_INSN(fmv_d_x, 0xf2000053, 0xfff0707f) -DECLARE_INSN(lbu, 0x4003, 0x707f) -DECLARE_INSN(syscall, 0x77, 0xffffffff) -DECLARE_INSN(fsgnj_s, 0x28000053, 0xfe00707f) -DECLARE_INSN(amomax_w, 0xa000202f, 0xf800707f) -DECLARE_INSN(fsgnj_d, 0x2a000053, 0xfe00707f) -DECLARE_INSN(mulhu, 0x2003033, 0xfe00707f) -DECLARE_INSN(fcvt_l_d, 0x42000053, 0xfff0007f) -DECLARE_INSN(fssr, 0xf8000053, 0xfff0707f) -DECLARE_INSN(setpcr, 0x2073, 0x707f) -DECLARE_INSN(fcvt_lu_s, 0x48000053, 0xfff0007f) -DECLARE_INSN(fcvt_s_l, 0x60000053, 0xfff0007f) -DECLARE_INSN(auipc, 0x17, 0x7f) -DECLARE_INSN(fcvt_lu_d, 0x4a000053, 0xfff0007f) -DECLARE_INSN(sc_d, 0x1800302f, 0xf800707f) -DECLARE_INSN(fmadd_s, 0x43, 0x600007f) -DECLARE_INSN(fsqrt_s, 0x20000053, 0xfff0007f) -DECLARE_INSN(amomin_w, 0x8000202f, 0xf800707f) -DECLARE_INSN(fsgnjn_s, 0x30000053, 0xfe00707f) -DECLARE_INSN(amoswap_d, 0x800302f, 0xf800707f) -DECLARE_INSN(fsqrt_d, 0x22000053, 0xfff0007f) -DECLARE_INSN(fmadd_d, 0x2000043, 0x600007f) -DECLARE_INSN(divw, 0x200403b, 0xfe00707f) -DECLARE_INSN(amomin_d, 0x8000302f, 0xf800707f) -DECLARE_INSN(divu, 0x2005033, 0xfe00707f) -DECLARE_INSN(amoswap_w, 0x800202f, 0xf800707f) -DECLARE_INSN(jalr, 0x6f, 0x707f) -DECLARE_INSN(fadd_s, 0x53, 0xfe00007f) -DECLARE_INSN(fsd, 0x3027, 0x707f) -DECLARE_INSN(sw, 0x2023, 0x707f) -DECLARE_INSN(fmsub_s, 0x47, 0x600007f) -DECLARE_INSN(lhu, 0x5003, 0x707f) -DECLARE_INSN(sh, 0x1023, 0x707f) -DECLARE_INSN(fsw, 0x2027, 0x707f) -DECLARE_INSN(sb, 0x23, 0x707f) -DECLARE_INSN(fmsub_d, 0x2000047, 0x600007f) -DECLARE_INSN(sd, 0x3023, 0x707f) diff --git a/riscv/pcr.h b/riscv/pcr.h deleted file mode 100644 index 6c6d986..0000000 --- a/riscv/pcr.h +++ /dev/null @@ -1,114 +0,0 @@ -// See LICENSE for license details. - -#ifndef _RISCV_PCR_H -#define _RISCV_PCR_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 PCR_SUP0 0 -#define PCR_SUP1 1 -#define PCR_EPC 2 -#define PCR_BADVADDR 3 -#define PCR_PTBR 4 -#define PCR_ASID 5 -#define PCR_COUNT 6 -#define PCR_COMPARE 7 -#define PCR_EVEC 8 -#define PCR_CAUSE 9 -#define PCR_SR 10 -#define PCR_HARTID 11 -#define PCR_IMPL 12 -#define PCR_FATC 13 -#define PCR_SEND_IPI 14 -#define PCR_CLR_IPI 15 -#define PCR_VECBANK 18 -#define PCR_VECCFG 19 -#define PCR_RESET 29 -#define PCR_TOHOST 30 -#define PCR_FROMHOST 31 - -#define IRQ_COP 2 -#define IRQ_IPI 5 -#define IRQ_HOST 6 -#define IRQ_TIMER 7 - -#define IMPL_SPIKE 1 -#define IMPL_ROCKET 2 - -#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_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_ACCELERATOR_DISABLED 12 - -// page table entry (PTE) fields -#define PTE_V 0x001 // Entry is a page Table descriptor -#define PTE_T 0x002 // Entry is a page Table, not a terminal node -#define PTE_G 0x004 // Global -#define PTE_UR 0x008 // User Write permission -#define PTE_UW 0x010 // User Read permission -#define PTE_UX 0x020 // User eXecute permission -#define PTE_SR 0x040 // Supervisor Read permission -#define PTE_SW 0x080 // Supervisor Write permission -#define PTE_SX 0x100 // Supervisor eXecute permission -#define PTE_PERM (PTE_SR | PTE_SW | PTE_SX | PTE_UR | PTE_UW | PTE_UX) - -#ifdef __riscv - -#ifdef __riscv64 -# define RISCV_PGLEVELS 3 -# define RISCV_PGSHIFT 13 -#else -# define RISCV_PGLEVELS 2 -# define RISCV_PGSHIFT 12 -#endif -#define RISCV_PGLEVEL_BITS 10 -#define RISCV_PGSIZE (1 << RISCV_PGSHIFT) - -#ifndef __ASSEMBLER__ - -#define mtpcr(reg,val) ({ long __tmp = (long)(val), __tmp2; \ - asm volatile ("mtpcr %0,%1,cr%2" : "=r"(__tmp2) : "r"(__tmp),"i"(reg)); \ - __tmp2; }) - -#define mfpcr(reg) ({ long __tmp; \ - asm volatile ("mfpcr %0,cr%1" : "=r"(__tmp) : "i"(reg)); \ - __tmp; }) - -#define setpcr(reg,val) ({ long __tmp; \ - asm volatile ("setpcr %0,cr%2,%1" : "=r"(__tmp) : "i"(val), "i"(reg)); \ - __tmp; }) - -#define clearpcr(reg,val) ({ long __tmp; \ - asm volatile ("clearpcr %0,cr%2,%1" : "=r"(__tmp) : "i"(val), "i"(reg)); \ - __tmp; }) - -#define rdcycle() ({ unsigned long __tmp; \ - asm volatile ("rdcycle %0" : "=r"(__tmp)); \ - __tmp; }) - -#endif - -#endif - -#endif diff --git a/riscv/processor.cc b/riscv/processor.cc index 3fe0d99..5e2910f 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -15,13 +15,14 @@ #include processor_t::processor_t(sim_t* _sim, mmu_t* _mmu, uint32_t _id) - : sim(_sim), mmu(_mmu), ext(NULL), id(_id), debug(false), opcode_bits(0) + : sim(_sim), mmu(_mmu), ext(NULL), id(_id), run(false), debug(false), + opcode_bits(0) { reset(true); mmu->set_processor(this); #define DECLARE_INSN(name, match, mask) REGISTER_INSN(this, name, match, mask) - #include "opcodes.h" + #include "encoding.h" #undef DECLARE_INSN } @@ -53,8 +54,8 @@ void state_t::reset() pcr_k1 = 0; count = 0; compare = 0; - cycle = 0; - fsr = 0; + fflags = 0; + frm = 0; load_reservation = -1; } @@ -77,13 +78,6 @@ void processor_t::reset(bool value) ext->reset(); // reset the extension } -uint32_t processor_t::set_fsr(uint32_t val) -{ - uint32_t old_fsr = state.fsr; - state.fsr = val & ~FSR_ZERO; // clear FSR bits that read as zero - return old_fsr; -} - void processor_t::take_interrupt() { uint32_t interrupts = (state.sr & SR_IP) >> SR_IP_SHIFT; @@ -155,8 +149,6 @@ void processor_t::step(size_t n) take_trap(npc, t); } - state.cycle += i; - // update timer and possibly register a timer interrupt uint32_t old_count = state.count; state.count += i; @@ -171,9 +163,9 @@ void processor_t::take_trap(reg_t pc, trap_t& t) id, t.name(), pc); // switch to supervisor, set previous supervisor bit, disable interrupts - set_pcr(PCR_SR, (((state.sr & ~SR_EI) | SR_S) & ~SR_PS & ~SR_PEI) | - ((state.sr & SR_S) ? SR_PS : 0) | - ((state.sr & SR_EI) ? SR_PEI : 0)); + set_pcr(CSR_STATUS, (((state.sr & ~SR_EI) | SR_S) & ~SR_PS & ~SR_PEI) | + ((state.sr & SR_S) ? SR_PS : 0) | + ((state.sr & SR_EI) ? SR_PEI : 0)); yield_load_reservation(); state.cause = t.cause(); @@ -186,7 +178,7 @@ void processor_t::take_trap(reg_t pc, trap_t& t) void processor_t::deliver_ipi() { if (run) - set_pcr(PCR_CLR_IPI, 1); + set_pcr(CSR_CLEAR_IPI, 1); } void processor_t::disasm(insn_t insn) @@ -202,7 +194,17 @@ reg_t processor_t::set_pcr(int which, reg_t val) switch (which) { - case PCR_SR: + case CSR_FFLAGS: + state.fflags = val & (FSR_AEXC >> FSR_AEXC_SHIFT); + break; + case CSR_FRM: + state.frm = val & (FSR_RD >> FSR_RD_SHIFT); + break; + case CSR_FCSR: + state.fflags = (val & FSR_AEXC) >> FSR_AEXC_SHIFT; + state.frm = (val & FSR_RD) >> FSR_RD_SHIFT; + break; + case CSR_STATUS: state.sr = (val & ~SR_IP) | (state.sr & SR_IP); #ifndef RISCV_ENABLE_64BIT state.sr &= ~(SR_S64 | SR_U64); @@ -215,39 +217,42 @@ reg_t processor_t::set_pcr(int which, reg_t val) state.sr &= ~SR_ZERO; mmu->flush_tlb(); break; - case PCR_EPC: + case CSR_EPC: state.epc = val; break; - case PCR_EVEC: + case CSR_EVEC: state.evec = val; break; - case PCR_COUNT: + case CSR_CYCLE: + case CSR_TIME: + case CSR_INSTRET: + case CSR_COUNT: state.count = val; break; - case PCR_COMPARE: + case CSR_COMPARE: set_interrupt(IRQ_TIMER, false); state.compare = val; break; - case PCR_PTBR: + case CSR_PTBR: state.ptbr = val & ~(PGSIZE-1); break; - case PCR_SEND_IPI: + case CSR_SEND_IPI: sim->send_ipi(val); break; - case PCR_CLR_IPI: + case CSR_CLEAR_IPI: set_interrupt(IRQ_IPI, val & 1); break; - case PCR_SUP0: + case CSR_SUP0: state.pcr_k0 = val; break; - case PCR_SUP1: + case CSR_SUP1: state.pcr_k1 = val; break; - case PCR_TOHOST: + case CSR_TOHOST: if (state.tohost == 0) state.tohost = val; break; - case PCR_FROMHOST: + case CSR_FROMHOST: set_interrupt(IRQ_HOST, val != 0); state.fromhost = val; break; @@ -260,41 +265,51 @@ reg_t processor_t::get_pcr(int which) { switch (which) { - case PCR_SR: + case CSR_FFLAGS: + return state.fflags; + case CSR_FRM: + return state.frm; + case CSR_FCSR: + return (state.fflags << FSR_AEXC_SHIFT) | (state.frm << FSR_RD_SHIFT); + case CSR_STATUS: return state.sr; - case PCR_EPC: + case CSR_EPC: return state.epc; - case PCR_BADVADDR: + case CSR_BADVADDR: return state.badvaddr; - case PCR_EVEC: + case CSR_EVEC: return state.evec; - case PCR_COUNT: + case CSR_CYCLE: + case CSR_TIME: + case CSR_INSTRET: + case CSR_COUNT: return state.count; - case PCR_COMPARE: + case CSR_COMPARE: return state.compare; - case PCR_CAUSE: + case CSR_CAUSE: return state.cause; - case PCR_PTBR: + case CSR_PTBR: return state.ptbr; - case PCR_ASID: + case CSR_ASID: return 0; - case PCR_FATC: + case CSR_FATC: mmu->flush_tlb(); return 0; - case PCR_HARTID: + case CSR_HARTID: return id; - case PCR_IMPL: + case CSR_IMPL: return 1; - case PCR_SUP0: + case CSR_SUP0: return state.pcr_k0; - case PCR_SUP1: + case CSR_SUP1: return state.pcr_k1; - case PCR_TOHOST: + case CSR_TOHOST: return state.tohost; - case PCR_FROMHOST: + case CSR_FROMHOST: return state.fromhost; + default: + return -1; } - return -1; } void processor_t::set_interrupt(int which, bool on) diff --git a/riscv/processor.h b/riscv/processor.h index 0256bd8..f53b269 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -28,13 +28,11 @@ struct state_t { void reset(); - // user-visible state reg_t pc; regfile_t XPR; regfile_t FPR; - reg_t cycle; - // privileged control registers + // control and status registers reg_t epc; reg_t badvaddr; reg_t evec; @@ -44,10 +42,11 @@ struct state_t reg_t cause; reg_t tohost; reg_t fromhost; - uint32_t sr; // only modify the status register using set_pcr() - uint32_t fsr; - uint32_t count; + reg_t count; uint32_t compare; + uint32_t sr; // only modify the status register using set_pcr() + uint32_t fflags; + uint32_t frm; reg_t load_reservation; }; @@ -65,10 +64,8 @@ public: void deliver_ipi(); // register an interprocessor interrupt bool running() { return run; } reg_t set_pcr(int which, reg_t val); - uint32_t set_fsr(uint32_t val); // set the floating-point status register void set_interrupt(int which, bool on); reg_t get_pcr(int which); - uint32_t get_fsr() { return state.fsr; } mmu_t* get_mmu() { return mmu; } state_t* get_state() { return &state; } extension_t* get_extension() { return ext; } diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in index 3c4480a..fd506c8 100644 --- a/riscv/riscv.mk.in +++ b/riscv/riscv.mk.in @@ -1,5 +1,5 @@ -get_insn_list = $(shell cat $(1) | sed 's/DECLARE_INSN(\(.*\),.*,.*)/\1/') -get_opcode = $(shell grep \\\<$(2)\\\> $(1) | sed 's/DECLARE_INSN(.*,\(.*\),.*)/\1/') +get_insn_list = $(shell grep ^DECLARE_INSN $(1) | sed 's/DECLARE_INSN(\(.*\),.*,.*)/\1/') +get_opcode = $(shell grep ^DECLARE_INSN.*\\\<$(2)\\\> $(1) | sed 's/DECLARE_INSN(.*,\(.*\),.*)/\1/') riscv_subproject_deps = \ softfloat_riscv \ @@ -20,7 +20,7 @@ riscv_hdrs = \ processor.h \ sim.h \ trap.h \ - opcodes.h \ + encoding.h \ cachesim.h \ memtracer.h \ extension.h \ @@ -45,10 +45,10 @@ riscv_test_srcs = riscv_gen_hdrs = \ riscv_gen_srcs = \ - $(addsuffix .cc, $(call get_insn_list,$(src_dir)/riscv/opcodes.h)) + $(addsuffix .cc, $(call get_insn_list,$(src_dir)/riscv/encoding.h)) $(riscv_gen_srcs): %.cc: insns/%.h insn_template.cc - sed 's/NAME/$(subst .cc,,$@)/' $(src_dir)/riscv/insn_template.cc | sed 's/OPCODE/$(call get_opcode,$(src_dir)/riscv/opcodes.h,$(subst .cc,,$@))/' > $@ + sed 's/NAME/$(subst .cc,,$@)/' $(src_dir)/riscv/insn_template.cc | sed 's/OPCODE/$(call get_opcode,$(src_dir)/riscv/encoding.h,$(subst .cc,,$@))/' > $@ riscv_junk = \ $(riscv_gen_srcs) \ diff --git a/riscv/sim.h b/riscv/sim.h index 34ed6e8..d643e6d 100644 --- a/riscv/sim.h +++ b/riscv/sim.h @@ -30,7 +30,7 @@ public: // returns the number of processors in this simulator size_t num_cores() { return procs.size(); } - processor_t* get_core(size_t i) { return procs[i]; } + processor_t* get_core(size_t i) { return procs.at(i); } // read one of the system control registers reg_t get_scr(int which);