From 5a2b96ef3e247cfa2dadca46e39a9db3576f7c7b Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Wed, 24 Jul 2024 12:20:38 +0200 Subject: [PATCH] adds logging categories for ISS --- src/iss/arch/riscv_hart_m_p.h | 114 ++++++++++++++++---------------- src/iss/arch/riscv_hart_mu_p.h | 116 ++++++++++++++++----------------- 2 files changed, 115 insertions(+), 115 deletions(-) diff --git a/src/iss/arch/riscv_hart_m_p.h b/src/iss/arch/riscv_hart_m_p.h index e45f292..ea24bb4 100644 --- a/src/iss/arch/riscv_hart_m_p.h +++ b/src/iss/arch/riscv_hart_m_p.h @@ -61,7 +61,7 @@ namespace iss { namespace arch { -template class riscv_hart_m_p : public BASE, public riscv_hart_common { +template class riscv_hart_m_p : public BASE, public riscv_hart_common { protected: const std::array lvl = {{'U', 'S', 'H', 'M'}}; const std::array trap_str = {{"" @@ -88,7 +88,7 @@ protected: public: using core = BASE; - using this_class = riscv_hart_m_p; + using this_class = riscv_hart_m_p; using phys_addr_t = typename core::phys_addr_t; using reg_t = typename core::reg_t; using addr_t = typename core::addr_t; @@ -275,7 +275,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} [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); }; @@ -290,7 +290,7 @@ public: protected: struct riscv_instrumentation_if : public iss::instrumentation_if { - riscv_instrumentation_if(riscv_hart_m_p& arch) + riscv_instrumentation_if(riscv_hart_m_p& arch) : arch(arch) {} /** * get the name of this architecture @@ -321,7 +321,7 @@ protected: std::unordered_map get_symbol_table(std::string name) override { return arch.get_sym_table(name); } - riscv_hart_m_p& arch; + riscv_hart_m_p& arch; }; friend struct riscv_instrumentation_if; @@ -432,8 +432,8 @@ protected: std::function hart_mem_wr_delegate; }; -template -riscv_hart_m_p::riscv_hart_m_p(feature_config cfg) +template +riscv_hart_m_p::riscv_hart_m_p(feature_config cfg) : state() , instr_if(*this) , cfg(cfg) { @@ -564,7 +564,7 @@ riscv_hart_m_p::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); }; } -template std::pair riscv_hart_m_p::load_file(std::string name, int type) { +template std::pair riscv_hart_m_p::load_file(std::string name, int type) { get_sym_table(name); try { tohost = symbol_table.at("tohost"); @@ -618,8 +618,8 @@ template std::pair riscv_hart_m throw std::runtime_error(fmt::format("memory load file not found, check if {} is a valid file", name)); } -template -inline void riscv_hart_m_p::insert_mem_range(uint64_t base, uint64_t size, std::function rd_f, +template +inline void riscv_hart_m_p::insert_mem_range(uint64_t base, uint64_t size, std::function rd_f, std::function wr_fn) { std::tuple entry{base, size}; auto it = std::upper_bound( @@ -631,8 +631,8 @@ inline void riscv_hart_m_p::insert_mem_range(uint64_t base, uint64_t memfn_write.insert(std::begin(memfn_write) + idx, wr_fn); } -template -iss::status riscv_hart_m_p::read(const address_type type, const access_type access, const uint32_t space, const uint64_t addr, +template +iss::status riscv_hart_m_p::read(const address_type type, const access_type access, const uint32_t space, const uint64_t addr, const unsigned length, uint8_t* const data) { #ifndef NDEBUG if(access && iss::access_type::DEBUG) { @@ -715,8 +715,8 @@ iss::status riscv_hart_m_p::read(const address_type type, const acce } } -template -iss::status riscv_hart_m_p::write(const address_type type, const access_type access, const uint32_t space, const uint64_t addr, +template +iss::status riscv_hart_m_p::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) { #ifndef NDEBUG const char* prefix = (access && iss::access_type::DEBUG) ? "debug " : ""; @@ -848,7 +848,7 @@ iss::status riscv_hart_m_p::write(const address_type type, const acc } } -template iss::status riscv_hart_m_p::read_csr(unsigned addr, reg_t& val) { +template iss::status riscv_hart_m_p::read_csr(unsigned addr, reg_t& val) { if(addr >= csr.size()) return iss::Err; auto req_priv_lvl = (addr >> 8) & 0x3; @@ -860,7 +860,7 @@ template iss::status riscv_hart_m_p return (this->*(it->second))(addr, val); } -template iss::status riscv_hart_m_p::write_csr(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_csr(unsigned addr, reg_t val) { if(addr >= csr.size()) return iss::Err; auto req_priv_lvl = (addr >> 8) & 0x3; @@ -874,22 +874,22 @@ template iss::status riscv_hart_m_p return (this->*(it->second))(addr, val); } -template iss::status riscv_hart_m_p::read_csr_reg(unsigned addr, reg_t& val) { +template iss::status riscv_hart_m_p::read_csr_reg(unsigned addr, reg_t& val) { val = csr[addr]; return iss::Ok; } -template iss::status riscv_hart_m_p::read_null(unsigned addr, reg_t& val) { +template iss::status riscv_hart_m_p::read_null(unsigned addr, reg_t& val) { val = 0; return iss::Ok; } -template iss::status riscv_hart_m_p::write_csr_reg(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_csr_reg(unsigned addr, reg_t val) { csr[addr] = val; return iss::Ok; } -template iss::status riscv_hart_m_p::read_cycle(unsigned addr, reg_t& val) { +template iss::status riscv_hart_m_p::read_cycle(unsigned addr, reg_t& val) { auto cycle_val = this->reg.icount + cycle_offset; if(addr == mcycle) { val = static_cast(cycle_val); @@ -899,7 +899,7 @@ template iss::status riscv_hart_m_p return iss::Ok; } -template iss::status riscv_hart_m_p::write_cycle(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_cycle(unsigned addr, reg_t val) { if(sizeof(typename traits::reg_t) != 4) { mcycle_csr = static_cast(val); } else { @@ -913,7 +913,7 @@ template iss::status riscv_hart_m_p return iss::Ok; } -template iss::status riscv_hart_m_p::read_instret(unsigned addr, reg_t& val) { +template iss::status riscv_hart_m_p::read_instret(unsigned addr, reg_t& val) { if((addr & 0xff) == (minstret & 0xff)) { val = static_cast(this->reg.instret); } else if((addr & 0xff) == (minstreth & 0xff)) { @@ -922,7 +922,7 @@ template iss::status riscv_hart_m_p return iss::Ok; } -template iss::status riscv_hart_m_p::write_instret(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_instret(unsigned addr, reg_t val) { if(sizeof(typename traits::reg_t) != 4) { this->reg.instret = static_cast(val); } else { @@ -936,7 +936,7 @@ template iss::status riscv_hart_m_p return iss::Ok; } -template iss::status riscv_hart_m_p::read_time(unsigned addr, reg_t& val) { +template iss::status riscv_hart_m_p::read_time(unsigned addr, reg_t& val) { uint64_t time_val = this->reg.icount / (100000000 / 32768 - 1); //-> ~3052; if(addr == time) { val = static_cast(time_val); @@ -948,23 +948,23 @@ template iss::status riscv_hart_m_p return iss::Ok; } -template iss::status riscv_hart_m_p::read_tvec(unsigned addr, reg_t& val) { +template iss::status riscv_hart_m_p::read_tvec(unsigned addr, reg_t& val) { val = FEAT & features_e::FEAT_CLIC ? csr[addr] : csr[addr] & ~2; return iss::Ok; } -template iss::status riscv_hart_m_p::read_status(unsigned addr, reg_t& val) { +template iss::status riscv_hart_m_p::read_status(unsigned addr, reg_t& val) { val = state.mstatus & hart_state_type::get_mask(); return iss::Ok; } -template iss::status riscv_hart_m_p::write_status(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_status(unsigned addr, reg_t val) { state.write_mstatus(val); check_interrupt(); return iss::Ok; } -template iss::status riscv_hart_m_p::read_cause(unsigned addr, reg_t& val) { +template iss::status riscv_hart_m_p::read_cause(unsigned addr, reg_t& val) { if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec] & 0x3) == 3) { val = csr[addr] & ((1UL << (traits::XLEN - 1)) | (mcause_max_irq - 1) | (0xfUL << 16)); val |= clic_mprev_lvl << 16; @@ -975,7 +975,7 @@ template iss::status riscv_hart_m_p return iss::Ok; } -template iss::status riscv_hart_m_p::write_cause(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_cause(unsigned addr, reg_t val) { if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec] & 0x3) == 3) { auto mask = ((1UL << (traits::XLEN - 1)) | (mcause_max_irq - 1) | (0xfUL << 16)); csr[addr] = (val & mask) | (csr[addr] & ~mask); @@ -989,36 +989,36 @@ template iss::status riscv_hart_m_p return iss::Ok; } -template iss::status riscv_hart_m_p::read_hartid(unsigned addr, reg_t& val) { +template iss::status riscv_hart_m_p::read_hartid(unsigned addr, reg_t& val) { val = mhartid_reg; return iss::Ok; } -template iss::status riscv_hart_m_p::read_ie(unsigned addr, reg_t& val) { +template iss::status riscv_hart_m_p::read_ie(unsigned addr, reg_t& val) { auto mask = get_irq_mask(); val = csr[mie] & mask; return iss::Ok; } -template iss::status riscv_hart_m_p::write_ie(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_ie(unsigned addr, reg_t val) { auto mask = get_irq_mask(); csr[mie] = (csr[mie] & ~mask) | (val & mask); check_interrupt(); return iss::Ok; } -template iss::status riscv_hart_m_p::read_ip(unsigned addr, reg_t& val) { +template iss::status riscv_hart_m_p::read_ip(unsigned addr, reg_t& val) { auto mask = get_irq_mask(); val = csr[mip] & mask; return iss::Ok; } -template iss::status riscv_hart_m_p::write_epc(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_epc(unsigned addr, reg_t val) { csr[addr] = val & get_pc_mask(); return iss::Ok; } -template iss::status riscv_hart_m_p::write_dcsr_dcsr(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_dcsr_dcsr(unsigned addr, reg_t val) { if(!debug_mode_active()) throw illegal_instruction_fault(this->fault_data); // +-------------- ebreakm @@ -1029,51 +1029,51 @@ template iss::status riscv_hart_m_p return iss::Ok; } -template iss::status riscv_hart_m_p::read_dcsr_reg(unsigned addr, reg_t& val) { +template iss::status riscv_hart_m_p::read_dcsr_reg(unsigned addr, reg_t& val) { if(!debug_mode_active()) throw illegal_instruction_fault(this->fault_data); val = csr[addr]; return iss::Ok; } -template iss::status riscv_hart_m_p::write_dcsr_reg(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_dcsr_reg(unsigned addr, reg_t val) { if(!debug_mode_active()) throw illegal_instruction_fault(this->fault_data); csr[addr] = val; return iss::Ok; } -template iss::status riscv_hart_m_p::read_dpc_reg(unsigned addr, reg_t& val) { +template iss::status riscv_hart_m_p::read_dpc_reg(unsigned addr, reg_t& val) { if(!debug_mode_active()) throw illegal_instruction_fault(this->fault_data); val = this->reg.DPC; return iss::Ok; } -template iss::status riscv_hart_m_p::write_dpc_reg(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_dpc_reg(unsigned addr, reg_t val) { if(!debug_mode_active()) throw illegal_instruction_fault(this->fault_data); this->reg.DPC = val; return iss::Ok; } -template iss::status riscv_hart_m_p::read_intstatus(unsigned addr, reg_t& val) { +template iss::status riscv_hart_m_p::read_intstatus(unsigned addr, reg_t& val) { val = (clic_mact_lvl & 0xff) << 24; return iss::Ok; } -template iss::status riscv_hart_m_p::write_intthresh(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_intthresh(unsigned addr, reg_t val) { csr[addr] = (val & 0xff) | (1 << (cfg.clic_int_ctl_bits)) - 1; return iss::Ok; } -template iss::status riscv_hart_m_p::write_xtvt(unsigned addr, reg_t val) { +template iss::status riscv_hart_m_p::write_xtvt(unsigned addr, reg_t val) { csr[addr] = val & ~0x3fULL; return iss::Ok; } -template -iss::status riscv_hart_m_p::read_mem(phys_addr_t paddr, unsigned length, uint8_t* const data) { +template +iss::status riscv_hart_m_p::read_mem(phys_addr_t paddr, unsigned length, uint8_t* const data) { switch(paddr.val) { default: { for(auto offs = 0U; offs < length; ++offs) { @@ -1084,8 +1084,8 @@ iss::status riscv_hart_m_p::read_mem(phys_addr_t paddr, unsigned len return iss::Ok; } -template -iss::status riscv_hart_m_p::write_mem(phys_addr_t paddr, unsigned length, const uint8_t* const data) { +template +iss::status riscv_hart_m_p::write_mem(phys_addr_t paddr, unsigned length, const uint8_t* const data) { switch(paddr.val) { // TODO remove UART, Peripherals should not be part of the ISS case 0xFFFF0000: // UART0 base, TXFIFO reg @@ -1143,8 +1143,8 @@ iss::status riscv_hart_m_p::write_mem(phys_addr_t paddr, unsigned le return iss::Ok; } -template -iss::status riscv_hart_m_p::read_clic(uint64_t addr, unsigned length, uint8_t* const data) { +template +iss::status riscv_hart_m_p::read_clic(uint64_t addr, unsigned length, uint8_t* const data) { if(addr == cfg.clic_base) { // cliccfg *data = clic_cfg_reg; for(auto i = 1; i < length; ++i) @@ -1163,8 +1163,8 @@ iss::status riscv_hart_m_p::read_clic(uint64_t addr, unsigned length return iss::Ok; } -template -iss::status riscv_hart_m_p::write_clic(uint64_t addr, unsigned length, const uint8_t* const data) { +template +iss::status riscv_hart_m_p::write_clic(uint64_t addr, unsigned length, const uint8_t* const data) { if(addr == cfg.clic_base) { // cliccfg clic_cfg_reg = (clic_cfg_reg & ~0x1e) | (*data & 0x1e); } else if(addr >= (cfg.clic_base + 0x40) && (addr + length) <= (cfg.clic_base + 0x40 + cfg.clic_num_trigger * 4)) { // clicinttrig @@ -1179,12 +1179,12 @@ iss::status riscv_hart_m_p::write_clic(uint64_t addr, unsigned lengt return iss::Ok; } -template inline void riscv_hart_m_p::reset(uint64_t address) { +template inline void riscv_hart_m_p::reset(uint64_t address) { BASE::reset(address); state.mstatus = hart_state_type::mstatus_reset_val; } -template void riscv_hart_m_p::check_interrupt() { +template void riscv_hart_m_p::check_interrupt() { // TODO: Implement CLIC functionality // auto ideleg = csr[mideleg]; // Multiple simultaneous interrupts and traps at the same privilege level are @@ -1207,7 +1207,7 @@ template void riscv_hart_m_p::check } } -template uint64_t riscv_hart_m_p::enter_trap(uint64_t flags, uint64_t addr, uint64_t tval) { +template uint64_t riscv_hart_m_p::enter_trap(uint64_t flags, uint64_t addr, uint64_t tval) { // flags are ACTIVE[31:31], CAUSE[30:16], TRAPID[15:0] // calculate and write mcause val auto const trap_id = bit_sub<0, 16>(flags); @@ -1260,7 +1260,7 @@ template uint64_t riscv_hart_m_p::e #else sprintf(buffer.data(), "0x%016lx", addr); #endif - CLOG(INFO, disass) << "Semihosting call at address " << buffer.data() << " occurred "; + NSCLOG(INFO, LOGCAT) << "Semihosting call at address " << buffer.data() << " occurred "; semihosting_cb(this, &(this->reg.X10) /*a0*/, &(this->reg.X11) /*a1*/); return this->reg.NEXT_PC; @@ -1316,18 +1316,18 @@ template uint64_t riscv_hart_m_p::e sprintf(buffer.data(), "0x%016lx", addr); #endif if((flags & 0xffffffff) != 0xffffffff) - CLOG(INFO, disass) << (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 << ")" << " at address " << buffer.data() << " occurred"; return this->reg.NEXT_PC; } -template uint64_t riscv_hart_m_p::leave_trap(uint64_t flags) { +template uint64_t riscv_hart_m_p::leave_trap(uint64_t flags) { state.mstatus.MIE = state.mstatus.MPIE; state.mstatus.MPIE = 1; // sets the pc to the value stored in the x epc register. this->reg.NEXT_PC = csr[mepc] & get_pc_mask(); - CLOG(INFO, disass) << "Executing xRET"; + NSCLOG(INFO, LOGCAT) << "Executing xRET"; check_interrupt(); this->reg.trap_state = this->reg.pending_trap; return this->reg.NEXT_PC; diff --git a/src/iss/arch/riscv_hart_mu_p.h b/src/iss/arch/riscv_hart_mu_p.h index 345ea27..fc27466 100644 --- a/src/iss/arch/riscv_hart_mu_p.h +++ b/src/iss/arch/riscv_hart_mu_p.h @@ -60,7 +60,7 @@ namespace iss { namespace arch { -template class riscv_hart_mu_p : public BASE, public riscv_hart_common { +template class riscv_hart_mu_p : public BASE, public riscv_hart_common { protected: const std::array lvl = {{'U', 'S', 'H', 'M'}}; const std::array trap_str = {{"" @@ -87,7 +87,7 @@ protected: public: using core = BASE; - using this_class = riscv_hart_mu_p; + using this_class = riscv_hart_mu_p; using phys_addr_t = typename core::phys_addr_t; using reg_t = typename core::reg_t; using addr_t = typename core::addr_t; @@ -316,7 +316,7 @@ public: protected: struct riscv_instrumentation_if : public iss::instrumentation_if { - riscv_instrumentation_if(riscv_hart_mu_p& arch) + riscv_instrumentation_if(riscv_hart_mu_p& arch) : arch(arch) {} /** * get the name of this architecture @@ -347,7 +347,7 @@ protected: std::unordered_map get_symbol_table(std::string name) override { return arch.get_sym_table(name); } - riscv_hart_mu_p& arch; + riscv_hart_mu_p& arch; }; friend struct riscv_instrumentation_if; @@ -461,8 +461,8 @@ protected: std::function hart_mem_wr_delegate; }; -template -riscv_hart_mu_p::riscv_hart_mu_p(feature_config cfg) +template +riscv_hart_mu_p::riscv_hart_mu_p(feature_config cfg) : state() , instr_if(*this) , cfg(cfg) { @@ -641,7 +641,7 @@ riscv_hart_mu_p::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); }; } -template std::pair riscv_hart_mu_p::load_file(std::string name, int type) { +template std::pair riscv_hart_mu_p::load_file(std::string name, int type) { FILE* fp = fopen(name.c_str(), "r"); if(fp) { std::array buf; @@ -709,8 +709,8 @@ template std::pair riscv_hart_m throw std::runtime_error(fmt::format("memory load file not found, check if {} is a valid file", name)); } -template -inline void riscv_hart_mu_p::insert_mem_range(uint64_t base, uint64_t size, std::function rd_f, +template +inline void riscv_hart_mu_p::insert_mem_range(uint64_t base, uint64_t size, std::function rd_f, std::function wr_fn) { std::tuple entry{base, size}; auto it = std::upper_bound( @@ -722,13 +722,13 @@ inline void riscv_hart_mu_p::insert_mem_range(uint64_t base, uint64_ memfn_write.insert(std::begin(memfn_write) + idx, wr_fn); } -template inline iss::status riscv_hart_mu_p::write_pmpcfg_reg(unsigned addr, reg_t val) { +template inline iss::status riscv_hart_mu_p::write_pmpcfg_reg(unsigned addr, reg_t val) { csr[addr] = val & 0x9f9f9f9f; return iss::Ok; } -template -bool riscv_hart_mu_p::pmp_check(const access_type type, const uint64_t addr, const unsigned len) { +template +bool riscv_hart_mu_p::pmp_check(const access_type type, const uint64_t addr, const unsigned len) { constexpr auto PMP_SHIFT = 2U; constexpr auto PMP_R = 0x1U; constexpr auto PMP_W = 0x2U; @@ -808,8 +808,8 @@ bool riscv_hart_mu_p::pmp_check(const access_type type, const uint64 return !any_active || this->reg.PRIV == PRIV_M; } -template -iss::status riscv_hart_mu_p::read(const address_type type, const access_type access, const uint32_t space, const uint64_t addr, +template +iss::status riscv_hart_mu_p::read(const address_type type, const access_type access, const uint32_t space, const uint64_t addr, const unsigned length, uint8_t* const data) { #ifndef NDEBUG if(access && iss::access_type::DEBUG) { @@ -901,8 +901,8 @@ iss::status riscv_hart_mu_p::read(const address_type type, const acc } } -template -iss::status riscv_hart_mu_p::write(const address_type type, const access_type access, const uint32_t space, const uint64_t addr, +template +iss::status riscv_hart_mu_p::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) { #ifndef NDEBUG const char* prefix = (access && iss::access_type::DEBUG) ? "debug " : ""; @@ -1043,7 +1043,7 @@ iss::status riscv_hart_mu_p::write(const address_type type, const ac } } -template iss::status riscv_hart_mu_p::read_csr(unsigned addr, reg_t& val) { +template iss::status riscv_hart_mu_p::read_csr(unsigned addr, reg_t& val) { if(addr >= csr.size()) return iss::Err; auto req_priv_lvl = (addr >> 8) & 0x3; @@ -1055,7 +1055,7 @@ template iss::status riscv_hart_mu_p*(it->second))(addr, val); } -template iss::status riscv_hart_mu_p::write_csr(unsigned addr, reg_t val) { +template iss::status riscv_hart_mu_p::write_csr(unsigned addr, reg_t val) { if(addr >= csr.size()) return iss::Err; auto req_priv_lvl = (addr >> 8) & 0x3; @@ -1069,22 +1069,22 @@ template iss::status riscv_hart_mu_p*(it->second))(addr, val); } -template iss::status riscv_hart_mu_p::read_csr_reg(unsigned addr, reg_t& val) { +template iss::status riscv_hart_mu_p::read_csr_reg(unsigned addr, reg_t& val) { val = csr[addr]; return iss::Ok; } -template iss::status riscv_hart_mu_p::read_null(unsigned addr, reg_t& val) { +template iss::status riscv_hart_mu_p::read_null(unsigned addr, reg_t& val) { val = 0; return iss::Ok; } -template iss::status riscv_hart_mu_p::write_csr_reg(unsigned addr, reg_t val) { +template iss::status riscv_hart_mu_p::write_csr_reg(unsigned addr, reg_t val) { csr[addr] = val; return iss::Ok; } -template iss::status riscv_hart_mu_p::read_cycle(unsigned addr, reg_t& val) { +template iss::status riscv_hart_mu_p::read_cycle(unsigned addr, reg_t& val) { auto cycle_val = this->reg.icount + cycle_offset; if(addr == mcycle) { val = static_cast(cycle_val); @@ -1094,7 +1094,7 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::write_cycle(unsigned addr, reg_t val) { +template iss::status riscv_hart_mu_p::write_cycle(unsigned addr, reg_t val) { if(sizeof(typename traits::reg_t) != 4) { mcycle_csr = static_cast(val); } else { @@ -1108,7 +1108,7 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::read_instret(unsigned addr, reg_t& val) { +template iss::status riscv_hart_mu_p::read_instret(unsigned addr, reg_t& val) { if((addr & 0xff) == (minstret & 0xff)) { val = static_cast(this->reg.instret); } else if((addr & 0xff) == (minstreth & 0xff)) { @@ -1117,7 +1117,7 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::write_instret(unsigned addr, reg_t val) { +template iss::status riscv_hart_mu_p::write_instret(unsigned addr, reg_t val) { if(sizeof(typename traits::reg_t) != 4) { this->reg.instret = static_cast(val); } else { @@ -1131,7 +1131,7 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::read_time(unsigned addr, reg_t& val) { +template iss::status riscv_hart_mu_p::read_time(unsigned addr, reg_t& val) { uint64_t time_val = this->reg.icount / (100000000 / 32768 - 1); //-> ~3052; if(addr == time) { val = static_cast(time_val); @@ -1143,22 +1143,22 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::read_tvec(unsigned addr, reg_t& val) { +template iss::status riscv_hart_mu_p::read_tvec(unsigned addr, reg_t& val) { val = FEAT & features_e::FEAT_CLIC ? csr[addr] : csr[addr] & ~2; return iss::Ok; } -template iss::status riscv_hart_mu_p::read_status(unsigned addr, reg_t& val) { +template iss::status riscv_hart_mu_p::read_status(unsigned addr, reg_t& val) { 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) { +template iss::status riscv_hart_mu_p::write_status(unsigned addr, reg_t val) { state.write_mstatus(val, (addr >> 8) & 0x3); check_interrupt(); return iss::Ok; } -template iss::status riscv_hart_mu_p::read_cause(unsigned addr, reg_t& val) { +template iss::status riscv_hart_mu_p::read_cause(unsigned addr, reg_t& val) { if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec] & 0x3) == 3) { val = csr[addr] & ((1UL << (traits::XLEN - 1)) | (mcause_max_irq - 1) | (0xfUL << 16)); auto mode = (addr >> 8) & 0x3; @@ -1178,7 +1178,7 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::write_cause(unsigned addr, reg_t val) { +template iss::status riscv_hart_mu_p::write_cause(unsigned addr, reg_t val) { if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec] & 0x3) == 3) { auto mask = ((1UL << (traits::XLEN - 1)) | (mcause_max_irq - 1) | (0xfUL << 16)); csr[addr] = (val & mask) | (csr[addr] & ~mask); @@ -1201,12 +1201,12 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::read_hartid(unsigned addr, reg_t& val) { +template iss::status riscv_hart_mu_p::read_hartid(unsigned addr, reg_t& val) { val = mhartid_reg; return iss::Ok; } -template iss::status riscv_hart_mu_p::read_ie(unsigned addr, reg_t& val) { +template iss::status riscv_hart_mu_p::read_ie(unsigned addr, reg_t& val) { auto mask = get_irq_mask((addr >> 8) & 0x3); val = csr[mie] & mask; if(this->reg.PRIV != 3) @@ -1214,14 +1214,14 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::write_ie(unsigned addr, reg_t val) { +template iss::status riscv_hart_mu_p::write_ie(unsigned addr, reg_t val) { auto mask = get_irq_mask((addr >> 8) & 0x3); csr[mie] = (csr[mie] & ~mask) | (val & mask); check_interrupt(); return iss::Ok; } -template iss::status riscv_hart_mu_p::read_ip(unsigned addr, reg_t& val) { +template iss::status riscv_hart_mu_p::read_ip(unsigned addr, reg_t& val) { auto mask = get_irq_mask((addr >> 8) & 0x3); val = csr[mip] & mask; if(this->reg.PRIV != 3) @@ -1229,24 +1229,24 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::write_ideleg(unsigned addr, reg_t val) { +template iss::status riscv_hart_mu_p::write_ideleg(unsigned addr, reg_t val) { auto mask = 0b000100010001; // only U mode supported csr[mideleg] = (csr[mideleg] & ~mask) | (val & mask); return iss::Ok; } -template iss::status riscv_hart_mu_p::write_edeleg(unsigned addr, reg_t val) { +template iss::status riscv_hart_mu_p::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 csr[medeleg] = (csr[medeleg] & ~mask) | (val & mask); return iss::Ok; } -template iss::status riscv_hart_mu_p::write_epc(unsigned addr, reg_t val) { +template iss::status riscv_hart_mu_p::write_epc(unsigned addr, reg_t val) { csr[addr] = val & get_pc_mask(); return iss::Ok; } -template iss::status riscv_hart_mu_p::write_dcsr_dcsr(unsigned addr, reg_t val) { +template iss::status riscv_hart_mu_p::write_dcsr_dcsr(unsigned addr, reg_t val) { if(!debug_mode_active()) throw illegal_instruction_fault(this->fault_data); // +-------------- ebreakm @@ -1257,35 +1257,35 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::read_dcsr_reg(unsigned addr, reg_t& val) { +template iss::status riscv_hart_mu_p::read_dcsr_reg(unsigned addr, reg_t& val) { if(!debug_mode_active()) throw illegal_instruction_fault(this->fault_data); val = csr[addr]; return iss::Ok; } -template iss::status riscv_hart_mu_p::write_dcsr_reg(unsigned addr, reg_t val) { +template iss::status riscv_hart_mu_p::write_dcsr_reg(unsigned addr, reg_t val) { if(!debug_mode_active()) throw illegal_instruction_fault(this->fault_data); csr[addr] = val; return iss::Ok; } -template iss::status riscv_hart_mu_p::read_dpc_reg(unsigned addr, reg_t& val) { +template iss::status riscv_hart_mu_p::read_dpc_reg(unsigned addr, reg_t& val) { if(!debug_mode_active()) throw illegal_instruction_fault(this->fault_data); val = this->reg.DPC; return iss::Ok; } -template iss::status riscv_hart_mu_p::write_dpc_reg(unsigned addr, reg_t val) { +template iss::status riscv_hart_mu_p::write_dpc_reg(unsigned addr, reg_t val) { if(!debug_mode_active()) throw illegal_instruction_fault(this->fault_data); this->reg.DPC = val; return iss::Ok; } -template iss::status riscv_hart_mu_p::read_intstatus(unsigned addr, reg_t& val) { +template iss::status riscv_hart_mu_p::read_intstatus(unsigned addr, reg_t& val) { auto mode = (addr >> 8) & 0x3; val = clic_uact_lvl & 0xff; if(mode == 0x3) @@ -1293,18 +1293,18 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::write_intthresh(unsigned addr, reg_t val) { +template iss::status riscv_hart_mu_p::write_intthresh(unsigned addr, reg_t val) { csr[addr] = (val & 0xff) | (1 << (cfg.clic_int_ctl_bits)) - 1; return iss::Ok; } -template iss::status riscv_hart_mu_p::write_xtvt(unsigned addr, reg_t val) { +template iss::status riscv_hart_mu_p::write_xtvt(unsigned addr, reg_t val) { csr[addr] = val & ~0x3fULL; return iss::Ok; } -template -iss::status riscv_hart_mu_p::read_mem(phys_addr_t paddr, unsigned length, uint8_t* const data) { +template +iss::status riscv_hart_mu_p::read_mem(phys_addr_t paddr, unsigned length, uint8_t* const data) { switch(paddr.val) { default: { for(auto offs = 0U; offs < length; ++offs) { @@ -1315,8 +1315,8 @@ iss::status riscv_hart_mu_p::read_mem(phys_addr_t paddr, unsigned le return iss::Ok; } -template -iss::status riscv_hart_mu_p::write_mem(phys_addr_t paddr, unsigned length, const uint8_t* const data) { +template +iss::status riscv_hart_mu_p::write_mem(phys_addr_t paddr, unsigned length, const uint8_t* const data) { switch(paddr.val) { // TODO remove UART, Peripherals should not be part of the ISS case 0xFFFF0000: // UART0 base, TXFIFO reg @@ -1377,8 +1377,8 @@ iss::status riscv_hart_mu_p::write_mem(phys_addr_t paddr, unsigned l return iss::Ok; } -template -iss::status riscv_hart_mu_p::read_clic(uint64_t addr, unsigned length, uint8_t* const data) { +template +iss::status riscv_hart_mu_p::read_clic(uint64_t addr, unsigned length, uint8_t* const data) { if(addr == cfg.clic_base) { // cliccfg *data = clic_cfg_reg; for(auto i = 1; i < length; ++i) @@ -1397,8 +1397,8 @@ iss::status riscv_hart_mu_p::read_clic(uint64_t addr, unsigned lengt return iss::Ok; } -template -iss::status riscv_hart_mu_p::write_clic(uint64_t addr, unsigned length, const uint8_t* const data) { +template +iss::status riscv_hart_mu_p::write_clic(uint64_t addr, unsigned length, const uint8_t* const data) { if(addr == cfg.clic_base) { // cliccfg clic_cfg_reg = (clic_cfg_reg & ~0x1e) | (*data & 0x1e); } else if(addr >= (cfg.clic_base + 0x40) && (addr + length) <= (cfg.clic_base + 0x40 + cfg.clic_num_trigger * 4)) { // clicinttrig @@ -1413,12 +1413,12 @@ iss::status riscv_hart_mu_p::write_clic(uint64_t addr, unsigned leng return iss::Ok; } -template inline void riscv_hart_mu_p::reset(uint64_t address) { +template inline void riscv_hart_mu_p::reset(uint64_t address) { BASE::reset(address); state.mstatus = hart_state_type::mstatus_reset_val; } -template void riscv_hart_mu_p::check_interrupt() { +template void riscv_hart_mu_p::check_interrupt() { // TODO: Implement CLIC functionality auto ideleg = csr[mideleg]; // Multiple simultaneous interrupts and traps at the same privilege level are @@ -1441,7 +1441,7 @@ template void riscv_hart_mu_p::chec } } -template uint64_t riscv_hart_mu_p::enter_trap(uint64_t flags, uint64_t addr, uint64_t instr) { +template uint64_t riscv_hart_mu_p::enter_trap(uint64_t flags, uint64_t addr, uint64_t instr) { // flags are ACTIVE[31:31], CAUSE[30:16], TRAPID[15:0] // calculate and write mcause val if(flags == std::numeric_limits::max()) @@ -1575,7 +1575,7 @@ template uint64_t riscv_hart_mu_p:: return this->reg.NEXT_PC; } -template uint64_t riscv_hart_mu_p::leave_trap(uint64_t flags) { +template uint64_t riscv_hart_mu_p::leave_trap(uint64_t flags) { auto cur_priv = this->reg.PRIV; auto inst_priv = (flags & 0x3) ? 3 : 0; if(inst_priv > cur_priv) {