checkpoint before refactor

This commit is contained in:
2021-03-06 07:17:42 +00:00
parent f7cec99fa6
commit dae8acb8a3
6 changed files with 55 additions and 29 deletions

View File

@ -54,8 +54,8 @@ void tgf_c::reset(uint64_t address) {
for(size_t i=0; i<traits<tgf_c>::NUM_REGS; ++i) set_reg(i, std::vector<uint8_t>(sizeof(traits<tgf_c>::reg_t),0));
reg.PC=address;
reg.NEXT_PC=reg.PC;
reg.PRIV=0x3;
reg.trap_state=0;
reg.machine_state=0x3;
reg.icount=0;
}

View File

@ -96,7 +96,7 @@ public:
core_wrapper(core_complex *owner)
: owner(owner) { }
uint32_t get_mode() { return this->reg.machine_state; }
uint32_t get_mode() { return this->reg.PRIV; }
inline void set_interrupt_execution(bool v) { this->interrupt_sim = v?1:0; }
@ -113,7 +113,7 @@ public:
void disass_output(uint64_t pc, const std::string instr) override {
if (INFO <= Log<Output2FILE<disass>>::reporting_level() && Output2FILE<disass>::stream()) {
std::stringstream s;
s << "[p:" << lvl[this->reg.machine_state] << ";s:0x" << std::hex << std::setfill('0')
s << "[p:" << lvl[this->reg.PRIV] << ";s:0x" << std::hex << std::setfill('0')
<< std::setw(sizeof(reg_t) * 2) << (reg_t)state.mstatus << std::dec << ";c:" << this->reg.icount << "]";
Log<Output2FILE<disass>>().get(INFO, "disass")
<< "0x" << std::setw(16) << std::right << std::setfill('0') << std::hex << pc << "\t\t" << std::setw(40)

View File

@ -914,12 +914,12 @@ private:
writeSpace2(traits::MEM, *(X+rs1) + (int16_t)imm, (int16_t)*(X+rs2));
// post execution stuff
if(this->sync_exec && POST_SYNC) this->do_sync(POST_SYNC, 16);
auto& trap_state = super::template get_reg<uint32_t>(arch::traits<ARCH>::TRAP_STATE);
auto* trap_state = reinterpret_cast<uint32_t*>(this->regs_base_ptr+arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::TRAP_STATE]);
// trap check
if(trap_state!=0){
super::core.enter_trap(trap_state, pc.val);
if(*trap_state!=0){
super::core.enter_trap(*trap_state, pc.val);
}
pc.val=super::template get_reg<reg_t>(arch::traits<ARCH>::NEXT_PC);
pc.val=*NEXT_PC;
return pc;
}
@ -1610,7 +1610,7 @@ private:
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {pred}, {succ}, {rs1}, {rd}", fmt::arg("mnemonic", "fence"),
fmt::arg("pred", name(pred)), fmt::arg("succ", name(succ)), fmt::arg("rs1", name(rs1)), fmt::arg("rd", name(rd)));
fmt::arg("pred", pred), fmt::arg("succ", succ), fmt::arg("rs1", name(rs1)), fmt::arg("rd", name(rd)));
this->core.disass_output(pc.val, mnemonic);
}
@ -1643,7 +1643,7 @@ private:
/* generate console output when executing the command */
auto mnemonic = fmt::format(
"{mnemonic:10} {rs1}, {rd}, {imm}", fmt::arg("mnemonic", "fence_i"),
fmt::arg("rs1", name(rs1)), fmt::arg("rd", name(rd)), fmt::arg("imm", name(imm)));
fmt::arg("rs1", name(rs1)), fmt::arg("rd", name(rd)), fmt::arg("imm", imm));
this->core.disass_output(pc.val, mnemonic);
}
@ -3341,6 +3341,19 @@ private:
pc = pc + ((instr & 3) == 3 ? 4 : 2);
return pc;
}
static constexpr typename traits::addr_t upper_bits = ~traits::PGMASK;
iss::status fetch_ins(virt_addr_t pc, uint8_t * data){
auto phys_pc = this->core.v2p(pc);
if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary
if (this->core.read(phys_pc, 2, data) != iss::Ok) return iss::Err;
if ((data[0] & 0x3) == 0x3) // this is a 32bit instruction
if (this->core.read(this->core.v2p(pc + 2), 2, data + 2) != iss::Ok) return iss::Err;
} else {
if (this->core.read(phys_pc, 4, data) != iss::Ok) return iss::Err;
}
return iss::Ok;
}
};
template <typename CODE_WORD> void debug_fn(CODE_WORD insn) {
@ -3367,18 +3380,15 @@ template <typename ARCH>
typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(virt_addr_t start, std::function<bool(void)> pred) {
// we fetch at max 4 byte, alignment is 2
enum {TRAP_ID=1<<16};
const typename traits::addr_t upper_bits = ~traits::PGMASK;
code_word_t insn = 0;
auto *const data = (uint8_t *)&insn;
auto pc=start;
while(pred){
auto paddr = this->core.v2p(pc);
if ((pc.val & upper_bits) != ((pc.val + 2) & upper_bits)) { // we may cross a page boundary
if (this->core.read(paddr, 2, data) != iss::Ok) throw trap_access(TRAP_ID, pc.val);
if ((insn & 0x3) == 0x3) // this is a 32bit instruction
if (this->core.read(this->core.v2p(pc + 2), 2, data + 2) != iss::Ok) throw trap_access(TRAP_ID, pc.val);
} else {
if (this->core.read(paddr, 4, data) != iss::Ok) throw trap_access(TRAP_ID, pc.val);
while(pred()){
auto res = fetch_ins(pc, data);
if(res!=iss::Ok){
auto new_pc = super::core.enter_trap(TRAP_ID, pc.val);
res = fetch_ins(virt_addr_t{access_type::FETCH, new_pc}, data);
if(res!=iss::Ok) throw simulation_stopped(0);
}
if (insn == 0x0000006f || (insn&0xffff)==0xa001) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
auto lut_val = extract_fields(insn);