Restructured DBT function to encapsulate the compilation process
This should enable the implementation of multi-threading of the compilation process
This commit is contained in:
@ -222,6 +222,7 @@ struct vm_info {
|
||||
int idxbits;
|
||||
int ptesize;
|
||||
uint64_t ptbase;
|
||||
bool is_active() { return levels;}
|
||||
};
|
||||
|
||||
class trap_load_access_fault : public trap_access {
|
||||
@ -450,7 +451,7 @@ public:
|
||||
|
||||
void load_file(std::string name, int type = -1) override;
|
||||
|
||||
virtual phys_addr_t v2p(const iss::addr_t &addr);
|
||||
virtual phys_addr_t virt2phys(const iss::addr_t &addr) override;
|
||||
|
||||
iss::status read(const iss::addr_t &addr, unsigned length, uint8_t *const data) override;
|
||||
iss::status write(const iss::addr_t &addr, unsigned length, const uint8_t *const data) override;
|
||||
@ -460,8 +461,6 @@ public:
|
||||
virtual uint64_t leave_trap(uint64_t flags) override;
|
||||
void wait_until(uint64_t flags) override;
|
||||
|
||||
void notify_phase(iss::arch_if::exec_phase phase);
|
||||
|
||||
void disass_output(uint64_t pc, const std::string instr) override {
|
||||
std::stringstream s;
|
||||
s << "[p:" << lvl[this->reg.machine_state] << ";s:0x" << std::hex << std::setfill('0')
|
||||
@ -486,6 +485,8 @@ protected:
|
||||
mem_type mem;
|
||||
csr_type csr;
|
||||
hart_state<reg_t> state;
|
||||
vm_info vm[2];
|
||||
void update_vm_info();
|
||||
unsigned to_host_wr_cnt = 0;
|
||||
std::stringstream uart_buf;
|
||||
std::unordered_map<reg_t, uint64_t> ptw;
|
||||
@ -571,7 +572,7 @@ template <typename BASE> void riscv_hart_msu_vp<BASE>::load_file(std::string nam
|
||||
const auto seg_data = pseg->get_data();
|
||||
if (fsize > 0) {
|
||||
auto res = this->write(
|
||||
typed_addr_t<PHYSICAL>(iss::DEBUG_WRITE, traits<BASE>::MEM, pseg->get_physical_address()),
|
||||
phys_addr_t(iss::access_type::DEBUG_WRITE, traits<BASE>::MEM, pseg->get_physical_address()),
|
||||
fsize, reinterpret_cast<const uint8_t *const>(seg_data));
|
||||
if (res != iss::Ok)
|
||||
LOG(ERROR) << "problem writing " << fsize << "bytes to 0x" << std::hex
|
||||
@ -586,13 +587,15 @@ template <typename BASE> void riscv_hart_msu_vp<BASE>::load_file(std::string nam
|
||||
}
|
||||
return;
|
||||
}
|
||||
throw std::runtime_error("memory load file is not a valid elf file");
|
||||
}
|
||||
throw std::runtime_error("memory load file not found");
|
||||
}
|
||||
|
||||
template <typename BASE>
|
||||
iss::status riscv_hart_msu_vp<BASE>::read(const iss::addr_t &addr, unsigned length, uint8_t *const data) {
|
||||
#ifndef NDEBUG
|
||||
if (addr.type & iss::DEBUG) {
|
||||
if (addr.access && iss::access_type::DEBUG) {
|
||||
LOG(DEBUG) << "debug read of " << length << " bytes @addr " << addr;
|
||||
} else {
|
||||
LOG(DEBUG) << "read of " << length << " bytes @addr " << addr;
|
||||
@ -601,9 +604,9 @@ iss::status riscv_hart_msu_vp<BASE>::read(const iss::addr_t &addr, unsigned leng
|
||||
try {
|
||||
switch (addr.space) {
|
||||
case traits<BASE>::MEM: {
|
||||
if ((addr.type & (iss::ACCESS_TYPE - iss::DEBUG)) == iss::FETCH && (addr.val & 0x1) == 1) {
|
||||
if ((addr.access == iss::access_type::FETCH || addr.access == iss::access_type::DEBUG_FETCH) && (addr.val & 0x1) == 1) {
|
||||
fault_data = addr.val;
|
||||
if ((addr.type & iss::DEBUG)) throw trap_access(0, addr.val);
|
||||
if (addr.access && iss::access_type::DEBUG) throw trap_access(0, addr.val);
|
||||
this->reg.trap_state = (1 << 31); // issue trap 0
|
||||
return iss::Err;
|
||||
}
|
||||
@ -615,12 +618,11 @@ iss::status riscv_hart_msu_vp<BASE>::read(const iss::addr_t &addr, unsigned leng
|
||||
auto len1 = split_addr - addr.val;
|
||||
auto res = read(addr, len1, data);
|
||||
if (res == iss::Ok)
|
||||
res = read(iss::addr_t{addr.type, addr.space, split_addr}, length - len1, data + len1);
|
||||
res = read(iss::addr_t{addr.access, addr.type, addr.space, split_addr}, length - len1, data + len1);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
phys_addr_t paddr = (addr.type & iss::ADDRESS_TYPE) == iss::PHYSICAL ? addr : v2p(addr);
|
||||
auto res = read_mem(paddr, length, data);
|
||||
auto res = read_mem( BASE::v2p(addr), length, data);
|
||||
if (res != iss::Ok) this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 5 (load access fault
|
||||
return res;
|
||||
} catch (trap_access &ta) {
|
||||
@ -668,7 +670,7 @@ iss::status riscv_hart_msu_vp<BASE>::read(const iss::addr_t &addr, unsigned leng
|
||||
template <typename BASE>
|
||||
iss::status riscv_hart_msu_vp<BASE>::write(const iss::addr_t &addr, unsigned length, const uint8_t *const data) {
|
||||
#ifndef NDEBUG
|
||||
const char *prefix = addr.type & iss::DEBUG ? "debug " : "";
|
||||
const char *prefix = (addr.access && iss::access_type::DEBUG)? "debug " : "";
|
||||
switch (length) {
|
||||
case 8:
|
||||
LOG(DEBUG) << prefix << "write of " << length << " bytes (0x" << std::hex << *(uint64_t *)&data[0] << std::dec
|
||||
@ -693,9 +695,9 @@ iss::status riscv_hart_msu_vp<BASE>::write(const iss::addr_t &addr, unsigned len
|
||||
try {
|
||||
switch (addr.space) {
|
||||
case traits<BASE>::MEM: {
|
||||
if ((addr.type & (iss::ACCESS_TYPE - iss::DEBUG)) == iss::FETCH && (addr.val & 0x1) == 1) {
|
||||
if ((addr.access && iss::access_type::FETCH) && (addr.val & 0x1) == 1) {
|
||||
fault_data = addr.val;
|
||||
if ((addr.type & iss::DEBUG)) throw trap_access(0, addr.val);
|
||||
if (addr.access && iss::access_type::DEBUG) throw trap_access(0, addr.val);
|
||||
this->reg.trap_state = (1 << 31); // issue trap 0
|
||||
return iss::Err;
|
||||
}
|
||||
@ -707,12 +709,11 @@ iss::status riscv_hart_msu_vp<BASE>::write(const iss::addr_t &addr, unsigned len
|
||||
auto len1 = split_addr - addr.val;
|
||||
auto res = write(addr, len1, data);
|
||||
if (res == iss::Ok)
|
||||
res = write(iss::addr_t{addr.type, addr.space, split_addr}, length - len1, data + len1);
|
||||
res = write(iss::addr_t{addr.access, addr.type, addr.space, split_addr}, length - len1, data + len1);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
phys_addr_t paddr = (addr.type & iss::ADDRESS_TYPE) == iss::PHYSICAL ? addr : v2p(addr);
|
||||
auto res = write_mem(paddr, length, data);
|
||||
auto res = write_mem(BASE::v2p(addr), length, data);
|
||||
if (res != iss::Ok) this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 7 (Store/AMO access fault)
|
||||
return res;
|
||||
} catch (trap_access &ta) {
|
||||
@ -720,7 +721,7 @@ iss::status riscv_hart_msu_vp<BASE>::write(const iss::addr_t &addr, unsigned len
|
||||
return iss::Err;
|
||||
}
|
||||
|
||||
phys_addr_t paddr = (addr.type & iss::ADDRESS_TYPE) == iss::PHYSICAL ? addr : v2p(addr);
|
||||
phys_addr_t paddr = BASE::v2p(addr);
|
||||
if ((paddr.val + length) > mem.size()) return iss::Err;
|
||||
switch (paddr.val) {
|
||||
case 0x10013000: // UART0 base, TXFIFO reg
|
||||
@ -842,6 +843,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_status(unsig
|
||||
if (this->reg.machine_state < req_priv_lvl) throw illegal_instruction_fault(this->fault_data);
|
||||
state.write_mstatus(val, req_priv_lvl);
|
||||
check_interrupt();
|
||||
update_vm_info();
|
||||
return iss::Ok;
|
||||
}
|
||||
|
||||
@ -901,6 +903,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_satp(unsigne
|
||||
return iss::Err;
|
||||
}
|
||||
state.satp = val;
|
||||
update_vm_info();
|
||||
return iss::Ok;
|
||||
}
|
||||
|
||||
@ -909,8 +912,9 @@ iss::status riscv_hart_msu_vp<BASE>::read_mem(phys_addr_t paddr, unsigned length
|
||||
if ((paddr.val + length) > mem.size()) return iss::Err;
|
||||
switch (paddr.val) {
|
||||
case 0x0200BFF8: { // CLINT base, mtime reg
|
||||
if(sizeof(reg_t)<length) return iss::Err;
|
||||
reg_t time_val=this->csr[time];
|
||||
if(sizeof(reg_t)<length) return iss::Err;
|
||||
reg_t time_val;
|
||||
this->read_csr(time, time_val);
|
||||
std::copy((uint8_t *)&time_val, ((uint8_t *)&time_val) + length, data);
|
||||
} break;
|
||||
case 0x10008000: {
|
||||
@ -960,7 +964,7 @@ iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_addr_t paddr, unsigned lengt
|
||||
mem_type::page_type &p = mem(paddr.val / mem.page_size);
|
||||
std::copy(data, data + length, p.data() + (paddr.val & mem.page_addr_mask));
|
||||
// tohost handling in case of riscv-test
|
||||
if ((paddr.type & iss::DEBUG) == 0) {
|
||||
if (paddr.access && iss::access_type::FUNC) {
|
||||
auto tohost_upper = (traits<BASE>::XLEN == 32 && paddr.val == (tohost + 4)) ||
|
||||
(traits<BASE>::XLEN == 64 && paddr.val == tohost);
|
||||
auto tohost_lower =
|
||||
@ -1003,15 +1007,23 @@ iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_addr_t paddr, unsigned lengt
|
||||
return iss::Ok;
|
||||
}
|
||||
|
||||
template<typename BASE>
|
||||
inline void riscv_hart_msu_vp<BASE>::notify_phase(iss::arch_if::exec_phase phase) {
|
||||
BASE::notify_phase(phase);
|
||||
}
|
||||
|
||||
template<typename BASE>
|
||||
inline void riscv_hart_msu_vp<BASE>::reset(uint64_t address) {
|
||||
BASE::reset(address);
|
||||
state.mstatus = hart_state<reg_t>::mstatus_reset_val;
|
||||
update_vm_info();
|
||||
}
|
||||
|
||||
template<typename BASE>
|
||||
inline void riscv_hart_msu_vp<BASE>::update_vm_info() {
|
||||
vm[1] = hart_state<reg_t>::decode_vm_info(this->reg.machine_state, state.satp);
|
||||
BASE::addr_mode[3]=BASE::addr_mode[2]=vm[1].is_active()?iss::address_type::VIRTUAL:iss::address_type::PHYSICAL;
|
||||
if(state.mstatus.MPRV)
|
||||
vm[0] = hart_state<reg_t>::decode_vm_info(state.mstatus.MPP, state.satp);
|
||||
else
|
||||
vm[0] = vm[1];
|
||||
BASE::addr_mode[1]=BASE::addr_mode[0]=vm[0].is_active()?iss::address_type::VIRTUAL:iss::address_type::PHYSICAL;
|
||||
ptw.clear();
|
||||
}
|
||||
|
||||
template <typename BASE> void riscv_hart_msu_vp<BASE>::check_interrupt() {
|
||||
@ -1042,37 +1054,12 @@ template <typename BASE> void riscv_hart_msu_vp<BASE>::check_interrupt() {
|
||||
}
|
||||
|
||||
template <typename BASE>
|
||||
typename riscv_hart_msu_vp<BASE>::phys_addr_t riscv_hart_msu_vp<BASE>::v2p(const iss::addr_t &addr) {
|
||||
const uint64_t tmp = reg_t(1) << (traits<BASE>::XLEN - 1);
|
||||
const uint64_t msk = tmp | (tmp - 1);
|
||||
|
||||
if (addr.space != traits<BASE>::MEM) { // non-memory access
|
||||
phys_addr_t ret(addr);
|
||||
ret.val &= msk;
|
||||
return ret;
|
||||
}
|
||||
|
||||
const auto type = (access_type)(addr.getAccessType() & ~iss::DEBUG);
|
||||
uint32_t mode = type != iss::FETCH && state.mstatus.MPRV ? // MPRV
|
||||
mode = state.mstatus.MPP:
|
||||
this->reg.machine_state;
|
||||
|
||||
const vm_info vm = hart_state<reg_t>::decode_vm_info(mode, state.satp);
|
||||
|
||||
if (vm.levels == 0) {
|
||||
phys_addr_t ret(addr);
|
||||
ret.val &= msk;
|
||||
return ret;
|
||||
}
|
||||
|
||||
const bool s_mode = mode == PRIV_S;
|
||||
const bool sum = state.mstatus.SUM;
|
||||
const bool mxr = state.mstatus.MXR;
|
||||
|
||||
typename riscv_hart_msu_vp<BASE>::phys_addr_t riscv_hart_msu_vp<BASE>::virt2phys(const iss::addr_t &addr) {
|
||||
const auto type = addr.access & iss::access_type::FUNC;
|
||||
auto it = ptw.find(addr.val >> PGSHIFT);
|
||||
if (it != ptw.end()) {
|
||||
const reg_t pte = it->second;
|
||||
const reg_t ad = PTE_A | ((type == iss::WRITE) * PTE_D);
|
||||
const reg_t ad = PTE_A | (type == iss::access_type::WRITE) * PTE_D;
|
||||
#ifdef RISCV_ENABLE_DIRTY
|
||||
// set accessed and possibly dirty bits.
|
||||
*(uint32_t *)ppte |= ad;
|
||||
@ -1080,11 +1067,21 @@ typename riscv_hart_msu_vp<BASE>::phys_addr_t riscv_hart_msu_vp<BASE>::v2p(const
|
||||
#else
|
||||
// take exception if access or possibly dirty bit is not set.
|
||||
if ((pte & ad) == ad)
|
||||
return {addr.getAccessType(), addr.space, (pte & (~PGMASK)) | (addr.val & PGMASK)};
|
||||
return {addr.access, addr.space, (pte & (~PGMASK)) | (addr.val & PGMASK)};
|
||||
else
|
||||
ptw.erase(it);
|
||||
ptw.erase(it); // throw an exception
|
||||
#endif
|
||||
} else {
|
||||
uint32_t mode = type != iss::access_type::FETCH && state.mstatus.MPRV ? // MPRV
|
||||
state.mstatus.MPP:
|
||||
this->reg.machine_state;
|
||||
|
||||
const vm_info& vm = this->vm[static_cast<uint16_t>(type)/2];
|
||||
|
||||
const bool s_mode = mode == PRIV_S;
|
||||
const bool sum = state.mstatus.SUM;
|
||||
const bool mxr = state.mstatus.MXR;
|
||||
|
||||
// verify bits xlen-1:va_bits-1 are all equal
|
||||
const int va_bits = PGSHIFT + vm.levels * vm.idxbits;
|
||||
const reg_t mask = (reg_t(1) << (traits<BASE>::XLEN > -(va_bits - 1))) - 1;
|
||||
@ -1099,25 +1096,24 @@ typename riscv_hart_msu_vp<BASE>::phys_addr_t riscv_hart_msu_vp<BASE>::v2p(const
|
||||
// check that physical address of PTE is legal
|
||||
reg_t pte = 0;
|
||||
const uint8_t res =
|
||||
this->read(phys_addr_t(addr.getAccessType(), traits<BASE>::MEM, base + idx * vm.ptesize), vm.ptesize,
|
||||
(uint8_t *)&pte);
|
||||
this->read(phys_addr_t{addr.access, traits<BASE>::MEM, base + idx * vm.ptesize}, vm.ptesize, (uint8_t *)&pte);
|
||||
if (res != 0) throw trap_load_access_fault(addr.val);
|
||||
const reg_t ppn = pte >> PTE_PPN_SHIFT;
|
||||
|
||||
if (PTE_TABLE(pte)) { // next level of page table
|
||||
base = ppn << PGSHIFT;
|
||||
} else if ((pte & PTE_U) ? s_mode && (type == iss::FETCH || !sum) : !s_mode) {
|
||||
} else if ((pte & PTE_U) ? s_mode && (type == iss::access_type::FETCH || !sum) : !s_mode) {
|
||||
break;
|
||||
} else if (!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) {
|
||||
break;
|
||||
} else if (type == iss::FETCH ? !(pte & PTE_X)
|
||||
: type == iss::READ ? !(pte & PTE_R) && !(mxr && (pte & PTE_X))
|
||||
} else if (type == iss::access_type::FETCH ? !(pte & PTE_X)
|
||||
: type == iss::access_type::READ ? !(pte & PTE_R) && !(mxr && (pte & PTE_X))
|
||||
: !((pte & PTE_R) && (pte & PTE_W))) {
|
||||
break;
|
||||
} else if ((ppn & ((reg_t(1) << ptshift) - 1)) != 0) {
|
||||
break;
|
||||
} else {
|
||||
const reg_t ad = PTE_A | ((type == iss::WRITE) * PTE_D);
|
||||
const reg_t ad = PTE_A | ((type == iss::access_type::WRITE) * PTE_D);
|
||||
#ifdef RISCV_ENABLE_DIRTY
|
||||
// set accessed and possibly dirty bits.
|
||||
*(uint32_t *)ppte |= ad;
|
||||
@ -1130,18 +1126,18 @@ typename riscv_hart_msu_vp<BASE>::phys_addr_t riscv_hart_msu_vp<BASE>::v2p(const
|
||||
const reg_t value = (ppn | (vpn & ((reg_t(1) << ptshift) - 1))) << PGSHIFT;
|
||||
const reg_t offset = addr.val & PGMASK;
|
||||
ptw[vpn] = value | (pte & 0xff);
|
||||
return {addr.getAccessType(), addr.space, value | offset};
|
||||
return {addr.access, addr.space, value | offset};
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (type) {
|
||||
case FETCH:
|
||||
case access_type::FETCH:
|
||||
this->fault_data = addr.val;
|
||||
throw trap_instruction_page_fault(addr.val);
|
||||
case READ:
|
||||
case access_type::READ:
|
||||
this->fault_data = addr.val;
|
||||
throw trap_load_page_fault(addr.val);
|
||||
case WRITE:
|
||||
case access_type::WRITE:
|
||||
this->fault_data = addr.val;
|
||||
throw trap_store_page_fault(addr.val);
|
||||
default:
|
||||
@ -1217,6 +1213,7 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t f
|
||||
CLOG(INFO, disass) << (trap_id ? "Interrupt" : "Trap") << " with cause '" << (trap_id ? irq_str[cause] : trap_str[cause])<<"' ("<<trap_id<<")"
|
||||
<< " at address " << buffer << " occurred, changing privilege level from " << lvl[cur_priv]
|
||||
<< " to " << lvl[new_priv];
|
||||
update_vm_info();
|
||||
return this->reg.NEXT_PC;
|
||||
}
|
||||
|
||||
@ -1253,6 +1250,7 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::leave_trap(uint64_t f
|
||||
// sets the pc to the value stored in the x epc register.
|
||||
this->reg.NEXT_PC = csr[uepc | inst_priv << 8];
|
||||
CLOG(INFO, disass) << "Executing xRET , changing privilege level from " << lvl[cur_priv] << " to " << lvl[this->reg.machine_state];
|
||||
update_vm_info();
|
||||
return this->reg.NEXT_PC;
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Created on: Sun Nov 19 14:05:47 CET 2017
|
||||
// Created on: Fri Dec 15 14:41:57 CET 2017
|
||||
// * rv32imac.h Author: <CoreDSL Generator>
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -98,9 +98,9 @@ struct traits<rv32imac> {
|
||||
|
||||
using code_word_t = uint32_t; //TODO: check removal
|
||||
|
||||
using virt_addr_t = iss::typed_addr_t<iss::VIRTUAL>;
|
||||
using virt_addr_t = iss::typed_addr_t<iss::address_type::VIRTUAL>;
|
||||
|
||||
using phys_addr_t = iss::typed_addr_t<iss::PHYSICAL>;
|
||||
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
|
||||
|
||||
constexpr static unsigned reg_bit_width(unsigned r) {
|
||||
const uint32_t RV32IMAC_reg_size[] = {32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64};
|
||||
@ -112,6 +112,8 @@ struct traits<rv32imac> {
|
||||
return RV32IMAC_reg_byte_offset[r];
|
||||
}
|
||||
|
||||
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
|
||||
|
||||
enum sreg_flag_e {FLAGS};
|
||||
|
||||
enum mem_type_e {MEM,CSR,FENCE,RES};
|
||||
@ -140,19 +142,20 @@ struct rv32imac: public arch_if {
|
||||
/// deprecated
|
||||
void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {};
|
||||
|
||||
void notify_phase(exec_phase phase){
|
||||
if(phase==ISTART){
|
||||
++reg.icount;
|
||||
reg.PC=reg.NEXT_PC;
|
||||
reg.trap_state=reg.pending_trap;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t get_icount() { return reg.icount;}
|
||||
|
||||
virtual phys_addr_t v2p(const iss::addr_t& pc);
|
||||
inline phys_addr_t v2p(const iss::addr_t& addr){
|
||||
if(addr.space != traits<rv32imac>::MEM ||
|
||||
addr.type == iss::address_type::PHYSICAL ||
|
||||
addr_mode[static_cast<uint16_t>(addr.access)&0x3]==address_type::PHYSICAL){
|
||||
return phys_addr_t(addr.access, addr.space, addr.val&traits<rv32imac>::addr_mask);
|
||||
} else
|
||||
return virt2phys(addr);
|
||||
}
|
||||
|
||||
virtual iss::sync_type needed_sync() const { return iss::PRE_SYNC; }
|
||||
virtual phys_addr_t virt2phys(const iss::addr_t& addr);
|
||||
|
||||
virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; }
|
||||
|
||||
protected:
|
||||
struct RV32IMAC_regs {
|
||||
@ -193,6 +196,8 @@ protected:
|
||||
uint32_t trap_state, pending_trap, machine_state;
|
||||
uint64_t icount;
|
||||
} reg;
|
||||
|
||||
address_type addr_mode[4];
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -28,7 +28,7 @@
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Created on: Sun Nov 19 14:05:47 CET 2017
|
||||
// Created on: Fri Dec 15 14:41:58 CET 2017
|
||||
// * rv64ia.h Author: <CoreDSL Generator>
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -98,9 +98,9 @@ struct traits<rv64ia> {
|
||||
|
||||
using code_word_t = uint64_t; //TODO: check removal
|
||||
|
||||
using virt_addr_t = iss::typed_addr_t<iss::VIRTUAL>;
|
||||
using virt_addr_t = iss::typed_addr_t<iss::address_type::VIRTUAL>;
|
||||
|
||||
using phys_addr_t = iss::typed_addr_t<iss::PHYSICAL>;
|
||||
using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
|
||||
|
||||
constexpr static unsigned reg_bit_width(unsigned r) {
|
||||
const uint32_t RV64IA_reg_size[] = {64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,32,32,32,64};
|
||||
@ -112,6 +112,8 @@ struct traits<rv64ia> {
|
||||
return RV64IA_reg_byte_offset[r];
|
||||
}
|
||||
|
||||
static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1);
|
||||
|
||||
enum sreg_flag_e {FLAGS};
|
||||
|
||||
enum mem_type_e {MEM,CSR,FENCE,RES};
|
||||
@ -140,19 +142,20 @@ struct rv64ia: public arch_if {
|
||||
/// deprecated
|
||||
void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {};
|
||||
|
||||
void notify_phase(exec_phase phase){
|
||||
if(phase==ISTART){
|
||||
++reg.icount;
|
||||
reg.PC=reg.NEXT_PC;
|
||||
reg.trap_state=reg.pending_trap;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t get_icount() { return reg.icount;}
|
||||
|
||||
virtual phys_addr_t v2p(const iss::addr_t& pc);
|
||||
inline phys_addr_t v2p(const iss::addr_t& addr){
|
||||
if(addr.space != traits<rv64ia>::MEM ||
|
||||
addr.type == iss::address_type::PHYSICAL ||
|
||||
addr_mode[static_cast<uint16_t>(addr.access)&0x3]==address_type::PHYSICAL){
|
||||
return phys_addr_t(addr.access, addr.space, addr.val&traits<rv64ia>::addr_mask);
|
||||
} else
|
||||
return virt2phys(addr);
|
||||
}
|
||||
|
||||
virtual iss::sync_type needed_sync() const { return iss::PRE_SYNC; }
|
||||
virtual phys_addr_t virt2phys(const iss::addr_t& addr);
|
||||
|
||||
virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; }
|
||||
|
||||
protected:
|
||||
struct RV64IA_regs {
|
||||
@ -193,6 +196,8 @@ protected:
|
||||
uint32_t trap_state, pending_trap, machine_state;
|
||||
uint64_t icount;
|
||||
} reg;
|
||||
|
||||
address_type addr_mode[4];
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ status riscv_target_adapter<ARCH>::read_single_register(unsigned int reg_no, std
|
||||
std::copy(reg_base + offset, reg_base + offset + reg_width, data.begin());
|
||||
std::fill(avail.begin(), avail.end(), 0xff);
|
||||
} else {
|
||||
typed_addr_t<iss::PHYSICAL> a(iss::DEBUG_READ, traits<ARCH>::CSR, reg_no - 65);
|
||||
typed_addr_t<iss::address_type::PHYSICAL> a(iss::access_type::DEBUG_READ, traits<ARCH>::CSR, reg_no - 65);
|
||||
data.resize(sizeof(typename traits<ARCH>::reg_t));
|
||||
avail.resize(sizeof(typename traits<ARCH>::reg_t));
|
||||
std::fill(avail.begin(), avail.end(), 0xff);
|
||||
@ -228,20 +228,20 @@ status riscv_target_adapter<ARCH>::write_single_register(unsigned int reg_no, co
|
||||
auto offset = traits<ARCH>::reg_byte_offset(reg_no);
|
||||
std::copy(data.begin(), data.begin() + reg_width, reg_base + offset);
|
||||
} else {
|
||||
typed_addr_t<iss::PHYSICAL> a(iss::DEBUG_WRITE, traits<ARCH>::CSR, reg_no - 65);
|
||||
typed_addr_t<iss::address_type::PHYSICAL> a(iss::access_type::DEBUG_WRITE, traits<ARCH>::CSR, reg_no - 65);
|
||||
core->write(a, data.size(), data.data());
|
||||
}
|
||||
return Ok;
|
||||
}
|
||||
|
||||
template <typename ARCH> status riscv_target_adapter<ARCH>::read_mem(uint64_t addr, std::vector<uint8_t> &data) {
|
||||
auto a = map_addr({iss::DEBUG_READ, iss::VIRTUAL, 0, addr});
|
||||
auto a = map_addr({iss::access_type::DEBUG_READ, iss::address_type::VIRTUAL, 0, addr});
|
||||
auto f = [&]() -> status { return core->read(a, data.size(), data.data()); };
|
||||
return srv->execute_syncronized(f);
|
||||
}
|
||||
|
||||
template <typename ARCH> status riscv_target_adapter<ARCH>::write_mem(uint64_t addr, const std::vector<uint8_t> &data) {
|
||||
auto a = map_addr({iss::DEBUG_READ, iss::VIRTUAL, 0, addr});
|
||||
auto a = map_addr({iss::access_type::DEBUG_READ, iss::address_type::VIRTUAL, 0, addr});
|
||||
return srv->execute_syncronized(&arch_if::write, core, a, data.size(), data.data());
|
||||
}
|
||||
|
||||
@ -292,8 +292,8 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::packetsize_query(std
|
||||
}
|
||||
|
||||
template <typename ARCH> status riscv_target_adapter<ARCH>::add_break(int type, uint64_t addr, unsigned int length) {
|
||||
auto saddr = map_addr({iss::CODE, iss::PHYSICAL, addr});
|
||||
auto eaddr = map_addr({iss::CODE, iss::PHYSICAL, addr + length});
|
||||
auto saddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr});
|
||||
auto eaddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr + length});
|
||||
target_adapter_base::bp_lut.addEntry(++target_adapter_base::bp_count, saddr.val, eaddr.val - saddr.val);
|
||||
LOG(TRACE) << "Adding breakpoint with handle " << target_adapter_base::bp_count << " for addr 0x" << std::hex
|
||||
<< saddr.val << std::dec;
|
||||
@ -302,7 +302,7 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::add_break(int type,
|
||||
}
|
||||
|
||||
template <typename ARCH> status riscv_target_adapter<ARCH>::remove_break(int type, uint64_t addr, unsigned int length) {
|
||||
auto saddr = map_addr({iss::CODE, iss::PHYSICAL, addr});
|
||||
auto saddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr});
|
||||
unsigned handle = target_adapter_base::bp_lut.getEntry(saddr.val);
|
||||
if (handle) {
|
||||
LOG(TRACE) << "Removing breakpoint with handle " << handle << " for addr 0x" << std::hex << saddr.val
|
||||
|
Reference in New Issue
Block a user