updates debugger hook to stop before fetching instructions

this relates to https://github.com/Minres/DBT-RISE-RISCV/issues/8 :
Debugger loses control when trap vector fetch fails

and https://github.com/Minres/DBT-RISE-RISCV/issues/7 : Two debugger
single-steps are required at reset vector
This commit is contained in:
Eyck Jentzsch 2024-08-17 12:37:57 +02:00
parent 0473aa5344
commit de79adc50d
3 changed files with 32 additions and 18 deletions

View File

@ -257,10 +257,14 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
while(!this->core.should_stop() &&
!(is_icount_limit_enabled(cond) && icount >= count_limit) &&
!(is_fcount_limit_enabled(cond) && fetch_count >= count_limit)){
fetch_count++;
if(this->debugging_enabled())
this->tgt_adapter->check_continue(*PC);
pc.val=*PC;
if(fetch_ins(pc, data)!=iss::Ok){
this->do_sync(POST_SYNC, std::numeric_limits<unsigned>::max());
pc.val = super::core.enter_trap(std::numeric_limits<uint64_t>::max(), pc.val, 0);
if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, std::numeric_limits<unsigned>::max());
process_spawn_blocks();
if(this->sync_exec && POST_SYNC) this->do_sync(PRE_SYNC, std::numeric_limits<unsigned>::max());
pc.val = super::core.enter_trap(arch::traits<ARCH>::RV_CAUSE_FETCH_ACCESS<<16, pc.val, 0);
} else {
if (is_jump_to_self_enabled(cond) &&
(instr == 0x0000006f || (instr&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
@ -311,11 +315,11 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
icount++;
instret++;
}
cycle++;
pc.val=*NEXT_PC;
this->core.reg.PC = this->core.reg.NEXT_PC;
*PC = *NEXT_PC;
this->core.reg.trap_state = this->core.reg.pending_trap;
}
fetch_count++;
cycle++;
}
return pc;
}

View File

@ -689,8 +689,10 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read(const address_type type, co
}
return res;
} catch(trap_access& ta) {
if( (access & access_type::DEBUG) == 0) {
this->reg.trap_state = (1UL << 31) | ta.id;
fault_data = ta.addr;
}
return iss::Err;
}
} break;
@ -717,8 +719,10 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read(const address_type type, co
}
return iss::Ok;
} catch(trap_access& ta) {
if((access & access_type::DEBUG) == 0) {
this->reg.trap_state = (1UL << 31) | ta.id;
fault_data = ta.addr;
}
return iss::Err;
}
}
@ -848,8 +852,10 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::write(const address_type type, c
}
return iss::Ok;
} catch(trap_access& ta) {
if((access & access_type::DEBUG) == 0) {
this->reg.trap_state = (1UL << 31) | ta.id;
fault_data = ta.addr;
}
return iss::Err;
}
}

View File

@ -333,10 +333,14 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
while(!this->core.should_stop() &&
!(is_icount_limit_enabled(cond) && icount >= count_limit) &&
!(is_fcount_limit_enabled(cond) && fetch_count >= count_limit)){
fetch_count++;
if(this->debugging_enabled())
this->tgt_adapter->check_continue(*PC);
pc.val=*PC;
if(fetch_ins(pc, data)!=iss::Ok){
this->do_sync(POST_SYNC, std::numeric_limits<unsigned>::max());
pc.val = super::core.enter_trap(std::numeric_limits<uint64_t>::max(), pc.val, 0);
if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, std::numeric_limits<unsigned>::max());
process_spawn_blocks();
if(this->sync_exec && POST_SYNC) this->do_sync(PRE_SYNC, std::numeric_limits<unsigned>::max());
pc.val = super::core.enter_trap(arch::traits<ARCH>::RV_CAUSE_FETCH_ACCESS<<16, pc.val, 0);
} else {
if (is_jump_to_self_enabled(cond) &&
(instr == 0x0000006f || (instr&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
@ -2673,11 +2677,11 @@ typename vm_base<ARCH>::virt_addr_t vm_impl<ARCH>::execute_inst(finish_cond_e co
icount++;
instret++;
}
cycle++;
pc.val=*NEXT_PC;
this->core.reg.PC = this->core.reg.NEXT_PC;
*PC = *NEXT_PC;
this->core.reg.trap_state = this->core.reg.pending_trap;
}
fetch_count++;
cycle++;
}
return pc;
}