Skip to content

Commit

Permalink
CSR: add switch for cycle, instret and htimedelta
Browse files Browse the repository at this point in the history
As old CSR module of XiangShan does not support any unpriv counter, it's better to add switch of unpriv counter in NEMU.

Also, openSBI asks that time and htimedelta should either implemented or both unimplemented. This patch add some marco to meet this.
  • Loading branch information
cebarobot committed Jul 10, 2024
1 parent ca25408 commit b5c8c9a
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 15 deletions.
10 changes: 6 additions & 4 deletions configs/riscv64-xs-ref_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ CONFIG_RVV=y
CONFIG_RV_DEBUG=y
CONFIG_RVH=y
# CONFIG_RV_SDEXT is not set
CONFIG_RV_SDTRIG=y
# CONFIG_RV_SDTRIG is not set
CONFIG_TRIGGER_NUM=4
CONFIG_RV_ZICNTR=y
# CONFIG_RV_CSR_CYCLE is not set
# CONFIG_RV_CSR_TIME is not set
CONFIG_RV_ZIHPM=y
# CONFIG_RV_CSR_INSTRET is not set
# CONFIG_RV_ZIHPM is not set
CONFIG_RV_CSR_MCOUNTINHIBIT=y
CONFIG_RV_CSR_MCOUNTINHIBIT_CNTR=y
CONFIG_RV_CSR_MCOUNTINHIBIT_HPM=y
Expand All @@ -39,8 +41,8 @@ CONFIG_RV_PMP_ACTIVE_NUM=16
CONFIG_PMP_GRANULARITY=12
CONFIG_RV_PMP_CHECK=y
CONFIG_RV_SVINVAL=y
CONFIG_RV_SSCOFPMF=y
CONFIG_RV_SMSTATEEN=y
# CONFIG_RV_SSCOFPMF is not set
# CONFIG_RV_SMSTATEEN is not set
CONFIG_MISA_UNCHANGEABLE=y
CONFIG_XTVEC_VECTORED_MODE=y
# CONFIG_TVAL_EX_II is not set
Expand Down
28 changes: 26 additions & 2 deletions src/isa/riscv64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,39 @@ menuconfig RV_ZICNTR
INFO: the CPI (cycles per instruction) of NEMU is set to 1.

if RV_ZICNTR
config RV_CSR_CYCLE
bool "Implement CSR cycle (0xc00)"
default n
help
If n, accessing to CSR cycle will raise illegal instruction exception.

Regardless of how this option is set, the TM bit of m/h/scounteren is
always writable to allow machine-level programs to simulate reading the
cycle register.

config RV_CSR_TIME
bool "Implement CSR time (0xc01)"
default n
help
If n, accessing to CSR time will raise illegal instruction exception.

If n, accessing to CSR htimedelta will also raise illegal instruction.
Either both time and htimedelta are implemented by hardware, or access
to both time and htimedelta traps into M-mode for emulation.

Regardless of how this option is set, the TM bit of m/h/scounteren is
always writable to allow machine-level programs to simulate reading the
time register.

config RV_CSR_INSTRET
bool "Implement CSR instret (0xc02)"
default n
help
If n, accessing to CSR instret will raise illegal instruction exception.

Regardless of how this option is set, the TM bit of m/h/scounteren is
always writable to allow machine programs to simulate reading the time
register.
always writable to allow machine-level programs to simulate reading the
instret register.

endif # RV_ZICNTR

Expand Down
30 changes: 26 additions & 4 deletions src/isa/riscv64/local-include/csr.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,32 @@
#endif // CONFIG_FPU_NONE

/** Unprivileged Counter/Timers **/
#ifdef CONFIG_RV_CSR_CYCLE
#define CSRS_UNPRIV_CYCLE(f) \
f(cycle , 0xC00)
#else // CONFIG_RV_CSR_CYCLE
#define CSRS_UNPRIV_CYCLE(f)
#endif // CONFIG_RV_CSR_CYCLE

#ifdef CONFIG_RV_CSR_TIME
#define CSRS_UNPRIV_TIME(f) \
f(csr_time , 0xC01)
#else // CONFIG_RV_CSR_TIME
#define CSRS_UNPRIV_TIME(f)
#endif // CONFIG_RV_CSR_TIME

#ifdef CONFIG_RV_CSR_INSTRET
#define CSRS_UNPRIV_INSTRET(f) \
f(instret , 0xC02)
#else // CONFIG_RV_CSR_INSTRET
#define CSRS_UNPRIV_INSTRET(f)
#endif // CONFIG_RV_CSR_INSTRET

#ifdef CONFIG_RV_ZICNTR
#define CSRS_UNPRIV_CNTR(f) \
f(cycle , 0xC00) \
CSRS_UNPRIV_CYCLE(f) \
CSRS_UNPRIV_TIME(f) \
f(instret , 0xC02)
CSRS_UNPRIV_INSTRET(f)
// There is `time_t` type in the C programming language.
// So We have to use another name for CSR time.
#else // CONFIG_RV_ZICNTR
Expand Down Expand Up @@ -207,8 +221,12 @@
#endif // CONFIG_RV_SDTRIG

/** Hypervisor Counter/Timer Virtualization Registers **/
#define CSRS_H_CONUTER_TIMER_VIRTUALIZATION(f) \
f(htimedelta , 0x605)
#ifdef CONFIG_RV_CSR_TIME
#define CSRS_H_CONUTER_TIMER_VIRTUALIZATION(f) \
f(htimedelta , 0x605)
#else // CONFIG_RV_CSR_TIME
#define CSRS_H_CONUTER_TIMER_VIRTUALIZATION(f)
#endif

/** Hypervisor State Enable Registers **/
#ifdef CONFIG_RV_SMSTATEEN
Expand Down Expand Up @@ -1176,16 +1194,20 @@ void set_mask(uint32_t reg, int idx, uint64_t mask, uint64_t vsew, uint64_t vlmu
#endif // CONFIG_RVV

#ifdef CONFIG_RV_ZICNTR
#ifdef CONFIG_RV_CSR_CYCLE
CSR_STRUCT_START(cycle)
CSR_STRUCT_END(cycle)
#endif // CONFIG_RV_CSR_CYCLE

#ifdef CONFIG_RV_CSR_TIME
CSR_STRUCT_START(csr_time)
CSR_STRUCT_END(csr_time)
#endif // CONFIG_RV_CSR_TIME

#ifdef CONFIG_RV_CSR_INSTRET
CSR_STRUCT_START(instret)
CSR_STRUCT_END(instret)
#endif // CONFIG_RV_CSR_INSTRET
#endif // CONFIG_RV_ZICNTR

#ifdef CONFIG_RV_ZIHPM
Expand Down
14 changes: 9 additions & 5 deletions src/isa/riscv64/system/priv.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,23 +456,27 @@ if (is_read(vsie)) { return (mie->val & (hideleg->val & (mideleg->val
return get_minstret();
}
#ifdef CONFIG_RV_ZICNTR
else if (is_read(cycle)) {
// NEMU emulates a hart with CPI = 1.
difftest_skip_ref();
return get_mcycle();
}
#ifdef CONFIG_RV_CSR_CYCLE
else if (is_read(cycle)) {
// NEMU emulates a hart with CPI = 1.
difftest_skip_ref();
return get_mcycle();
}
#endif // CONFIG_RV_CSR_CYCLE
#ifdef CONFIG_RV_CSR_TIME
else if (is_read(csr_time)) {
difftest_skip_ref();
return clint_uptime();
}
#endif // CONFIG_RV_CSR_TIME
#ifdef CONFIG_RV_CSR_INSTRET
else if (is_read(instret)) {
// The number of retired instruction should be the same between dut and ref.
// But instruction counter of NEMU is not accurate when enabling Performance optimization.
difftest_skip_ref();
return get_minstret();
}
#endif // CONFIG_RV_CSR_INSTRET
#endif // CONFIG_RV_ZICNTR
#ifndef CONFIG_RVH
if (is_read(mip)) { difftest_skip_ref(); }
Expand Down

0 comments on commit b5c8c9a

Please sign in to comment.