aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscv/csrs.cc19
-rw-r--r--riscv/csrs.h6
-rw-r--r--riscv/processor.cc9
3 files changed, 28 insertions, 6 deletions
diff --git a/riscv/csrs.cc b/riscv/csrs.cc
index 0e8bf6d..50fb1a2 100644
--- a/riscv/csrs.cc
+++ b/riscv/csrs.cc
@@ -285,7 +285,8 @@ mseccfg_csr_t::mseccfg_csr_t(processor_t* const proc, const reg_t addr):
void mseccfg_csr_t::verify_permissions(insn_t insn, bool write) const {
basic_csr_t::verify_permissions(insn, write);
- if (!proc->extension_enabled(EXT_SMEPMP))
+ if (!proc->extension_enabled(EXT_SMEPMP) &&
+ !proc->extension_enabled(EXT_ZICFILP))
throw trap_illegal_instruction(insn.bits());
}
@@ -322,6 +323,11 @@ bool mseccfg_csr_t::unlogged_write(const reg_t val) noexcept {
proc->get_mmu()->flush_tlb();
+ if (proc->extension_enabled(EXT_ZICFILP)) {
+ new_val &= ~MSECCFG_MLPE;
+ new_val |= (val & MSECCFG_MLPE);
+ }
+
return basic_csr_t::unlogged_write(new_val);
}
@@ -414,6 +420,7 @@ reg_t base_status_csr_t::compute_sstatus_write_mask() const noexcept {
| (has_fs ? SSTATUS_FS : 0)
| (proc->any_custom_extensions() ? SSTATUS_XS : 0)
| (has_vs ? SSTATUS_VS : 0)
+ | (proc->extension_enabled(EXT_ZICFILP) ? SSTATUS_SPELP : 0)
;
}
@@ -497,7 +504,9 @@ bool mstatus_csr_t::unlogged_write(const reg_t val) noexcept {
| (proc->extension_enabled('S') ? MSTATUS_TSR : 0)
| (has_page ? MSTATUS_TVM : 0)
| (has_gva ? MSTATUS_GVA : 0)
- | (has_mpv ? MSTATUS_MPV : 0);
+ | (has_mpv ? MSTATUS_MPV : 0)
+ | (proc->extension_enabled(EXT_ZICFILP) ? (MSTATUS_SPELP | MSTATUS_MPELP) : 0)
+ ;
const reg_t requested_mpp = proc->legalize_privilege(get_field(val, MSTATUS_MPP));
const reg_t adjusted_val = set_field(val, MSTATUS_MPP, requested_mpp);
@@ -1284,7 +1293,8 @@ dcsr_csr_t::dcsr_csr_t(processor_t* const proc, const reg_t addr):
ebreakvu(false),
halt(false),
v(false),
- cause(0) {
+ cause(0),
+ pelp(elp_t::NO_LP_EXPECTED) {
}
void dcsr_csr_t::verify_permissions(insn_t insn, bool write) const {
@@ -1307,6 +1317,7 @@ reg_t dcsr_csr_t::read() const noexcept {
result = set_field(result, DCSR_STEP, step);
result = set_field(result, DCSR_PRV, prv);
result = set_field(result, CSR_DCSR_V, v);
+ result = set_field(result, DCSR_PELP, pelp);
return result;
}
@@ -1321,6 +1332,8 @@ bool dcsr_csr_t::unlogged_write(const reg_t val) noexcept {
ebreakvu = proc->extension_enabled('H') ? get_field(val, CSR_DCSR_EBREAKVU) : false;
halt = get_field(val, DCSR_HALT);
v = proc->extension_enabled('H') ? get_field(val, CSR_DCSR_V) : false;
+ pelp = proc->extension_enabled(EXT_ZICFILP) ?
+ static_cast<elp_t>(get_field(val, DCSR_PELP)) : elp_t::NO_LP_EXPECTED;
return true;
}
diff --git a/riscv/csrs.h b/riscv/csrs.h
index b3dfe1c..a472801 100644
--- a/riscv/csrs.h
+++ b/riscv/csrs.h
@@ -21,6 +21,11 @@
class processor_t;
struct state_t;
+enum struct elp_t {
+ NO_LP_EXPECTED = 0,
+ LP_EXPECTED = 1,
+};
+
// Parent, abstract class for all CSRs
class csr_t {
public:
@@ -690,6 +695,7 @@ class dcsr_csr_t: public csr_t {
bool halt;
bool v;
uint8_t cause;
+ elp_t pelp;
};
typedef std::shared_ptr<dcsr_csr_t> dcsr_csr_t_p;
diff --git a/riscv/processor.cc b/riscv/processor.cc
index cfce08f..09ff3e2 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -443,7 +443,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 +454,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) {