diff --git a/disasm/isa_parser.cc b/disasm/isa_parser.cc index fa8cadda..25d1affe 100644 --- a/disasm/isa_parser.cc +++ b/disasm/isa_parser.cc @@ -300,6 +300,8 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv) extension_table[EXT_ZCMOP] = true; } else if (ext_str == "zalasr") { extension_table[EXT_ZALASR] = true; + } else if (ext_str == "ssqosid") { + extension_table[EXT_SSQOSID] = true; } else if (ext_str[0] == 'x') { extension_table['X'] = true; if (ext_str.size() == 1) { diff --git a/riscv/csrs.cc b/riscv/csrs.cc index 47836469..b3a09a64 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -1692,3 +1692,22 @@ bool smcntrpmf_csr_t::unlogged_write(const reg_t val) noexcept { prev_val = read(); return masked_csr_t::unlogged_write(val); } + +srmcfg_csr_t::srmcfg_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init): + masked_csr_t(proc, addr, mask, init) { +} + +void srmcfg_csr_t::verify_permissions(insn_t insn, bool write) const { + csr_t::verify_permissions(insn, write); + + if (!proc->extension_enabled(EXT_SSQOSID)) + throw trap_illegal_instruction(insn.bits()); + + if (proc->extension_enabled(EXT_SMSTATEEN)) { + if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & MSTATEEN0_PRIV114)) + throw trap_illegal_instruction(insn.bits()); + } + + if (state->v) + throw trap_virtual_instruction(insn.bits()); +} diff --git a/riscv/csrs.h b/riscv/csrs.h index 887749a6..ad3f7a31 100644 --- a/riscv/csrs.h +++ b/riscv/csrs.h @@ -843,4 +843,11 @@ class smcntrpmf_csr_t : public masked_csr_t { private: std::optional prev_val; }; + +// srmcfg CSR provided by Ssqosid extension +class srmcfg_csr_t: public masked_csr_t { + public: + srmcfg_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init); + virtual void verify_permissions(insn_t insn, bool write) const override; +}; #endif diff --git a/riscv/encoding.h b/riscv/encoding.h index 78318a65..249b3fa0 100644 --- a/riscv/encoding.h +++ b/riscv/encoding.h @@ -4,7 +4,7 @@ /* * This file is auto-generated by running 'make' in - * https://github.com/riscv/riscv-opcodes (61d2ef4) + * https://github.com/riscv/riscv-opcodes (a014979) */ #ifndef RISCV_CSR_ENCODING_H @@ -177,11 +177,14 @@ #define MSTATEEN0_CS 0x00000001 #define MSTATEEN0_FCSR 0x00000002 #define MSTATEEN0_JVT 0x00000004 +#define MSTATEEN0_PRIV114 0x0080000000000000 +#define MSTATEEN0_HENVCFGH 0x0100000000000000 #define MSTATEEN0_HCONTEXT 0x0200000000000000 -#define MSTATEEN0_CD 0x0100000000000000 #define MSTATEEN0_HENVCFG 0x4000000000000000 #define MSTATEEN_HSTATEEN 0x8000000000000000 +#define MSTATEEN0H_PRIV114 0x00800000 +#define MSTATEEN0H_HENVCFGH 0x01000000 #define MSTATEEN0H_HCONTEXT 0x02000000 #define MSTATEEN0H_HENVCFG 0x40000000 #define MSTATEENH_HSTATEEN 0x80000000 @@ -339,6 +342,10 @@ #define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V) +/* srmcfg CSR fields */ +#define SRMCFG_RCID 0x00000FFF +#define SRMCFG_MCID 0x0FFF0000 + #ifdef __riscv #if __riscv_xlen == 64 @@ -3196,6 +3203,7 @@ #define CSR_SIREG6 0x157 #define CSR_STOPEI 0x15c #define CSR_SATP 0x180 +#define CSR_SRMCFG 0x181 #define CSR_SCONTEXT 0x5a8 #define CSR_VSSTATUS 0x200 #define CSR_VSIE 0x204 @@ -5144,6 +5152,7 @@ DECLARE_CSR(sireg5, CSR_SIREG5) DECLARE_CSR(sireg6, CSR_SIREG6) DECLARE_CSR(stopei, CSR_STOPEI) DECLARE_CSR(satp, CSR_SATP) +DECLARE_CSR(srmcfg, CSR_SRMCFG) DECLARE_CSR(scontext, CSR_SCONTEXT) DECLARE_CSR(vsstatus, CSR_VSSTATUS) DECLARE_CSR(vsie, CSR_VSIE) diff --git a/riscv/isa_parser.h b/riscv/isa_parser.h index 7773ba58..6719a649 100644 --- a/riscv/isa_parser.h +++ b/riscv/isa_parser.h @@ -84,6 +84,7 @@ typedef enum { EXT_ZIMOP, EXT_ZCMOP, EXT_ZALASR, + EXT_SSQOSID, NUM_ISA_EXTENSIONS } isa_extension_t; diff --git a/riscv/processor.cc b/riscv/processor.cc index 09e8e1c2..3c923ea7 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -483,7 +483,7 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) (proc->extension_enabled(EXT_ZCMT) ? SSTATEEN0_JVT : 0) | SSTATEEN0_CS; const reg_t hstateen0_mask = sstateen0_mask | HSTATEEN0_SENVCFG | HSTATEEN_SSTATEEN; - const reg_t mstateen0_mask = hstateen0_mask; + const reg_t mstateen0_mask = hstateen0_mask | (proc->extension_enabled(EXT_SSQOSID) ? MSTATEEN0_PRIV114 : 0); for (int i = 0; i < 4; i++) { const reg_t mstateen_mask = i == 0 ? mstateen0_mask : MSTATEEN_HSTATEEN; mstateen[i] = std::make_shared(proc, CSR_MSTATEEN0 + i, mstateen_mask, 0); @@ -585,6 +585,12 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) } } + if (proc->extension_enabled_const(EXT_SSQOSID)) { + const reg_t srmcfg_mask = SRMCFG_MCID | SRMCFG_RCID; + srmcfg = std::make_shared(proc, CSR_SRMCFG, srmcfg_mask, 0); + csrmap[CSR_SRMCFG] = srmcfg; + } + serialized = false; log_reg_write.clear(); diff --git a/riscv/processor.h b/riscv/processor.h index a2e42865..0394e090 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -170,6 +170,8 @@ struct state_t csr_t_p stimecmp; csr_t_p vstimecmp; + csr_t_p srmcfg; + bool serialized; // whether timer CSRs are in a well-defined state // When true, execute a single instruction and then enter debug mode. This