diff options
-rw-r--r-- | .github/workflows/continuous-integration.yml | 4 | ||||
-rw-r--r-- | ci-tests/testlib.c | 30 | ||||
-rw-r--r-- | disasm/disasm.cc | 61 | ||||
-rw-r--r-- | disasm/isa_parser.cc | 2 | ||||
-rw-r--r-- | riscv/cfg.cc | 21 | ||||
-rw-r--r-- | riscv/cfg.h | 66 | ||||
-rw-r--r-- | riscv/clint.cc | 2 | ||||
-rw-r--r-- | riscv/debug_module.cc | 6 | ||||
-rw-r--r-- | riscv/debug_module.h | 18 | ||||
-rw-r--r-- | riscv/encoding.h | 46 | ||||
-rw-r--r-- | riscv/insns/fmvh_x_d.h | 2 | ||||
-rw-r--r-- | riscv/insns/mop_r_N.h | 2 | ||||
-rw-r--r-- | riscv/insns/mop_rr_N.h | 2 | ||||
-rw-r--r-- | riscv/isa_parser.h | 1 | ||||
-rw-r--r-- | riscv/mmu.cc | 25 | ||||
-rw-r--r-- | riscv/mmu.h | 2 | ||||
-rw-r--r-- | riscv/processor.cc | 2 | ||||
-rw-r--r-- | riscv/riscv.mk.in | 5 | ||||
-rw-r--r-- | riscv/sim.cc | 10 | ||||
-rw-r--r-- | riscv/zvk_ext_macros.h | 4 | ||||
-rw-r--r-- | spike_main/spike-log-parser.cc | 14 | ||||
-rw-r--r-- | spike_main/spike.cc | 30 |
22 files changed, 201 insertions, 154 deletions
diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 48ef2c1..ecb0a6c 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -29,7 +29,7 @@ jobs: run: sudo xargs apt-get install -y < .github/workflows/apt-packages.txt - run: | - for commit in $(git rev-list origin/master..HEAD); do + for commit in $(git rev-list origin/master..HEAD | tac); do git checkout $commit echo "Checking commit $commit" ci-tests/build-spike @@ -49,7 +49,7 @@ jobs: run: xargs brew install --overwrite < .github/workflows/brew-packages.txt - run: | - for commit in $(git rev-list origin/master..HEAD); do + for commit in $(git rev-list origin/master..HEAD | tail -r); do git checkout $commit echo "Checking commit $commit" ci-tests/build-spike diff --git a/ci-tests/testlib.c b/ci-tests/testlib.c index 559a1f8..5e39c1b 100644 --- a/ci-tests/testlib.c +++ b/ci-tests/testlib.c @@ -14,36 +14,12 @@ static std::vector<std::pair<reg_t, abstract_mem_t*>> make_mems(const std::vecto int main() { - std::vector<mem_cfg_t> mem_cfg { mem_cfg_t(0x80000000, 0x10000000) }; - std::vector<size_t> hartids = {0}; - cfg_t cfg(std::make_pair(0, 0), - nullptr, - "rv64gcv", - "MSU", - "vlen:128,elen:64", - false, - endianness_little, - 16, - (1 << PMP_SHIFT), - mem_cfg, - hartids, - false, - 4); + cfg_t cfg; std::vector<device_factory_t*> plugin_devices; std::vector<std::string> htif_args {"pk", "hello"}; - debug_module_config_t dm_config = { - .progbufsize = 2, - .max_sba_data_width = 0, - .require_authentication = false, - .abstract_rti = 0, - .support_hasel = true, - .support_abstract_csr_access = true, - .support_abstract_fpr_access = true, - .support_haltgroups = true, - .support_impebreak = true - }; + debug_module_config_t dm_config; std::vector<std::pair<reg_t, abstract_mem_t*>> mems = - make_mems(cfg.mem_layout()); + make_mems(cfg.mem_layout); sim_t sim(&cfg, false, mems, plugin_devices, diff --git a/disasm/disasm.cc b/disasm/disasm.cc index ad48ea8..08571a2 100644 --- a/disasm/disasm.cc +++ b/disasm/disasm.cc @@ -2172,15 +2172,58 @@ void disassembler_t::add_instructions(const isa_parser_t* isa) DEFINE_RTYPE(czero_nez); } + if (isa->extension_enabled(EXT_ZIMOP)) { + DEFINE_R1TYPE(mop_r_0); + DEFINE_R1TYPE(mop_r_1); + DEFINE_R1TYPE(mop_r_2); + DEFINE_R1TYPE(mop_r_3); + DEFINE_R1TYPE(mop_r_4); + DEFINE_R1TYPE(mop_r_5); + DEFINE_R1TYPE(mop_r_6); + DEFINE_R1TYPE(mop_r_7); + DEFINE_R1TYPE(mop_r_8); + DEFINE_R1TYPE(mop_r_9); + DEFINE_R1TYPE(mop_r_10); + DEFINE_R1TYPE(mop_r_11); + DEFINE_R1TYPE(mop_r_12); + DEFINE_R1TYPE(mop_r_13); + DEFINE_R1TYPE(mop_r_14); + DEFINE_R1TYPE(mop_r_15); + DEFINE_R1TYPE(mop_r_16); + DEFINE_R1TYPE(mop_r_17); + DEFINE_R1TYPE(mop_r_18); + DEFINE_R1TYPE(mop_r_19); + DEFINE_R1TYPE(mop_r_20); + DEFINE_R1TYPE(mop_r_21); + DEFINE_R1TYPE(mop_r_22); + DEFINE_R1TYPE(mop_r_23); + DEFINE_R1TYPE(mop_r_24); + DEFINE_R1TYPE(mop_r_25); + DEFINE_R1TYPE(mop_r_26); + DEFINE_R1TYPE(mop_r_27); + DEFINE_R1TYPE(mop_r_28); + DEFINE_R1TYPE(mop_r_29); + DEFINE_R1TYPE(mop_r_30); + DEFINE_R1TYPE(mop_r_31); + DEFINE_RTYPE(mop_rr_0); + DEFINE_RTYPE(mop_rr_1); + DEFINE_RTYPE(mop_rr_2); + DEFINE_RTYPE(mop_rr_3); + DEFINE_RTYPE(mop_rr_4); + DEFINE_RTYPE(mop_rr_5); + DEFINE_RTYPE(mop_rr_6); + DEFINE_RTYPE(mop_rr_7); + } + if (isa->extension_enabled(EXT_ZCMOP)) { - DISASM_INSN("c.mop.1", c_mop_1, 0, {}); - DISASM_INSN("c.mop.3", c_mop_3, 0, {}); - DISASM_INSN("c.mop.5", c_mop_5, 0, {}); - DISASM_INSN("c.mop.7", c_mop_7, 0, {}); - DISASM_INSN("c.mop.9", c_mop_9, 0, {}); - DISASM_INSN("c.mop.11", c_mop_11, 0, {}); - DISASM_INSN("c.mop.13", c_mop_13, 0, {}); - DISASM_INSN("c.mop.15", c_mop_15, 0, {}); + DISASM_INSN("c.mop.1", c_mop_1, 0, {}); + DISASM_INSN("c.mop.3", c_mop_3, 0, {}); + DISASM_INSN("c.mop.5", c_mop_5, 0, {}); + DISASM_INSN("c.mop.7", c_mop_7, 0, {}); + DISASM_INSN("c.mop.9", c_mop_9, 0, {}); + DISASM_INSN("c.mop.11", c_mop_11, 0, {}); + DISASM_INSN("c.mop.13", c_mop_13, 0, {}); + DISASM_INSN("c.mop.15", c_mop_15, 0, {}); } if (isa->extension_enabled(EXT_ZKND) || @@ -2347,7 +2390,7 @@ disassembler_t::disassembler_t(const isa_parser_t *isa) // next-highest priority: other instructions in same base ISA std::string fallback_isa_string = std::string("rv") + std::to_string(isa->get_max_xlen()) + - "gqchv_zfh_zba_zbb_zbc_zbs_zcb_zicbom_zicboz_zicond_zkn_zkr_zks_svinval_zcmop"; + "gqchv_zfh_zba_zbb_zbc_zbs_zcb_zicbom_zicboz_zicond_zkn_zkr_zks_svinval_zcmop_zimop"; isa_parser_t fallback_isa(fallback_isa_string.c_str(), DEFAULT_PRIV); add_instructions(&fallback_isa); diff --git a/disasm/isa_parser.cc b/disasm/isa_parser.cc index ef51310..fa8cadd 100644 --- a/disasm/isa_parser.cc +++ b/disasm/isa_parser.cc @@ -294,6 +294,8 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv) extension_table[EXT_SSCSRIND] = true; } else if (ext_str == "smcntrpmf") { extension_table[EXT_SMCNTRPMF] = true; + } else if (ext_str == "zimop") { + extension_table[EXT_ZIMOP] = true; } else if (ext_str == "zcmop") { extension_table[EXT_ZCMOP] = true; } else if (ext_str == "zalasr") { diff --git a/riscv/cfg.cc b/riscv/cfg.cc index 457aa92..d105eb5 100644 --- a/riscv/cfg.cc +++ b/riscv/cfg.cc @@ -3,6 +3,8 @@ #include "cfg.h" #include "mmu.h" #include "decode.h" +#include "encoding.h" +#include "platform.h" mem_cfg_t::mem_cfg_t(reg_t base, reg_t size) : base(base), size(size) { @@ -25,3 +27,22 @@ bool mem_cfg_t::check_if_supported(reg_t base, reg_t size) (size > 0) && ((base + size > base) || (base + size == 0)); } + +cfg_t::cfg_t() +{ + // The default system configuration + initrd_bounds = std::make_pair((reg_t)0, (reg_t)0); + bootargs = nullptr; + isa = DEFAULT_ISA; + priv = DEFAULT_PRIV; + varch = DEFAULT_VARCH; + misaligned = false; + endianness = endianness_little; + pmpregions = 16; + pmpgranularity = (1 << PMP_SHIFT); + mem_layout = std::vector<mem_cfg_t>({mem_cfg_t(reg_t(DRAM_BASE), (size_t)2048 << 20)}); + hartids = std::vector<size_t>({0}); + explicit_hartids = false; + real_time_clint = false; + trigger_count = 4; +} diff --git a/riscv/cfg.h b/riscv/cfg.h index 422c1ae..63465e6 100644 --- a/riscv/cfg.h +++ b/riscv/cfg.h @@ -61,52 +61,26 @@ private: class cfg_t { public: - cfg_t(std::pair<reg_t, reg_t> default_initrd_bounds, - const char *default_bootargs, - const char *default_isa, const char *default_priv, - const char *default_varch, - const bool default_misaligned, - const endianness_t default_endianness, - const reg_t default_pmpregions, - const reg_t default_pmpgranularity, - const std::vector<mem_cfg_t> &default_mem_layout, - const std::vector<size_t> default_hartids, - bool default_real_time_clint, - const reg_t default_trigger_count) - : initrd_bounds(default_initrd_bounds), - bootargs(default_bootargs), - isa(default_isa), - priv(default_priv), - varch(default_varch), - misaligned(default_misaligned), - endianness(default_endianness), - pmpregions(default_pmpregions), - pmpgranularity(default_pmpgranularity), - mem_layout(default_mem_layout), - hartids(default_hartids), - explicit_hartids(false), - real_time_clint(default_real_time_clint), - trigger_count(default_trigger_count) - {} - - cfg_arg_t<std::pair<reg_t, reg_t>> initrd_bounds; - cfg_arg_t<const char *> bootargs; - cfg_arg_t<const char *> isa; - cfg_arg_t<const char *> priv; - cfg_arg_t<const char *> varch; - bool misaligned; - endianness_t endianness; - reg_t pmpregions; - reg_t pmpgranularity; - cfg_arg_t<std::vector<mem_cfg_t>> mem_layout; - std::optional<reg_t> start_pc; - cfg_arg_t<std::vector<size_t>> hartids; - bool explicit_hartids; - cfg_arg_t<bool> real_time_clint; - reg_t trigger_count; - - size_t nprocs() const { return hartids().size(); } - size_t max_hartid() const { return hartids().back(); } + cfg_t(); + + std::pair<reg_t, reg_t> initrd_bounds; + const char * bootargs; + const char * isa; + const char * priv; + const char * varch; + bool misaligned; + endianness_t endianness; + reg_t pmpregions; + reg_t pmpgranularity; + std::vector<mem_cfg_t> mem_layout; + std::optional<reg_t> start_pc; + std::vector<size_t> hartids; + bool explicit_hartids; + bool real_time_clint; + reg_t trigger_count; + + size_t nprocs() const { return hartids.size(); } + size_t max_hartid() const { return hartids.back(); } }; #endif diff --git a/riscv/clint.cc b/riscv/clint.cc index 2fb9ef3..7e7e89c 100644 --- a/riscv/clint.cc +++ b/riscv/clint.cc @@ -121,7 +121,7 @@ clint_t* clint_parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base, if (fdt_parse_clint(fdt, base, "riscv,clint0") == 0) return new clint_t(sim, sim->CPU_HZ / sim->INSNS_PER_RTC_TICK, - sim->get_cfg().real_time_clint()); + sim->get_cfg().real_time_clint); else return nullptr; } diff --git a/riscv/debug_module.cc b/riscv/debug_module.cc index 07723c5..5d49605 100644 --- a/riscv/debug_module.cc +++ b/riscv/debug_module.cc @@ -514,7 +514,7 @@ bool debug_module_t::dmi_read(unsigned address, uint32_t *value) unsigned base = hawindowsel * 32; for (unsigned i = 0; i < 32; i++) { unsigned n = base + i; - if (n < sim->get_cfg().nprocs() && hart_array_mask[sim->get_cfg().hartids()[n]]) { + if (n < sim->get_cfg().nprocs() && hart_array_mask[sim->get_cfg().hartids[n]]) { result |= 1 << i; } } @@ -916,7 +916,7 @@ bool debug_module_t::dmi_write(unsigned address, uint32_t value) for (unsigned i = 0; i < 32; i++) { unsigned n = base + i; if (n < sim->get_cfg().nprocs()) { - hart_array_mask[sim->get_cfg().hartids()[n]] = (value >> i) & 1; + hart_array_mask[sim->get_cfg().hartids[n]] = (value >> i) & 1; } } } @@ -1030,5 +1030,5 @@ hart_debug_state_t& debug_module_t::selected_hart_state() size_t debug_module_t::selected_hart_id() const { - return sim->get_cfg().hartids().at(dmcontrol.hartsel); + return sim->get_cfg().hartids.at(dmcontrol.hartsel); } diff --git a/riscv/debug_module.h b/riscv/debug_module.h index 75109f6..bca29b2 100644 --- a/riscv/debug_module.h +++ b/riscv/debug_module.h @@ -14,15 +14,15 @@ class processor_t; typedef struct { // Size of program_buffer in 32-bit words, as exposed to the rest of the // world. - unsigned progbufsize; - unsigned max_sba_data_width; - bool require_authentication; - unsigned abstract_rti; - bool support_hasel; - bool support_abstract_csr_access; - bool support_abstract_fpr_access; - bool support_haltgroups; - bool support_impebreak; + unsigned progbufsize = 2; + unsigned max_sba_data_width = 0; + bool require_authentication = false; + unsigned abstract_rti = 0; + bool support_hasel = true; + bool support_abstract_csr_access = true; + bool support_abstract_fpr_access = true; + bool support_haltgroups = true; + bool support_impebreak = true; } debug_module_config_t; typedef struct { diff --git a/riscv/encoding.h b/riscv/encoding.h index 81d829c..78318a6 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 (37413c8) + * https://github.com/riscv/riscv-opcodes (61d2ef4) */ #ifndef RISCV_CSR_ENCODING_H @@ -29,6 +29,7 @@ #define MSTATUS_TVM 0x00100000 #define MSTATUS_TW 0x00200000 #define MSTATUS_TSR 0x00400000 +#define MSTATUS_SPELP 0x00800000 #define MSTATUS32_SD 0x80000000 #define MSTATUS_UXL 0x0000000300000000 #define MSTATUS_SXL 0x0000000C00000000 @@ -36,6 +37,7 @@ #define MSTATUS_MBE 0x0000002000000000 #define MSTATUS_GVA 0x0000004000000000 #define MSTATUS_MPV 0x0000008000000000 +#define MSTATUS_MPELP 0x0000020000000000 #define MSTATUS64_SD 0x8000000000000000 #define MSTATUSH_SBE 0x00000010 @@ -54,6 +56,7 @@ #define SSTATUS_XS 0x00018000 #define SSTATUS_SUM 0x00040000 #define SSTATUS_MXR 0x00080000 +#define SSTATUS_SPELP 0x00800000 #define SSTATUS32_SD 0x80000000 #define SSTATUS_UXL 0x0000000300000000 #define SSTATUS64_SD 0x8000000000000000 @@ -79,6 +82,7 @@ #define DCSR_XDEBUGVER (3U<<30) #define DCSR_NDRESET (1<<29) #define DCSR_FULLRESET (1<<28) +#define DCSR_PELP (1<<18) #define DCSR_EBREAKM (1<<15) #define DCSR_EBREAKH (1<<14) #define DCSR_EBREAKS (1<<13) @@ -157,6 +161,8 @@ #define SIP_STIP MIP_STIP #define MENVCFG_FIOM 0x00000001 +#define MENVCFG_LPE 0x00000004 +#define MENVCFG_SSE 0x00000008 #define MENVCFG_CBIE 0x00000030 #define MENVCFG_CBCFE 0x00000040 #define MENVCFG_CBZE 0x00000080 @@ -195,6 +201,8 @@ #define MHPMEVENTH_OF 0x80000000 #define HENVCFG_FIOM 0x00000001 +#define HENVCFG_LPE 0x00000004 +#define HENVCFG_SSE 0x00000008 #define HENVCFG_CBIE 0x00000030 #define HENVCFG_CBCFE 0x00000040 #define HENVCFG_CBZE 0x00000080 @@ -230,6 +238,8 @@ #define HSTATEENH_SSTATEEN 0x80000000 #define SENVCFG_FIOM 0x00000001 +#define SENVCFG_LPE 0x00000004 +#define SENVCFG_SSE 0x00000008 #define SENVCFG_CBIE 0x00000030 #define SENVCFG_CBCFE 0x00000040 #define SENVCFG_CBZE 0x00000080 @@ -243,6 +253,7 @@ #define MSECCFG_RLB 0x00000004 #define MSECCFG_USEED 0x00000100 #define MSECCFG_SSEED 0x00000200 +#define MSECCFG_MLPE 0x00000400 /* jvt fields */ #define JVT_MODE 0x3F @@ -682,6 +693,10 @@ #define MASK_C_SRAI 0xec03 #define MATCH_C_SRLI 0x8001 #define MASK_C_SRLI 0xec03 +#define MATCH_C_SSPOPCHK_X5 0x6281 +#define MASK_C_SSPOPCHK_X5 0xffff +#define MATCH_C_SSPUSH_X1 0x6081 +#define MASK_C_SSPUSH_X1 0xffff #define MATCH_C_SUB 0x8c01 #define MASK_C_SUB 0xfc63 #define MATCH_C_SUBW 0x9c01 @@ -1990,6 +2005,20 @@ #define MASK_SROIW 0xfe00707f #define MATCH_SROW 0x2000503b #define MASK_SROW 0xfe00707f +#define MATCH_SSAMOSWAP_D 0x4800302f +#define MASK_SSAMOSWAP_D 0xf800707f +#define MATCH_SSAMOSWAP_W 0x4800202f +#define MASK_SSAMOSWAP_W 0xf800707f +#define MATCH_SSPOPCHK_X1 0xcdc0c073 +#define MASK_SSPOPCHK_X1 0xffffffff +#define MATCH_SSPOPCHK_X5 0xcdc2c073 +#define MASK_SSPOPCHK_X5 0xffffffff +#define MATCH_SSPUSH_X1 0xce104073 +#define MASK_SSPUSH_X1 0xffffffff +#define MATCH_SSPUSH_X5 0xce504073 +#define MASK_SSPUSH_X5 0xffffffff +#define MATCH_SSRDP 0xcdc04073 +#define MASK_SSRDP 0xfffff07f #define MATCH_STAS16 0xf4002077 #define MASK_STAS16 0xfe00707f #define MATCH_STAS32 0xf0002077 @@ -3102,6 +3131,7 @@ #define CSR_VXSAT 0x9 #define CSR_VXRM 0xa #define CSR_VCSR 0xf +#define CSR_SSP 0x11 #define CSR_SEED 0x15 #define CSR_JVT 0x17 #define CSR_CYCLE 0xc00 @@ -3560,6 +3590,8 @@ #define CAUSE_FETCH_PAGE_FAULT 0xc #define CAUSE_LOAD_PAGE_FAULT 0xd #define CAUSE_STORE_PAGE_FAULT 0xf +#define CAUSE_SOFTWARE_CHECK_FAULT 0x12 +#define CAUSE_HARDWARE_ERROR_FAULT 0x13 #define CAUSE_FETCH_GUEST_PAGE_FAULT 0x14 #define CAUSE_LOAD_GUEST_PAGE_FAULT 0x15 #define CAUSE_VIRTUAL_INSTRUCTION 0x16 @@ -3823,6 +3855,8 @@ DECLARE_INSN(c_sq, MATCH_C_SQ, MASK_C_SQ) DECLARE_INSN(c_sqsp, MATCH_C_SQSP, MASK_C_SQSP) DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI) DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI) +DECLARE_INSN(c_sspopchk_x5, MATCH_C_SSPOPCHK_X5, MASK_C_SSPOPCHK_X5) +DECLARE_INSN(c_sspush_x1, MATCH_C_SSPUSH_X1, MASK_C_SSPUSH_X1) DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB) DECLARE_INSN(c_subw, MATCH_C_SUBW, MASK_C_SUBW) DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW) @@ -4477,6 +4511,13 @@ DECLARE_INSN(sro, MATCH_SRO, MASK_SRO) DECLARE_INSN(sroi, MATCH_SROI, MASK_SROI) DECLARE_INSN(sroiw, MATCH_SROIW, MASK_SROIW) DECLARE_INSN(srow, MATCH_SROW, MASK_SROW) +DECLARE_INSN(ssamoswap_d, MATCH_SSAMOSWAP_D, MASK_SSAMOSWAP_D) +DECLARE_INSN(ssamoswap_w, MATCH_SSAMOSWAP_W, MASK_SSAMOSWAP_W) +DECLARE_INSN(sspopchk_x1, MATCH_SSPOPCHK_X1, MASK_SSPOPCHK_X1) +DECLARE_INSN(sspopchk_x5, MATCH_SSPOPCHK_X5, MASK_SSPOPCHK_X5) +DECLARE_INSN(sspush_x1, MATCH_SSPUSH_X1, MASK_SSPUSH_X1) +DECLARE_INSN(sspush_x5, MATCH_SSPUSH_X5, MASK_SSPUSH_X5) +DECLARE_INSN(ssrdp, MATCH_SSRDP, MASK_SSRDP) DECLARE_INSN(stas16, MATCH_STAS16, MASK_STAS16) DECLARE_INSN(stas32, MATCH_STAS32, MASK_STAS32) DECLARE_INSN(stsa16, MATCH_STSA16, MASK_STSA16) @@ -5038,6 +5079,7 @@ DECLARE_CSR(vstart, CSR_VSTART) DECLARE_CSR(vxsat, CSR_VXSAT) DECLARE_CSR(vxrm, CSR_VXRM) DECLARE_CSR(vcsr, CSR_VCSR) +DECLARE_CSR(ssp, CSR_SSP) DECLARE_CSR(seed, CSR_SEED) DECLARE_CSR(jvt, CSR_JVT) DECLARE_CSR(cycle, CSR_CYCLE) @@ -5497,6 +5539,8 @@ DECLARE_CAUSE("machine_ecall", CAUSE_MACHINE_ECALL) DECLARE_CAUSE("fetch page fault", CAUSE_FETCH_PAGE_FAULT) DECLARE_CAUSE("load page fault", CAUSE_LOAD_PAGE_FAULT) DECLARE_CAUSE("store page fault", CAUSE_STORE_PAGE_FAULT) +DECLARE_CAUSE("software check fault", CAUSE_SOFTWARE_CHECK_FAULT) +DECLARE_CAUSE("hardware error fault", CAUSE_HARDWARE_ERROR_FAULT) DECLARE_CAUSE("fetch guest page fault", CAUSE_FETCH_GUEST_PAGE_FAULT) DECLARE_CAUSE("load guest page fault", CAUSE_LOAD_GUEST_PAGE_FAULT) DECLARE_CAUSE("virtual instruction", CAUSE_VIRTUAL_INSTRUCTION) diff --git a/riscv/insns/fmvh_x_d.h b/riscv/insns/fmvh_x_d.h index 961ad76..28abb60 100644 --- a/riscv/insns/fmvh_x_d.h +++ b/riscv/insns/fmvh_x_d.h @@ -4,4 +4,4 @@ require_extension(EXT_ZFA); require_fp; ui64_f64 ui; ui.f = FRS1_D; -WRITE_RD(ui.ui >> 32); +WRITE_RD(sext32(ui.ui >> 32)); diff --git a/riscv/insns/mop_r_N.h b/riscv/insns/mop_r_N.h new file mode 100644 index 0000000..fa2687e --- /dev/null +++ b/riscv/insns/mop_r_N.h @@ -0,0 +1,2 @@ +require_extension(EXT_ZIMOP); +WRITE_RD(0); diff --git a/riscv/insns/mop_rr_N.h b/riscv/insns/mop_rr_N.h new file mode 100644 index 0000000..fa2687e --- /dev/null +++ b/riscv/insns/mop_rr_N.h @@ -0,0 +1,2 @@ +require_extension(EXT_ZIMOP); +WRITE_RD(0); diff --git a/riscv/isa_parser.h b/riscv/isa_parser.h index a84b6fe..7773ba5 100644 --- a/riscv/isa_parser.h +++ b/riscv/isa_parser.h @@ -81,6 +81,7 @@ typedef enum { EXT_SMCSRIND, EXT_SSCSRIND, EXT_SMCNTRPMF, + EXT_ZIMOP, EXT_ZCMOP, EXT_ZALASR, NUM_ISA_EXTENSIONS diff --git a/riscv/mmu.cc b/riscv/mmu.cc index 285ef6d..165be53 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -387,7 +387,7 @@ reg_t mmu_t::pmp_homogeneous(reg_t addr, reg_t len) return true; } -reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_type, bool virt, bool hlvx) +reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_type, bool virt, bool hlvx, bool is_for_vs_pt_addr) { if (!virt) return gpa; @@ -400,6 +400,14 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty reg_t maxgpa = (1ULL << maxgpabits) - 1; bool mxr = proc->state.sstatus->readvirt(false) & MSTATUS_MXR; + // tinst is set to 0x3000/0x3020 - for RV64 read/write respectively for + // VS-stage address translation (for spike HSXLEN == VSXLEN always) else + // tinst is set to 0x2000/0x2020 - for RV32 read/write respectively for + // VS-stage address translation else set to 0 + int tinst = 0; + tinst |= (is_for_vs_pt_addr == true) ? 0x2000 : 0; + tinst |= ((proc->get_const_xlen() == 64) && (is_for_vs_pt_addr == true)) ? 0x1000 : 0; + tinst |= ((type == STORE) && (is_for_vs_pt_addr == true)) ? 0x0020 : 0; reg_t base = vm.ptbase; if ((gpa & ~maxgpa) == 0) { @@ -466,9 +474,9 @@ reg_t mmu_t::s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_ty } switch (trap_type) { - case FETCH: throw trap_instruction_guest_page_fault(gva, gpa >> 2, 0); - case LOAD: throw trap_load_guest_page_fault(gva, gpa >> 2, 0); - case STORE: throw trap_store_guest_page_fault(gva, gpa >> 2, 0); + case FETCH: throw trap_instruction_guest_page_fault(gva, gpa >> 2, tinst); + case LOAD: throw trap_load_guest_page_fault(gva, gpa >> 2, tinst); + case STORE: throw trap_store_guest_page_fault(gva, gpa >> 2, tinst); default: abort(); } } @@ -484,7 +492,7 @@ reg_t mmu_t::walk(mem_access_info_t access_info) reg_t satp = proc->get_state()->satp->readvirt(virt); vm_info vm = decode_vm_info(proc->get_const_xlen(), false, mode, satp); if (vm.levels == 0) - return s2xlate(addr, addr & ((reg_t(2) << (proc->xlen-1))-1), type, type, virt, hlvx) & ~page_mask; // zero-extend from xlen + return s2xlate(addr, addr & ((reg_t(2) << (proc->xlen-1))-1), type, type, virt, hlvx, false) & ~page_mask; // zero-extend from xlen bool s_mode = mode == PRV_S; bool sum = proc->state.sstatus->readvirt(virt) & MSTATUS_SUM; @@ -503,7 +511,7 @@ reg_t mmu_t::walk(mem_access_info_t access_info) reg_t idx = (addr >> (PGSHIFT + ptshift)) & ((1 << vm.idxbits) - 1); // check that physical address of PTE is legal - auto pte_paddr = s2xlate(addr, base + idx * vm.ptesize, LOAD, type, virt, false); + auto pte_paddr = s2xlate(addr, base + idx * vm.ptesize, LOAD, type, virt, false, true); reg_t pte = pte_load(pte_paddr, addr, virt, type, vm.ptesize); reg_t ppn = (pte & ~reg_t(PTE_ATTR)) >> PTE_PPN_SHIFT; bool pbmte = virt ? (proc->get_state()->henvcfg->read() & HENVCFG_PBMTE) : (proc->get_state()->menvcfg->read() & MENVCFG_PBMTE); @@ -536,6 +544,9 @@ reg_t mmu_t::walk(mem_access_info_t access_info) if ((pte & ad) != ad) { if (hade) { + // Check for write permission to the first-stage PT in second-stage + // PTE and set the D bit in the second-stage PTE if needed + s2xlate(addr, base + idx * vm.ptesize, STORE, type, virt, false, true); // set accessed and possibly dirty bits. pte_store(pte_paddr, pte | ad, addr, virt, type, vm.ptesize); } else { @@ -555,7 +566,7 @@ reg_t mmu_t::walk(mem_access_info_t access_info) | (vpn & ((reg_t(1) << napot_bits) - 1)) | (vpn & ((reg_t(1) << ptshift) - 1))) << PGSHIFT; reg_t phys = page_base | (addr & page_mask); - return s2xlate(addr, phys, type, type, virt, hlvx) & ~page_mask; + return s2xlate(addr, phys, type, type, virt, hlvx, false) & ~page_mask; } } diff --git a/riscv/mmu.h b/riscv/mmu.h index ce50527..a163fe4 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -391,7 +391,7 @@ private: const char* fill_from_mmio(reg_t vaddr, reg_t paddr); // perform a stage2 translation for a given guest address - reg_t s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_type, bool virt, bool hlvx); + reg_t s2xlate(reg_t gva, reg_t gpa, access_type type, access_type trap_type, bool virt, bool hlvx, bool is_for_vs_pt_addr); // perform a page table walk for a given VA; set referenced/dirty bits reg_t walk(mem_access_info_t access_info); diff --git a/riscv/processor.cc b/riscv/processor.cc index 5a43d56..1bb1fc9 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -54,7 +54,7 @@ processor_t::processor_t(const isa_parser_t *isa, const cfg_t *cfg, } #endif - parse_varch_string(cfg->varch()); + parse_varch_string(cfg->varch); register_base_instructions(); mmu = new mmu_t(sim, cfg->endianness, this); diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in index 76c2ed7..04747c9 100644 --- a/riscv/riscv.mk.in +++ b/riscv/riscv.mk.in @@ -1388,6 +1388,10 @@ riscv_insn_ext_zvksh = \ vsm3c_vi \ vsm3me_vv \ +riscv_insn_ext_zimop = \ + mop_r_N \ + mop_rr_N \ + riscv_insn_ext_zvk = \ $(riscv_insn_ext_zvbb) \ $(riscv_insn_ext_zvbc) \ @@ -1426,6 +1430,7 @@ riscv_insn_list = \ $(riscv_insn_priv) \ $(riscv_insn_smrnmi) \ $(riscv_insn_svinval) \ + $(riscv_insn_ext_zimop) \ riscv_gen_srcs = $(addsuffix .cc,$(riscv_insn_list)) diff --git a/riscv/sim.cc b/riscv/sim.cc index 639c68d..57e9630 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -46,7 +46,7 @@ sim_t::sim_t(const cfg_t *cfg, bool halted, bool socket_enabled, FILE *cmd_file) // needed for command line option --cmd : htif_t(args), - isa(cfg->isa(), cfg->priv()), + isa(cfg->isa, cfg->priv), cfg(cfg), mems(mems), procs(std::max(cfg->nprocs(), size_t(1))), @@ -99,9 +99,9 @@ sim_t::sim_t(const cfg_t *cfg, bool halted, debug_mmu = new mmu_t(this, cfg->endianness, NULL); for (size_t i = 0; i < cfg->nprocs(); i++) { - procs[i] = new processor_t(&isa, cfg, this, cfg->hartids()[i], halted, + procs[i] = new processor_t(&isa, cfg, this, cfg->hartids[i], halted, log_file.get(), sout_); - harts[cfg->hartids()[i]] = procs[i]; + harts[cfg->hartids[i]] = procs[i]; } // When running without using a dtb, skip the fdt-based configuration steps @@ -134,13 +134,13 @@ sim_t::sim_t(const cfg_t *cfg, bool halted, strstream << fin.rdbuf(); dtb = strstream.str(); } else { - std::pair<reg_t, reg_t> initrd_bounds = cfg->initrd_bounds(); + std::pair<reg_t, reg_t> initrd_bounds = cfg->initrd_bounds; std::string device_nodes; for (const device_factory_t *factory : device_factories) device_nodes.append(factory->generate_dts(this)); dts = make_dts(INSNS_PER_RTC_TICK, CPU_HZ, initrd_bounds.first, initrd_bounds.second, - cfg->bootargs(), cfg->pmpregions, cfg->pmpgranularity, + cfg->bootargs, cfg->pmpregions, cfg->pmpgranularity, procs, mems, device_nodes); dtb = dts_compile(dts); } diff --git a/riscv/zvk_ext_macros.h b/riscv/zvk_ext_macros.h index 75aa56a..f094629 100644 --- a/riscv/zvk_ext_macros.h +++ b/riscv/zvk_ext_macros.h @@ -750,7 +750,7 @@ // - 'rs1', unsigned, SEW width, by value, constant. #define VI_ZVK_VX_WIDENING_ULOOP(BODY) \ do { \ - VI_CHECK_DSS(true); \ + VI_CHECK_DSS(false); \ VI_LOOP_BASE \ switch (sew) { \ case e8: { \ @@ -788,7 +788,7 @@ // - 'zimm5', unsigned, SEW width, by value, constant. #define VI_ZVK_VI_WIDENING_ULOOP(BODY) \ do { \ - VI_CHECK_DSS(true); \ + VI_CHECK_DSS(false); \ VI_LOOP_BASE \ switch (sew) { \ case e8: { \ diff --git a/spike_main/spike-log-parser.cc b/spike_main/spike-log-parser.cc index 6ac4ab0..a054e95 100644 --- a/spike_main/spike-log-parser.cc +++ b/spike_main/spike-log-parser.cc @@ -28,19 +28,7 @@ int main(int UNUSED argc, char** argv) parser.option(0, "isa", 1, [&](const char* s){isa_string = s;}); parser.parse(argv); - cfg_t cfg(/*default_initrd_bounds=*/std::make_pair((reg_t)0, (reg_t)0), - /*default_bootargs=*/nullptr, - /*default_isa=*/DEFAULT_ISA, - /*default_priv=*/DEFAULT_PRIV, - /*default_varch=*/DEFAULT_VARCH, - /*default_misaligned=*/false, - /*default_endianness*/endianness_little, - /*default_pmpregions=*/16, - /*default_pmpgranularity=*/(1 << PMP_SHIFT), - /*default_mem_layout=*/std::vector<mem_cfg_t>(), - /*default_hartids=*/std::vector<size_t>(), - /*default_real_time_clint=*/false, - /*default_trigger_count=*/4); + cfg_t cfg; isa_parser_t isa(isa_string, DEFAULT_PRIV); processor_t p(&isa, &cfg, 0, 0, false, nullptr, cerr); diff --git a/spike_main/spike.cc b/spike_main/spike.cc index 5376ab9..b5a1ce4 100644 --- a/spike_main/spike.cc +++ b/spike_main/spike.cc @@ -348,32 +348,10 @@ int main(int argc, char** argv) bool use_rbb = false; unsigned dmi_rti = 0; reg_t blocksz = 64; - debug_module_config_t dm_config = { - .progbufsize = 2, - .max_sba_data_width = 0, - .require_authentication = false, - .abstract_rti = 0, - .support_hasel = true, - .support_abstract_csr_access = true, - .support_abstract_fpr_access = true, - .support_haltgroups = true, - .support_impebreak = true - }; + debug_module_config_t dm_config; cfg_arg_t<size_t> nprocs(1); - cfg_t cfg(/*default_initrd_bounds=*/std::make_pair((reg_t)0, (reg_t)0), - /*default_bootargs=*/nullptr, - /*default_isa=*/DEFAULT_ISA, - /*default_priv=*/DEFAULT_PRIV, - /*default_varch=*/DEFAULT_VARCH, - /*default_misaligned=*/false, - /*default_endianness*/endianness_little, - /*default_pmpregions=*/16, - /*default_pmpgranularity=*/(1 << PMP_SHIFT), - /*default_mem_layout=*/parse_mem_layout("2048"), - /*default_hartids=*/std::vector<size_t>(), - /*default_real_time_clint=*/false, - /*default_trigger_count=*/4); + cfg_t cfg; auto const device_parser = [&plugin_device_factories](const char *s) { const std::string device_args(s); @@ -493,10 +471,10 @@ int main(int argc, char** argv) help(); std::vector<std::pair<reg_t, abstract_mem_t*>> mems = - make_mems(cfg.mem_layout()); + make_mems(cfg.mem_layout); if (kernel && check_file_exists(kernel)) { - const char *isa = cfg.isa(); + const char *isa = cfg.isa; kernel_size = get_file_size(kernel); if (isa[2] == '6' && isa[3] == '4') kernel_offset = 0x200000; |