diff --git a/src/iss/arch/riscv_hart_m_p.h b/src/iss/arch/riscv_hart_m_p.h
index 8365a5d..59b16f9 100644
--- a/src/iss/arch/riscv_hart_m_p.h
+++ b/src/iss/arch/riscv_hart_m_p.h
@@ -182,7 +182,7 @@ public:
return traits::MISA_VAL&0b0100?~1:~3;
}
- riscv_hart_m_p();
+ riscv_hart_m_p(feature_config cfg = feature_config{});
virtual ~riscv_hart_m_p() = default;
void reset(uint64_t address) override;
@@ -194,9 +194,9 @@ public:
iss::status write(const address_type type, const access_type access, const uint32_t space,
const uint64_t addr, const unsigned length, const uint8_t *const data) override;
- virtual uint64_t enter_trap(uint64_t flags) override { return riscv_hart_m_p::enter_trap(flags, fault_data, fault_data); }
- virtual uint64_t enter_trap(uint64_t flags, uint64_t addr, uint64_t instr) override;
- virtual uint64_t leave_trap(uint64_t flags) override;
+ uint64_t enter_trap(uint64_t flags) override { return riscv_hart_m_p::enter_trap(flags, fault_data, fault_data); }
+ uint64_t enter_trap(uint64_t flags, uint64_t addr, uint64_t instr) override;
+ uint64_t leave_trap(uint64_t flags) override;
const reg_t& get_mhartid() const { return mhartid_reg; }
void set_mhartid(reg_t mhartid) { mhartid_reg = mhartid; };
@@ -208,14 +208,6 @@ public:
iss::instrumentation_if *get_instrumentation_if() override { return &instr_if; }
- void setMemReadCb(std::function const& memReadCb) {
- mem_read_cb = memReadCb;
- }
-
- void setMemWriteCb(std::function const& memWriteCb) {
- mem_write_cb = memWriteCb;
- }
-
void set_csr(unsigned addr, reg_t val){
csr[addr & csr.page_addr_mask] = val;
}
@@ -337,8 +329,6 @@ protected:
}
reg_t mhartid_reg{0x0};
- std::functionmem_read_cb;
- std::function mem_write_cb;
void check_interrupt();
bool pmp_check(const access_type type, const uint64_t addr, const unsigned len);
@@ -346,23 +336,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_m_p::riscv_hart_m_p()
+riscv_hart_m_p::riscv_hart_m_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){
@@ -385,7 +374,10 @@ riscv_hart_m_p::riscv_hart_m_p()
//csr_wr_cb[addr] = &this_class::write_csr_reg;
}
// common regs
- const std::array addrs{{misa, mvendorid, marchid, mimpid, mepc, mtvec, mscratch, mcause, mtval, mscratch}};
+ const std::array addrs{{
+ misa, mvendorid, marchid, mimpid,
+ mepc, mtvec, mscratch, mcause, mtval
+ }};
for(auto addr: addrs) {
csr_rd_cb[addr] = &this_class::read_csr_reg;
csr_wr_cb[addr] = &this_class::write_csr_reg;
@@ -416,6 +408,8 @@ riscv_hart_m_p::riscv_hart_m_p()
csr_rd_cb[mie] = &this_class::read_ie;
csr_wr_cb[mie] = &this_class::write_ie;
csr_rd_cb[mhartid] = &this_class::read_hartid;
+ csr_rd_cb[mcounteren] = &this_class::read_null;
+ csr_wr_cb[mcounteren] = &this_class::write_null;
csr_wr_cb[misa] = &this_class::write_null;
csr_wr_cb[mvendorid] = &this_class::write_null;
csr_wr_cb[marchid] = &this_class::write_null;
@@ -436,29 +430,27 @@ riscv_hart_m_p::riscv_hart_m_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_int_reg_t{.raw=0});
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;
@@ -582,7 +574,7 @@ iss::status riscv_hart_m_p::read(const address_type type, const acce
}
auto phys_addr = type==iss::address_type::PHYSICAL?phys_addr_t{access, space, addr}:BASE::v2p(iss::addr_t{access, type, space, addr});
auto res = iss::Err;
- if(!is_fetch(access) && memfn_range.size()){
+ if(access != access_type::FETCH && memfn_range.size()){
auto it = std::find_if(std::begin(memfn_range), std::end(memfn_range), [phys_addr](std::tuple const& a){
return std::get<0>(a)<=phys_addr.val && (std::get<0>(a)+std::get<1>(a))>phys_addr.val;
});
@@ -863,7 +855,7 @@ template iss::status riscv_hart_m_p
}
template iss::status riscv_hart_m_p::read_tvec(unsigned addr, reg_t &val) {
- val = csr[mtvec] & ~2;
+ val = csr[addr] & ~2;
return iss::Ok;
}
@@ -879,7 +871,7 @@ template iss::status riscv_hart_m_p
}
template iss::status riscv_hart_m_p::write_cause(unsigned addr, reg_t val) {
- csr[mcause] = val & ((1UL<<(traits::XLEN-1))| (mcause_max_irq-1));
+ csr[addr] = val & ((1UL<<(traits::XLEN-1))| (mcause_max_irq-1));
return iss::Ok;
}
@@ -959,7 +951,6 @@ iss::status riscv_hart_m_p::write_intthresh(unsigned addr, reg_t val
template
iss::status riscv_hart_m_p::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) {
- if(mem_read_cb) return mem_read_cb(paddr, length, data);
switch (paddr.val) {
case 0x0200BFF8: { // CLINT base, mtime reg
if (sizeof(reg_t) < length) return iss::Err;
@@ -984,14 +975,12 @@ iss::status riscv_hart_m_p::read_mem(phys_addr_t paddr, unsigned len
template
iss::status riscv_hart_m_p::write_mem(phys_addr_t paddr, unsigned length, const uint8_t *const data) {
- if(mem_write_cb) return mem_write_cb(paddr, length, data);
switch (paddr.val) {
case 0x10013000: // UART0 base, TXFIFO reg
case 0x10023000: // UART1 base, TXFIFO reg
uart_buf << (char)data[0];
if (((char)data[0]) == '\n' || data[0] == 0) {
- // LOG(INFO)<<"UART"<<((paddr.val>>16)&0x3)<<" send
- // '"<>16)&0x3)<<" send '"<::write_mem(phys_addr_t paddr, unsigned le
template
iss::status riscv_hart_m_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+0x1000+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 {
@@ -1081,17 +1070,18 @@ iss::status riscv_hart_m_p::read_clic(uint64_t addr, unsigned length
template
iss::status riscv_hart_m_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+0x40+cfg.clic_num_trigger*4)){ // 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+0x1000+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);
+ clic_int_reg[offset].raw &= 0xf0c70101; // clicIntCtlBits->0xf0, clicintattr->0xc7, clicintie->0x1, clicintip->0x1
}
return iss::Ok;
}
@@ -1109,8 +1099,8 @@ template void riscv_hart_m_p::check
// any synchronous traps.
auto ena_irq = csr[mip] & csr[mie];
- bool mie = state.mstatus.MIE;
- auto m_enabled = this->reg.PRIV < PRIV_M || (this->reg.PRIV == PRIV_M && mie);
+ bool mstatus_mie = state.mstatus.MIE;
+ auto m_enabled = this->reg.PRIV < PRIV_M || mstatus_mie;
auto enabled_interrupts = m_enabled ? ena_irq : 0;
if (enabled_interrupts != 0) {
diff --git a/src/iss/arch/riscv_hart_msu_vp.h b/src/iss/arch/riscv_hart_msu_vp.h
index a742d08..54e93fd 100644
--- a/src/iss/arch/riscv_hart_msu_vp.h
+++ b/src/iss/arch/riscv_hart_msu_vp.h
@@ -312,14 +312,6 @@ public:
iss::instrumentation_if *get_instrumentation_if() override { return &instr_if; }
- void setMemReadCb(std::function const& memReadCb) {
- mem_read_cb = memReadCb;
- }
-
- void setMemWriteCb(std::function const& memWriteCb) {
- mem_write_cb = memWriteCb;
- }
-
void set_csr(unsigned addr, reg_t val){
csr[addr & csr.page_addr_mask] = val;
}
@@ -422,8 +414,6 @@ private:
}
reg_t mhartid_reg{0x0};
- std::functionmem_read_cb;
- std::function mem_write_cb;
protected:
void check_interrupt();
@@ -1031,7 +1021,6 @@ template iss::status riscv_hart_msu_vp::write_fcsr(unsigne
template
iss::status riscv_hart_msu_vp::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) {
- if(mem_read_cb) return mem_read_cb(paddr, length, data);
switch (paddr.val) {
case 0x0200BFF8: { // CLINT base, mtime reg
if (sizeof(reg_t) < length) return iss::Err;
@@ -1056,7 +1045,6 @@ iss::status riscv_hart_msu_vp::read_mem(phys_addr_t paddr, unsigned length
template
iss::status riscv_hart_msu_vp::write_mem(phys_addr_t paddr, unsigned length, const uint8_t *const data) {
- if(mem_write_cb) return mem_write_cb(paddr, length, data);
switch (paddr.val) {
case 0x10013000: // UART0 base, TXFIFO reg
case 0x10023000: // UART1 base, TXFIFO reg
diff --git a/src/iss/arch/riscv_hart_mu_p.h b/src/iss/arch/riscv_hart_mu_p.h
index 55c8f0c..eb05618 100644
--- a/src/iss/arch/riscv_hart_mu_p.h
+++ b/src/iss/arch/riscv_hart_mu_p.h
@@ -223,14 +223,6 @@ public:
iss::instrumentation_if *get_instrumentation_if() override { return &instr_if; }
- void setMemReadCb(std::function const& memReadCb) {
- mem_read_cb = memReadCb;
- }
-
- void setMemWriteCb(std::function const& memWriteCb) {
- mem_write_cb = memWriteCb;
- }
-
void set_csr(unsigned addr, reg_t val){
csr[addr & csr.page_addr_mask] = val;
}
@@ -250,26 +242,24 @@ protected:
*/
const std::string core_type_name() const override { return traits::core_type; }
- virtual uint64_t get_pc() { return arch.get_pc(); };
+ uint64_t get_pc() override { return arch.reg.PC; };
- virtual uint64_t get_next_pc() { return arch.get_next_pc(); };
+ uint64_t get_next_pc() override { return arch.reg.NEXT_PC; };
uint64_t get_instr_word() override { return arch.instruction; }
- uint64_t get_instr_count() { return arch.icount; }
+ uint64_t get_instr_count() override { return arch.icount; }
uint64_t get_pendig_traps() override { return arch.trap_state; }
uint64_t get_total_cycles() override { return arch.icount + arch.cycle_offset; }
- virtual void set_curr_instr_cycles(unsigned cycles) { arch.cycle_offset += cycles - 1; };
+ void set_curr_instr_cycles(unsigned cycles) override { arch.cycle_offset += cycles - 1; };
riscv_hart_mu_p &arch;
};
friend struct riscv_instrumentation_if;
- addr_t get_pc() { return this->reg.PC; }
- addr_t get_next_pc() { return this->reg.NEXT_PC; }
virtual iss::status read_mem(phys_addr_t addr, unsigned length, uint8_t *const data);
virtual iss::status write_mem(phys_addr_t addr, unsigned length, const uint8_t *const data);
@@ -357,8 +347,6 @@ protected:
}
reg_t mhartid_reg{0x0};
- std::functionmem_read_cb;
- std::function mem_write_cb;
void check_interrupt();
bool pmp_check(const access_type type, const uint64_t addr, const unsigned len);
@@ -1020,14 +1008,12 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::read_status(unsigned addr, reg_t &val) {
- auto req_priv_lvl = (addr >> 8) & 0x3;
- val = state.mstatus & hart_state_type::get_mask(req_priv_lvl);
+ val = state.mstatus & hart_state_type::get_mask((addr >> 8) & 0x3);
return iss::Ok;
}
template iss::status riscv_hart_mu_p::write_status(unsigned addr, reg_t val) {
- auto req_priv_lvl = (addr >> 8) & 0x3;
- state.write_mstatus(val, req_priv_lvl);
+ state.write_mstatus(val, (addr >> 8) & 0x3);
check_interrupt();
return iss::Ok;
}
@@ -1129,7 +1115,6 @@ iss::status riscv_hart_mu_p::write_intthresh(unsigned addr, reg_t va
template
iss::status riscv_hart_mu_p::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) {
- if(mem_read_cb) return mem_read_cb(paddr, length, data);
switch (paddr.val) {
case 0x0200BFF8: { // CLINT base, mtime reg
if (sizeof(reg_t) < length) return iss::Err;
@@ -1154,7 +1139,6 @@ iss::status riscv_hart_mu_p::read_mem(phys_addr_t paddr, unsigned le
template
iss::status riscv_hart_mu_p::write_mem(phys_addr_t paddr, unsigned length, const uint8_t *const data) {
- if(mem_write_cb) return mem_write_cb(paddr, length, data);
switch (paddr.val) {
case 0x10013000: // UART0 base, TXFIFO reg
case 0x10023000: // UART1 base, TXFIFO reg
@@ -1279,8 +1263,8 @@ template void riscv_hart_mu_p::chec
// any synchronous traps.
auto ena_irq = csr[mip] & csr[mie];
- bool mie = state.mstatus.MIE;
- auto m_enabled = this->reg.PRIV < PRIV_M || mie;
+ bool mstatus_mie = state.mstatus.MIE;
+ auto m_enabled = this->reg.PRIV < PRIV_M || mstatus_mie;
auto enabled_interrupts = m_enabled ? ena_irq & ~ideleg : 0;
if (enabled_interrupts != 0) {