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:
parent
0473aa5344
commit
de79adc50d
|
@ -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() &&
|
while(!this->core.should_stop() &&
|
||||||
!(is_icount_limit_enabled(cond) && icount >= count_limit) &&
|
!(is_icount_limit_enabled(cond) && icount >= count_limit) &&
|
||||||
!(is_fcount_limit_enabled(cond) && fetch_count >= 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){
|
if(fetch_ins(pc, data)!=iss::Ok){
|
||||||
this->do_sync(POST_SYNC, std::numeric_limits<unsigned>::max());
|
if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, std::numeric_limits<unsigned>::max());
|
||||||
pc.val = super::core.enter_trap(std::numeric_limits<uint64_t>::max(), pc.val, 0);
|
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 {
|
} else {
|
||||||
if (is_jump_to_self_enabled(cond) &&
|
if (is_jump_to_self_enabled(cond) &&
|
||||||
(instr == 0x0000006f || (instr&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
(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++;
|
icount++;
|
||||||
instret++;
|
instret++;
|
||||||
}
|
}
|
||||||
cycle++;
|
*PC = *NEXT_PC;
|
||||||
pc.val=*NEXT_PC;
|
|
||||||
this->core.reg.PC = this->core.reg.NEXT_PC;
|
|
||||||
this->core.reg.trap_state = this->core.reg.pending_trap;
|
this->core.reg.trap_state = this->core.reg.pending_trap;
|
||||||
}
|
}
|
||||||
|
fetch_count++;
|
||||||
|
cycle++;
|
||||||
}
|
}
|
||||||
return pc;
|
return pc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -689,8 +689,10 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read(const address_type type, co
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
} catch(trap_access& ta) {
|
} catch(trap_access& ta) {
|
||||||
this->reg.trap_state = (1UL << 31) | ta.id;
|
if( (access & access_type::DEBUG) == 0) {
|
||||||
fault_data = ta.addr;
|
this->reg.trap_state = (1UL << 31) | ta.id;
|
||||||
|
fault_data = ta.addr;
|
||||||
|
}
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
@ -717,8 +719,10 @@ iss::status riscv_hart_m_p<BASE, FEAT, LOGCAT>::read(const address_type type, co
|
||||||
}
|
}
|
||||||
return iss::Ok;
|
return iss::Ok;
|
||||||
} catch(trap_access& ta) {
|
} catch(trap_access& ta) {
|
||||||
this->reg.trap_state = (1UL << 31) | ta.id;
|
if((access & access_type::DEBUG) == 0) {
|
||||||
fault_data = ta.addr;
|
this->reg.trap_state = (1UL << 31) | ta.id;
|
||||||
|
fault_data = ta.addr;
|
||||||
|
}
|
||||||
return iss::Err;
|
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;
|
return iss::Ok;
|
||||||
} catch(trap_access& ta) {
|
} catch(trap_access& ta) {
|
||||||
this->reg.trap_state = (1UL << 31) | ta.id;
|
if((access & access_type::DEBUG) == 0) {
|
||||||
fault_data = ta.addr;
|
this->reg.trap_state = (1UL << 31) | ta.id;
|
||||||
|
fault_data = ta.addr;
|
||||||
|
}
|
||||||
return iss::Err;
|
return iss::Err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() &&
|
while(!this->core.should_stop() &&
|
||||||
!(is_icount_limit_enabled(cond) && icount >= count_limit) &&
|
!(is_icount_limit_enabled(cond) && icount >= count_limit) &&
|
||||||
!(is_fcount_limit_enabled(cond) && fetch_count >= 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){
|
if(fetch_ins(pc, data)!=iss::Ok){
|
||||||
this->do_sync(POST_SYNC, std::numeric_limits<unsigned>::max());
|
if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, std::numeric_limits<unsigned>::max());
|
||||||
pc.val = super::core.enter_trap(std::numeric_limits<uint64_t>::max(), pc.val, 0);
|
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 {
|
} else {
|
||||||
if (is_jump_to_self_enabled(cond) &&
|
if (is_jump_to_self_enabled(cond) &&
|
||||||
(instr == 0x0000006f || (instr&0xffff)==0xa001)) throw simulation_stopped(0); // 'J 0' or 'C.J 0'
|
(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++;
|
icount++;
|
||||||
instret++;
|
instret++;
|
||||||
}
|
}
|
||||||
cycle++;
|
*PC = *NEXT_PC;
|
||||||
pc.val=*NEXT_PC;
|
|
||||||
this->core.reg.PC = this->core.reg.NEXT_PC;
|
|
||||||
this->core.reg.trap_state = this->core.reg.pending_trap;
|
this->core.reg.trap_state = this->core.reg.pending_trap;
|
||||||
}
|
}
|
||||||
|
fetch_count++;
|
||||||
|
cycle++;
|
||||||
}
|
}
|
||||||
return pc;
|
return pc;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue