fixes FCSR behavior if no floating point is implemented
This commit is contained in:
parent
c376e34b2b
commit
42efced1eb
|
@ -377,8 +377,8 @@ protected:
|
|||
|
||||
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_plain(unsigned addr, reg_t& val);
|
||||
iss::status write_plain(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);
|
||||
|
@ -399,17 +399,19 @@ protected:
|
|||
iss::status read_intstatus(unsigned addr, reg_t& val);
|
||||
iss::status write_intthresh(unsigned addr, reg_t val);
|
||||
iss::status write_xtvt(unsigned addr, reg_t val);
|
||||
iss::status write_dcsr_dcsr(unsigned addr, reg_t val);
|
||||
iss::status read_dcsr_reg(unsigned addr, reg_t& val);
|
||||
iss::status write_dcsr_reg(unsigned addr, reg_t val);
|
||||
iss::status read_dpc_reg(unsigned addr, reg_t& val);
|
||||
iss::status write_dpc_reg(unsigned addr, reg_t val);
|
||||
iss::status write_dcsr(unsigned addr, reg_t val);
|
||||
iss::status read_debug(unsigned addr, reg_t& val);
|
||||
iss::status write_dscratch(unsigned addr, reg_t val);
|
||||
iss::status read_dpc(unsigned addr, reg_t& val);
|
||||
iss::status write_dpc(unsigned addr, reg_t val);
|
||||
iss::status read_fcsr(unsigned addr, reg_t& val);
|
||||
iss::status write_fcsr(unsigned addr, reg_t val);
|
||||
|
||||
virtual iss::status read_custom_csr_reg(unsigned addr, reg_t& val) { return iss::status::Err; };
|
||||
virtual iss::status write_custom_csr_reg(unsigned addr, reg_t val) { return iss::status::Err; };
|
||||
virtual iss::status read_custom_csr(unsigned addr, reg_t& val) { return iss::status::Err; };
|
||||
virtual iss::status write_custom_csr(unsigned addr, reg_t val) { return iss::status::Err; };
|
||||
|
||||
void register_custom_csr_rd(unsigned addr) { csr_rd_cb[addr] = &this_class::read_custom_csr_reg; }
|
||||
void register_custom_csr_wr(unsigned addr) { csr_wr_cb[addr] = &this_class::write_custom_csr_reg; }
|
||||
void register_custom_csr_rd(unsigned addr) { csr_rd_cb[addr] = &this_class::read_custom_csr; }
|
||||
void register_custom_csr_wr(unsigned addr) { csr_wr_cb[addr] = &this_class::write_custom_csr; }
|
||||
|
||||
reg_t mhartid_reg{0x0};
|
||||
|
||||
|
@ -446,18 +448,21 @@ riscv_hart_m_p<BASE, FEAT, LOGCAT>::riscv_hart_m_p(feature_config cfg)
|
|||
csr[mimpid] = 1;
|
||||
|
||||
uart_buf.str("");
|
||||
if(traits<BASE>::FLEN > 0)
|
||||
csr_rd_cb[fcsr] = &this_class::read_fcsr;
|
||||
csr_wr_cb[fcsr] = &this_class::write_fcsr;
|
||||
for(unsigned addr = mhpmcounter3; addr <= mhpmcounter31; ++addr) {
|
||||
csr_rd_cb[addr] = &this_class::read_null;
|
||||
csr_wr_cb[addr] = &this_class::write_csr_reg;
|
||||
csr_wr_cb[addr] = &this_class::write_plain;
|
||||
}
|
||||
if(traits<BASE>::XLEN == 32)
|
||||
for(unsigned addr = mhpmcounter3h; addr <= mhpmcounter31h; ++addr) {
|
||||
csr_rd_cb[addr] = &this_class::read_null;
|
||||
csr_wr_cb[addr] = &this_class::write_csr_reg;
|
||||
csr_wr_cb[addr] = &this_class::write_plain;
|
||||
}
|
||||
for(unsigned addr = mhpmevent3; addr <= mhpmevent31; ++addr) {
|
||||
csr_rd_cb[addr] = &this_class::read_null;
|
||||
csr_wr_cb[addr] = &this_class::write_csr_reg;
|
||||
csr_wr_cb[addr] = &this_class::write_plain;
|
||||
}
|
||||
for(unsigned addr = hpmcounter3; addr <= hpmcounter31; ++addr) {
|
||||
csr_rd_cb[addr] = &this_class::read_null;
|
||||
|
@ -465,18 +470,17 @@ riscv_hart_m_p<BASE, FEAT, LOGCAT>::riscv_hart_m_p(feature_config cfg)
|
|||
if(traits<BASE>::XLEN == 32)
|
||||
for(unsigned addr = hpmcounter3h; addr <= hpmcounter31h; ++addr) {
|
||||
csr_rd_cb[addr] = &this_class::read_null;
|
||||
// csr_wr_cb[addr] = &this_class::write_csr_reg;
|
||||
}
|
||||
// common regs
|
||||
const std::array<unsigned, 4> roaddrs{{misa, mvendorid, marchid, mimpid}};
|
||||
for(auto addr : roaddrs) {
|
||||
csr_rd_cb[addr] = &this_class::read_csr_reg;
|
||||
csr_rd_cb[addr] = &this_class::read_plain;
|
||||
csr_wr_cb[addr] = &this_class::write_null;
|
||||
}
|
||||
const std::array<unsigned, 4> rwaddrs{{mepc, mtvec, mscratch, mtval}};
|
||||
for(auto addr : rwaddrs) {
|
||||
csr_rd_cb[addr] = &this_class::read_csr_reg;
|
||||
csr_wr_cb[addr] = &this_class::write_csr_reg;
|
||||
csr_rd_cb[addr] = &this_class::read_plain;
|
||||
csr_wr_cb[addr] = &this_class::write_plain;
|
||||
}
|
||||
// special handling & overrides
|
||||
csr_rd_cb[time] = &this_class::read_time;
|
||||
|
@ -517,7 +521,7 @@ riscv_hart_m_p<BASE, FEAT, LOGCAT>::riscv_hart_m_p(feature_config cfg)
|
|||
csr_wr_cb[marchid] = &this_class::write_null;
|
||||
csr_wr_cb[mimpid] = &this_class::write_null;
|
||||
if(FEAT & FEAT_CLIC) {
|
||||
csr_rd_cb[mtvt] = &this_class::read_csr_reg;
|
||||
csr_rd_cb[mtvt] = &this_class::read_plain;
|
||||
csr_wr_cb[mtvt] = &this_class::write_xtvt;
|
||||
// csr_rd_cb[mxnti] = &this_class::read_csr_reg;
|
||||
// csr_wr_cb[mxnti] = &this_class::write_csr_reg;
|
||||
|
@ -527,7 +531,7 @@ riscv_hart_m_p<BASE, FEAT, LOGCAT>::riscv_hart_m_p(feature_config cfg)
|
|||
// csr_wr_cb[mscratchcsw] = &this_class::write_csr_reg;
|
||||
// csr_rd_cb[mscratchcswl] = &this_class::read_csr_reg;
|
||||
// csr_wr_cb[mscratchcswl] = &this_class::write_csr_reg;
|
||||
csr_rd_cb[mintthresh] = &this_class::read_csr_reg;
|
||||
csr_rd_cb[mintthresh] = &this_class::read_plain;
|
||||
csr_wr_cb[mintthresh] = &this_class::write_intthresh;
|
||||
clic_int_reg.resize(cfg.clic_num_irq, clic_int_reg_t{.raw = 0});
|
||||
clic_cfg_reg = 0x20;
|
||||
|
@ -553,14 +557,14 @@ riscv_hart_m_p<BASE, FEAT, LOGCAT>::riscv_hart_m_p(feature_config cfg)
|
|||
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;
|
||||
csr_rd_cb[dscratch0] = &this_class::read_dcsr_reg;
|
||||
csr_wr_cb[dscratch1] = &this_class::write_dcsr_reg;
|
||||
csr_rd_cb[dscratch1] = &this_class::read_dcsr_reg;
|
||||
csr_wr_cb[dpc] = &this_class::write_dpc_reg;
|
||||
csr_rd_cb[dpc] = &this_class::read_dpc_reg;
|
||||
csr_wr_cb[dcsr] = &this_class::write_dcsr_dcsr;
|
||||
csr_rd_cb[dcsr] = &this_class::read_dcsr_reg;
|
||||
csr_wr_cb[dscratch0] = &this_class::write_dscratch;
|
||||
csr_rd_cb[dscratch0] = &this_class::read_debug;
|
||||
csr_wr_cb[dscratch1] = &this_class::write_dscratch;
|
||||
csr_rd_cb[dscratch1] = &this_class::read_debug;
|
||||
csr_wr_cb[dpc] = &this_class::write_dpc;
|
||||
csr_rd_cb[dpc] = &this_class::read_dpc;
|
||||
csr_wr_cb[dcsr] = &this_class::write_dcsr;
|
||||
csr_rd_cb[dcsr] = &this_class::read_debug;
|
||||
}
|
||||
hart_mem_rd_delegate = [this](phys_addr_t a, unsigned l, uint8_t* const d) -> iss::status { return this->read_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); };
|
||||
|
@ -665,7 +669,7 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read(const address_type type, co
|
|||
}
|
||||
phys_addr_t phys_addr{access, space, addr};
|
||||
auto res = iss::Err;
|
||||
if(access != access_type::FETCH && memfn_range.size()) {
|
||||
if(!is_fetch(access) && memfn_range.size()) {
|
||||
auto it =
|
||||
std::find_if(std::begin(memfn_range), std::end(memfn_range), [phys_addr](std::tuple<uint64_t, uint64_t> const& a) {
|
||||
return std::get<0>(a) <= phys_addr.val && (std::get<0>(a) + std::get<1>(a)) > phys_addr.val;
|
||||
|
@ -692,11 +696,6 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read(const address_type type, co
|
|||
case traits<BASE>::CSR: {
|
||||
if(length != sizeof(reg_t))
|
||||
return iss::Err;
|
||||
// We emulate the FCSR in the architectural state
|
||||
if(addr == 3) {
|
||||
*data = this->get_fcsr();
|
||||
return iss::Ok;
|
||||
}
|
||||
return read_csr(addr, *reinterpret_cast<reg_t* const>(data));
|
||||
} break;
|
||||
case traits<BASE>::FENCE: {
|
||||
|
@ -767,7 +766,7 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write(const address_type type, c
|
|||
}
|
||||
phys_addr_t phys_addr{access, space, addr};
|
||||
auto res = iss::Err;
|
||||
if(access != access_type::FETCH && memfn_range.size()) {
|
||||
if(!is_fetch(access) && memfn_range.size()) {
|
||||
auto it =
|
||||
std::find_if(std::begin(memfn_range), std::end(memfn_range), [phys_addr](std::tuple<uint64_t, uint64_t> const& a) {
|
||||
return std::get<0>(a) <= phys_addr.val && (std::get<0>(a) + std::get<1>(a)) > phys_addr.val;
|
||||
|
@ -798,8 +797,6 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write(const address_type type, c
|
|||
case 0x10023000: // UART1 base, TXFIFO reg
|
||||
uart_buf << (char)data[0];
|
||||
if(((char)data[0]) == '\n' || data[0] == 0) {
|
||||
// CPPLOG(INFO)<<"UART"<<((paddr.val>>16)&0x3)<<" send
|
||||
// '"<<uart_buf.str()<<"'";
|
||||
std::cout << uart_buf.str();
|
||||
uart_buf.str("");
|
||||
}
|
||||
|
@ -828,11 +825,6 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write(const address_type type, c
|
|||
case traits<BASE>::CSR: {
|
||||
if(length != sizeof(reg_t))
|
||||
return iss::Err;
|
||||
// We emulate the FCSR in the architectural state
|
||||
if(addr == 3) {
|
||||
this->set_fcsr(*data);
|
||||
return iss::Ok;
|
||||
}
|
||||
return write_csr(addr, *reinterpret_cast<const reg_t*>(data));
|
||||
} break;
|
||||
case traits<BASE>::FENCE: {
|
||||
|
@ -889,12 +881,6 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_csr(unsigned addr, reg_t v
|
|||
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) {
|
||||
val = csr[addr];
|
||||
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) {
|
||||
val = 0;
|
||||
|
@ -902,7 +888,13 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_null(unsigned addr, reg_t&
|
|||
}
|
||||
|
||||
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) {
|
||||
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_plain(unsigned addr, reg_t& val) {
|
||||
val = csr[addr];
|
||||
return iss::Ok;
|
||||
}
|
||||
|
||||
template <typename BASE, features_e FEAT, typename LOGCAT>
|
||||
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_plain(unsigned addr, reg_t val) {
|
||||
csr[addr] = val;
|
||||
return iss::Ok;
|
||||
}
|
||||
|
@ -1052,7 +1044,7 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_epc(unsigned addr, reg_t v
|
|||
}
|
||||
|
||||
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) {
|
||||
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_dcsr(unsigned addr, reg_t val) {
|
||||
if(!debug_mode_active())
|
||||
throw illegal_instruction_fault(this->fault_data);
|
||||
// +-------------- ebreakm
|
||||
|
@ -1064,7 +1056,7 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_dcsr_dcsr(unsigned addr, r
|
|||
}
|
||||
|
||||
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) {
|
||||
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_debug(unsigned addr, reg_t& val) {
|
||||
if(!debug_mode_active())
|
||||
throw illegal_instruction_fault(this->fault_data);
|
||||
val = csr[addr];
|
||||
|
@ -1072,7 +1064,7 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_dcsr_reg(unsigned addr, reg
|
|||
}
|
||||
|
||||
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) {
|
||||
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_dscratch(unsigned addr, reg_t val) {
|
||||
if(!debug_mode_active())
|
||||
throw illegal_instruction_fault(this->fault_data);
|
||||
csr[addr] = val;
|
||||
|
@ -1080,7 +1072,7 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_dcsr_reg(unsigned addr, re
|
|||
}
|
||||
|
||||
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) {
|
||||
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_dpc(unsigned addr, reg_t& val) {
|
||||
if(!debug_mode_active())
|
||||
throw illegal_instruction_fault(this->fault_data);
|
||||
val = this->reg.DPC;
|
||||
|
@ -1088,7 +1080,7 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_dpc_reg(unsigned addr, reg_
|
|||
}
|
||||
|
||||
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) {
|
||||
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_dpc(unsigned addr, reg_t val) {
|
||||
if(!debug_mode_active())
|
||||
throw illegal_instruction_fault(this->fault_data);
|
||||
this->reg.DPC = val;
|
||||
|
@ -1101,6 +1093,18 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_intstatus(unsigned addr, re
|
|||
return iss::Ok;
|
||||
}
|
||||
|
||||
template <typename BASE, features_e FEAT, typename LOGCAT>
|
||||
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read_fcsr(unsigned addr, reg_t& val) {
|
||||
val = this->get_fcsr();
|
||||
return iss::Ok;
|
||||
}
|
||||
|
||||
template <typename BASE, features_e FEAT, typename LOGCAT>
|
||||
iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write_fcsr(unsigned addr, reg_t val) {
|
||||
this->set_fcsr(val);
|
||||
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) {
|
||||
csr[addr] = (val & 0xff) | (1 << (cfg.clic_int_ctl_bits)) - 1;
|
||||
|
|
|
@ -39,7 +39,9 @@
|
|||
#include "iss/instrumentation_if.h"
|
||||
#include "iss/log_categories.h"
|
||||
#include "iss/vm_if.h"
|
||||
#include "iss/vm_types.h"
|
||||
#include "riscv_hart_common.h"
|
||||
#include <stdexcept>
|
||||
#ifndef FMT_HEADER_ONLY
|
||||
#define FMT_HEADER_ONLY
|
||||
#endif
|
||||
|
|
|
@ -39,7 +39,9 @@
|
|||
#include "iss/instrumentation_if.h"
|
||||
#include "iss/log_categories.h"
|
||||
#include "iss/vm_if.h"
|
||||
#include "iss/vm_types.h"
|
||||
#include "riscv_hart_common.h"
|
||||
#include <stdexcept>
|
||||
#ifndef FMT_HEADER_ONLY
|
||||
#define FMT_HEADER_ONLY
|
||||
#endif
|
||||
|
@ -302,7 +304,7 @@ public:
|
|||
void set_mhartid(reg_t mhartid) { mhartid_reg = mhartid; };
|
||||
|
||||
void disass_output(uint64_t pc, const std::string instr) override {
|
||||
CLOG(INFO, disass) << fmt::format("0x{:016x} {:40} [p:{};s:0x{:x};c:{}]", pc, instr, lvl[this->reg.PRIV], (reg_t)state.mstatus,
|
||||
NSCLOG(INFO, LOGCAT) << fmt::format("0x{:016x} {:40} [p:{};s:0x{:x};c:{}]", pc, instr, lvl[this->reg.PRIV], (reg_t)state.mstatus,
|
||||
this->reg.icount + cycle_offset);
|
||||
};
|
||||
|
||||
|
@ -402,8 +404,8 @@ protected:
|
|||
|
||||
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_plain(unsigned addr, reg_t& val);
|
||||
iss::status write_plain(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);
|
||||
|
@ -426,15 +428,17 @@ protected:
|
|||
iss::status read_intstatus(unsigned addr, reg_t& val);
|
||||
iss::status write_intthresh(unsigned addr, reg_t val);
|
||||
iss::status write_xtvt(unsigned addr, reg_t val);
|
||||
iss::status write_dcsr_dcsr(unsigned addr, reg_t val);
|
||||
iss::status read_dcsr_reg(unsigned addr, reg_t& val);
|
||||
iss::status write_dcsr_reg(unsigned addr, reg_t val);
|
||||
iss::status read_dpc_reg(unsigned addr, reg_t& val);
|
||||
iss::status write_dpc_reg(unsigned addr, reg_t val);
|
||||
iss::status write_pmpcfg_reg(unsigned addr, reg_t val);
|
||||
iss::status write_dcsr(unsigned addr, reg_t val);
|
||||
iss::status read_debug(unsigned addr, reg_t& val);
|
||||
iss::status write_dscratch(unsigned addr, reg_t val);
|
||||
iss::status read_dpc(unsigned addr, reg_t& val);
|
||||
iss::status write_dpc(unsigned addr, reg_t val);
|
||||
iss::status read_fcsr(unsigned addr, reg_t& val);
|
||||
iss::status write_fcsr(unsigned addr, reg_t val);
|
||||
iss::status write_pmpcfg(unsigned addr, reg_t val);
|
||||
|
||||
virtual iss::status read_custom_csr_reg(unsigned addr, reg_t& val) { return iss::status::Err; };
|
||||
virtual iss::status write_custom_csr_reg(unsigned addr, reg_t val) { return iss::status::Err; };
|
||||
virtual iss::status read_custom_csr(unsigned addr, reg_t& val) { return iss::status::Err; };
|
||||
virtual iss::status write_custom_csr(unsigned addr, reg_t val) { return iss::status::Err; };
|
||||
|
||||
void register_custom_csr_rd(unsigned addr) { csr_rd_cb[addr] = &this_class::read_custom_csr_reg; }
|
||||
void register_custom_csr_wr(unsigned addr) { csr_wr_cb[addr] = &this_class::write_custom_csr_reg; }
|
||||
|
@ -474,18 +478,21 @@ riscv_hart_mu_p<BASE, FEAT, LOGCAT>::riscv_hart_mu_p(feature_config cfg)
|
|||
csr[mimpid] = 1;
|
||||
|
||||
uart_buf.str("");
|
||||
if(traits<BASE>::FLEN > 0)
|
||||
csr_rd_cb[fcsr] = &this_class::read_fcsr;
|
||||
csr_wr_cb[fcsr] = &this_class::write_fcsr;
|
||||
for(unsigned addr = mhpmcounter3; addr <= mhpmcounter31; ++addr) {
|
||||
csr_rd_cb[addr] = &this_class::read_null;
|
||||
csr_wr_cb[addr] = &this_class::write_csr_reg;
|
||||
csr_wr_cb[addr] = &this_class::write_plain;
|
||||
}
|
||||
if(traits<BASE>::XLEN == 32)
|
||||
for(unsigned addr = mhpmcounter3h; addr <= mhpmcounter31h; ++addr) {
|
||||
csr_rd_cb[addr] = &this_class::read_null;
|
||||
csr_wr_cb[addr] = &this_class::write_csr_reg;
|
||||
csr_wr_cb[addr] = &this_class::write_plain;
|
||||
}
|
||||
for(unsigned addr = mhpmevent3; addr <= mhpmevent31; ++addr) {
|
||||
csr_rd_cb[addr] = &this_class::read_null;
|
||||
csr_wr_cb[addr] = &this_class::write_csr_reg;
|
||||
csr_wr_cb[addr] = &this_class::write_plain;
|
||||
}
|
||||
for(unsigned addr = hpmcounter3; addr <= hpmcounter31; ++addr) {
|
||||
csr_rd_cb[addr] = &this_class::read_null;
|
||||
|
@ -493,12 +500,11 @@ riscv_hart_mu_p<BASE, FEAT, LOGCAT>::riscv_hart_mu_p(feature_config cfg)
|
|||
if(traits<BASE>::XLEN == 32)
|
||||
for(unsigned addr = hpmcounter3h; addr <= hpmcounter31h; ++addr) {
|
||||
csr_rd_cb[addr] = &this_class::read_null;
|
||||
// csr_wr_cb[addr] = &this_class::write_csr_reg;
|
||||
}
|
||||
// common regs
|
||||
const std::array<unsigned, 4> roaddrs{{misa, mvendorid, marchid, mimpid}};
|
||||
for(auto addr : roaddrs) {
|
||||
csr_rd_cb[addr] = &this_class::read_csr_reg;
|
||||
csr_rd_cb[addr] = &this_class::read_plain;
|
||||
csr_wr_cb[addr] = &this_class::write_null;
|
||||
}
|
||||
const std::array<unsigned, 8> rwaddrs{{
|
||||
|
@ -512,8 +518,8 @@ riscv_hart_mu_p<BASE, FEAT, LOGCAT>::riscv_hart_mu_p(feature_config cfg)
|
|||
utval,
|
||||
}};
|
||||
for(auto addr : rwaddrs) {
|
||||
csr_rd_cb[addr] = &this_class::read_csr_reg;
|
||||
csr_wr_cb[addr] = &this_class::write_csr_reg;
|
||||
csr_rd_cb[addr] = &this_class::read_plain;
|
||||
csr_wr_cb[addr] = &this_class::write_plain;
|
||||
}
|
||||
// special handling & overrides
|
||||
csr_rd_cb[time] = &this_class::read_time;
|
||||
|
@ -558,18 +564,18 @@ riscv_hart_mu_p<BASE, FEAT, LOGCAT>::riscv_hart_mu_p(feature_config cfg)
|
|||
|
||||
if(FEAT & FEAT_PMP) {
|
||||
for(size_t i = pmpaddr0; i <= pmpaddr15; ++i) {
|
||||
csr_rd_cb[i] = &this_class::read_csr_reg;
|
||||
csr_wr_cb[i] = &this_class::write_csr_reg;
|
||||
csr_rd_cb[i] = &this_class::read_plain;
|
||||
csr_wr_cb[i] = &this_class::write_plain;
|
||||
}
|
||||
for(size_t i = pmpcfg0; i < pmpcfg0 + 16 / sizeof(reg_t); ++i) {
|
||||
csr_rd_cb[i] = &this_class::read_csr_reg;
|
||||
csr_wr_cb[i] = &this_class::write_pmpcfg_reg;
|
||||
csr_rd_cb[i] = &this_class::read_plain;
|
||||
csr_wr_cb[i] = &this_class::write_pmpcfg;
|
||||
}
|
||||
}
|
||||
if(FEAT & FEAT_EXT_N) {
|
||||
csr_rd_cb[mideleg] = &this_class::read_csr_reg;
|
||||
csr_rd_cb[mideleg] = &this_class::read_plain;
|
||||
csr_wr_cb[mideleg] = &this_class::write_ideleg;
|
||||
csr_rd_cb[medeleg] = &this_class::read_csr_reg;
|
||||
csr_rd_cb[medeleg] = &this_class::read_plain;
|
||||
csr_wr_cb[medeleg] = &this_class::write_edeleg;
|
||||
csr_rd_cb[uie] = &this_class::read_ie;
|
||||
csr_wr_cb[uie] = &this_class::write_ie;
|
||||
|
@ -583,7 +589,7 @@ riscv_hart_mu_p<BASE, FEAT, LOGCAT>::riscv_hart_mu_p(feature_config cfg)
|
|||
csr_rd_cb[utvec] = &this_class::read_tvec;
|
||||
}
|
||||
if(FEAT & FEAT_CLIC) {
|
||||
csr_rd_cb[mtvt] = &this_class::read_csr_reg;
|
||||
csr_rd_cb[mtvt] = &this_class::read_plain;
|
||||
csr_wr_cb[mtvt] = &this_class::write_xtvt;
|
||||
// csr_rd_cb[mxnti] = &this_class::read_csr_reg;
|
||||
// csr_wr_cb[mxnti] = &this_class::write_csr_reg;
|
||||
|
@ -593,14 +599,14 @@ riscv_hart_mu_p<BASE, FEAT, LOGCAT>::riscv_hart_mu_p(feature_config cfg)
|
|||
// csr_wr_cb[mscratchcsw] = &this_class::write_csr_reg;
|
||||
// csr_rd_cb[mscratchcswl] = &this_class::read_csr_reg;
|
||||
// csr_wr_cb[mscratchcswl] = &this_class::write_csr_reg;
|
||||
csr_rd_cb[mintthresh] = &this_class::read_csr_reg;
|
||||
csr_rd_cb[mintthresh] = &this_class::read_plain;
|
||||
csr_wr_cb[mintthresh] = &this_class::write_intthresh;
|
||||
if(FEAT & FEAT_EXT_N) {
|
||||
csr_rd_cb[utvt] = &this_class::read_csr_reg;
|
||||
csr_rd_cb[utvt] = &this_class::read_plain;
|
||||
csr_wr_cb[utvt] = &this_class::write_xtvt;
|
||||
csr_rd_cb[uintstatus] = &this_class::read_intstatus;
|
||||
csr_wr_cb[uintstatus] = &this_class::write_null;
|
||||
csr_rd_cb[uintthresh] = &this_class::read_csr_reg;
|
||||
csr_rd_cb[uintthresh] = &this_class::read_plain;
|
||||
csr_wr_cb[uintthresh] = &this_class::write_intthresh;
|
||||
}
|
||||
clic_int_reg.resize(cfg.clic_num_irq, clic_int_reg_t{.raw = 0});
|
||||
|
@ -629,14 +635,14 @@ riscv_hart_mu_p<BASE, FEAT, LOGCAT>::riscv_hart_mu_p(feature_config cfg)
|
|||
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;
|
||||
csr_rd_cb[dscratch0] = &this_class::read_dcsr_reg;
|
||||
csr_wr_cb[dscratch1] = &this_class::write_dcsr_reg;
|
||||
csr_rd_cb[dscratch1] = &this_class::read_dcsr_reg;
|
||||
csr_wr_cb[dpc] = &this_class::write_dpc_reg;
|
||||
csr_rd_cb[dpc] = &this_class::read_dpc_reg;
|
||||
csr_wr_cb[dcsr] = &this_class::write_dcsr_dcsr;
|
||||
csr_rd_cb[dcsr] = &this_class::read_dcsr_reg;
|
||||
csr_wr_cb[dscratch0] = &this_class::write_dscratch;
|
||||
csr_rd_cb[dscratch0] = &this_class::read_debug;
|
||||
csr_wr_cb[dscratch1] = &this_class::write_dscratch;
|
||||
csr_rd_cb[dscratch1] = &this_class::read_debug;
|
||||
csr_wr_cb[dpc] = &this_class::write_dpc;
|
||||
csr_rd_cb[dpc] = &this_class::read_dpc;
|
||||
csr_wr_cb[dcsr] = &this_class::write_dcsr;
|
||||
csr_rd_cb[dcsr] = &this_class::read_debug;
|
||||
}
|
||||
hart_mem_rd_delegate = [this](phys_addr_t a, unsigned l, uint8_t* const d) -> iss::status { return this->read_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); };
|
||||
|
@ -725,7 +731,7 @@ inline void riscv_hart_mu_p<BASE, FEAT, LOGCAT>::insert_mem_range(uint64_t base,
|
|||
}
|
||||
|
||||
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) {
|
||||
inline iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_pmpcfg(unsigned addr, reg_t val) {
|
||||
csr[addr] = val & 0x9f9f9f9f;
|
||||
return iss::Ok;
|
||||
}
|
||||
|
@ -988,8 +994,6 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write(const address_type type,
|
|||
case 0x10023000: // UART1 base, TXFIFO reg
|
||||
uart_buf << (char)data[0];
|
||||
if(((char)data[0]) == '\n' || data[0] == 0) {
|
||||
// CPPLOG(INFO)<<"UART"<<((addr>>16)&0x3)<<" send
|
||||
// '"<<uart_buf.str()<<"'";
|
||||
std::cout << uart_buf.str();
|
||||
uart_buf.str("");
|
||||
}
|
||||
|
@ -1074,12 +1078,6 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_csr(unsigned addr, reg_t
|
|||
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) {
|
||||
val = csr[addr];
|
||||
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) {
|
||||
val = 0;
|
||||
|
@ -1087,7 +1085,13 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_null(unsigned addr, reg_t&
|
|||
}
|
||||
|
||||
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) {
|
||||
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_plain(unsigned addr, reg_t& val) {
|
||||
val = csr[addr];
|
||||
return iss::Ok;
|
||||
}
|
||||
|
||||
template <typename BASE, features_e FEAT, typename LOGCAT>
|
||||
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_plain(unsigned addr, reg_t val) {
|
||||
csr[addr] = val;
|
||||
return iss::Ok;
|
||||
}
|
||||
|
@ -1161,6 +1165,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_tvec(unsigned addr, reg_t&
|
|||
val = FEAT & features_e::FEAT_CLIC ? csr[addr] : csr[addr] & ~2;
|
||||
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) {
|
||||
val = state.mstatus & hart_state_type::get_mask((addr >> 8) & 0x3);
|
||||
|
@ -1272,7 +1277,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_epc(unsigned addr, reg_t
|
|||
}
|
||||
|
||||
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) {
|
||||
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_dcsr(unsigned addr, reg_t val) {
|
||||
if(!debug_mode_active())
|
||||
throw illegal_instruction_fault(this->fault_data);
|
||||
// +-------------- ebreakm
|
||||
|
@ -1284,7 +1289,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_dcsr_dcsr(unsigned addr,
|
|||
}
|
||||
|
||||
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) {
|
||||
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_debug(unsigned addr, reg_t& val) {
|
||||
if(!debug_mode_active())
|
||||
throw illegal_instruction_fault(this->fault_data);
|
||||
val = csr[addr];
|
||||
|
@ -1292,7 +1297,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_dcsr_reg(unsigned addr, re
|
|||
}
|
||||
|
||||
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) {
|
||||
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_dscratch(unsigned addr, reg_t val) {
|
||||
if(!debug_mode_active())
|
||||
throw illegal_instruction_fault(this->fault_data);
|
||||
csr[addr] = val;
|
||||
|
@ -1300,7 +1305,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_dcsr_reg(unsigned addr, r
|
|||
}
|
||||
|
||||
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) {
|
||||
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_dpc(unsigned addr, reg_t& val) {
|
||||
if(!debug_mode_active())
|
||||
throw illegal_instruction_fault(this->fault_data);
|
||||
val = this->reg.DPC;
|
||||
|
@ -1308,7 +1313,7 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_dpc_reg(unsigned addr, reg
|
|||
}
|
||||
|
||||
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) {
|
||||
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_dpc(unsigned addr, reg_t val) {
|
||||
if(!debug_mode_active())
|
||||
throw illegal_instruction_fault(this->fault_data);
|
||||
this->reg.DPC = val;
|
||||
|
@ -1324,6 +1329,18 @@ iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_intstatus(unsigned addr, r
|
|||
return iss::Ok;
|
||||
}
|
||||
|
||||
template <typename BASE, features_e FEAT, typename LOGCAT>
|
||||
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::read_fcsr(unsigned addr, reg_t& val) {
|
||||
val = this->get_fcsr();
|
||||
return iss::Ok;
|
||||
}
|
||||
|
||||
template <typename BASE, features_e FEAT, typename LOGCAT>
|
||||
iss::status riscv_hart_mu_p<BASE, FEAT, LOGCAT>::write_fcsr(unsigned addr, reg_t val) {
|
||||
this->set_fcsr(val);
|
||||
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) {
|
||||
csr[addr] = (val & 0xff) | (1 << (cfg.clic_int_ctl_bits)) - 1;
|
||||
|
|
Loading…
Reference in New Issue