From de79adc50d0143349cfbd3d69306bf13ee8eb39b Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Sat, 17 Aug 2024 12:37:57 +0200 Subject: [PATCH] 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 --- gen_input/templates/interp/CORENAME.cpp.gtl | 16 ++++++++++------ src/iss/arch/riscv_hart_m_p.h | 18 ++++++++++++------ src/vm/interp/vm_tgc5c.cpp | 16 ++++++++++------ 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/gen_input/templates/interp/CORENAME.cpp.gtl b/gen_input/templates/interp/CORENAME.cpp.gtl index 1c45797..d2ebedd 100644 --- a/gen_input/templates/interp/CORENAME.cpp.gtl +++ b/gen_input/templates/interp/CORENAME.cpp.gtl @@ -257,10 +257,14 @@ typename vm_base::virt_addr_t vm_impl::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::max()); - pc.val = super::core.enter_trap(std::numeric_limits::max(), pc.val, 0); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, std::numeric_limits::max()); + process_spawn_blocks(); + if(this->sync_exec && POST_SYNC) this->do_sync(PRE_SYNC, std::numeric_limits::max()); + pc.val = super::core.enter_trap(arch::traits::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::virt_addr_t vm_impl::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; } diff --git a/src/iss/arch/riscv_hart_m_p.h b/src/iss/arch/riscv_hart_m_p.h index bbd2b49..8b27dec 100644 --- a/src/iss/arch/riscv_hart_m_p.h +++ b/src/iss/arch/riscv_hart_m_p.h @@ -689,8 +689,10 @@ iss::status riscv_hart_m_p::read(const address_type type, co } return res; } catch(trap_access& ta) { - this->reg.trap_state = (1UL << 31) | ta.id; - fault_data = ta.addr; + 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::read(const address_type type, co } return iss::Ok; } catch(trap_access& ta) { - this->reg.trap_state = (1UL << 31) | ta.id; - fault_data = ta.addr; + 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::write(const address_type type, c } return iss::Ok; } catch(trap_access& ta) { - this->reg.trap_state = (1UL << 31) | ta.id; - fault_data = ta.addr; + if((access & access_type::DEBUG) == 0) { + this->reg.trap_state = (1UL << 31) | ta.id; + fault_data = ta.addr; + } return iss::Err; } } diff --git a/src/vm/interp/vm_tgc5c.cpp b/src/vm/interp/vm_tgc5c.cpp index 7cd10ad..7d4161a 100644 --- a/src/vm/interp/vm_tgc5c.cpp +++ b/src/vm/interp/vm_tgc5c.cpp @@ -333,10 +333,14 @@ typename vm_base::virt_addr_t vm_impl::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::max()); - pc.val = super::core.enter_trap(std::numeric_limits::max(), pc.val, 0); + if(this->sync_exec && PRE_SYNC) this->do_sync(PRE_SYNC, std::numeric_limits::max()); + process_spawn_blocks(); + if(this->sync_exec && POST_SYNC) this->do_sync(PRE_SYNC, std::numeric_limits::max()); + pc.val = super::core.enter_trap(arch::traits::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::virt_addr_t vm_impl::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; }