diff options
-rw-r--r-- | riscv/abstract_device.h | 7 | ||||
-rw-r--r-- | riscv/clint.cc | 2 | ||||
-rw-r--r-- | riscv/csr_init.cc | 21 | ||||
-rw-r--r-- | riscv/csrs.cc | 6 | ||||
-rw-r--r-- | riscv/mmu.cc | 14 | ||||
-rw-r--r-- | riscv/mmu.h | 1 | ||||
-rw-r--r-- | riscv/ns16550.cc | 2 | ||||
-rw-r--r-- | riscv/plic.cc | 2 | ||||
-rw-r--r-- | riscv/processor.cc | 7 | ||||
-rw-r--r-- | riscv/processor.h | 2 | ||||
-rw-r--r-- | riscv/sim.cc | 25 |
11 files changed, 48 insertions, 41 deletions
diff --git a/riscv/abstract_device.h b/riscv/abstract_device.h index d8ddbab..41f5c3f 100644 --- a/riscv/abstract_device.h +++ b/riscv/abstract_device.h @@ -46,4 +46,11 @@ mmio_device_map_t& mmio_device_map(); std::string generate_dts(const sim_t* sim, const std::vector<std::string>& sargs) const override { return generate(sim, sargs); } \ }; device_factory_t *name##_factory = new name##_factory_t(); +#define REGISTER_BUILTIN_DEVICE(name, parse, generate) \ + class name##_factory_t : public device_factory_t { \ + public: \ + name##_t* parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base, const std::vector<std::string>& sargs) const override { return parse(fdt, sim, base, sargs); } \ + std::string generate_dts(const sim_t* sim, const std::vector<std::string>& sargs) const override { return generate(sim, sargs); } \ + }; device_factory_t *name##_factory = new name##_factory_t(); + #endif diff --git a/riscv/clint.cc b/riscv/clint.cc index 3d5c984..e16ebdd 100644 --- a/riscv/clint.cc +++ b/riscv/clint.cc @@ -145,4 +145,4 @@ std::string clint_generate_dts(const sim_t* sim, const std::vector<std::string>& return s.str(); } -REGISTER_DEVICE(clint, clint_parse_from_fdt, clint_generate_dts) +REGISTER_BUILTIN_DEVICE(clint, clint_parse_from_fdt, clint_generate_dts) diff --git a/riscv/csr_init.cc b/riscv/csr_init.cc index 0acd1c7..24ff498 100644 --- a/riscv/csr_init.cc +++ b/riscv/csr_init.cc @@ -430,6 +430,17 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa) auto sireg = std::make_shared<sscsrind_reg_csr_t>(proc, CSR_SIREG, siselect); add_ireg_proxy(proc, sireg); add_supervisor_csr(CSR_SIREG, std::make_shared<virtualized_indirect_csr_t>(proc, sireg, vsireg)); + if (proc->extension_enabled(EXT_SSCCFG) || proc->extension_enabled(EXT_SMCDELEG)) { + // case CSR_SIREG + if (proc->extension_enabled_const(EXT_ZICNTR)) { + sireg->add_ireg_proxy(SISELECT_SMCDELEG_START, mcycle); + sireg->add_ireg_proxy(SISELECT_SMCDELEG_INSTRET, minstret); + } + if (proc->extension_enabled_const(EXT_ZIHPM)) { + for (size_t j = 0; j < (SISELECT_SMCDELEG_END - SISELECT_SMCDELEG_HPMEVENT_3 + 1); j++) + sireg->add_ireg_proxy(SISELECT_SMCDELEG_HPMCOUNTER_3 + j, csrmap[CSR_HPMCOUNTER3 + j]); + } + } const reg_t vsireg_csrs[] = { CSR_VSIREG2, CSR_VSIREG3, CSR_VSIREG4, CSR_VSIREG5, CSR_VSIREG6 }; const reg_t sireg_csrs[] = { CSR_SIREG2, CSR_SIREG3, CSR_SIREG4, CSR_SIREG5, CSR_SIREG6 }; @@ -443,16 +454,6 @@ void state_t::csr_init(processor_t* const proc, reg_t max_isa) // Smcdeleg if (proc->extension_enabled(EXT_SSCCFG) || proc->extension_enabled(EXT_SMCDELEG)) { switch (sireg_csrs[i]) { - case CSR_SIREG: - if (proc->extension_enabled_const(EXT_ZICNTR)) { - sireg->add_ireg_proxy(SISELECT_SMCDELEG_START, mcycle); - sireg->add_ireg_proxy(SISELECT_SMCDELEG_INSTRET, minstret); - } - if (proc->extension_enabled_const(EXT_ZIHPM)) { - for (size_t j = 0; j < (SISELECT_SMCDELEG_END - SISELECT_SMCDELEG_HPMEVENT_3 + 1); j++) - sireg->add_ireg_proxy(SISELECT_SMCDELEG_HPMCOUNTER_3 + j, csrmap[CSR_HPMCOUNTER3 + j]); - } - break; case CSR_SIREG4: if (xlen == 32) { if (proc->extension_enabled_const(EXT_ZICNTR)) { diff --git a/riscv/csrs.cc b/riscv/csrs.cc index 3a32712..76f600d 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -121,7 +121,7 @@ bool pmpaddr_csr_t::unlogged_write(const reg_t val) noexcept { const bool locked = !lock_bypass && (cfg & PMP_L); if (pmpidx < proc->n_pmp && !locked && !next_locked_and_tor()) { - this->val = val & ((reg_t(1) << (MAX_PADDR_BITS - PMP_SHIFT)) - 1); + this->val = val & ((reg_t(1) << (proc->paddr_bits() - PMP_SHIFT)) - 1); } else return false; @@ -1098,7 +1098,7 @@ bool base_atp_csr_t::satp_valid(reg_t val) const noexcept { } reg_t base_atp_csr_t::compute_new_satp(reg_t val) const noexcept { - reg_t rv64_ppn_mask = (reg_t(1) << (MAX_PADDR_BITS - PGSHIFT)) - 1; + reg_t rv64_ppn_mask = (reg_t(1) << (proc->paddr_bits() - PGSHIFT)) - 1; reg_t mode_mask = proc->get_xlen() == 32 ? SATP32_MODE : SATP64_MODE; reg_t asid_mask_if_enabled = proc->get_xlen() == 32 ? SATP32_ASID : SATP64_ASID; @@ -1326,7 +1326,7 @@ bool hgatp_csr_t::unlogged_write(const reg_t val) noexcept { HGATP32_MODE | (proc->supports_impl(IMPL_MMU_VMID) ? HGATP32_VMID : 0); } else { - mask = (HGATP64_PPN & ((reg_t(1) << (MAX_PADDR_BITS - PGSHIFT)) - 1)) | + mask = (HGATP64_PPN & ((reg_t(1) << (proc->paddr_bits() - PGSHIFT)) - 1)) | (proc->supports_impl(IMPL_MMU_VMID) ? HGATP64_VMID : 0); if (get_field(val, HGATP64_MODE) == HGATP_MODE_OFF || diff --git a/riscv/mmu.cc b/riscv/mmu.cc index 30fc47a..b080697 100644 --- a/riscv/mmu.cc +++ b/riscv/mmu.cc @@ -369,8 +369,18 @@ void mmu_t::store_slow_path(reg_t original_addr, reg_t len, const uint8_t* bytes store_slow_path_intrapage(len, bytes, access_info, actually_store); } - if (actually_store && proc && unlikely(proc->get_log_commits_enabled())) - proc->state.log_mem_write.push_back(std::make_tuple(original_addr, reg_from_bytes(len, bytes), len)); + if (actually_store && proc && unlikely(proc->get_log_commits_enabled())) { + // amocas.q sends len == 16, reg_from_bytes only supports up to 8 + // bytes per conversion. Make multiple entries in the log + reg_t offset = 0; + const auto reg_size = sizeof(reg_t); + while (unlikely(len > reg_size)) { + proc->state.log_mem_write.push_back(std::make_tuple(original_addr + offset, reg_from_bytes(reg_size, bytes + offset), reg_size)); + offset += reg_size; + len -= reg_size; + } + proc->state.log_mem_write.push_back(std::make_tuple(original_addr + offset, reg_from_bytes(len, bytes + offset), len)); + } } tlb_entry_t mmu_t::refill_tlb(reg_t vaddr, reg_t paddr, char* host_addr, access_type type) diff --git a/riscv/mmu.h b/riscv/mmu.h index 94f3a97..48340cf 100644 --- a/riscv/mmu.h +++ b/riscv/mmu.h @@ -18,7 +18,6 @@ // virtual memory configuration #define PGSHIFT 12 const reg_t PGSIZE = 1 << PGSHIFT; -#define MAX_PADDR_BITS 64 // observability hooks for load, store and fetch // intentionally empty not to cause runtime overhead diff --git a/riscv/ns16550.cc b/riscv/ns16550.cc index 15e0873..4bda6f4 100644 --- a/riscv/ns16550.cc +++ b/riscv/ns16550.cc @@ -361,4 +361,4 @@ ns16550_t* ns16550_parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base } } -REGISTER_DEVICE(ns16550, ns16550_parse_from_fdt, ns16550_generate_dts) +REGISTER_BUILTIN_DEVICE(ns16550, ns16550_parse_from_fdt, ns16550_generate_dts) diff --git a/riscv/plic.cc b/riscv/plic.cc index b6d204b..0310538 100644 --- a/riscv/plic.cc +++ b/riscv/plic.cc @@ -436,4 +436,4 @@ plic_t* plic_parse_from_fdt(const void* fdt, const sim_t* sim, reg_t* base, cons return nullptr; } -REGISTER_DEVICE(plic, plic_parse_from_fdt, plic_generate_dts) +REGISTER_BUILTIN_DEVICE(plic, plic_parse_from_fdt, plic_generate_dts) diff --git a/riscv/processor.cc b/riscv/processor.cc index f11cfc0..6d914f0 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -607,13 +607,6 @@ void processor_t::disasm(insn_t insn) } } -int processor_t::paddr_bits() -{ - unsigned max_xlen = isa.get_max_xlen(); - assert(xlen == max_xlen); - return max_xlen == 64 ? 50 : 34; -} - void processor_t::put_csr(int which, reg_t val) { val = zext_xlen(val); diff --git a/riscv/processor.h b/riscv/processor.h index cc2897a..4ca3ce7 100644 --- a/riscv/processor.h +++ b/riscv/processor.h @@ -273,6 +273,7 @@ public: mmu_t* get_mmu() { return mmu; } state_t* get_state() { return &state; } unsigned get_xlen() const { return xlen; } + unsigned paddr_bits() { return isa.get_max_xlen() == 64 ? 56 : 34; } unsigned get_const_xlen() const { // Any code that assumes a const xlen should use this method to // document that assumption. If Spike ever changes to allow @@ -421,7 +422,6 @@ private: void take_trigger_action(triggers::action_t action, reg_t breakpoint_tval, reg_t epc, bool virt); void disasm(insn_t insn); // disassemble and print an instruction void register_insn(insn_desc_t, bool); - int paddr_bits(); void enter_debug_mode(uint8_t cause, uint8_t ext_cause); diff --git a/riscv/sim.cc b/riscv/sim.cc index 388d729..fb643d6 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -118,8 +118,8 @@ sim_t::sim_t(const cfg_t *cfg, bool halted, // particular, the default device tree configuration that you get without // setting the dtb_file argument has one. std::vector<device_factory_sargs_t> device_factories = { - {clint_factory, {}}, // clint must be element 0 - {plic_factory, {}}, // plic must be element 1 + {clint_factory, {}}, + {plic_factory, {}}, {ns16550_factory, {}}}; device_factories.insert(device_factories.end(), plugin_device_factories.begin(), @@ -253,10 +253,15 @@ sim_t::sim_t(const cfg_t *cfg, bool halted, std::shared_ptr<abstract_device_t> dev_ptr(device); add_device(device_base, dev_ptr); - if (i == 0) // clint_factory + if (dynamic_cast<clint_t*>(&*dev_ptr)) { + assert(!clint); clint = std::static_pointer_cast<clint_t>(dev_ptr); - else if (i == 1) // plic_factory + } + + if (dynamic_cast<plic_t*>(&*dev_ptr)) { + assert(!plic); plic = std::static_pointer_cast<plic_t>(dev_ptr); + } } } } @@ -337,22 +342,16 @@ void sim_t::set_procs_debug(bool value) procs[i]->set_debug(value); } -static bool paddr_ok(reg_t addr) -{ - static_assert(MAX_PADDR_BITS == 8 * sizeof(addr)); - return true; -} - bool sim_t::mmio_load(reg_t paddr, size_t len, uint8_t* bytes) { - if (paddr + len < paddr || !paddr_ok(paddr + len - 1)) + if (paddr + len < paddr) return false; return bus.load(paddr, len, bytes); } bool sim_t::mmio_store(reg_t paddr, size_t len, const uint8_t* bytes) { - if (paddr + len < paddr || !paddr_ok(paddr + len - 1)) + if (paddr + len < paddr) return false; return bus.store(paddr, len, bytes); } @@ -403,8 +402,6 @@ void sim_t::set_rom() } char* sim_t::addr_to_mem(reg_t paddr) { - if (!paddr_ok(paddr)) - return NULL; auto desc = bus.find_device(paddr >> PGSHIFT << PGSHIFT, PGSIZE); if (auto mem = dynamic_cast<abstract_mem_t*>(desc.second)) return mem->contents(paddr - desc.first); |