Skip to content

Commit

Permalink
csr: Support Advanced Interrupt Architecture/AIA extension (#383)
Browse files Browse the repository at this point in the history
* add CSRs: miselect,  mireg,  mtopei,  mtopi,
 	    siselect,  sireg,  stopei,  stopi,
	   vsiselect, vsireg, vstopei, vstopi,
	    mvien, mvip,
	    hvien, hvictl, hviprio1, hviprio2,

* permission checking: access mireg, sireg, vsireg, sip, sie, stopei
  • Loading branch information
sinceforYy committed Jul 5, 2024
1 parent 26e4497 commit 0b2e23f
Show file tree
Hide file tree
Showing 6 changed files with 262 additions and 2 deletions.
2 changes: 2 additions & 0 deletions configs/riscv64-xs-ref_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ CONFIG_XTVEC_VECTORED_MODE=y
CONFIG_FS_CLEAN_STATE=y
CONFIG_USE_XS_ARCH_CSRS=y
CONFIG_RVV_AGNOSTIC=y
CONFIG_RV_AIA=y
CONFIG_RV_IMSIC=y
# end of ISA-dependent Options for riscv64

CONFIG_ENGINE_INTERPRETER=y
Expand Down
10 changes: 10 additions & 0 deletions src/isa/riscv64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ config TRIGGER_NUM
depends on RV_SDTRIG
default 10

config RV_AIA
bool "(Beta) RISC-V Advanced Interrupt Architecture v1.0"
depends on RVH
default n

config RV_IMSIC
bool "Incoming MSI Controller"
depends on RV_AIA
default n

menuconfig RV_ZICNTR
bool "RISC-V Zicntr Extensions for Base Counters and Timers, v2.0"
default y
Expand Down
22 changes: 21 additions & 1 deletion src/isa/riscv64/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,27 @@ void init_isa() {
hstatus->vsxl = 2; // equal to max len (spike)
vsstatus->val = mstatus->val & SSTATUS_RMASK;
mideleg->val |= ((1 << 12) | (1 << 10) | (1 << 6) | (1 << 2));
#endif
#endif // CONFIG_RVH
#ifdef CONFIG_RV_IMSIC
miselect->val = 0;
siselect->val = 0;
vsiselect->val = 0;
mireg->val = 0;
sireg->val = 0;
vsireg->val = 0;
mtopi->val = 0;
stopi->val = 0;
vstopi->val = 0;
mvien->val = 0;
mvip->val = 0;
hvien->val = 0;
hvictl->val = 0;
hviprio1->val = 0;
hviprio2->val = 0;
mtopei->val = 0;
stopei->val = 0;
vstopei->val = 0;
#endif // CONFIG_RV_IMSIC

misa->mxl = 2; // XLEN = 64

Expand Down
139 changes: 138 additions & 1 deletion src/isa/riscv64/local-include/csr.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,15 @@
#define CSRS_S_CUSTOM_1(f) \
CSRS_S_XIANGSHAN_CTRL(f)

/** Supervisor Advanced Interrupt Architecture Registers **/
#ifdef CONFIG_RV_IMSIC
#define CSRS_S_AIA(f) \
f(siselect , 0x150) f(sireg , 0x151) \
f(stopei , 0x15C) f(stopi , 0xDB0)
#else
#define CSRS_S_AIA(f)
#endif // CONFIG_RV_IMSIC

/** ALL **/
#define CSRS_S(f) \
CSRS_S_TRAP_SETUP(f) \
Expand All @@ -165,6 +174,7 @@
CSRS_S_DEBUG_TRACE(f) \
CSRS_S_STATE_ENABLE(f) \
CSRS_S_SCOFPMF(f) \
CSRS_S_AIA(f) \
CSRS_S_CUSTOM_1(f)


Expand Down Expand Up @@ -214,6 +224,17 @@
f(vsscratch , 0x240) f(vsepc , 0x241) f(vscause , 0x242) \
f(vstval , 0x243) f(vsip , 0x244) f(vsatp , 0x280)

/** Hypervisor and VS AIA Registers **/
#ifdef CONFIG_RV_IMSIC
#define CSRS_H_VS_AIA(f) \
f(vsiselect , 0x250) f(vsireg , 0x251) \
f(vstopei , 0x25C) f(hvien , 0x608) \
f(hvictl , 0x609) f(hviprio1 , 0x646) \
f(hviprio2 , 0x647) f(vstopi , 0xEB0)
#else
#define CSRS_H_VS_AIA(f)
#endif // CONFIG_RV_IMSIC

/** ALL **/
#define CSRS_H_VS(f) \
CSRS_H_TRAP_SETUP(f) \
Expand All @@ -223,6 +244,7 @@
CSRS_H_DEBUG_TRACE(f) \
CSRS_H_CONUTER_TIMER_VIRTUALIZATION(f) \
CSRS_H_STATE_ENABLE(f) \
CSRS_H_VS_AIA(f) \
CSRS_VS(f)

#else // CONFIG_RVH
Expand Down Expand Up @@ -364,6 +386,16 @@
#define CSRS_DEBUG_MODE(f)
#endif // CONFIG_RV_SDEXT

/** Machine AIA Registers **/
#ifdef CONFIG_RV_IMSIC
#define CSRS_M_AIA(f) \
f(mvien , 0x308) f(mvip , 0x309) \
f(miselect , 0x350) f(mireg , 0x351) \
f(mtopei , 0x35C) f(mtopi , 0xFB0)
#else
#define CSRS_M_AIA(f)
#endif // CONFIG_RV_IMSIC

/** ALL **/
#define CSRS_M(f) \
CSRS_M_INFOMATION(f) \
Expand All @@ -376,6 +408,7 @@
CSRS_M_COUNTER_TIMERS(f) \
CSRS_M_COUNTER_SETUP(f) \
CSRS_M_DEBUG_TRACE(f) \
CSRS_M_AIA(f) \
CSRS_DEBUG_MODE(f)


Expand Down Expand Up @@ -691,6 +724,42 @@ CSR_STRUCT_END(mcontext)

#endif // CONFIG_RV_SDTRIG

#ifdef CONFIG_RV_IMSIC
CSR_STRUCT_START(miselect)
CSR_STRUCT_END(miselect)

CSR_STRUCT_START(mireg)
CSR_STRUCT_END(mireg)

CSR_STRUCT_START(mtopei)
uint64_t iprio : 11; // [10: 0]
uint64_t pad : 5; // [15:11]
uint64_t iid : 11; // [26:16]
CSR_STRUCT_END(mtopei)

CSR_STRUCT_START(mtopi)
uint64_t iprio : 8; // [ 7: 0]
uint64_t pad : 8; // [15: 8]
uint64_t iid : 12; // [27:16]
CSR_STRUCT_END(mtopi)

CSR_STRUCT_START(mvien)
uint64_t pad0 : 1; // [0]
uint64_t ssie : 1; // [1]
uint64_t pad1 : 7; // [8:2]
uint64_t seie : 1; // [9]
CSR_STRUCT_END(mvien)

CSR_STRUCT_START(mvip)
uint64_t pad0 : 1; // [0]
uint64_t ssip : 1; // [1]
uint64_t pad1 : 3; // [4:2]
uint64_t stip : 1; // [5]
uint64_t pad2 : 3; // [8:6]
uint64_t seip : 1; // [9]
CSR_STRUCT_END(mvip)
#endif // CONFIG_RV_IMSIC

/* Supervisor-level CSR */

CSR_STRUCT_START(sstatus)
Expand Down Expand Up @@ -774,6 +843,26 @@ CSR_STRUCT_START(srnctl)
CSR_STRUCT_END(srnctl)
#endif

/** Supervisor Advanced Interrupt Architecture CSRs **/
#ifdef CONFIG_RV_IMSIC
CSR_STRUCT_START(siselect)
CSR_STRUCT_END(siselect)

CSR_STRUCT_START(sireg)
CSR_STRUCT_END(sireg)

CSR_STRUCT_START(stopei)
uint64_t iid : 11; // [10: 0]
uint64_t pad : 5; // [15:11]
uint64_t iprio : 11; // [26:16]
CSR_STRUCT_END(stopei)

CSR_STRUCT_START(stopi)
uint64_t iprio : 8; // [ 7: 0]
uint64_t pad : 8; // [15: 8]
uint64_t iid : 12; // [27:16]
CSR_STRUCT_END(stopi)
#endif // CONFIG_RV_IMSIC

/* hypervisor and Virtual Supervisor CSR */

Expand Down Expand Up @@ -971,7 +1060,47 @@ CSR_STRUCT_START(vsatp)
};
CSR_STRUCT_END(vsatp)

#endif //CONFIG_RVH
#endif // CONFIG_RVH

/** Hypervisor and VS AIA CSRs **/
#ifdef CONFIG_RV_IMSIC
CSR_STRUCT_START(hvien)
CSR_STRUCT_END(hvien)

CSR_STRUCT_START(hvictl)
uint64_t iprio : 8; // [7:0]
uint64_t ipriom : 1; // [8]
uint64_t dpr : 1; // [9]
uint64_t pad0 : 6; // [15:10]
uint64_t iid : 12; // [27:16]
uint64_t pad1 : 2; // [29:28]
uint64_t vti : 1; // [30]
CSR_STRUCT_END(hvictl)

CSR_STRUCT_START(hviprio1)
CSR_STRUCT_END(hviprio1)

CSR_STRUCT_START(hviprio2)
CSR_STRUCT_END(hviprio2)

CSR_STRUCT_START(vsiselect)
CSR_STRUCT_END(vsiselect)

CSR_STRUCT_START(vsireg)
CSR_STRUCT_END(vsireg)

CSR_STRUCT_START(vstopei)
uint64_t iid : 11; // [10: 0]
uint64_t pad : 5; // [15:11]
uint64_t iprio : 11; // [26:16]
CSR_STRUCT_END(vstopei)

CSR_STRUCT_START(vstopi)
uint64_t iprio : 8; // [ 7: 0]
uint64_t pad : 8; // [15: 8]
uint64_t iid : 12; // [27:16]
CSR_STRUCT_END(vstopi)
#endif // CONFIG_RV_IMSIC

/* Unprivileged CSR */

Expand Down Expand Up @@ -1167,6 +1296,14 @@ MAP(CSRS, CSRS_DECL)
// SD, UXL, MXR, SUM, XS, FS, VS, SPP, UBE, SPIE, SIE
#define SSTATUS_RMASK 0x80000003000de762UL

/** AIA **/
#ifdef CONFIG_RV_IMSIC
#define ISELECT_2F_MASK 0x2F
#define ISELECT_3F_MASK 0x3F
#define ISELECT_6F_MASK 0x6F
#define ISELECT_MAX_MASK 0xFF
#define VSISELECT_MAX_MASK 0x1FF
#endif // CONFIG_RV_IMSIC

/**
* Function declaration
Expand Down
15 changes: 15 additions & 0 deletions src/isa/riscv64/reg.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ void isa_reg_display() {
mideleg->val, medeleg->val);
printf("mtval: " FMT_WORD " stval: " FMT_WORD " mtvec: " FMT_WORD " stvec: " FMT_WORD "\n",
mtval->val, stval->val, mtvec->val, stvec->val);
#ifdef CONFIG_RV_IMSIC
printf("miselect: " FMT_WORD " siselect: " FMT_WORD " mireg: " FMT_WORD " sireg: " FMT_WORD "\n",
miselect->val, siselect->val, mireg->val, sireg->val);
printf("mtopi: " FMT_WORD " stopi: " FMT_WORD " mvien: " FMT_WORD " mvip: " FMT_WORD "\n",
mtopi->val, stopi->val, mvien->val, mvip->val);
printf("mtopei: " FMT_WORD " stopei: " FMT_WORD "\n",
mtopei->val, stopei->val);
#endif // CONFIG_RV_IMSIC
#ifdef CONFIG_RVH
printf("mtval2: " FMT_WORD " mtinst: " FMT_WORD " hstatus: " FMT_WORD " hideleg: " FMT_WORD "\n",
mtval2->val, mtinst->val, hstatus->val, hideleg->val);
Expand All @@ -71,6 +79,13 @@ void isa_reg_display() {
hgatp->val, vsscratch->val, cpu.vsstatus, vstvec->val);
printf("vsepc: " FMT_WORD " vscause: " FMT_WORD " vstval: " FMT_WORD " vsatp: " FMT_WORD "\n",
vsepc->val, vscause->val, vstval->val, vsatp->val);
#ifdef CONFIG_RV_IMSIC
printf("hvien: " FMT_WORD " hvictl: " FMT_WORD " hviprio1: " FMT_WORD " hviprio2: " FMT_WORD "\n",
hvien->val, hvictl->val, hviprio1->val, hviprio2->val);
printf("vsiselect: " FMT_WORD " vsireg: " FMT_WORD " vstopi: " FMT_WORD "\n",
vsiselect->val, vsireg->val, vstopi->val);
printf("vstopei: " FMT_WORD "\n", vstopei->val);
#endif // CONFIG_RV_IMSIC
printf("virtualization mode: %ld\n", cpu.v);
#endif
printf("privilege mode:%ld\n", cpu.mode);
Expand Down
76 changes: 76 additions & 0 deletions src/isa/riscv64/system/priv.c
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,11 @@ static inline void csr_write(word_t *dest, word_t src) {
// Update vsatp without checking if vsatp.mode is legal, when hart is not in MODE_VS.
update_vsatp(new_val);
}else if (is_write(mstatus)) { mstatus->val = mask_bitset(mstatus->val, MSTATUS_WMASK, src); }
#ifdef CONFIG_RV_IMSIC
else if (is_write(mtopi)) { return; }
else if (is_write(stopi)) { return; }
else if (is_write(vstopi)) { return; }
#endif // CONFIG_RV_IMSIC
#else
if (is_write(mstatus)) {
#ifndef CONFIG_RVH
Expand Down Expand Up @@ -882,10 +887,81 @@ static inline void smstateen_extension_permit_check(word_t *dest, const word_t *
}
#endif // CONFIG_RV_SMSTATEEN

// AIA extension check
// !!! Only support in RVH
#ifdef CONFIG_RV_IMSIC
static void aia_extension_permit_check(word_t *dest, const word_t *src, uint32_t csrid) {
if (is_access(stopei)) {
if (!cpu.v && (cpu.mode == MODE_S) && mvien->seie) {
longjmp_exception(EX_II);
}
}
if (is_access(mireg)) {
if (cpu.mode == MODE_M) {
if ((miselect->val <= ISELECT_2F_MASK) ||
((miselect->val > ISELECT_3F_MASK) && (miselect->val <= ISELECT_6F_MASK)) ||
(miselect->val > ISELECT_MAX_MASK) ||
(miselect->val & 0x1)) {
longjmp_exception(EX_II);
}
}
}
if (is_access(sireg)) {
if (!cpu.v && (cpu.mode == MODE_S) && mvien->seie) {
if ((siselect->val > ISELECT_6F_MASK) && (siselect->val <= ISELECT_MAX_MASK)) {
longjmp_exception(EX_II);
}
}
if ((cpu.mode == MODE_M) || (!cpu.v && (cpu.mode == MODE_S))) {
if ((siselect->val <= ISELECT_2F_MASK) ||
((siselect->val > ISELECT_3F_MASK) && (siselect->val <= ISELECT_6F_MASK)) ||
(siselect->val > ISELECT_MAX_MASK) ||
(siselect->val & 0x1)) {
longjmp_exception(EX_II);
}
}
if (cpu.v && (cpu.mode == MODE_S)) {
if (vsiselect->val > VSISELECT_MAX_MASK) {
longjmp_exception(EX_II);
}
if (((vsiselect->val > ISELECT_2F_MASK) && (vsiselect->val <= ISELECT_3F_MASK)) ||
((vsiselect->val > 0x80) && (vsiselect->val <= ISELECT_MAX_MASK) && (vsiselect->val & 0x1))) {
longjmp_exception(EX_VI);
}
}
if (cpu.v && (cpu.mode == MODE_U)) {
longjmp_exception(EX_VI);
}
}
if (is_access(vsireg)) {
if ((cpu.mode == MODE_M) || (!cpu.v && (cpu.mode == MODE_S))) {
if ((vsiselect->val <= ISELECT_6F_MASK) ||
(vsiselect->val > ISELECT_MAX_MASK) ||
(vsiselect->val & 0x1)) {
longjmp_exception(EX_II);
}
}
if (cpu.v) {
longjmp_exception(EX_VI);
}
}
if (is_access(sip) || is_access(sie)) {
if (cpu.v && (cpu.mode == MODE_S)) {
if (hvictl->vti) {
longjmp_exception(EX_VI);
}
}
}
}
#endif // CONFIG_RV_IMSIC

static void csrrw(rtlreg_t *dest, const rtlreg_t *src, uint32_t csrid) {
#ifdef CONFIG_RV_SMSTATEEN
smstateen_extension_permit_check(dest, src, csrid);
#endif // CONFIG_RV_SMSTATEEN
#ifdef CONFIG_RV_IMSIC
aia_extension_permit_check(dest, src, csrid);
#endif // CONFIG_RV_IMSIC
if (!csr_is_legal(csrid, src != NULL)) {
Logti("Illegal csr id %u", csrid);
longjmp_exception(EX_II);
Expand Down

0 comments on commit 0b2e23f

Please sign in to comment.