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() && |     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) { | ||||||
|  |                 if( (access & access_type::DEBUG) == 0) { | ||||||
|                     this->reg.trap_state = (1UL << 31) | ta.id; |                     this->reg.trap_state = (1UL << 31) | ta.id; | ||||||
|                     fault_data = ta.addr; |                     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) { | ||||||
|  |         if((access & access_type::DEBUG) == 0) { | ||||||
|             this->reg.trap_state = (1UL << 31) | ta.id; |             this->reg.trap_state = (1UL << 31) | ta.id; | ||||||
|             fault_data = ta.addr; |             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) { | ||||||
|  |         if((access & access_type::DEBUG) == 0) { | ||||||
|             this->reg.trap_state = (1UL << 31) | ta.id; |             this->reg.trap_state = (1UL << 31) | ta.id; | ||||||
|             fault_data = ta.addr; |             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; | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user