X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=riscv%2Fprocessor.cc;h=064c4520569c2f850ff855561829a66c52d4cdcc;hb=1a623701469c08e72685d44a4ebed9157ab4bfe2;hp=1a41f604e9681e2f03d09c93314adafa72f9d7bd;hpb=167a876c4fb9fc8c0d51c6f2696dc732ac7b5984;p=riscv-isa-sim.git diff --git a/riscv/processor.cc b/riscv/processor.cc index 1a41f60..064c452 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -7,7 +7,6 @@ #include "sim.h" #include "mmu.h" #include "disasm.h" -#include "gdbserver.h" #include #include #include @@ -22,7 +21,8 @@ processor_t::processor_t(const char* isa, sim_t* sim, uint32_t id, bool halt_on_reset) - : debug(false), sim(sim), ext(NULL), id(id), halt_on_reset(halt_on_reset) + : debug(false), halt_request(false), sim(sim), ext(NULL), id(id), + halt_on_reset(halt_on_reset) { parse_isa_string(isa); register_base_instructions(); @@ -200,7 +200,7 @@ void processor_t::enter_debug_mode(uint8_t cause) state.dcsr.prv = state.prv; set_privilege(PRV_M); state.dpc = state.pc; - state.pc = DEBUG_ROM_START; + state.pc = debug_rom_entry(); } void processor_t::take_trap(trap_t& t, reg_t epc) @@ -213,6 +213,15 @@ void processor_t::take_trap(trap_t& t, reg_t epc) t.get_badaddr()); } + if (state.dcsr.cause) { + if (t.cause() == CAUSE_BREAKPOINT) { + state.pc = debug_rom_entry(); + } else { + state.pc = DEBUG_ROM_EXCEPTION; + } + return; + } + if (t.cause() == CAUSE_BREAKPOINT && ( (state.prv == PRV_M && state.dcsr.ebreakm) || (state.prv == PRV_H && state.dcsr.ebreakh) || @@ -222,11 +231,6 @@ void processor_t::take_trap(trap_t& t, reg_t epc) return; } - if (state.dcsr.cause) { - state.pc = DEBUG_ROM_EXCEPTION; - return; - } - // by default, trap to M-mode, unless delegated to S-mode reg_t bit = t.cause(); reg_t deleg = state.medeleg; @@ -373,9 +377,10 @@ void processor_t::set_csr(int which, reg_t val) | SSTATUS_XS | SSTATUS_PUM; return set_csr(CSR_MSTATUS, (state.mstatus & ~mask) | (val & mask)); } - case CSR_SIP: - return set_csr(CSR_MIP, - (state.mip & ~state.mideleg) | (val & state.mideleg)); + case CSR_SIP: { + reg_t mask = MIP_SSIP & state.mideleg; + return set_csr(CSR_MIP, (state.mip & ~mask) | (val & mask)); + } case CSR_SIE: return set_csr(CSR_MIE, (state.mie & ~state.mideleg) | (val & state.mideleg)); @@ -419,7 +424,7 @@ void processor_t::set_csr(int which, reg_t val) { mcontrol_t *mc = &state.mcontrol[state.tselect]; if (mc->dmode && !state.dcsr.cause) { - throw trap_illegal_instruction(); + break; } mc->dmode = get_field(val, MCONTROL_DMODE(xlen)); mc->select = get_field(val, MCONTROL_SELECT); @@ -437,12 +442,13 @@ void processor_t::set_csr(int which, reg_t val) // Assume we're here because of csrw. if (mc->execute) mc->timing = 0; - if (mc->load) - mc->timing = 1; trigger_updated(); } break; case CSR_TDATA2: + if (state.mcontrol[state.tselect].dmode && !state.dcsr.cause) { + break; + } if (state.tselect < state.num_triggers) { state.tdata2[state.tselect] = val; }