X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=riscv%2Fprocessor.cc;h=ad84b6e0a19b633ef6e6710335d522f3ae9fcd30;hb=54bd259cd529294e9c0967bd0e9e20d8fa30dc3b;hp=6eb5ddb9fc8c975e1efadca13f66f2e96a1d4d23;hpb=980a0121e0b7244020bba7a8f422d97e7886fb08;p=riscv-isa-sim.git diff --git a/riscv/processor.cc b/riscv/processor.cc index 6eb5ddb..ad84b6e 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -8,6 +8,7 @@ #include "mmu.h" #include "htif.h" #include "disasm.h" +#include "gdbserver.h" #include #include #include @@ -21,8 +22,8 @@ #define STATE state processor_t::processor_t(const char* isa, sim_t* sim, uint32_t id) - : sim(sim), ext(NULL), disassembler(new disassembler_t), - id(id), run(false), debug(false) + : debug(false), sim(sim), ext(NULL), disassembler(new disassembler_t), + id(id), run(false) { parse_isa_string(isa); @@ -192,12 +193,29 @@ void processor_t::set_privilege(reg_t prv) state.prv = prv; } +void processor_t::enter_debug_mode(uint8_t cause) +{ + fprintf(stderr, "enter_debug_mode(%d)\n", cause); + state.dcsr.cause = cause; + state.dcsr.prv = state.prv; + state.prv = PRV_M; + state.dpc = state.pc; + state.pc = DEBUG_ROM_START; + debug = true; // TODO +} + void processor_t::take_trap(trap_t& t, reg_t epc) { if (debug) fprintf(stderr, "core %3d: exception %s, epc 0x%016" PRIx64 "\n", id, t.name(), epc); + if (t.cause() == CAUSE_BREAKPOINT && + sim->gdbserver && sim->gdbserver->connected()) { + enter_debug_mode(DCSR_CAUSE_SWBP); + return; + } + // by default, trap to M-mode, unless delegated to S-mode reg_t bit = t.cause(); reg_t deleg = state.medeleg; @@ -254,7 +272,7 @@ static bool validate_vm(int max_xlen, reg_t vm) void processor_t::set_csr(int which, reg_t val) { val = zext_xlen(val); - reg_t delegable_ints = MIP_SSIP | MIP_STIP | (1 << IRQ_HOST) | (1 << IRQ_COP); + reg_t delegable_ints = MIP_SSIP | MIP_STIP | MIP_SEIP | (1 << IRQ_COP); reg_t all_ints = delegable_ints | MIP_MSIP | MIP_MTIP; switch (which) { @@ -300,13 +318,10 @@ void processor_t::set_csr(int which, reg_t val) break; } case CSR_MIP: { - reg_t mask = MIP_SSIP | MIP_STIP | MIP_MSIP; + reg_t mask = MIP_SSIP | MIP_STIP; state.mip = (state.mip & ~mask) | (val & mask); break; } - case CSR_MIPI: - state.mip = set_field(state.mip, MIP_MSIP, val & 1); - break; case CSR_MIE: state.mie = (state.mie & ~all_ints) | (val & all_ints); break; @@ -349,6 +364,23 @@ void processor_t::set_csr(int which, reg_t val) case CSR_MSCRATCH: state.mscratch = val; break; case CSR_MCAUSE: state.mcause = val; break; case CSR_MBADADDR: state.mbadaddr = val; break; + case DCSR_ADDRESS: + // TODO: Use get_field style + state.dcsr.prv = (val & DCSR_PRV_MASK) >> DCSR_PRV_OFFSET; + state.dcsr.step = (val & DCSR_STEP_MASK) >> DCSR_STEP_OFFSET; + // TODO: ndreset and fullreset + state.dcsr.ebreakm = (val & DCSR_EBREAKM_MASK) >> DCSR_EBREAKM_OFFSET; + state.dcsr.ebreakh = (val & DCSR_EBREAKH_MASK) >> DCSR_EBREAKH_OFFSET; + state.dcsr.ebreaks = (val & DCSR_EBREAKS_MASK) >> DCSR_EBREAKS_OFFSET; + state.dcsr.ebreaku = (val & DCSR_EBREAKU_MASK) >> DCSR_EBREAKU_OFFSET; + state.dcsr.halt = (val & DCSR_HALT_MASK) >> DCSR_HALT_OFFSET; + break; + case DPC_ADDRESS: + state.dpc = val; + break; + case DSCRATCH_ADDRESS: + state.dscratch = val; + break; } } @@ -424,7 +456,6 @@ reg_t processor_t::get_csr(int which) case CSR_SSCRATCH: return state.sscratch; case CSR_MSTATUS: return state.mstatus; case CSR_MIP: return state.mip; - case CSR_MIPI: return 0; case CSR_MIE: return state.mie; case CSR_MEPC: return state.mepc; case CSR_MSCRATCH: return state.mscratch; @@ -438,6 +469,31 @@ reg_t processor_t::get_csr(int which) case CSR_MTVEC: return state.mtvec; case CSR_MEDELEG: return state.medeleg; case CSR_MIDELEG: return state.mideleg; + case DCSR_ADDRESS: + { + uint32_t value = + (1 << DCSR_XDEBUGVER_OFFSET) | + (0 << DCSR_HWBPCOUNT_OFFSET) | + (0 << DCSR_NDRESET_OFFSET) | + (0 << DCSR_FULLRESET_OFFSET) | + (state.dcsr.prv << DCSR_PRV_OFFSET) | + (state.dcsr.step << DCSR_STEP_OFFSET) | + (sim->debug_module.get_interrupt(id) << DCSR_DEBUGINT_OFFSET) | + (0 << DCSR_STOPCYCLE_OFFSET) | + (0 << DCSR_STOPTIME_OFFSET) | + (state.dcsr.ebreakm << DCSR_EBREAKM_OFFSET) | + (state.dcsr.ebreakh << DCSR_EBREAKH_OFFSET) | + (state.dcsr.ebreaks << DCSR_EBREAKS_OFFSET) | + (state.dcsr.ebreaku << DCSR_EBREAKU_OFFSET) | + (state.dcsr.halt << DCSR_HALT_OFFSET) | + (state.dcsr.cause << DCSR_CAUSE_OFFSET); + fprintf(stderr, "DCSR: 0x%x\n", value); + return value; + } + case DPC_ADDRESS: + return state.dpc; + case DSCRATCH_ADDRESS: + return state.dscratch; } throw trap_illegal_instruction(); } @@ -527,23 +583,20 @@ void processor_t::register_base_instructions() bool processor_t::load(reg_t addr, size_t len, uint8_t* bytes) { - try { - auto res = get_csr(addr / (max_xlen / 8)); - memcpy(bytes, &res, len); - return true; - } catch (trap_illegal_instruction& t) { - return false; - } + return false; } bool processor_t::store(reg_t addr, size_t len, const uint8_t* bytes) { - try { - reg_t value = 0; - memcpy(&value, bytes, len); - set_csr(addr / (max_xlen / 8), value); - return true; - } catch (trap_illegal_instruction& t) { - return false; + switch (addr) + { + case 0: + state.mip &= ~MIP_MSIP; + if (bytes[0] & 1) + state.mip |= MIP_MSIP; + return true; + + default: + return false; } }