Skip to content

Commit 2e86ec4

Browse files
authored
Merge pull request #1582 from mylai-mtk/zicfilp-upstream
Support Zicfilp
2 parents d527f1e + 677e030 commit 2e86ec4

File tree

20 files changed

+140
-12
lines changed

20 files changed

+140
-12
lines changed

disasm/disasm.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,12 @@ void disassembler_t::add_instructions(const isa_parser_t* isa)
868868
DEFINE_XAMO(amocas_h)
869869
}
870870

871+
if (isa->extension_enabled(EXT_ZICFILP)) {
872+
// lpad encodes as `auipc x0, label`, so it needs to be added before auipc
873+
// for higher disassembling priority
874+
DISASM_INSN("lpad", lpad, 0, {&bigimm});
875+
}
876+
871877
add_insn(new disasm_insn_t("j", match_jal, mask_jal | mask_rd, {&jump_target}));
872878
add_insn(new disasm_insn_t("jal", match_jal | match_rd_ra, mask_jal | mask_rd, {&jump_target}));
873879
add_insn(new disasm_insn_t("jal", match_jal, mask_jal, {&xrd, &jump_target}));

disasm/isa_parser.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,8 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv)
306306
extension_table[EXT_ZALASR] = true;
307307
} else if (ext_str == "ssqosid") {
308308
extension_table[EXT_SSQOSID] = true;
309+
} else if (ext_str == "zicfilp") {
310+
extension_table[EXT_ZICFILP] = true;
309311
} else if (ext_str[0] == 'x') {
310312
extension_table['X'] = true;
311313
if (ext_str.size() == 1) {

riscv/csrs.cc

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,8 @@ mseccfg_csr_t::mseccfg_csr_t(processor_t* const proc, const reg_t addr):
285285

286286
void mseccfg_csr_t::verify_permissions(insn_t insn, bool write) const {
287287
basic_csr_t::verify_permissions(insn, write);
288-
if (!proc->extension_enabled(EXT_SMEPMP))
288+
if (!proc->extension_enabled(EXT_SMEPMP) &&
289+
!proc->extension_enabled(EXT_ZICFILP))
289290
throw trap_illegal_instruction(insn.bits());
290291
}
291292

@@ -322,6 +323,11 @@ bool mseccfg_csr_t::unlogged_write(const reg_t val) noexcept {
322323

323324
proc->get_mmu()->flush_tlb();
324325

326+
if (proc->extension_enabled(EXT_ZICFILP)) {
327+
new_val &= ~MSECCFG_MLPE;
328+
new_val |= (val & MSECCFG_MLPE);
329+
}
330+
325331
return basic_csr_t::unlogged_write(new_val);
326332
}
327333

@@ -414,6 +420,7 @@ reg_t base_status_csr_t::compute_sstatus_write_mask() const noexcept {
414420
| (has_fs ? SSTATUS_FS : 0)
415421
| (proc->any_custom_extensions() ? SSTATUS_XS : 0)
416422
| (has_vs ? SSTATUS_VS : 0)
423+
| (proc->extension_enabled(EXT_ZICFILP) ? SSTATUS_SPELP : 0)
417424
;
418425
}
419426

@@ -497,7 +504,9 @@ bool mstatus_csr_t::unlogged_write(const reg_t val) noexcept {
497504
| (proc->extension_enabled('S') ? MSTATUS_TSR : 0)
498505
| (has_page ? MSTATUS_TVM : 0)
499506
| (has_gva ? MSTATUS_GVA : 0)
500-
| (has_mpv ? MSTATUS_MPV : 0);
507+
| (has_mpv ? MSTATUS_MPV : 0)
508+
| (proc->extension_enabled(EXT_ZICFILP) ? (MSTATUS_SPELP | MSTATUS_MPELP) : 0)
509+
;
501510

502511
const reg_t requested_mpp = proc->legalize_privilege(get_field(val, MSTATUS_MPP));
503512
const reg_t adjusted_val = set_field(val, MSTATUS_MPP, requested_mpp);
@@ -897,6 +906,7 @@ bool medeleg_csr_t::unlogged_write(const reg_t val) noexcept {
897906
| (1 << CAUSE_LOAD_PAGE_FAULT)
898907
| (1 << CAUSE_STORE_PAGE_FAULT)
899908
| (proc->extension_enabled('H') ? hypervisor_exceptions : 0)
909+
| (proc->extension_enabled(EXT_ZICFILP) ? (1 << CAUSE_SOFTWARE_CHECK_FAULT) : 0)
900910
;
901911
return basic_csr_t::unlogged_write((read() & ~mask) | (val & mask));
902912
}
@@ -1284,7 +1294,8 @@ dcsr_csr_t::dcsr_csr_t(processor_t* const proc, const reg_t addr):
12841294
ebreakvu(false),
12851295
halt(false),
12861296
v(false),
1287-
cause(0) {
1297+
cause(0),
1298+
pelp(elp_t::NO_LP_EXPECTED) {
12881299
}
12891300

12901301
void dcsr_csr_t::verify_permissions(insn_t insn, bool write) const {
@@ -1307,6 +1318,7 @@ reg_t dcsr_csr_t::read() const noexcept {
13071318
result = set_field(result, DCSR_STEP, step);
13081319
result = set_field(result, DCSR_PRV, prv);
13091320
result = set_field(result, CSR_DCSR_V, v);
1321+
result = set_field(result, DCSR_PELP, pelp);
13101322
return result;
13111323
}
13121324

@@ -1321,13 +1333,17 @@ bool dcsr_csr_t::unlogged_write(const reg_t val) noexcept {
13211333
ebreakvu = proc->extension_enabled('H') ? get_field(val, CSR_DCSR_EBREAKVU) : false;
13221334
halt = get_field(val, DCSR_HALT);
13231335
v = proc->extension_enabled('H') ? get_field(val, CSR_DCSR_V) : false;
1336+
pelp = proc->extension_enabled(EXT_ZICFILP) ?
1337+
static_cast<elp_t>(get_field(val, DCSR_PELP)) : elp_t::NO_LP_EXPECTED;
13241338
return true;
13251339
}
13261340

1327-
void dcsr_csr_t::write_cause_and_prv(uint8_t cause, reg_t prv, bool v) noexcept {
1341+
void dcsr_csr_t::update_fields(const uint8_t cause, const reg_t prv,
1342+
const bool v, const elp_t pelp) noexcept {
13281343
this->cause = cause;
13291344
this->prv = prv;
13301345
this->v = v;
1346+
this->pelp = pelp;
13311347
log_write();
13321348
}
13331349

riscv/csrs.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@
2121
class processor_t;
2222
struct state_t;
2323

24+
enum struct elp_t {
25+
NO_LP_EXPECTED = 0,
26+
LP_EXPECTED = 1,
27+
};
28+
2429
// Parent, abstract class for all CSRs
2530
class csr_t {
2631
public:
@@ -676,7 +681,8 @@ class dcsr_csr_t: public csr_t {
676681
dcsr_csr_t(processor_t* const proc, const reg_t addr);
677682
virtual void verify_permissions(insn_t insn, bool write) const override;
678683
virtual reg_t read() const noexcept override;
679-
void write_cause_and_prv(uint8_t cause, reg_t prv, bool v) noexcept;
684+
void update_fields(const uint8_t cause, const reg_t prv,
685+
const bool v, const elp_t pelp) noexcept;
680686
protected:
681687
virtual bool unlogged_write(const reg_t val) noexcept override;
682688
public:
@@ -690,6 +696,7 @@ class dcsr_csr_t: public csr_t {
690696
bool halt;
691697
bool v;
692698
uint8_t cause;
699+
elp_t pelp;
693700
};
694701

695702
typedef std::shared_ptr<dcsr_csr_t> dcsr_csr_t_p;

riscv/decode_macros.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,3 +321,23 @@ inline long double to_f(float128_t f) { long double r; memcpy(&r, &f, sizeof(r))
321321
reg_t h##field = get_field(STATE.henvcfg->read(), HENVCFG_##field)
322322

323323
#endif
324+
325+
#define software_check(x, tval) (unlikely(!(x)) ? throw trap_software_check(tval) : (void) 0)
326+
#define ZICFILP_xLPE(v, prv) \
327+
({ \
328+
reg_t lpe = 0ULL; \
329+
if (p->extension_enabled(EXT_ZICFILP)) { \
330+
DECLARE_XENVCFG_VARS(LPE); \
331+
const reg_t msecLPE = get_field(STATE.mseccfg->read(), MSECCFG_MLPE); \
332+
switch (prv) { \
333+
case PRV_U: lpe = p->extension_enabled('S') ? sLPE : mLPE; break; \
334+
case PRV_S: lpe = (v) ? hLPE : mLPE; break; \
335+
case PRV_M: lpe = msecLPE; break; \
336+
default: abort(); \
337+
} \
338+
} \
339+
lpe; \
340+
})
341+
#define ZICFILP_IS_LP_EXPECTED(reg_num) \
342+
(((reg_num) != 1 && (reg_num) != 5 && (reg_num) != 7) ? \
343+
elp_t::LP_EXPECTED : elp_t::NO_LP_EXPECTED)

riscv/encoding.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
/*
66
* This file is auto-generated by running 'make' in
7-
* https://github.com/riscv/riscv-opcodes (a014979)
7+
* https://github.com/riscv/riscv-opcodes (4ad822d)
88
*/
99

1010
#ifndef RISCV_CSR_ENCODING_H
@@ -346,6 +346,9 @@
346346
#define SRMCFG_RCID 0x00000FFF
347347
#define SRMCFG_MCID 0x0FFF0000
348348

349+
/* software check exception xtval codes */
350+
#define LANDING_PAD_FAULT 2
351+
349352
#ifdef __riscv
350353

351354
#if __riscv_xlen == 64
@@ -1464,6 +1467,8 @@
14641467
#define MASK_LH_AQ 0xfdf0707f
14651468
#define MATCH_LHU 0x5003
14661469
#define MASK_LHU 0x707f
1470+
#define MATCH_LPAD 0x17
1471+
#define MASK_LPAD 0xfff
14671472
#define MATCH_LQ 0x300f
14681473
#define MASK_LQ 0x707f
14691474
#define MATCH_LR_D 0x1000302f
@@ -4245,6 +4250,7 @@ DECLARE_INSN(ldu, MATCH_LDU, MASK_LDU)
42454250
DECLARE_INSN(lh, MATCH_LH, MASK_LH)
42464251
DECLARE_INSN(lh_aq, MATCH_LH_AQ, MASK_LH_AQ)
42474252
DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU)
4253+
DECLARE_INSN(lpad, MATCH_LPAD, MASK_LPAD)
42484254
DECLARE_INSN(lq, MATCH_LQ, MASK_LQ)
42494255
DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D)
42504256
DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W)

riscv/execute.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ void processor_t::step(size_t n)
280280

281281
in_wfi = false;
282282
insn_fetch_t fetch = mmu->load_insn(pc);
283+
execute_insn_prehook(fetch.insn);
283284
if (debug && !state.serialized)
284285
disasm(fetch.insn);
285286
pc = execute_insn_logged(this, pc, fetch);
@@ -291,6 +292,7 @@ void processor_t::step(size_t n)
291292
// Main simulation loop, fast path.
292293
for (auto ic_entry = _mmu->access_icache(pc); ; ) {
293294
auto fetch = ic_entry->data;
295+
execute_insn_prehook(fetch.insn);
294296
pc = execute_insn_fast(this, pc, fetch);
295297
ic_entry = ic_entry->next;
296298
if (unlikely(ic_entry->tag != pc))

riscv/insns/c_jalr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@ require(insn.rvc_rs1() != 0);
33
reg_t tmp = npc;
44
set_pc(RVC_RS1 & ~reg_t(1));
55
WRITE_REG(X_RA, tmp);
6+
7+
if (ZICFILP_xLPE(STATE.v, STATE.prv)) {
8+
STATE.elp = ZICFILP_IS_LP_EXPECTED(insn.rvc_rs1());
9+
}

riscv/insns/c_jr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
require_extension(EXT_ZCA);
22
require(insn.rvc_rs1() != 0);
33
set_pc(RVC_RS1 & ~reg_t(1));
4+
5+
if (ZICFILP_xLPE(STATE.v, STATE.prv)) {
6+
STATE.elp = ZICFILP_IS_LP_EXPECTED(insn.rvc_rs1());
7+
}

riscv/insns/dret.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
require(STATE.debug_mode);
22
set_pc_and_serialize(STATE.dpc->read());
3+
if (ZICFILP_xLPE(STATE.dcsr->v, STATE.dcsr->prv)) {
4+
STATE.elp = STATE.dcsr->pelp;
5+
}
36
p->set_privilege(STATE.dcsr->prv, STATE.dcsr->v);
47
if (STATE.prv < PRV_M)
58
STATE.mstatus->write(STATE.mstatus->read() & ~MSTATUS_MPRV);

0 commit comments

Comments
 (0)