fixes sysc compile issues

This commit is contained in:
Eyck Jentzsch 2023-06-12 09:58:24 +02:00
parent 0b5de90fb1
commit 99a9970ddd
4 changed files with 50 additions and 48 deletions

View File

@ -316,6 +316,9 @@ public:
csr[addr & csr.page_addr_mask] = val;
}
void set_irq_num(unsigned i) {
mcause_max_irq=1<<util::ilog2(i);
}
protected:
struct riscv_instrumentation_if : public iss::instrumentation_if {
@ -328,21 +331,21 @@ protected:
*/
const std::string core_type_name() const override { return traits<BASE>::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_word() override { return arch.reg.instruction; }
uint64_t get_instr_count() { return arch.icount; }
uint64_t get_instr_count() override { return arch.reg.icount; }
uint64_t get_pendig_traps() override { return arch.trap_state; }
uint64_t get_pendig_traps() override { return arch.reg.trap_state; }
uint64_t get_total_cycles() override { return arch.icount + arch.cycle_offset; }
uint64_t get_total_cycles() override { return arch.reg.icount + arch.cycle_offset; }
void update_last_instr_cycles(unsigned cycles) override { arch.cycle_offset += cycles - 1; };
bool is_branch_taken() override { return arch.last_branch; };
bool is_branch_taken() override { return arch.reg.last_branch; };
riscv_hart_msu_vp<BASE> &arch;
};
@ -381,16 +384,17 @@ protected:
std::unordered_map<unsigned, rd_csr_f> csr_rd_cb;
std::unordered_map<unsigned, wr_csr_f> csr_wr_cb;
private:
iss::status read_reg(unsigned addr, reg_t &val);
iss::status write_reg(unsigned addr, reg_t val);
std::vector<uint8_t> tcm;
iss::status read_csr_reg(unsigned addr, reg_t &val);
iss::status write_csr_reg(unsigned addr, reg_t val);
iss::status read_null(unsigned addr, reg_t &val);
iss::status write_null(unsigned addr, reg_t val){return iss::status::Ok;}
iss::status read_cycle(unsigned addr, reg_t &val);
iss::status write_cycle(unsigned addr, reg_t val);
iss::status read_instret(unsigned addr, reg_t &val);
iss::status write_instret(unsigned addr, reg_t val);
iss::status read_mtvec(unsigned addr, reg_t &val);
iss::status read_tvec(unsigned addr, reg_t &val);
iss::status read_time(unsigned addr, reg_t &val);
iss::status read_status(unsigned addr, reg_t &val);
iss::status write_status(unsigned addr, reg_t val);
@ -398,6 +402,8 @@ private:
iss::status read_ie(unsigned addr, reg_t &val);
iss::status write_ie(unsigned addr, reg_t val);
iss::status read_ip(unsigned addr, reg_t &val);
iss::status write_ideleg(unsigned addr, reg_t val);
iss::status write_edeleg(unsigned addr, reg_t val);
iss::status read_hartid(unsigned addr, reg_t &val);
iss::status write_epc(unsigned addr, reg_t val);
iss::status read_satp(unsigned addr, reg_t &val);
@ -417,7 +423,6 @@ private:
reg_t mhartid_reg{0x0};
protected:
void check_interrupt();
};
@ -434,22 +439,22 @@ riscv_hart_msu_vp<BASE>::riscv_hart_msu_vp()
uart_buf.str("");
for (unsigned addr = mhpmcounter3; addr <= mhpmcounter31; ++addr){
csr_rd_cb[addr] = &this_class::read_null;
csr_wr_cb[addr] = &this_class::write_reg;
csr_wr_cb[addr] = &this_class::write_csr_reg;
}
for (unsigned addr = mhpmcounter3h; addr <= mhpmcounter31h; ++addr){
csr_rd_cb[addr] = &this_class::read_null;
csr_wr_cb[addr] = &this_class::write_reg;
csr_wr_cb[addr] = &this_class::write_csr_reg;
}
for (unsigned addr = mhpmevent3; addr <= mhpmevent31; ++addr){
csr_rd_cb[addr] = &this_class::read_null;
csr_wr_cb[addr] = &this_class::write_reg;
csr_wr_cb[addr] = &this_class::write_csr_reg;
}
for (unsigned addr = hpmcounter3; addr <= hpmcounter31; ++addr){
csr_rd_cb[addr] = &this_class::read_null;
}
for (unsigned addr = cycleh; addr <= hpmcounter31h; ++addr){
csr_rd_cb[addr] = &this_class::read_null;
//csr_wr_cb[addr] = &this_class::write_reg;
//csr_wr_cb[addr] = &this_class::write_csr_reg;
}
// common regs
const std::array<unsigned, 22> addrs{{
@ -459,25 +464,25 @@ riscv_hart_msu_vp<BASE>::riscv_hart_msu_vp()
uepc, utvec, uscratch, ucause, utval, uscratch
}};
for(auto addr: addrs) {
csr_rd_cb[addr] = &this_class::read_reg;
csr_wr_cb[addr] = &this_class::write_reg;
csr_rd_cb[addr] = &this_class::read_csr_reg;
csr_wr_cb[addr] = &this_class::write_csr_reg;
}
// special handling & overrides
csr_rd_cb[time] = &this_class::read_time;
csr_rd_cb[timeh] = &this_class::read_time;
if(traits<BASE>::XLEN==32) csr_rd_cb[timeh] = &this_class::read_time;
csr_rd_cb[cycle] = &this_class::read_cycle;
csr_rd_cb[cycleh] = &this_class::read_cycle;
if(traits<BASE>::XLEN==32) csr_rd_cb[cycleh] = &this_class::read_cycle;
csr_rd_cb[instret] = &this_class::read_instret;
csr_rd_cb[instreth] = &this_class::read_instret;
if(traits<BASE>::XLEN==32) csr_rd_cb[instreth] = &this_class::read_instret;
csr_rd_cb[mcycle] = &this_class::read_cycle;
csr_wr_cb[mcycle] = &this_class::write_cycle;
csr_rd_cb[mcycleh] = &this_class::read_cycle;
csr_wr_cb[mcycleh] = &this_class::write_cycle;
if(traits<BASE>::XLEN==32) csr_rd_cb[mcycleh] = &this_class::read_cycle;
if(traits<BASE>::XLEN==32) csr_wr_cb[mcycleh] = &this_class::write_cycle;
csr_rd_cb[minstret] = &this_class::read_instret;
csr_wr_cb[minstret] = &this_class::write_instret;
csr_rd_cb[minstreth] = &this_class::read_instret;
csr_wr_cb[minstreth] = &this_class::write_instret;
if(traits<BASE>::XLEN==32) csr_rd_cb[minstreth] = &this_class::read_instret;
if(traits<BASE>::XLEN==32) csr_wr_cb[minstreth] = &this_class::write_instret;
csr_rd_cb[mstatus] = &this_class::read_status;
csr_wr_cb[mstatus] = &this_class::write_status;
csr_wr_cb[mcause] = &this_class::write_cause;
@ -527,10 +532,10 @@ template <typename BASE> std::pair<uint64_t, bool> riscv_hart_msu_vp<BASE>::load
if (fp) {
std::array<char, 5> buf;
auto n = fread(buf.data(), 1, 4, fp);
fclose(fp);
if (n != 4) throw std::runtime_error("input file has insufficient size");
buf[4] = 0;
if (strcmp(buf.data() + 1, "ELF") == 0) {
fclose(fp);
// Create elfio reader
ELFIO::elfio reader;
// Load ELF data
@ -549,7 +554,7 @@ template <typename BASE> std::pair<uint64_t, bool> riscv_hart_msu_vp<BASE>::load
traits<BASE>::MEM, pseg->get_physical_address(),
fsize, reinterpret_cast<const uint8_t *const>(seg_data));
if (res != iss::Ok)
LOG(ERROR) << "problem writing " << fsize << "bytes to 0x" << std::hex
LOG(ERR) << "problem writing " << fsize << "bytes to 0x" << std::hex
<< pseg->get_physical_address();
}
}
@ -673,7 +678,7 @@ iss::status riscv_hart_msu_vp<BASE>::read(const address_type type, const access_
}
return iss::Ok;
} catch (trap_access &ta) {
this->reg.trap_state = (1 << 31) | ta.id;
this->reg.trap_state = (1UL << 31) | ta.id;
fault_data=ta.addr;
return iss::Err;
}
@ -730,12 +735,12 @@ iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access
write_mem(phys_addr_t{access, space, addr}, length, data):
write_mem(BASE::v2p(iss::addr_t{access, type, space, addr}), length, data);
if (unlikely(res != iss::Ok)) {
this->reg.trap_state = (1 << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault)
this->reg.trap_state = (1UL << 31) | (7UL << 16); // issue trap 7 (Store/AMO access fault)
fault_data=addr;
}
return res;
} catch (trap_access &ta) {
this->reg.trap_state = (1 << 31) | ta.id;
this->reg.trap_state = (1UL << 31) | ta.id;
fault_data=ta.addr;
return iss::Err;
}
@ -800,7 +805,7 @@ iss::status riscv_hart_msu_vp<BASE>::write(const address_type type, const access
}
return iss::Ok;
} catch (trap_access &ta) {
this->reg.trap_state = (1 << 31) | ta.id;
this->reg.trap_state = (1UL << 31) | ta.id;
fault_data=ta.addr;
return iss::Err;
}
@ -858,8 +863,6 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_cycle(unsigne
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_cycle(unsigned addr, reg_t val) {
if (sizeof(typename traits<BASE>::reg_t) != 4) {
if (addr == mcycleh)
return iss::Err;
mcycle_csr = static_cast<uint64_t>(val);
} else {
if (addr == mcycle) {
@ -876,7 +879,6 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_instret(unsig
if ((addr&0xff) == (minstret&0xff)) {
val = static_cast<reg_t>(this->reg.instret);
} else if ((addr&0xff) == (minstreth&0xff)) {
if (sizeof(typename traits<BASE>::reg_t) != 4) return iss::Err;
val = static_cast<reg_t>(this->reg.instret >> 32);
}
return iss::Ok;
@ -884,8 +886,6 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_instret(unsig
template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_instret(unsigned addr, reg_t val) {
if (sizeof(typename traits<BASE>::reg_t) != 4) {
if ((addr&0xff) == (minstreth&0xff))
return iss::Err;
this->reg.instret = static_cast<uint64_t>(val);
} else {
if ((addr&0xff) == (minstret&0xff)) {
@ -1234,6 +1234,7 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t f
auto cur_priv = this->reg.PRIV;
// flags are ACTIVE[31:31], CAUSE[30:16], TRAPID[15:0]
// calculate and write mcause val
if(flags==std::numeric_limits<uint64_t>::max()) flags=this->reg.trap_state;
auto trap_id = bit_sub<0, 16>(flags);
auto cause = bit_sub<16, 15>(flags);
if (trap_id == 0 && cause == 11) cause = 0x8 + cur_priv; // adjust environment call cause

View File

@ -284,6 +284,7 @@ public:
}
riscv_hart_mu_p(feature_config cfg = feature_config{});
virtual ~riscv_hart_mu_p() = default;
void reset(uint64_t address) override;
@ -332,17 +333,17 @@ protected:
uint64_t get_next_pc() override { return arch.reg.NEXT_PC; };
uint64_t get_instr_word() override { return arch.instruction; }
uint64_t get_instr_word() override { return arch.reg.instruction; }
uint64_t get_instr_count() override { return arch.icount; }
uint64_t get_instr_count() override { return arch.reg.icount; }
uint64_t get_pendig_traps() override { return arch.trap_state; }
uint64_t get_pendig_traps() override { return arch.reg.trap_state; }
uint64_t get_total_cycles() override { return arch.icount + arch.cycle_offset; }
uint64_t get_total_cycles() override { return arch.reg.icount + arch.cycle_offset; }
void update_last_instr_cycles(unsigned cycles) override { arch.cycle_offset += cycles - 1; };
bool is_branch_taken() override { return arch.last_branch; };
bool is_branch_taken() override { return arch.reg.last_branch; };
riscv_hart_mu_p<BASE, FEAT> &arch;
};
@ -949,7 +950,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT>::write(const address_type type, const ac
res = hart_mem_wr_delegate( phys_addr, length, data);
}
if (unlikely(res != iss::Ok)) {
this->reg.trap_state = (1UL << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault)
this->reg.trap_state = (1UL << 31) | (7UL << 16); // issue trap 7 (Store/AMO access fault)
fault_data=addr;
}
return res;

View File

@ -118,7 +118,7 @@ public:
std::stringstream s;
s << "[p:" << lvl[this->reg.PRIV] << ";s:0x" << std::hex << std::setfill('0')
<< std::setw(sizeof(reg_t) * 2) << (reg_t)this->state.mstatus << std::dec << ";c:"
<< this->icount + this->cycle_offset << "]";
<< this->reg.icount + this->cycle_offset << "]";
SCCDEBUG(owner->name())<<"disass: "
<< "0x" << std::setw(16) << std::right << std::setfill('0') << std::hex << pc << "\t\t" << std::setw(40)
<< std::setfill(' ') << std::left << instr << s.str();
@ -178,7 +178,7 @@ public:
void wait_until(uint64_t flags) override {
SCCDEBUG(owner->name()) << "Sleeping until interrupt";
while(this->pending_trap == 0 && (this->csr[arch::mip] & this->csr[arch::mie]) == 0) {
while(this->reg.pending_trap == 0 && (this->csr[arch::mip] & this->csr[arch::mie]) == 0) {
sc_core::wait(wfi_evt);
}
PLAT::wait_until(flags);
@ -207,7 +207,7 @@ public:
this->csr[arch::mip] &= ~mask;
this->check_interrupt();
if(value)
SCCTRACE(owner->name()) << "Triggering interrupt " << id << " Pending trap: " << this->pending_trap;
SCCTRACE(owner->name()) << "Triggering interrupt " << id << " Pending trap: " << this->reg.pending_trap;
}
private: