fixes duplicate variable declaration and templates

This commit is contained in:
2023-05-27 10:20:49 +02:00
parent ee6218279e
commit a123beb301
17 changed files with 380 additions and 808 deletions

View File

@ -280,7 +280,7 @@ public:
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, this->icount + cycle_offset);
pc, instr, (reg_t)state.mstatus, this->reg.icount + cycle_offset);
};
iss::instrumentation_if *get_instrumentation_if() override { return &instr_if; }
@ -308,17 +308,17 @@ protected:
uint64_t get_next_pc() override { return arch.reg.NEXT_PC; };
uint64_t get_instr_word() override { return arch.instruction; }
uint64_t get_instr_word() override { return arch.reg.instruction; }
uint64_t get_instr_count() override { return arch.icount; }
uint64_t get_instr_count() override { return arch.reg.icount; }
uint64_t get_pendig_traps() override { return arch.trap_state; }
uint64_t get_pendig_traps() override { return arch.reg.trap_state; }
uint64_t get_total_cycles() override { return arch.icount + arch.cycle_offset; }
uint64_t get_total_cycles() override { return arch.reg.icount + arch.cycle_offset; }
void update_last_instr_cycles(unsigned cycles) override { arch.cycle_offset += cycles - 1; };
bool is_branch_taken() override { return arch.last_branch; };
bool is_branch_taken() override { return arch.reg.last_branch; };
riscv_hart_m_p<BASE, FEAT> &arch;
};
@ -657,12 +657,12 @@ iss::status riscv_hart_m_p<BASE, FEAT>::read(const address_type type, const acce
if (unlikely(is_fetch(access) && (addr&(alignment-1)))) {
fault_data = addr;
if (is_debug(access)) throw trap_access(0, addr);
this->trap_state = (1UL << 31); // issue trap 0
this->reg.trap_state = (1UL << 31); // issue trap 0
return iss::Err;
}
try {
if(!is_debug(access) && (addr&(alignment-1))){
this->trap_state = (1UL << 31) | 4<<16;
this->reg.trap_state = (1UL << 31) | 4<<16;
fault_data=addr;
return iss::Err;
}
@ -681,12 +681,12 @@ iss::status riscv_hart_m_p<BASE, FEAT>::read(const address_type type, const acce
res = hart_mem_rd_delegate( phys_addr, length, data);
}
if (unlikely(res != iss::Ok)){
this->trap_state = (1UL << 31) | (5 << 16); // issue trap 5 (load access fault
this->reg.trap_state = (1UL << 31) | (5 << 16); // issue trap 5 (load access fault
fault_data=addr;
}
return res;
} catch (trap_access &ta) {
this->trap_state = (1UL << 31) | ta.id;
this->reg.trap_state = (1UL << 31) | ta.id;
fault_data=ta.addr;
return iss::Err;
}
@ -712,7 +712,7 @@ iss::status riscv_hart_m_p<BASE, FEAT>::read(const address_type type, const acce
}
return iss::Ok;
} catch (trap_access &ta) {
this->trap_state = (1UL << 31) | ta.id;
this->reg.trap_state = (1UL << 31) | ta.id;
fault_data=ta.addr;
return iss::Err;
}
@ -750,12 +750,12 @@ iss::status riscv_hart_m_p<BASE, FEAT>::write(const address_type type, const acc
if (unlikely((access && iss::access_type::FETCH) && (addr & 0x1) == 1)) {
fault_data = addr;
if (access && iss::access_type::DEBUG) throw trap_access(0, addr);
this->trap_state = (1UL << 31); // issue trap 0
this->reg.trap_state = (1UL << 31); // issue trap 0
return iss::Err;
}
try {
if(length>1 && (addr&(length-1)) && (access&access_type::DEBUG) != access_type::DEBUG){
this->trap_state = (1UL << 31) | 6<<16;
this->reg.trap_state = (1UL << 31) | 6<<16;
fault_data=addr;
return iss::Err;
}
@ -774,12 +774,12 @@ iss::status riscv_hart_m_p<BASE, FEAT>::write(const address_type type, const acc
res = write_mem( phys_addr, length, data);
}
if (unlikely(res != iss::Ok)) {
this->trap_state = (1UL << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault)
this->reg.trap_state = (1UL << 31) | (7 << 16); // issue trap 7 (Store/AMO access fault)
fault_data=addr;
}
return res;
} catch (trap_access &ta) {
this->trap_state = (1UL << 31) | ta.id;
this->reg.trap_state = (1UL << 31) | ta.id;
fault_data=ta.addr;
return iss::Err;
}
@ -839,7 +839,7 @@ iss::status riscv_hart_m_p<BASE, FEAT>::write(const address_type type, const acc
}
return iss::Ok;
} catch (trap_access &ta) {
this->trap_state = (1UL << 31) | ta.id;
this->reg.trap_state = (1UL << 31) | ta.id;
fault_data=ta.addr;
return iss::Err;
}
@ -885,7 +885,7 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>
}
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::read_cycle(unsigned addr, reg_t &val) {
auto cycle_val = this->icount + cycle_offset;
auto cycle_val = this->reg.icount + cycle_offset;
if (addr == mcycle) {
val = static_cast<reg_t>(cycle_val);
} else if (addr == mcycleh) {
@ -904,35 +904,35 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>
mcycle_csr = (static_cast<uint64_t>(val)<<32) + (mcycle_csr & 0xffffffff);
}
}
cycle_offset = mcycle_csr-this->icount; // TODO: relying on wrap-around
cycle_offset = mcycle_csr-this->reg.icount; // TODO: relying on wrap-around
return iss::Ok;
}
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::read_instret(unsigned addr, reg_t &val) {
if ((addr&0xff) == (minstret&0xff)) {
val = static_cast<reg_t>(this->instret);
val = static_cast<reg_t>(this->reg.instret);
} else if ((addr&0xff) == (minstreth&0xff)) {
val = static_cast<reg_t>(this->instret >> 32);
val = static_cast<reg_t>(this->reg.instret >> 32);
}
return iss::Ok;
}
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::write_instret(unsigned addr, reg_t val) {
if (sizeof(typename traits<BASE>::reg_t) != 4) {
this->instret = static_cast<uint64_t>(val);
this->reg.instret = static_cast<uint64_t>(val);
} else {
if ((addr&0xff) == (minstret&0xff)) {
this->instret = (this->instret & 0xffffffff00000000) + val;
this->reg.instret = (this->reg.instret & 0xffffffff00000000) + val;
} else {
this->instret = (static_cast<uint64_t>(val)<<32) + (this->instret & 0xffffffff);
this->reg.instret = (static_cast<uint64_t>(val)<<32) + (this->reg.instret & 0xffffffff);
}
}
this->instret--;
this->reg.instret--;
return iss::Ok;
}
template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::read_time(unsigned addr, reg_t &val) {
uint64_t time_val = this->icount / (100000000 / 32768 - 1); //-> ~3052;
uint64_t time_val = this->reg.icount / (100000000 / 32768 - 1); //-> ~3052;
if (addr == time) {
val = static_cast<reg_t>(time_val);
} else if (addr == timeh) {
@ -1074,18 +1074,6 @@ iss::status riscv_hart_m_p<BASE, FEAT>::write_xtvt(unsigned addr, reg_t val) {
template <typename BASE, features_e FEAT>
iss::status riscv_hart_m_p<BASE, FEAT>::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) {
switch (paddr.val) {
case 0x0200BFF8: { // CLINT base, mtime reg
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: {
const mem_type::page_type &p = mem(paddr.val / mem.page_size);
uint64_t offs = paddr.val & mem.page_addr_mask;
std::copy(p.data() + offs, p.data() + offs + length, data);
if (this->icount > 30000) data[3] |= 0x80;
} break;
default: {
for(auto offs=0U; offs<length; ++offs) {
*(data + offs)=mem[(paddr.val+offs)%mem.size()];
@ -1098,29 +1086,13 @@ iss::status riscv_hart_m_p<BASE, FEAT>::read_mem(phys_addr_t paddr, unsigned len
template <typename BASE, features_e FEAT>
iss::status riscv_hart_m_p<BASE, FEAT>::write_mem(phys_addr_t paddr, unsigned length, const uint8_t *const data) {
switch (paddr.val) {
case 0x10013000: // UART0 base, TXFIFO reg
case 0x10023000: // UART1 base, TXFIFO reg
uart_buf << (char)data[0];
case 0xFFFF0000: // UART0 base, TXFIFO reg
if (((char)data[0]) == '\n' || data[0] == 0) {
LOG(INFO)<<"UART"<<((paddr.val>>16)&0x3)<<" send '"<<uart_buf.str()<<"'";
std::cout << uart_buf.str();
LOG(INFO)<<"UART"<<((paddr.val>>12)&0x3)<<" send '"<<uart_buf.str()<<"'";
uart_buf.str("");
}
} else if(((char)data[0]) != '\r')
uart_buf << (char)data[0];
break;
case 0x10008000: { // HFROSC base, hfrosccfg reg
mem_type::page_type &p = mem(paddr.val / mem.page_size);
size_t offs = paddr.val & mem.page_addr_mask;
std::copy(data, data + length, p.data() + offs);
uint8_t &x = *(p.data() + offs + 3);
if (x & 0x40) x |= 0x80; // hfroscrdy = 1 if hfroscen==1
} break;
case 0x10008008: { // HFROSC base, pllcfg reg
mem_type::page_type &p = mem(paddr.val / mem.page_size);
size_t offs = paddr.val & mem.page_addr_mask;
std::copy(data, data + length, p.data() + offs);
uint8_t &x = *(p.data() + offs + 3);
x |= 0x80; // set pll lock upon writing
} break;
default: {
mem_type::page_type &p = mem(paddr.val / mem.page_size);
std::copy(data, data + length, p.data() + (paddr.val & mem.page_addr_mask));
@ -1142,7 +1114,7 @@ iss::status riscv_hart_m_p<BASE, FEAT>::write_mem(phys_addr_t paddr, unsigned le
LOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar
<< "), stopping simulation";
}
this->trap_state=std::numeric_limits<uint32_t>::max();
this->reg.trap_state=std::numeric_limits<uint32_t>::max();
this->interrupt_sim=hostvar;
break;
//throw(iss::simulation_stopped(hostvar));
@ -1227,7 +1199,7 @@ template <typename BASE, features_e FEAT> void riscv_hart_m_p<BASE, FEAT>::check
enabled_interrupts >>= 1;
res++;
}
this->pending_trap = res << 16 | 1; // 0x80 << 24 | (cause << 16) | trap_id
this->reg.pending_trap = res << 16 | 1; // 0x80 << 24 | (cause << 16) | trap_id
}
}
@ -1275,7 +1247,7 @@ template <typename BASE, features_e FEAT> uint64_t riscv_hart_m_p<BASE, FEAT>::e
fault_data = 0;
} else {
csr[mepc] = this->reg.NEXT_PC & get_pc_mask(); // store next address if interrupt
this->pending_trap = 0;
this->reg.pending_trap = 0;
}
csr[mcause] = (trap_id << (traits<BASE>::XLEN-1)) + cause;
// update mstatus
@ -1305,7 +1277,7 @@ template <typename BASE, features_e FEAT> uint64_t riscv_hart_m_p<BASE, FEAT>::e
}
// reset trap state
this->reg.PRIV = new_priv;
this->trap_state = 0;
this->reg.trap_state = 0;
std::array<char, 32> buffer;
#if defined(_MSC_VER)
sprintf(buffer.data(), "0x%016llx", addr);
@ -1326,7 +1298,7 @@ template <typename BASE, features_e FEAT> uint64_t riscv_hart_m_p<BASE, FEAT>::l
this->reg.NEXT_PC = csr[mepc] & get_pc_mask();
CLOG(INFO, disass) << "Executing xRET";
check_interrupt();
this->trap_state = this->pending_trap;
this->reg.trap_state = this->reg.pending_trap;
return this->reg.NEXT_PC;
}