aboutsummaryrefslogtreecommitdiff
path: root/riscv/processor.cc
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2024-03-21 13:21:31 -0700
committerGitHub <noreply@github.com>2024-03-21 13:21:31 -0700
commit2e86ec4b83c2fe3eb19669244357d288be8b45fa (patch)
tree4c11369a500362d979a17a6538af402fcdcf3aa9 /riscv/processor.cc
parentd527f1e4df711af07f3a20a478aa187d7146feb1 (diff)
parent677e030594aa51ea8d6304d24b7da2ecd7006fe8 (diff)
downloadriscv-isa-sim-2e86ec4b83c2fe3eb19669244357d288be8b45fa.zip
riscv-isa-sim-2e86ec4b83c2fe3eb19669244357d288be8b45fa.tar.gz
riscv-isa-sim-2e86ec4b83c2fe3eb19669244357d288be8b45fa.tar.bz2
Merge pull request #1582 from mylai-mtk/zicfilp-upstream
Support Zicfilp
Diffstat (limited to 'riscv/processor.cc')
-rw-r--r--riscv/processor.cc39
1 files changed, 34 insertions, 5 deletions
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 1c0486b..347fff3 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -94,6 +94,14 @@ processor_t::~processor_t()
delete disassembler;
}
+static void zicfilp_check_if_lpad_required(const elp_t elp, insn_t insn)
+{
+ if (unlikely(elp == elp_t::LP_EXPECTED)) {
+ // also see riscv/lpad.h for more checks performed
+ software_check((insn.bits() & MASK_LPAD) == MATCH_LPAD, LANDING_PAD_FAULT);
+ }
+}
+
static void bad_option_string(const char *option, const char *value,
const char *msg)
{
@@ -374,7 +382,8 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
(1 << CAUSE_USER_ECALL) |
(1 << CAUSE_FETCH_PAGE_FAULT) |
(1 << CAUSE_LOAD_PAGE_FAULT) |
- (1 << CAUSE_STORE_PAGE_FAULT);
+ (1 << CAUSE_STORE_PAGE_FAULT) |
+ (1 << CAUSE_SOFTWARE_CHECK_FAULT);
csrmap[CSR_HEDELEG] = hedeleg = std::make_shared<masked_csr_t>(proc, CSR_HEDELEG, hedeleg_mask, 0);
csrmap[CSR_HCOUNTEREN] = hcounteren = std::make_shared<masked_csr_t>(proc, CSR_HCOUNTEREN, counteren_mask, 0);
htimedelta = std::make_shared<basic_csr_t>(proc, CSR_HTIMEDELTA, 0);
@@ -443,7 +452,8 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
(proc->extension_enabled(EXT_ZICBOZ) ? MENVCFG_CBZE : 0) |
(proc->extension_enabled(EXT_SVADU) ? MENVCFG_ADUE: 0) |
(proc->extension_enabled(EXT_SVPBMT) ? MENVCFG_PBMTE : 0) |
- (proc->extension_enabled(EXT_SSTC) ? MENVCFG_STCE : 0);
+ (proc->extension_enabled(EXT_SSTC) ? MENVCFG_STCE : 0) |
+ (proc->extension_enabled(EXT_ZICFILP) ? MENVCFG_LPE : 0);
const reg_t menvcfg_init = (proc->extension_enabled(EXT_SVPBMT) ? MENVCFG_PBMTE : 0);
menvcfg = std::make_shared<envcfg_csr_t>(proc, CSR_MENVCFG, menvcfg_mask, menvcfg_init);
if (xlen == 32) {
@@ -453,13 +463,15 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
csrmap[CSR_MENVCFG] = menvcfg;
}
const reg_t senvcfg_mask = (proc->extension_enabled(EXT_ZICBOM) ? SENVCFG_CBCFE | SENVCFG_CBIE : 0) |
- (proc->extension_enabled(EXT_ZICBOZ) ? SENVCFG_CBZE : 0);
+ (proc->extension_enabled(EXT_ZICBOZ) ? SENVCFG_CBZE : 0) |
+ (proc->extension_enabled(EXT_ZICFILP) ? SENVCFG_LPE : 0);
csrmap[CSR_SENVCFG] = senvcfg = std::make_shared<senvcfg_csr_t>(proc, CSR_SENVCFG, senvcfg_mask, 0);
const reg_t henvcfg_mask = (proc->extension_enabled(EXT_ZICBOM) ? HENVCFG_CBCFE | HENVCFG_CBIE : 0) |
(proc->extension_enabled(EXT_ZICBOZ) ? HENVCFG_CBZE : 0) |
(proc->extension_enabled(EXT_SVADU) ? HENVCFG_ADUE: 0) |
(proc->extension_enabled(EXT_SVPBMT) ? HENVCFG_PBMTE : 0) |
- (proc->extension_enabled(EXT_SSTC) ? HENVCFG_STCE : 0);
+ (proc->extension_enabled(EXT_SSTC) ? HENVCFG_STCE : 0) |
+ (proc->extension_enabled(EXT_ZICFILP) ? HENVCFG_LPE : 0);
const reg_t henvcfg_init = (proc->extension_enabled(EXT_SVPBMT) ? HENVCFG_PBMTE : 0);
henvcfg = std::make_shared<henvcfg_csr_t>(proc, CSR_HENVCFG, henvcfg_mask, henvcfg_init, menvcfg);
if (xlen == 32) {
@@ -590,6 +602,8 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
last_inst_priv = 0;
last_inst_xlen = 0;
last_inst_flen = 0;
+
+ elp = elp_t::NO_LP_EXPECTED;
}
void processor_t::set_debug(bool value)
@@ -810,8 +824,10 @@ const char* processor_t::get_privilege_string()
void processor_t::enter_debug_mode(uint8_t cause)
{
+ const bool has_zicfilp = extension_enabled(EXT_ZICFILP);
state.debug_mode = true;
- state.dcsr->write_cause_and_prv(cause, state.prv, state.v);
+ state.dcsr->update_fields(cause, state.prv, state.v, state.elp);
+ state.elp = elp_t::NO_LP_EXPECTED;
set_privilege(PRV_M, false);
state.dpc->write(state.pc);
state.pc = DEBUG_ROM_ENTRY;
@@ -880,6 +896,8 @@ void processor_t::take_trap(trap_t& t, reg_t epc)
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);
+ s = set_field(s, MSTATUS_SPELP, state.elp);
+ state.elp = elp_t::NO_LP_EXPECTED;
state.sstatus->write(s);
set_privilege(PRV_S, true);
} else if (state.prv <= PRV_S && bit < max_xlen && ((hsdeleg >> bit) & 1)) {
@@ -896,6 +914,8 @@ void processor_t::take_trap(trap_t& t, reg_t epc)
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);
+ s = set_field(s, MSTATUS_SPELP, state.elp);
+ state.elp = elp_t::NO_LP_EXPECTED;
state.nonvirtual_sstatus->write(s);
if (extension_enabled('H')) {
s = state.hstatus->read();
@@ -927,6 +947,8 @@ void processor_t::take_trap(trap_t& t, reg_t epc)
s = set_field(s, MSTATUS_MIE, 0);
s = set_field(s, MSTATUS_MPV, curr_virt);
s = set_field(s, MSTATUS_GVA, t.has_gva());
+ s = set_field(s, MSTATUS_MPELP, state.elp);
+ state.elp = elp_t::NO_LP_EXPECTED;
state.mstatus->write(s);
if (state.mstatush) state.mstatush->write(s >> 32); // log mstatush change
set_privilege(PRV_M, false);
@@ -961,6 +983,13 @@ const char* processor_t::get_symbol(uint64_t addr)
return sim->get_symbol(addr);
}
+void processor_t::execute_insn_prehook(insn_t insn)
+{
+ if (extension_enabled(EXT_ZICFILP)) {
+ zicfilp_check_if_lpad_required(state.elp, insn);
+ }
+}
+
void processor_t::disasm(insn_t insn)
{
uint64_t bits = insn.bits();