applies clang-format

This commit is contained in:
Eyck Jentzsch 2024-07-24 14:48:50 +02:00
parent 5a2b96ef3e
commit e87b7d5fd0
2 changed files with 143 additions and 78 deletions

View File

@ -61,7 +61,8 @@
namespace iss { namespace iss {
namespace arch { namespace arch {
template <typename BASE, features_e FEAT = FEAT_NONE, typename LOGCAT=logging::disass> class riscv_hart_m_p : public BASE, public riscv_hart_common { template <typename BASE, features_e FEAT = FEAT_NONE, typename LOGCAT = logging::disass>
class riscv_hart_m_p : public BASE, public riscv_hart_common {
protected: protected:
const std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}}; const std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
const std::array<const char*, 16> trap_str = {{"" const std::array<const char*, 16> trap_str = {{""
@ -276,7 +277,7 @@ public:
void disass_output(uint64_t pc, const std::string instr) override { void disass_output(uint64_t pc, const std::string instr) override {
NSCLOG(INFO, LOGCAT) << fmt::format("0x{:016x} {:40} [s:0x{:x};c:{}]", pc, instr, (reg_t)state.mstatus, NSCLOG(INFO, LOGCAT) << fmt::format("0x{:016x} {:40} [s:0x{:x};c:{}]", pc, instr, (reg_t)state.mstatus,
this->reg.icount + cycle_offset); this->reg.icount + cycle_offset);
}; };
iss::instrumentation_if* get_instrumentation_if() override { return &instr_if; } iss::instrumentation_if* get_instrumentation_if() override { return &instr_if; }
@ -564,7 +565,8 @@ riscv_hart_m_p<BASE, FEAT, LOGCAT>::riscv_hart_m_p(feature_config cfg)
hart_mem_wr_delegate = [this](phys_addr_t a, unsigned l, uint8_t const* const d) -> iss::status { return this->write_mem(a, l, d); }; hart_mem_wr_delegate = [this](phys_addr_t a, unsigned l, uint8_t const* const d) -> iss::status { return this->write_mem(a, l, d); };
} }
template <typename BASE, features_e FEAT, typename LOGCAT> std::pair<uint64_t, bool> riscv_hart_m_p<BASE, FEAT, LOGCAT>::load_file(std::string name, int type) { template <typename BASE, features_e FEAT, typename LOGCAT>
std::pair<uint64_t, bool> riscv_hart_m_p<BASE, FEAT, LOGCAT>::load_file(std::string name, int type) {
get_sym_table(name); get_sym_table(name);
try { try {
tohost = symbol_table.at("tohost"); tohost = symbol_table.at("tohost");
@ -620,7 +622,7 @@ template <typename BASE, features_e FEAT, typename LOGCAT> std::pair<uint64_t, b
template <typename BASE, features_e FEAT, typename LOGCAT> template <typename BASE, features_e FEAT, typename LOGCAT>
inline void riscv_hart_m_p<BASE, FEAT, LOGCAT>::insert_mem_range(uint64_t base, uint64_t size, std::function<mem_read_f> rd_f, inline void riscv_hart_m_p<BASE, FEAT, LOGCAT>::insert_mem_range(uint64_t base, uint64_t size, std::function<mem_read_f> rd_f,
std::function<mem_write_f> wr_fn) { std::function<mem_write_f> wr_fn) {
std::tuple<uint64_t, uint64_t> entry{base, size}; std::tuple<uint64_t, uint64_t> entry{base, size};
auto it = std::upper_bound( auto it = std::upper_bound(
memfn_range.begin(), memfn_range.end(), entry, memfn_range.begin(), memfn_range.end(), entry,
@ -632,8 +634,8 @@ inline void riscv_hart_m_p<BASE, FEAT, LOGCAT>::insert_mem_range(uint64_t base,
} }
template <typename BASE, features_e FEAT, typename LOGCAT> template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read(const address_type type, const access_type access, const uint32_t space, const uint64_t addr, iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read(const address_type type, const access_type access, const uint32_t space,
const unsigned length, uint8_t* const data) { const uint64_t addr, const unsigned length, uint8_t* const data) {
#ifndef NDEBUG #ifndef NDEBUG
if(access && iss::access_type::DEBUG) { if(access && iss::access_type::DEBUG) {
CPPLOG(TRACEALL) << "debug read of " << length << " bytes @addr 0x" << std::hex << addr; CPPLOG(TRACEALL) << "debug read of " << length << " bytes @addr 0x" << std::hex << addr;
@ -716,8 +718,8 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read(const address_type type, co
} }
template <typename BASE, features_e FEAT, typename LOGCAT> template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write(const address_type type, const access_type access, const uint32_t space, const uint64_t addr, iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write(const address_type type, const access_type access, const uint32_t space,
const unsigned length, const uint8_t* const data) { const uint64_t addr, const unsigned length, const uint8_t* const data) {
#ifndef NDEBUG #ifndef NDEBUG
const char* prefix = (access && iss::access_type::DEBUG) ? "debug " : ""; const char* prefix = (access && iss::access_type::DEBUG) ? "debug " : "";
switch(length) { switch(length) {
@ -848,7 +850,8 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write(const address_type type, c
} }
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_csr(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_csr(unsigned addr, reg_t& val) {
if(addr >= csr.size()) if(addr >= csr.size())
return iss::Err; return iss::Err;
auto req_priv_lvl = (addr >> 8) & 0x3; auto req_priv_lvl = (addr >> 8) & 0x3;
@ -860,7 +863,8 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return (this->*(it->second))(addr, val); return (this->*(it->second))(addr, val);
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_csr(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_csr(unsigned addr, reg_t val) {
if(addr >= csr.size()) if(addr >= csr.size())
return iss::Err; return iss::Err;
auto req_priv_lvl = (addr >> 8) & 0x3; auto req_priv_lvl = (addr >> 8) & 0x3;
@ -874,22 +878,26 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return (this->*(it->second))(addr, val); return (this->*(it->second))(addr, val);
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_csr_reg(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_csr_reg(unsigned addr, reg_t& val) {
val = csr[addr]; val = csr[addr];
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_null(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_null(unsigned addr, reg_t& val) {
val = 0; val = 0;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_csr_reg(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_csr_reg(unsigned addr, reg_t val) {
csr[addr] = val; csr[addr] = val;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_cycle(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_cycle(unsigned addr, reg_t& val) {
auto cycle_val = this->reg.icount + cycle_offset; auto cycle_val = this->reg.icount + cycle_offset;
if(addr == mcycle) { if(addr == mcycle) {
val = static_cast<reg_t>(cycle_val); val = static_cast<reg_t>(cycle_val);
@ -899,7 +907,8 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_cycle(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_cycle(unsigned addr, reg_t val) {
if(sizeof(typename traits<BASE>::reg_t) != 4) { if(sizeof(typename traits<BASE>::reg_t) != 4) {
mcycle_csr = static_cast<uint64_t>(val); mcycle_csr = static_cast<uint64_t>(val);
} else { } else {
@ -913,7 +922,8 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_instret(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_instret(unsigned addr, reg_t& val) {
if((addr & 0xff) == (minstret & 0xff)) { if((addr & 0xff) == (minstret & 0xff)) {
val = static_cast<reg_t>(this->reg.instret); val = static_cast<reg_t>(this->reg.instret);
} else if((addr & 0xff) == (minstreth & 0xff)) { } else if((addr & 0xff) == (minstreth & 0xff)) {
@ -922,7 +932,8 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_instret(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_instret(unsigned addr, reg_t val) {
if(sizeof(typename traits<BASE>::reg_t) != 4) { if(sizeof(typename traits<BASE>::reg_t) != 4) {
this->reg.instret = static_cast<uint64_t>(val); this->reg.instret = static_cast<uint64_t>(val);
} else { } else {
@ -936,7 +947,8 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_time(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_time(unsigned addr, reg_t& val) {
uint64_t time_val = this->reg.icount / (100000000 / 32768 - 1); //-> ~3052; uint64_t time_val = this->reg.icount / (100000000 / 32768 - 1); //-> ~3052;
if(addr == time) { if(addr == time) {
val = static_cast<reg_t>(time_val); val = static_cast<reg_t>(time_val);
@ -948,23 +960,27 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_tvec(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_tvec(unsigned addr, reg_t& val) {
val = FEAT & features_e::FEAT_CLIC ? csr[addr] : csr[addr] & ~2; val = FEAT & features_e::FEAT_CLIC ? csr[addr] : csr[addr] & ~2;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_status(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_status(unsigned addr, reg_t& val) {
val = state.mstatus & hart_state_type::get_mask(); val = state.mstatus & hart_state_type::get_mask();
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_status(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_status(unsigned addr, reg_t val) {
state.write_mstatus(val); state.write_mstatus(val);
check_interrupt(); check_interrupt();
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_cause(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_cause(unsigned addr, reg_t& val) {
if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec] & 0x3) == 3) { if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec] & 0x3) == 3) {
val = csr[addr] & ((1UL << (traits<BASE>::XLEN - 1)) | (mcause_max_irq - 1) | (0xfUL << 16)); val = csr[addr] & ((1UL << (traits<BASE>::XLEN - 1)) | (mcause_max_irq - 1) | (0xfUL << 16));
val |= clic_mprev_lvl << 16; val |= clic_mprev_lvl << 16;
@ -975,7 +991,8 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_cause(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_cause(unsigned addr, reg_t val) {
if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec] & 0x3) == 3) { if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec] & 0x3) == 3) {
auto mask = ((1UL << (traits<BASE>::XLEN - 1)) | (mcause_max_irq - 1) | (0xfUL << 16)); auto mask = ((1UL << (traits<BASE>::XLEN - 1)) | (mcause_max_irq - 1) | (0xfUL << 16));
csr[addr] = (val & mask) | (csr[addr] & ~mask); csr[addr] = (val & mask) | (csr[addr] & ~mask);
@ -989,36 +1006,42 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_hartid(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_hartid(unsigned addr, reg_t& val) {
val = mhartid_reg; val = mhartid_reg;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_ie(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_ie(unsigned addr, reg_t& val) {
auto mask = get_irq_mask(); auto mask = get_irq_mask();
val = csr[mie] & mask; val = csr[mie] & mask;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_ie(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_ie(unsigned addr, reg_t val) {
auto mask = get_irq_mask(); auto mask = get_irq_mask();
csr[mie] = (csr[mie] & ~mask) | (val & mask); csr[mie] = (csr[mie] & ~mask) | (val & mask);
check_interrupt(); check_interrupt();
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_ip(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_ip(unsigned addr, reg_t& val) {
auto mask = get_irq_mask(); auto mask = get_irq_mask();
val = csr[mip] & mask; val = csr[mip] & mask;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_epc(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_epc(unsigned addr, reg_t val) {
csr[addr] = val & get_pc_mask(); csr[addr] = val & get_pc_mask();
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_dcsr_dcsr(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_dcsr_dcsr(unsigned addr, reg_t val) {
if(!debug_mode_active()) if(!debug_mode_active())
throw illegal_instruction_fault(this->fault_data); throw illegal_instruction_fault(this->fault_data);
// +-------------- ebreakm // +-------------- ebreakm
@ -1029,45 +1052,52 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_dcsr_reg(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_dcsr_reg(unsigned addr, reg_t& val) {
if(!debug_mode_active()) if(!debug_mode_active())
throw illegal_instruction_fault(this->fault_data); throw illegal_instruction_fault(this->fault_data);
val = csr[addr]; val = csr[addr];
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_dcsr_reg(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_dcsr_reg(unsigned addr, reg_t val) {
if(!debug_mode_active()) if(!debug_mode_active())
throw illegal_instruction_fault(this->fault_data); throw illegal_instruction_fault(this->fault_data);
csr[addr] = val; csr[addr] = val;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_dpc_reg(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_dpc_reg(unsigned addr, reg_t& val) {
if(!debug_mode_active()) if(!debug_mode_active())
throw illegal_instruction_fault(this->fault_data); throw illegal_instruction_fault(this->fault_data);
val = this->reg.DPC; val = this->reg.DPC;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_dpc_reg(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_dpc_reg(unsigned addr, reg_t val) {
if(!debug_mode_active()) if(!debug_mode_active())
throw illegal_instruction_fault(this->fault_data); throw illegal_instruction_fault(this->fault_data);
this->reg.DPC = val; this->reg.DPC = val;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_intstatus(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_intstatus(unsigned addr, reg_t& val) {
val = (clic_mact_lvl & 0xff) << 24; val = (clic_mact_lvl & 0xff) << 24;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_intthresh(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_intthresh(unsigned addr, reg_t val) {
csr[addr] = (val & 0xff) | (1 << (cfg.clic_int_ctl_bits)) - 1; csr[addr] = (val & 0xff) | (1 << (cfg.clic_int_ctl_bits)) - 1;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_xtvt(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_xtvt(unsigned addr, reg_t val) {
csr[addr] = val & ~0x3fULL; csr[addr] = val & ~0x3fULL;
return iss::Ok; return iss::Ok;
} }
@ -1207,7 +1237,8 @@ template <typename BASE, features_e FEAT, typename LOGCAT> void riscv_hart_m_p<B
} }
} }
template <typename BASE, features_e FEAT, typename LOGCAT> uint64_t riscv_hart_m_p<BASE, FEAT, LOGCAT>::enter_trap(uint64_t flags, uint64_t addr, uint64_t tval) { template <typename BASE, features_e FEAT, typename LOGCAT>
uint64_t riscv_hart_m_p<BASE, FEAT, LOGCAT>::enter_trap(uint64_t flags, uint64_t addr, uint64_t tval) {
// flags are ACTIVE[31:31], CAUSE[30:16], TRAPID[15:0] // flags are ACTIVE[31:31], CAUSE[30:16], TRAPID[15:0]
// calculate and write mcause val // calculate and write mcause val
auto const trap_id = bit_sub<0, 16>(flags); auto const trap_id = bit_sub<0, 16>(flags);
@ -1317,8 +1348,8 @@ template <typename BASE, features_e FEAT, typename LOGCAT> uint64_t riscv_hart_m
#endif #endif
if((flags & 0xffffffff) != 0xffffffff) if((flags & 0xffffffff) != 0xffffffff)
NSCLOG(INFO, LOGCAT) << (trap_id ? "Interrupt" : "Trap") << " with cause '" << (trap_id ? irq_str[cause] : trap_str[cause]) << "' (" NSCLOG(INFO, LOGCAT) << (trap_id ? "Interrupt" : "Trap") << " with cause '" << (trap_id ? irq_str[cause] : trap_str[cause]) << "' ("
<< cause << ")" << cause << ")"
<< " at address " << buffer.data() << " occurred"; << " at address " << buffer.data() << " occurred";
return this->reg.NEXT_PC; return this->reg.NEXT_PC;
} }

View File

@ -60,7 +60,8 @@
namespace iss { namespace iss {
namespace arch { namespace arch {
template <typename BASE, features_e FEAT = FEAT_NONE, typename LOGCAT=logging::disass> class riscv_hart_mu_p : public BASE, public riscv_hart_common { template <typename BASE, features_e FEAT = FEAT_NONE, typename LOGCAT = logging::disass>
class riscv_hart_mu_p : public BASE, public riscv_hart_common {
protected: protected:
const std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}}; const std::array<const char, 4> lvl = {{'U', 'S', 'H', 'M'}};
const std::array<const char*, 16> trap_str = {{"" const std::array<const char*, 16> trap_str = {{""
@ -641,7 +642,8 @@ riscv_hart_mu_p<BASE, FEAT, LOGCAT>::riscv_hart_mu_p(feature_config cfg)
hart_mem_wr_delegate = [this](phys_addr_t a, unsigned l, uint8_t const* const d) -> iss::status { return this->write_mem(a, l, d); }; hart_mem_wr_delegate = [this](phys_addr_t a, unsigned l, uint8_t const* const d) -> iss::status { return this->write_mem(a, l, d); };
} }
template <typename BASE, features_e FEAT, typename LOGCAT> std::pair<uint64_t, bool> riscv_hart_mu_p<BASE, FEAT, LOGCAT>::load_file(std::string name, int type) { template <typename BASE, features_e FEAT, typename LOGCAT>
std::pair<uint64_t, bool> riscv_hart_mu_p<BASE, FEAT, LOGCAT>::load_file(std::string name, int type) {
FILE* fp = fopen(name.c_str(), "r"); FILE* fp = fopen(name.c_str(), "r");
if(fp) { if(fp) {
std::array<char, 5> buf; std::array<char, 5> buf;
@ -711,7 +713,7 @@ template <typename BASE, features_e FEAT, typename LOGCAT> std::pair<uint64_t, b
template <typename BASE, features_e FEAT, typename LOGCAT> template <typename BASE, features_e FEAT, typename LOGCAT>
inline void riscv_hart_mu_p<BASE, FEAT, LOGCAT>::insert_mem_range(uint64_t base, uint64_t size, std::function<mem_read_f> rd_f, inline void riscv_hart_mu_p<BASE, FEAT, LOGCAT>::insert_mem_range(uint64_t base, uint64_t size, std::function<mem_read_f> rd_f,
std::function<mem_write_f> wr_fn) { std::function<mem_write_f> wr_fn) {
std::tuple<uint64_t, uint64_t> entry{base, size}; std::tuple<uint64_t, uint64_t> entry{base, size};
auto it = std::upper_bound( auto it = std::upper_bound(
memfn_range.begin(), memfn_range.end(), entry, memfn_range.begin(), memfn_range.end(), entry,
@ -722,7 +724,8 @@ inline void riscv_hart_mu_p<BASE, FEAT, LOGCAT>::insert_mem_range(uint64_t base,
memfn_write.insert(std::begin(memfn_write) + idx, wr_fn); memfn_write.insert(std::begin(memfn_write) + idx, wr_fn);
} }
template <typename BASE, features_e FEAT, typename LOGCAT> inline iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_pmpcfg_reg(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
inline iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_pmpcfg_reg(unsigned addr, reg_t val) {
csr[addr] = val & 0x9f9f9f9f; csr[addr] = val & 0x9f9f9f9f;
return iss::Ok; return iss::Ok;
} }
@ -809,8 +812,8 @@ bool riscv_hart_mu_p<BASE, FEAT, LOGCAT>::pmp_check(const access_type type, cons
} }
template <typename BASE, features_e FEAT, typename LOGCAT> template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read(const address_type type, const access_type access, const uint32_t space, const uint64_t addr, iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read(const address_type type, const access_type access, const uint32_t space,
const unsigned length, uint8_t* const data) { const uint64_t addr, const unsigned length, uint8_t* const data) {
#ifndef NDEBUG #ifndef NDEBUG
if(access && iss::access_type::DEBUG) { if(access && iss::access_type::DEBUG) {
CPPLOG(TRACEALL) << "debug read of " << length << " bytes @addr 0x" << std::hex << addr; CPPLOG(TRACEALL) << "debug read of " << length << " bytes @addr 0x" << std::hex << addr;
@ -902,8 +905,8 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read(const address_type type, c
} }
template <typename BASE, features_e FEAT, typename LOGCAT> template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write(const address_type type, const access_type access, const uint32_t space, const uint64_t addr, iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write(const address_type type, const access_type access, const uint32_t space,
const unsigned length, const uint8_t* const data) { const uint64_t addr, const unsigned length, const uint8_t* const data) {
#ifndef NDEBUG #ifndef NDEBUG
const char* prefix = (access && iss::access_type::DEBUG) ? "debug " : ""; const char* prefix = (access && iss::access_type::DEBUG) ? "debug " : "";
switch(length) { switch(length) {
@ -1043,7 +1046,8 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write(const address_type type,
} }
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_csr(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_csr(unsigned addr, reg_t& val) {
if(addr >= csr.size()) if(addr >= csr.size())
return iss::Err; return iss::Err;
auto req_priv_lvl = (addr >> 8) & 0x3; auto req_priv_lvl = (addr >> 8) & 0x3;
@ -1055,7 +1059,8 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return (this->*(it->second))(addr, val); return (this->*(it->second))(addr, val);
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_csr(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_csr(unsigned addr, reg_t val) {
if(addr >= csr.size()) if(addr >= csr.size())
return iss::Err; return iss::Err;
auto req_priv_lvl = (addr >> 8) & 0x3; auto req_priv_lvl = (addr >> 8) & 0x3;
@ -1069,22 +1074,26 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return (this->*(it->second))(addr, val); return (this->*(it->second))(addr, val);
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_csr_reg(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_csr_reg(unsigned addr, reg_t& val) {
val = csr[addr]; val = csr[addr];
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_null(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_null(unsigned addr, reg_t& val) {
val = 0; val = 0;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_csr_reg(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_csr_reg(unsigned addr, reg_t val) {
csr[addr] = val; csr[addr] = val;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_cycle(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_cycle(unsigned addr, reg_t& val) {
auto cycle_val = this->reg.icount + cycle_offset; auto cycle_val = this->reg.icount + cycle_offset;
if(addr == mcycle) { if(addr == mcycle) {
val = static_cast<reg_t>(cycle_val); val = static_cast<reg_t>(cycle_val);
@ -1094,7 +1103,8 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_cycle(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_cycle(unsigned addr, reg_t val) {
if(sizeof(typename traits<BASE>::reg_t) != 4) { if(sizeof(typename traits<BASE>::reg_t) != 4) {
mcycle_csr = static_cast<uint64_t>(val); mcycle_csr = static_cast<uint64_t>(val);
} else { } else {
@ -1108,7 +1118,8 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_instret(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_instret(unsigned addr, reg_t& val) {
if((addr & 0xff) == (minstret & 0xff)) { if((addr & 0xff) == (minstret & 0xff)) {
val = static_cast<reg_t>(this->reg.instret); val = static_cast<reg_t>(this->reg.instret);
} else if((addr & 0xff) == (minstreth & 0xff)) { } else if((addr & 0xff) == (minstreth & 0xff)) {
@ -1117,7 +1128,8 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_instret(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_instret(unsigned addr, reg_t val) {
if(sizeof(typename traits<BASE>::reg_t) != 4) { if(sizeof(typename traits<BASE>::reg_t) != 4) {
this->reg.instret = static_cast<uint64_t>(val); this->reg.instret = static_cast<uint64_t>(val);
} else { } else {
@ -1131,7 +1143,8 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_time(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_time(unsigned addr, reg_t& val) {
uint64_t time_val = this->reg.icount / (100000000 / 32768 - 1); //-> ~3052; uint64_t time_val = this->reg.icount / (100000000 / 32768 - 1); //-> ~3052;
if(addr == time) { if(addr == time) {
val = static_cast<reg_t>(time_val); val = static_cast<reg_t>(time_val);
@ -1143,22 +1156,26 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_tvec(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_tvec(unsigned addr, reg_t& val) {
val = FEAT & features_e::FEAT_CLIC ? csr[addr] : csr[addr] & ~2; val = FEAT & features_e::FEAT_CLIC ? csr[addr] : csr[addr] & ~2;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_status(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_status(unsigned addr, reg_t& val) {
val = state.mstatus & hart_state_type::get_mask((addr >> 8) & 0x3); val = state.mstatus & hart_state_type::get_mask((addr >> 8) & 0x3);
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_status(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_status(unsigned addr, reg_t val) {
state.write_mstatus(val, (addr >> 8) & 0x3); state.write_mstatus(val, (addr >> 8) & 0x3);
check_interrupt(); check_interrupt();
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_cause(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_cause(unsigned addr, reg_t& val) {
if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec] & 0x3) == 3) { if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec] & 0x3) == 3) {
val = csr[addr] & ((1UL << (traits<BASE>::XLEN - 1)) | (mcause_max_irq - 1) | (0xfUL << 16)); val = csr[addr] & ((1UL << (traits<BASE>::XLEN - 1)) | (mcause_max_irq - 1) | (0xfUL << 16));
auto mode = (addr >> 8) & 0x3; auto mode = (addr >> 8) & 0x3;
@ -1178,7 +1195,8 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_cause(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_cause(unsigned addr, reg_t val) {
if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec] & 0x3) == 3) { if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec] & 0x3) == 3) {
auto mask = ((1UL << (traits<BASE>::XLEN - 1)) | (mcause_max_irq - 1) | (0xfUL << 16)); auto mask = ((1UL << (traits<BASE>::XLEN - 1)) | (mcause_max_irq - 1) | (0xfUL << 16));
csr[addr] = (val & mask) | (csr[addr] & ~mask); csr[addr] = (val & mask) | (csr[addr] & ~mask);
@ -1201,12 +1219,14 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_hartid(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_hartid(unsigned addr, reg_t& val) {
val = mhartid_reg; val = mhartid_reg;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_ie(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_ie(unsigned addr, reg_t& val) {
auto mask = get_irq_mask((addr >> 8) & 0x3); auto mask = get_irq_mask((addr >> 8) & 0x3);
val = csr[mie] & mask; val = csr[mie] & mask;
if(this->reg.PRIV != 3) if(this->reg.PRIV != 3)
@ -1214,14 +1234,16 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_ie(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_ie(unsigned addr, reg_t val) {
auto mask = get_irq_mask((addr >> 8) & 0x3); auto mask = get_irq_mask((addr >> 8) & 0x3);
csr[mie] = (csr[mie] & ~mask) | (val & mask); csr[mie] = (csr[mie] & ~mask) | (val & mask);
check_interrupt(); check_interrupt();
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_ip(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_ip(unsigned addr, reg_t& val) {
auto mask = get_irq_mask((addr >> 8) & 0x3); auto mask = get_irq_mask((addr >> 8) & 0x3);
val = csr[mip] & mask; val = csr[mip] & mask;
if(this->reg.PRIV != 3) if(this->reg.PRIV != 3)
@ -1229,24 +1251,28 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_ideleg(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_ideleg(unsigned addr, reg_t val) {
auto mask = 0b000100010001; // only U mode supported auto mask = 0b000100010001; // only U mode supported
csr[mideleg] = (csr[mideleg] & ~mask) | (val & mask); csr[mideleg] = (csr[mideleg] & ~mask) | (val & mask);
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_edeleg(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_edeleg(unsigned addr, reg_t val) {
auto mask = 0b1011001111110111; // bit 14/10 (reserved), bit 11 (Env call), and 3 (break) are hardwired to 0 auto mask = 0b1011001111110111; // bit 14/10 (reserved), bit 11 (Env call), and 3 (break) are hardwired to 0
csr[medeleg] = (csr[medeleg] & ~mask) | (val & mask); csr[medeleg] = (csr[medeleg] & ~mask) | (val & mask);
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_epc(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_epc(unsigned addr, reg_t val) {
csr[addr] = val & get_pc_mask(); csr[addr] = val & get_pc_mask();
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_dcsr_dcsr(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_dcsr_dcsr(unsigned addr, reg_t val) {
if(!debug_mode_active()) if(!debug_mode_active())
throw illegal_instruction_fault(this->fault_data); throw illegal_instruction_fault(this->fault_data);
// +-------------- ebreakm // +-------------- ebreakm
@ -1257,35 +1283,40 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_dcsr_reg(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_dcsr_reg(unsigned addr, reg_t& val) {
if(!debug_mode_active()) if(!debug_mode_active())
throw illegal_instruction_fault(this->fault_data); throw illegal_instruction_fault(this->fault_data);
val = csr[addr]; val = csr[addr];
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_dcsr_reg(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_dcsr_reg(unsigned addr, reg_t val) {
if(!debug_mode_active()) if(!debug_mode_active())
throw illegal_instruction_fault(this->fault_data); throw illegal_instruction_fault(this->fault_data);
csr[addr] = val; csr[addr] = val;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_dpc_reg(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_dpc_reg(unsigned addr, reg_t& val) {
if(!debug_mode_active()) if(!debug_mode_active())
throw illegal_instruction_fault(this->fault_data); throw illegal_instruction_fault(this->fault_data);
val = this->reg.DPC; val = this->reg.DPC;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_dpc_reg(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_dpc_reg(unsigned addr, reg_t val) {
if(!debug_mode_active()) if(!debug_mode_active())
throw illegal_instruction_fault(this->fault_data); throw illegal_instruction_fault(this->fault_data);
this->reg.DPC = val; this->reg.DPC = val;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_intstatus(unsigned addr, reg_t& val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_intstatus(unsigned addr, reg_t& val) {
auto mode = (addr >> 8) & 0x3; auto mode = (addr >> 8) & 0x3;
val = clic_uact_lvl & 0xff; val = clic_uact_lvl & 0xff;
if(mode == 0x3) if(mode == 0x3)
@ -1293,12 +1324,14 @@ template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_har
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_intthresh(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_intthresh(unsigned addr, reg_t val) {
csr[addr] = (val & 0xff) | (1 << (cfg.clic_int_ctl_bits)) - 1; csr[addr] = (val & 0xff) | (1 << (cfg.clic_int_ctl_bits)) - 1;
return iss::Ok; return iss::Ok;
} }
template <typename BASE, features_e FEAT, typename LOGCAT> iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_xtvt(unsigned addr, reg_t val) { template <typename BASE, features_e FEAT, typename LOGCAT>
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_xtvt(unsigned addr, reg_t val) {
csr[addr] = val & ~0x3fULL; csr[addr] = val & ~0x3fULL;
return iss::Ok; return iss::Ok;
} }
@ -1441,7 +1474,8 @@ template <typename BASE, features_e FEAT, typename LOGCAT> void riscv_hart_mu_p<
} }
} }
template <typename BASE, features_e FEAT, typename LOGCAT> uint64_t riscv_hart_mu_p<BASE, FEAT, LOGCAT>::enter_trap(uint64_t flags, uint64_t addr, uint64_t instr) { template <typename BASE, features_e FEAT, typename LOGCAT>
uint64_t riscv_hart_mu_p<BASE, FEAT, LOGCAT>::enter_trap(uint64_t flags, uint64_t addr, uint64_t instr) {
// flags are ACTIVE[31:31], CAUSE[30:16], TRAPID[15:0] // flags are ACTIVE[31:31], CAUSE[30:16], TRAPID[15:0]
// calculate and write mcause val // calculate and write mcause val
if(flags == std::numeric_limits<uint64_t>::max()) if(flags == std::numeric_limits<uint64_t>::max())