arch/risc-v: add risc-v SSTC extension support

SSTC extension allows nuttx to implement S-mode timer directly,
which is useful for starting at S-mode.

Signed-off-by: Inochi Amaoto <inochiama@outlook.com>
This commit is contained in:
Inochi Amaoto 2024-04-15 19:12:20 +08:00 committed by Alan Carvalho de Assis
parent 1d7afb571f
commit 3cabc92427
4 changed files with 98 additions and 0 deletions

View File

@ -520,6 +520,11 @@ config ARCH_USE_S_MODE
and/or U-mode (in case of separate kernel-/userspaces). This provides
an option to run the kernel in S-mode, if the target supports it.
config ARCH_RV_EXT_SSTC
bool "Enable RISC-V SSTC extension support"
default n
depends on ARCH_USE_S_MODE
choice
prompt "Toolchain Selection"
default RISCV_TOOLCHAIN_GNU_RV64

View File

@ -135,10 +135,19 @@
#define CSR_STVAL 0x143
#define CSR_SIP 0x144
/* Supervisor Environment Configuration Registers */
#define CSR_SENVCFG 0x10a
/* Supervisor Protection and Translation Registers */
#define CSR_SATP 0x180
/* Supervisor Time Registers */
#define CSR_STIMECMP 0x14d
#define CSR_STIMECMPH 0x15d
/* Machine Information Registers */
#define CSR_MVENDORID 0xf11
@ -164,6 +173,11 @@
#define CSR_MTVAL 0x343
#define CSR_MIP 0x344
/* Machine Environment Configuration Registers */
#define CSR_MENVCFG 0x30a
#define CSR_MENVCFGH 0x31a
/* Machine Protection and Translation */
#define CSR_PMPCFG0 0x3a0
@ -354,6 +368,23 @@
#define MSTATUS_WPRI (UINT64_C(0x1ffffff) << 38 | UINT64_C(0x1ff) << 23 | 0x15)
#endif
/* In menvcfg register */
#define MENVCFG_FIOM (0x1 << 0)
#define MENVCFG_CBIE (0x3 << 4)
#define MENVCFG_CBIE_ILL (0x0 << 4)
#define MENVCFG_CBIE_FLUSH (0x1 << 4)
#define MENVCFG_CBIE_INV (0x3 << 4)
#define MENVCFG_CBCFE (0x1 << 6)
#define MENVCFG_CBZE (0x1 << 7)
#ifdef CONFIG_ARCH_RV32
#define MENVCFG_PBMTE (0x1 << 30)
#define MENVCFG_STCE (0x1 << 31)
#else
#define MENVCFG_PBMTE (UINT64_C(0x1) << 62)
#define MENVCFG_STCE (UINT64_C(0x1) << 63)
#endif
/* In mie (machine interrupt enable) register */
#define MIE_SSIE (0x1 << 1) /* Supervisor Software Interrupt Enable */
@ -405,6 +436,15 @@
#define SIP_STIP MIP_STIP
#define SIP_SEIP MIP_SEIP
/* In senvcfg register */
#define SENVCFG_FIOM MENVCFG_FIOM
#define SENVCFG_CBIE MENVCFG_CBIE
#define SENVCFG_CBIE_ILL MENVCFG_CBIE_ILL
#define SENVCFG_CBIE_FLUSH MENVCFG_CBIE_FLUSH
#define SENVCFG_CBIE_INV MENVCFG_CBIE_INV
#define SENVCFG_CBCFE MENVCFG_CBCFE
#define SENVCFG_CBZE MENVCFG_CBZE
/* In pmpcfg (PMP configuration) register */
#define PMPCFG_R (1 << 0) /* readable ? */
@ -418,6 +458,40 @@
#define PMPCFG_A_MASK (3 << 3) /* address-matching mode mask */
#define PMPCFG_L (1 << 7) /* locked ? */
/* In mcounteren/scounteren register */
#define COUNTEREN_CY (0x1 << 0)
#define COUNTEREN_TM (0x1 << 1)
#define COUNTEREN_IR (0x1 << 2)
#define COUNTEREN_HPM3 (0x1 << 3)
#define COUNTEREN_HPM4 (0x1 << 4)
#define COUNTEREN_HPM5 (0x1 << 5)
#define COUNTEREN_HPM6 (0x1 << 6)
#define COUNTEREN_HPM7 (0x1 << 7)
#define COUNTEREN_HPM8 (0x1 << 8)
#define COUNTEREN_HPM9 (0x1 << 9)
#define COUNTEREN_HPM10 (0x1 << 10)
#define COUNTEREN_HPM11 (0x1 << 11)
#define COUNTEREN_HPM12 (0x1 << 12)
#define COUNTEREN_HPM13 (0x1 << 13)
#define COUNTEREN_HPM14 (0x1 << 14)
#define COUNTEREN_HPM15 (0x1 << 15)
#define COUNTEREN_HPM16 (0x1 << 16)
#define COUNTEREN_HPM17 (0x1 << 17)
#define COUNTEREN_HPM18 (0x1 << 18)
#define COUNTEREN_HPM19 (0x1 << 19)
#define COUNTEREN_HPM20 (0x1 << 20)
#define COUNTEREN_HPM21 (0x1 << 21)
#define COUNTEREN_HPM22 (0x1 << 22)
#define COUNTEREN_HPM23 (0x1 << 23)
#define COUNTEREN_HPM24 (0x1 << 24)
#define COUNTEREN_HPM25 (0x1 << 25)
#define COUNTEREN_HPM26 (0x1 << 26)
#define COUNTEREN_HPM27 (0x1 << 27)
#define COUNTEREN_HPM28 (0x1 << 28)
#define COUNTEREN_HPM29 (0x1 << 29)
#define COUNTEREN_HPM30 (0x1 << 30)
#define COUNTEREN_HPM31 (0x1 << 31)
/****************************************************************************
* Public Types
****************************************************************************/

View File

@ -44,6 +44,7 @@
# define CSR_CAUSE CSR_SCAUSE /* Interrupt cause register */
# define CSR_TVAL CSR_STVAL /* Trap value register */
# define CSR_TVEC CSR_STVEC /* Trap vector base addr register */
# define CSR_ENVCFG CSR_SENVCFG /* Env configuration register */
/* In status register */
@ -86,6 +87,7 @@
# define CSR_CAUSE CSR_MCAUSE /* Interrupt cause register */
# define CSR_TVAL CSR_MTVAL /* Trap value register */
# define CSR_TVEC CSR_MTVEC /* Trap vector base addr register */
# define CSR_ENVCFG CSR_MENVCFG /* Env configuration register */
/* In status register */

View File

@ -127,6 +127,19 @@ static void riscv_mtimer_set_mtimecmp(struct riscv_mtimer_lowerhalf_s *priv,
__MB();
}
#else
#ifdef CONFIG_ARCH_RV_EXT_SSTC
static inline void riscv_write_stime(uint64_t value)
{
#ifdef CONFIG_ARCH_RV64
WRITE_CSR(CSR_STIMECMP, value);
#else
WRITE_CSR(CSR_STIMECMP, (uint32_t)value);
WRITE_CSR(CSR_STIMECMPH, (uint32_t)(value >> 32));
#endif
}
#endif
static uint64_t riscv_mtimer_get_mtime(struct riscv_mtimer_lowerhalf_s *priv)
{
UNUSED(priv);
@ -137,7 +150,11 @@ static void riscv_mtimer_set_mtimecmp(struct riscv_mtimer_lowerhalf_s *priv,
uint64_t value)
{
UNUSED(priv);
#ifndef CONFIG_ARCH_RV_EXT_SSTC
riscv_sbi_set_timer(value);
#else
riscv_write_stime(value);
#endif
}
#endif