#define SSTATUS32_SD 0x80000000
#define SSTATUS64_SD 0x8000000000000000
+#define DCSR_PRV (3<<14)
+
#define MIP_SSIP (1 << IRQ_S_SOFT)
#define MIP_HSIP (1 << IRQ_H_SOFT)
#define MIP_MSIP (1 << IRQ_M_SOFT)
gs.saved_mcause = ((uint64_t) gs.read_debug_ram(1) << 32) | gs.read_debug_ram(0);
gs.saved_mstatus = ((uint64_t) gs.read_debug_ram(3) << 32) | gs.read_debug_ram(2);
gs.dcsr = ((uint64_t) gs.read_debug_ram(5) << 32) | gs.read_debug_ram(4);
-
-#if 0
- // TODO: This scheme doesn't work, because we're unable to write to eg.
- // 0x108 to clear debug int with mstatus configured this way.
-
- // Set mstatus.mprv, and mstatus.mpp to dcsr.prv.
- // This ensures that memory accesses act as they would in whatever mode
- // the processor was in when we interrupted it. A fancier debugger
- // might walk page tables itself and perform its own address
- // translation.
- reg_t mstatus = gs.saved_mstatus;
- mstatus = set_field(mstatus, MSTATUS_MPRV, 1);
- mstatus = set_field(mstatus, MSTATUS_MPP, get_field(gs.dcsr, DCSR_PRV));
- gs.write_debug_ram(0, ld(S0, 0, (uint16_t) DEBUG_RAM_START + 16));
- gs.write_debug_ram(1, csrw(S0, CSR_MSTATUS));
- gs.write_debug_ram(2, jal(0, (uint32_t) (DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4*2))));
- gs.write_debug_ram(4, mstatus);
- gs.write_debug_ram(5, mstatus >> 32);
- gs.set_interrupt(0);
- state = WRITE_MSTATUS;
-#endif
return true;
}
}
if (get_field(proc->state.mstatus, MSTATUS_VM) == VM_MBARE)
mode = PRV_M;
+ fprintf(stderr, "translate(0x%lx, %d), mstatus=0x%lx, prv=%ld, mode=%ld, pum=%d\n",
+ addr, type, proc->state.mstatus, proc->state.prv, mode, pum);
if (mode == PRV_M) {
reg_t msb_mask = (reg_t(2) << (proc->xlen-1))-1; // zero-extend from xlen
return addr & msb_mask;
void mmu_t::load_slow_path(reg_t addr, reg_t len, uint8_t* bytes)
{
reg_t paddr = translate(addr, LOAD);
+ fprintf(stderr, "load_slow_path 0x%lx -> 0x%lx\n", addr, paddr);
if (sim->addr_is_mem(paddr)) {
memcpy(bytes, sim->addr_to_mem(paddr), len);
if (tracer.interested_in_range(paddr, paddr + PGSIZE, LOAD))
void mmu_t::store_slow_path(reg_t addr, reg_t len, const uint8_t* bytes)
{
reg_t paddr = translate(addr, STORE);
+ fprintf(stderr, "store_slow_path 0x%lx -> 0x%lx\n", addr, paddr);
if (sim->addr_is_mem(paddr)) {
memcpy(sim->addr_to_mem(paddr), bytes, len);
if (tracer.interested_in_range(paddr, paddr + PGSIZE, STORE))
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;
set_privilege(PRV_M);
void processor_t::set_csr(int which, reg_t val)
{
+ fprintf(stderr, "set_csr(0x%x, 0x%lx)\n", which, val);
val = zext_xlen(val);
reg_t delegable_ints = MIP_SSIP | MIP_STIP | MIP_SEIP | (1 << IRQ_COP);
reg_t all_ints = delegable_ints | MIP_MSIP | MIP_MTIP;