|
|
|
@ -327,10 +327,10 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) |
|
|
|
mcounteren = std::make_shared<masked_csr_t>(proc, CSR_MCOUNTEREN, counteren_mask, 0); |
|
|
|
if (proc->extension_enabled_const('U')) csrmap[CSR_MCOUNTEREN] = mcounteren; |
|
|
|
csrmap[CSR_SCOUNTEREN] = scounteren = std::make_shared<masked_csr_t>(proc, CSR_SCOUNTEREN, counteren_mask, 0); |
|
|
|
auto nonvirtual_sepc = std::make_shared<epc_csr_t>(proc, CSR_SEPC); |
|
|
|
nonvirtual_sepc = std::make_shared<epc_csr_t>(proc, CSR_SEPC); |
|
|
|
csrmap[CSR_VSEPC] = vsepc = std::make_shared<epc_csr_t>(proc, CSR_VSEPC); |
|
|
|
csrmap[CSR_SEPC] = sepc = std::make_shared<virtualized_csr_t>(proc, nonvirtual_sepc, vsepc); |
|
|
|
auto nonvirtual_stval = std::make_shared<basic_csr_t>(proc, CSR_STVAL, 0); |
|
|
|
nonvirtual_stval = std::make_shared<basic_csr_t>(proc, CSR_STVAL, 0); |
|
|
|
csrmap[CSR_VSTVAL] = vstval = std::make_shared<basic_csr_t>(proc, CSR_VSTVAL, 0); |
|
|
|
csrmap[CSR_STVAL] = stval = std::make_shared<virtualized_csr_t>(proc, nonvirtual_stval, vstval); |
|
|
|
auto sscratch = std::make_shared<basic_csr_t>(proc, CSR_SSCRATCH, 0); |
|
|
|
@ -338,13 +338,13 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) |
|
|
|
// Note: if max_isa does not include H, we don't really need this virtualized_csr_t at all (though it doesn't hurt):
|
|
|
|
csrmap[CSR_SSCRATCH] = std::make_shared<virtualized_csr_t>(proc, sscratch, vsscratch); |
|
|
|
csrmap[CSR_VSSCRATCH] = vsscratch; |
|
|
|
auto nonvirtual_stvec = std::make_shared<tvec_csr_t>(proc, CSR_STVEC); |
|
|
|
nonvirtual_stvec = std::make_shared<tvec_csr_t>(proc, CSR_STVEC); |
|
|
|
csrmap[CSR_VSTVEC] = vstvec = std::make_shared<tvec_csr_t>(proc, CSR_VSTVEC); |
|
|
|
csrmap[CSR_STVEC] = stvec = std::make_shared<virtualized_csr_t>(proc, nonvirtual_stvec, vstvec); |
|
|
|
auto nonvirtual_satp = std::make_shared<satp_csr_t>(proc, CSR_SATP); |
|
|
|
csrmap[CSR_VSATP] = vsatp = std::make_shared<base_atp_csr_t>(proc, CSR_VSATP); |
|
|
|
csrmap[CSR_SATP] = satp = std::make_shared<virtualized_satp_csr_t>(proc, nonvirtual_satp, vsatp); |
|
|
|
auto nonvirtual_scause = std::make_shared<cause_csr_t>(proc, CSR_SCAUSE); |
|
|
|
nonvirtual_scause = std::make_shared<cause_csr_t>(proc, CSR_SCAUSE); |
|
|
|
csrmap[CSR_VSCAUSE] = vscause = std::make_shared<cause_csr_t>(proc, CSR_VSCAUSE); |
|
|
|
csrmap[CSR_SCAUSE] = scause = std::make_shared<virtualized_csr_t>(proc, nonvirtual_scause, vscause); |
|
|
|
csrmap[CSR_MTVAL2] = mtval2 = std::make_shared<hypervisor_csr_t>(proc, CSR_MTVAL2); |
|
|
|
@ -382,7 +382,7 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) |
|
|
|
csrmap[CSR_HTVAL] = htval = std::make_shared<basic_csr_t>(proc, CSR_HTVAL, 0); |
|
|
|
csrmap[CSR_HTINST] = htinst = std::make_shared<basic_csr_t>(proc, CSR_HTINST, 0); |
|
|
|
csrmap[CSR_HGATP] = hgatp = std::make_shared<hgatp_csr_t>(proc, CSR_HGATP); |
|
|
|
auto nonvirtual_sstatus = std::make_shared<sstatus_proxy_csr_t>(proc, CSR_SSTATUS, mstatus); |
|
|
|
nonvirtual_sstatus = std::make_shared<sstatus_proxy_csr_t>(proc, CSR_SSTATUS, mstatus); |
|
|
|
csrmap[CSR_VSSTATUS] = vsstatus = std::make_shared<vsstatus_csr_t>(proc, CSR_VSSTATUS); |
|
|
|
csrmap[CSR_SSTATUS] = sstatus = std::make_shared<sstatus_csr_t>(proc, nonvirtual_sstatus, vsstatus); |
|
|
|
|
|
|
|
@ -837,19 +837,19 @@ void processor_t::take_trap(trap_t& t, reg_t epc) |
|
|
|
} else if (state.prv <= PRV_S && bit < max_xlen && ((hsdeleg >> bit) & 1)) { |
|
|
|
// Handle the trap in HS-mode
|
|
|
|
set_virt(false); |
|
|
|
reg_t vector = (state.stvec->read() & 1) && interrupt ? 4 * bit : 0; |
|
|
|
state.pc = (state.stvec->read() & ~(reg_t)1) + vector; |
|
|
|
state.scause->write(t.cause()); |
|
|
|
state.sepc->write(epc); |
|
|
|
state.stval->write(t.get_tval()); |
|
|
|
reg_t vector = (state.nonvirtual_stvec->read() & 1) && interrupt ? 4 * bit : 0; |
|
|
|
state.pc = (state.nonvirtual_stvec->read() & ~(reg_t)1) + vector; |
|
|
|
state.nonvirtual_scause->write(t.cause()); |
|
|
|
state.nonvirtual_sepc->write(epc); |
|
|
|
state.nonvirtual_stval->write(t.get_tval()); |
|
|
|
state.htval->write(t.get_tval2()); |
|
|
|
state.htinst->write(t.get_tinst()); |
|
|
|
|
|
|
|
reg_t s = state.sstatus->read(); |
|
|
|
reg_t s = state.nonvirtual_sstatus->read(); |
|
|
|
s = set_field(s, MSTATUS_SPIE, get_field(s, MSTATUS_SIE)); |
|
|
|
s = set_field(s, MSTATUS_SPP, state.prv); |
|
|
|
s = set_field(s, MSTATUS_SIE, 0); |
|
|
|
state.sstatus->write(s); |
|
|
|
state.nonvirtual_sstatus->write(s); |
|
|
|
if (extension_enabled('H')) { |
|
|
|
s = state.hstatus->read(); |
|
|
|
if (curr_virt) |
|
|
|
|