diff --git a/incl/iss/arch/riscv_hart_common.h b/incl/iss/arch/riscv_hart_common.h
index 8f79290..f8584be 100644
--- a/incl/iss/arch/riscv_hart_common.h
+++ b/incl/iss/arch/riscv_hart_common.h
@@ -214,6 +214,14 @@ struct vm_info {
bool is_active() { return levels; }
};
+struct feature_config {
+ uint64_t clic_base{0xc0000000};
+ unsigned clic_num_irq{16};
+ unsigned clic_num_trigger{0};
+ uint64_t tcm_base{0x10000000};
+ uint64_t tcm_size{0x8000};
+};
+
class trap_load_access_fault : public trap_access {
public:
trap_load_access_fault(uint64_t badaddr)
diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h
index 722e221..ae5031f 100644
--- a/incl/iss/arch/riscv_hart_mu_p.h
+++ b/incl/iss/arch/riscv_hart_mu_p.h
@@ -197,7 +197,7 @@ public:
return traits::MISA_VAL&0b0100?~1:~3;
}
- riscv_hart_mu_p();
+ riscv_hart_mu_p(feature_config cfg = feature_config{});
virtual ~riscv_hart_mu_p() = default;
void reset(uint64_t address) override;
@@ -363,23 +363,22 @@ protected:
std::vector> memfn_read;
std::vector> memfn_write;
void insert_mem_range(uint64_t, uint64_t, std::function, std::function);
- uint64_t clic_base_addr{0};
- unsigned clic_num_irq{0};
- unsigned clic_num_trigger{0};
+ feature_config cfg;
unsigned mcause_max_irq{16};
inline bool debug_mode_active() {return this->reg.PRIV&0x4;}
};
template
-riscv_hart_mu_p::riscv_hart_mu_p()
+riscv_hart_mu_p::riscv_hart_mu_p(feature_config cfg)
: state()
-, instr_if(*this) {
+, instr_if(*this)
+, cfg(cfg) {
// reset values
csr[misa] = traits::MISA_VAL;
csr[mvendorid] = 0x669;
csr[marchid] = traits::MARCHID_VAL;
csr[mimpid] = 1;
- csr[mclicbase] = 0xc0000000; // TODO: should be taken from YAML file
+ csr[mclicbase] = cfg.clic_base; // TODO: should be taken from YAML file
uart_buf.str("");
for (unsigned addr = mhpmcounter3; addr <= mhpmcounter31; ++addr){
@@ -485,29 +484,27 @@ riscv_hart_mu_p::riscv_hart_mu_p()
csr_rd_cb[mclicbase] = &this_class::read_csr_reg;
csr_wr_cb[mclicbase] = &this_class::write_null;
- clic_base_addr=0xC0000000;
- clic_num_irq=16;
- clic_int_reg.resize(clic_num_irq);
+ clic_int_reg.resize(cfg.clic_num_irq);
clic_cfg_reg=0x20;
- clic_info_reg = (/*CLICINTCTLBITS*/ 4U<<21) + clic_num_irq;
- mcause_max_irq=clic_num_irq+16;
- insert_mem_range(clic_base_addr, 0x5000UL,
+ clic_info_reg = (/*CLICINTCTLBITS*/ 4U<<21) + cfg.clic_num_irq;
+ mcause_max_irq=cfg.clic_num_irq+16;
+ insert_mem_range(cfg.clic_base, 0x5000UL,
[this](phys_addr_t addr, unsigned length, uint8_t * const data) { return read_clic(addr.val, length, data);},
[this](phys_addr_t addr, unsigned length, uint8_t const * const data) {return write_clic(addr.val, length, data);});
}
if(FEAT & FEAT_TCM) {
- tcm.resize(0x8000);
+ tcm.resize(cfg.tcm_size);
std::function read_clic_cb = [this](phys_addr_t addr, unsigned length, uint8_t * const data) {
- auto offset=addr.val-0x10000000;
+ auto offset=addr.val-this->cfg.tcm_base;
std::copy(tcm.data() + offset, tcm.data() + offset + length, data);
return iss::Ok;
};
std::function write_clic_cb = [this](phys_addr_t addr, unsigned length, uint8_t const * const data) {
- auto offset=addr.val-0x10000000;
+ auto offset=addr.val-this->cfg.tcm_base;
std::copy(data, data + length, tcm.data() + offset);
return iss::Ok;
};
- insert_mem_range(0x10000000, 0x8000UL, read_clic_cb, write_clic_cb);
+ insert_mem_range(cfg.tcm_base, cfg.tcm_size, read_clic_cb, write_clic_cb);
}
if(FEAT & FEAT_DEBUG){
csr_wr_cb[dscratch0] = &this_class::write_dcsr_reg;
@@ -1239,15 +1236,15 @@ iss::status riscv_hart_mu_p::write_mem(phys_addr_t paddr, unsigned l
template
iss::status riscv_hart_mu_p::read_clic(uint64_t addr, unsigned length, uint8_t *const data) {
- if(addr==clic_base_addr) { // cliccfg
+ if(addr==cfg.clic_base) { // cliccfg
*data=clic_cfg_reg;
for(auto i=1; i=(clic_base_addr+4) && (addr+length)<=(clic_base_addr+8)){ // clicinfo
+ } else if(addr>=(cfg.clic_base+4) && (addr+length)<=(cfg.clic_base+8)){ // clicinfo
read_reg_uint32(addr, clic_info_reg, data, length);
- } else if(addr>=(clic_base_addr+0x40) && (addr+length)<=(clic_base_addr+0x40+clic_num_trigger*4)){ // clicinttrig
+ } else if(addr>=(cfg.clic_base+0x40) && (addr+length)<=(cfg.clic_base+0x40+cfg.clic_num_trigger*4)){ // clicinttrig
auto offset = ((addr&0x7fff)-0x40)/4;
read_reg_uint32(addr, clic_inttrig_reg[offset], data, length);
- } else if(addr>=(clic_base_addr+0x1000) && (addr+length)<=(clic_base_addr+clic_num_irq*4)){ // clicintip/clicintie/clicintattr/clicintctl
+ } else if(addr>=(cfg.clic_base+0x1000) && (addr+length)<=(cfg.clic_base+cfg.clic_num_irq*4)){ // clicintip/clicintie/clicintattr/clicintctl
auto offset = ((addr&0x7fff)-0x1000)/4;
read_reg_uint32(addr, clic_int_reg[offset].raw, data, length);
} else {
@@ -1258,15 +1255,15 @@ iss::status riscv_hart_mu_p::read_clic(uint64_t addr, unsigned lengt
template
iss::status riscv_hart_mu_p::write_clic(uint64_t addr, unsigned length, const uint8_t *const data) {
- if(addr==clic_base_addr) { // cliccfg
+ if(addr==cfg.clic_base) { // cliccfg
clic_cfg_reg = *data;
clic_cfg_reg&= 0x7e;
-// } else if(addr>=(clic_base_addr+4) && (addr+length)<=(clic_base_addr+4)){ // clicinfo
+// } else if(addr>=(cfg.clic_base+4) && (addr+length)<=(cfg.clic_base+4)){ // clicinfo
// write_uint32(addr, clic_info_reg, data, length);
- } else if(addr>=(clic_base_addr+0x40) && (addr+length)<=(clic_base_addr+0xC0)){ // clicinttrig
+ } else if(addr>=(cfg.clic_base+0x40) && (addr+length)<=(cfg.clic_base+0xC0)){ // clicinttrig
auto offset = ((addr&0x7fff)-0x40)/4;
write_reg_uint32(addr, clic_inttrig_reg[offset], data, length);
- } else if(addr>=(clic_base_addr+0x1000) && (addr+length)<=(clic_base_addr+clic_num_irq*4)){ // clicintip/clicintie/clicintattr/clicintctl
+ } else if(addr>=(cfg.clic_base+0x1000) && (addr+length)<=(cfg.clic_base+cfg.clic_num_irq*4)){ // clicintip/clicintie/clicintattr/clicintctl
auto offset = ((addr&0x7fff)-0x1000)/4;
write_reg_uint32(addr, clic_int_reg[offset].raw, data, length);
}