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:
		| @@ -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; | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user