Browse Source

Explicitly use the nonvirtual S-mode CSRs when going to HS-mode

Since we're going to move the change to state->v next.
pull/1366/head
Scott Johnson 3 years ago
committed by Andrew Waterman
parent
commit
505ddebeff
  1. 24
      riscv/processor.cc
  2. 7
      riscv/processor.h

24
riscv/processor.cc

@ -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); mcounteren = std::make_shared<masked_csr_t>(proc, CSR_MCOUNTEREN, counteren_mask, 0);
if (proc->extension_enabled_const('U')) csrmap[CSR_MCOUNTEREN] = mcounteren; 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); 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_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); 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_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); 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); 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): // 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_SSCRATCH] = std::make_shared<virtualized_csr_t>(proc, sscratch, vsscratch);
csrmap[CSR_VSSCRATCH] = 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_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); 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); 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_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); 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_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_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); 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_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_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); 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_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); 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)) { } else if (state.prv <= PRV_S && bit < max_xlen && ((hsdeleg >> bit) & 1)) {
// Handle the trap in HS-mode // Handle the trap in HS-mode
set_virt(false); set_virt(false);
reg_t vector = (state.stvec->read() & 1) && interrupt ? 4 * bit : 0; reg_t vector = (state.nonvirtual_stvec->read() & 1) && interrupt ? 4 * bit : 0;
state.pc = (state.stvec->read() & ~(reg_t)1) + vector; state.pc = (state.nonvirtual_stvec->read() & ~(reg_t)1) + vector;
state.scause->write(t.cause()); state.nonvirtual_scause->write(t.cause());
state.sepc->write(epc); state.nonvirtual_sepc->write(epc);
state.stval->write(t.get_tval()); state.nonvirtual_stval->write(t.get_tval());
state.htval->write(t.get_tval2()); state.htval->write(t.get_tval2());
state.htinst->write(t.get_tinst()); 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_SPIE, get_field(s, MSTATUS_SIE));
s = set_field(s, MSTATUS_SPP, state.prv); s = set_field(s, MSTATUS_SPP, state.prv);
s = set_field(s, MSTATUS_SIE, 0); s = set_field(s, MSTATUS_SIE, 0);
state.sstatus->write(s); state.nonvirtual_sstatus->write(s);
if (extension_enabled('H')) { if (extension_enabled('H')) {
s = state.hstatus->read(); s = state.hstatus->read();
if (curr_virt) if (curr_virt)

7
riscv/processor.h

@ -110,6 +110,13 @@ struct state_t
virtualized_csr_t_p satp; virtualized_csr_t_p satp;
csr_t_p scause; csr_t_p scause;
// When taking a trap into HS-mode, we must access the nonvirtualized HS-mode CSRs directly:
csr_t_p nonvirtual_stvec;
csr_t_p nonvirtual_scause;
csr_t_p nonvirtual_sepc;
csr_t_p nonvirtual_stval;
sstatus_proxy_csr_t_p nonvirtual_sstatus;
csr_t_p mtval2; csr_t_p mtval2;
csr_t_p mtinst; csr_t_p mtinst;
csr_t_p hstatus; csr_t_p hstatus;

Loading…
Cancel
Save