#include "config.h"
#include "sim.h"
#include "mmu.h"
-#include "htif.h"
#include "disasm.h"
#include "gdbserver.h"
#include <cinttypes>
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)
+ id(id), halt_on_reset(halt_on_reset)
{
parse_isa_string(isa);
mmu = new mmu_t(sim, this);
- reset(true);
+ reset();
register_base_instructions();
}
#endif
}
-void processor_t::reset(bool value)
+void processor_t::reset()
{
- if (run == !value)
- return;
- run = !value;
-
state.reset();
state.dcsr.halt = halt_on_reset;
halt_on_reset = false;
void processor_t::enter_debug_mode(uint8_t 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;
set_privilege(PRV_M);
state.dpc = state.pc;
state.pc = DEBUG_ROM_START;
- debug = true; // TODO
+ //debug = true; // TODO
}
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;
set_csr(CSR_MSTATUS, s);
set_privilege(PRV_S);
} else {
- if (state.dcsr.cause) {
- state.pc = DEBUG_ROM_EXCEPTION;
- state.dpc = epc;
- } else {
- state.pc = state.mtvec;
- state.mepc = epc;
- }
+ state.pc = state.mtvec;
+ state.mepc = epc;
state.mcause = t.cause();
if (t.has_badaddr())
state.mbadaddr = t.get_badaddr();
return vm == VM_MBARE;
}
+int processor_t::paddr_bits()
+{
+ assert(xlen == max_xlen);
+ return max_xlen == 64 ? 50 : 34;
+}
+
void processor_t::set_csr(int which, reg_t val)
{
val = zext_xlen(val);
case CSR_SIE:
return set_csr(CSR_MIE,
(state.mie & ~state.mideleg) | (val & state.mideleg));
+ case CSR_SPTBR: {
+ // upper bits of sptbr are the ASID; we only support ASID = 0
+ state.sptbr = val & (((reg_t)1 << (paddr_bits() - PGSHIFT)) - 1);
+ break;
+ }
case CSR_SEPC: state.sepc = val; break;
case CSR_STVEC: state.stvec = val >> 2 << 2; break;
- case CSR_SPTBR: state.sptbr = val; break;
case CSR_SSCRATCH: state.sscratch = val; break;
case CSR_SCAUSE: state.scause = val; break;
case CSR_SBADADDR: state.sbadaddr = val; break;
case CSR_MCAUSE: state.mcause = val; break;
case CSR_MBADADDR: state.mbadaddr = val; break;
case CSR_DCSR:
- // TODO: Use get_field style
state.dcsr.prv = get_field(val, DCSR_PRV);
state.dcsr.step = get_field(val, DCSR_STEP);
// TODO: ndreset and fullreset
return state.scause | ((state.scause >> (max_xlen-1)) << (xlen-1));
return state.scause;
case CSR_SPTBR: return state.sptbr;
- case CSR_SASID: return 0;
case CSR_SSCRATCH: return state.sscratch;
case CSR_MSTATUS: return state.mstatus;
case CSR_MIP: return state.mip;
case CSR_MTVEC: return state.mtvec;
case CSR_MEDELEG: return state.medeleg;
case CSR_MIDELEG: return state.mideleg;
+ case CSR_TDRSELECT: return 0;
case CSR_DCSR:
{
uint32_t v = 0;