aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscv/abstract_device.h7
-rw-r--r--riscv/clint.cc2
-rw-r--r--riscv/csr_init.cc21
-rw-r--r--riscv/csrs.cc6
-rw-r--r--riscv/mmu.cc14
-rw-r--r--riscv/mmu.h1
-rw-r--r--riscv/ns16550.cc2
-rw-r--r--riscv/plic.cc2
-rw-r--r--riscv/processor.cc7
-rw-r--r--riscv/processor.h2
-rw-r--r--riscv/sim.cc25
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);