#include "mmu.h"
#include "htif.h"
#include "disasm.h"
+#include "gdbserver.h"
#include <cinttypes>
#include <cmath>
#include <cstdlib>
#undef STATE
#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)
+processor_t::processor_t(const char* isa, sim_t* sim, uint32_t id,
+ bool halt_on_reset)
+ : debug(false), sim(sim), ext(NULL), disassembler(new disassembler_t),
+ id(id), run(false), halt_on_reset(halt_on_reset)
{
parse_isa_string(isa);
load_reservation = -1;
}
-void processor_t::set_debug_int()
-{
- state.dcsr.debugint = true;
-}
-
void processor_t::set_debug(bool value)
{
debug = value;
run = !value;
state.reset();
+ state.dcsr.halt = halt_on_reset;
+ halt_on_reset = false;
set_csr(CSR_MSTATUS, state.mstatus);
if (ext)
void processor_t::enter_debug_mode(uint8_t cause)
{
- fprintf(stderr, "enter_debug_mode(%d)\n", cause);
+ fprintf(stderr, "enter_debug_mode(%d), mstatus=0x%lx, prv=0x%lx\n", cause, state.mstatus, state.prv);
state.dcsr.cause = cause;
state.dcsr.prv = state.prv;
- state.prv = PRV_M;
+ set_privilege(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)
+ if (debug) {
fprintf(stderr, "core %3d: exception %s, epc 0x%016" PRIx64 "\n",
id, t.name(), epc);
+ if (t.has_badaddr())
+ fprintf(stderr, "core %3d: badaddr 0x%016" PRIx64 "\n", id,
+ t.get_badaddr());
+ }
if (t.cause() == CAUSE_BREAKPOINT &&
sim->gdbserver && sim->gdbserver->connected()) {
set_csr(CSR_MSTATUS, s);
set_privilege(PRV_S);
} else {
- state.pc = state.mtvec;
+ if (state.dcsr.cause) {
+ state.pc = DEBUG_ROM_EXCEPTION;
+ } else {
+ state.pc = state.mtvec;
+ }
state.mcause = t.cause();
state.mepc = epc;
if (t.has_badaddr())
case CSR_MEDELEG: return state.medeleg;
case CSR_MIDELEG: return state.mideleg;
case DCSR_ADDRESS:
- return
+ {
+ 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) |
- (state.dcsr.debugint << DCSR_DEBUGINT_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.ebreaku << DCSR_EBREAKU_OFFSET) |
(state.dcsr.halt << DCSR_HALT_OFFSET) |
(state.dcsr.cause << DCSR_CAUSE_OFFSET);
+ return value;
+ }
case DPC_ADDRESS:
return state.dpc;
case DSCRATCH_ADDRESS: