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); }