Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide accessibility control of xcontext CSRs through stateen0[57] CSR #1550

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions riscv/csrs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1127,6 +1127,22 @@ void counter_proxy_csr_t::verify_permissions(insn_t insn, bool write) const {
}
}

context_proxy_csr_t::context_proxy_csr_t(processor_t* const proc, const reg_t addr, csr_t_p delegate):
proxy_csr_t(proc, addr, delegate) {
}

void context_proxy_csr_t::verify_permissions(insn_t insn, bool write) const {
if (proc->extension_enabled(EXT_SMSTATEEN)) {
if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & MSTATEEN0_HCONTEXT))
throw trap_illegal_instruction(insn.bits());

if (state->v && !(state->hstateen[0]->read() & HSTATEEN0_SCONTEXT))
throw trap_virtual_instruction(insn.bits());
}

proxy_csr_t::verify_permissions(insn, write);
}

mevent_csr_t::mevent_csr_t(processor_t* const proc, const reg_t addr):
basic_csr_t(proc, addr, 0) {
}
Expand Down Expand Up @@ -1252,6 +1268,31 @@ void debug_mode_csr_t::verify_permissions(insn_t insn, bool write) const {
throw trap_illegal_instruction(insn.bits());
}

mscontext_csr_t::mscontext_csr_t(processor_t* const proc, const reg_t addr, csr_t_p delegate):
proxy_csr_t(proc, addr, delegate) {
}

void mscontext_csr_t::verify_permissions(insn_t insn, bool write) const {
if (proc->extension_enabled(EXT_SMSTATEEN)) {
if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & MSTATEEN0_HCONTEXT))
throw trap_illegal_instruction(insn.bits());

if (state->v && !(state->hstateen[0]->read() & HSTATEEN0_SCONTEXT))
throw trap_virtual_instruction(insn.bits());
}

// Address of mscontext does not conform to the CSR conventions, i.e., csr_priv == PRV_S
if (!proc->extension_enabled('S'))
throw trap_illegal_instruction(insn.bits());

unsigned priv = state->prv == PRV_S && !state->v ? PRV_HS : state->prv;
if (priv < PRV_S) {
if (state->v)
throw trap_virtual_instruction(insn.bits());
throw trap_illegal_instruction(insn.bits());
}
}

dpc_csr_t::dpc_csr_t(processor_t* const proc, const reg_t addr):
epc_csr_t(proc, addr) {
}
Expand Down Expand Up @@ -1614,6 +1655,22 @@ void jvt_csr_t::verify_permissions(insn_t insn, bool write) const {
}
}

context_csr_t::context_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init):
masked_csr_t(proc, addr, mask, init) {
}

void context_csr_t::verify_permissions(insn_t insn, bool write) const {
if (proc->extension_enabled(EXT_SMSTATEEN)) {
if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & MSTATEEN0_HCONTEXT))
throw trap_illegal_instruction(insn.bits());

if (state->v && !(state->hstateen[0]->read() & HSTATEEN0_SCONTEXT))
throw trap_virtual_instruction(insn.bits());
}

basic_csr_t::verify_permissions(insn, write);
}

virtualized_indirect_csr_t::virtualized_indirect_csr_t(processor_t* const proc, csr_t_p orig, csr_t_p virt):
virtualized_csr_t(proc, orig, virt) {
}
Expand Down
18 changes: 18 additions & 0 deletions riscv/csrs.h
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,12 @@ class counter_proxy_csr_t: public proxy_csr_t {
bool myenable(csr_t_p counteren) const noexcept;
};

class context_proxy_csr_t: public proxy_csr_t {
public:
context_proxy_csr_t(processor_t* const proc, const reg_t addr, csr_t_p delegate);
virtual void verify_permissions(insn_t insn, bool write) const override;
};

class mevent_csr_t: public basic_csr_t {
public:
mevent_csr_t(processor_t* const proc, const reg_t addr);
Expand Down Expand Up @@ -664,6 +670,12 @@ class debug_mode_csr_t: public basic_csr_t {
virtual void verify_permissions(insn_t insn, bool write) const override;
};

class mscontext_csr_t: public proxy_csr_t {
public:
mscontext_csr_t(processor_t* const proc, const reg_t addr, csr_t_p delegate);
virtual void verify_permissions(insn_t insn, bool write) const override;
};

class dpc_csr_t: public epc_csr_t {
public:
dpc_csr_t(processor_t* const proc, const reg_t addr);
Expand Down Expand Up @@ -808,6 +820,12 @@ class jvt_csr_t: public basic_csr_t {
virtual void verify_permissions(insn_t insn, bool write) const override;
};

class context_csr_t: public masked_csr_t {
public:
context_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init);
virtual void verify_permissions(insn_t insn, bool write) const override;
};

// Sscsrind registers needs permissions checked
// (the original virtualized_csr_t does not call verify_permission of the underlying CSRs)
class virtualized_indirect_csr_t: public virtualized_csr_t {
Expand Down
9 changes: 5 additions & 4 deletions riscv/processor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -418,10 +418,11 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
csrmap[CSR_TINFO] = std::make_shared<const_csr_t>(proc, CSR_TINFO, 0);
}
unsigned scontext_length = (xlen == 32 ? 16 : 34); // debug spec suggests 16-bit for RV32 and 34-bit for RV64
csrmap[CSR_SCONTEXT] = scontext = std::make_shared<masked_csr_t>(proc, CSR_SCONTEXT, (reg_t(1) << scontext_length) - 1, 0);
csrmap[CSR_SCONTEXT] = scontext = std::make_shared<context_csr_t>(proc, CSR_SCONTEXT, (reg_t(1) << scontext_length) - 1, 0);
unsigned hcontext_length = (xlen == 32 ? 6 : 13) + (proc->extension_enabled('H') ? 1 : 0); // debug spec suggest 7-bit (6-bit) for RV32 and 14-bit (13-bit) for RV64 with (without) H extension
csrmap[CSR_HCONTEXT] = std::make_shared<masked_csr_t>(proc, CSR_HCONTEXT, (reg_t(1) << hcontext_length) - 1, 0);
csrmap[CSR_MCONTEXT] = mcontext = std::make_shared<proxy_csr_t>(proc, CSR_MCONTEXT, csrmap[CSR_HCONTEXT]);
csrmap[CSR_HCONTEXT] = std::make_shared<context_csr_t>(proc, CSR_HCONTEXT, (reg_t(1) << hcontext_length) - 1, 0);
csrmap[CSR_MCONTEXT] = mcontext = std::make_shared<context_proxy_csr_t>(proc, CSR_MCONTEXT, csrmap[CSR_HCONTEXT]);
csrmap[CSR_MSCONTEXT] = std::make_shared<mscontext_csr_t>(proc, CSR_MSCONTEXT, scontext);
debug_mode = false;
single_step = STEP_NONE;

Expand Down Expand Up @@ -482,7 +483,7 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
const reg_t sstateen0_mask = (proc->extension_enabled(EXT_ZFINX) ? SSTATEEN0_FCSR : 0) |
(proc->extension_enabled(EXT_ZCMT) ? SSTATEEN0_JVT : 0) |
SSTATEEN0_CS;
const reg_t hstateen0_mask = sstateen0_mask | HSTATEEN0_SENVCFG | HSTATEEN_SSTATEEN;
const reg_t hstateen0_mask = sstateen0_mask | HSTATEEN0_SCONTEXT | HSTATEEN0_SENVCFG | HSTATEEN_SSTATEEN;
const reg_t mstateen0_mask = hstateen0_mask;
for (int i = 0; i < 4; i++) {
const reg_t mstateen_mask = i == 0 ? mstateen0_mask : MSTATEEN_HSTATEEN;
Expand Down
Loading