lib: sbi: Add support for smcsrind and smcdeleg
authorAtish Patra <atishp@rivosinc.com>
Sat, 17 Feb 2024 00:06:08 +0000 (16:06 -0800)
committerAnup Patel <anup@brainfault.org>
Mon, 4 Mar 2024 04:50:41 +0000 (10:20 +0530)
Smcsrind allows generic indirect CSR access mechanism while
Smcdeleg allows delegating hpmcounters in Supervisor mode.

Enable both extensions and set the appropriate bits in mstateen
and menvcfg.

Co-developed-by: Kaiwen Xue <kaiwenxue1@gmail.com>
Signed-off-by: Atish Patra <atishp@rivosinc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
include/sbi/riscv_encoding.h
include/sbi/sbi_hart.h
lib/sbi/sbi_hart.c

index e74cc0df1c407e77716d2116c4864ffbe959c709..eb5306973d68ac4300685e02702c4b80cb831f2d 100644 (file)
 
 #define ENVCFG_STCE                    (_ULL(1) << 63)
 #define ENVCFG_PBMTE                   (_ULL(1) << 62)
+#define ENVCFG_CDE                     (_ULL(1) << 60)
 #define ENVCFG_CBZE                    (_UL(1) << 7)
 #define ENVCFG_CBCFE                   (_UL(1) << 6)
 #define ENVCFG_CBIE_SHIFT              4
 /* Supervisor Configuration */
 #define CSR_SENVCFG                    0x10a
 
+/* Supervisor Conter Inhibit */
+#define CSR_SCOUNTINHIBIT              0x120
+
 /* Supervisor Trap Handling */
 #define CSR_SSCRATCH                   0x140
 #define CSR_SEPC                       0x141
 /* Supervisor Protection and Translation */
 #define CSR_SATP                       0x180
 
-/* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
+/* Supervisor Indirect Register Alias */
 #define CSR_SISELECT                   0x150
 #define CSR_SIREG                      0x151
+#define CSR_SIREG2                     0x152
+#define CSR_SIREG3                     0x153
+#define CSR_SIREG4                     0x155
+#define CSR_SIREG5                     0x156
+#define CSR_SIREG6                     0x157
 
 /* Supervisor-Level Interrupts (AIA) */
 #define CSR_STOPEI                     0x15c
 #define CSR_HVIPRIO1                   0x646
 #define CSR_HVIPRIO2                   0x647
 
-/* VS-Level Window to Indirectly Accessed Registers (H-extension with AIA) */
+/* Virtual Supervisor Indirect Alias */
 #define CSR_VSISELECT                  0x250
 #define CSR_VSIREG                     0x251
+#define CSR_VSIREG2                    0x252
+#define CSR_VSIREG3                    0x253
+#define CSR_VSIREG4                    0x255
+#define CSR_VSIREG5                    0x256
+#define CSR_VSIREG6                    0x257
 
 /* VS-Level Interrupts (H-extension with AIA) */
 #define CSR_VSTOPEI                    0x25c
 #define CSR_DSCRATCH0                  0x7b2
 #define CSR_DSCRATCH1                  0x7b3
 
-/* Machine-Level Window to Indirectly Accessed Registers (AIA) */
+/* Machine Indirect Register Alias */
 #define CSR_MISELECT                   0x350
 #define CSR_MIREG                      0x351
+#define CSR_MIREG2                     0x352
+#define CSR_MIREG3                     0x353
+#define CSR_MIREG4                     0x355
+#define CSR_MIREG5                     0x356
+#define CSR_MIREG6                     0x357
 
 /* Machine-Level Interrupts (AIA) */
 #define CSR_MTOPEI                     0x35c
index 10dc3df5d2fc496452de3864563b738e05360897..cc78eec6f65a06024a2828c43414e7fe0fbf003d 100644 (file)
@@ -55,6 +55,14 @@ enum sbi_hart_extensions {
        SBI_HART_EXT_SVPBMT,
        /** Hart has debug trigger extension */
        SBI_HART_EXT_SDTRIG,
+       /** Hart has Smcsrind extension */
+       SBI_HART_EXT_SMCSRIND,
+       /** Hart has Smcdeleg extension */
+       SBI_HART_EXT_SMCDELEG,
+       /** Hart has Sscsrind extension */
+       SBI_HART_EXT_SSCSRIND,
+       /** Hart has Ssccfg extension */
+       SBI_HART_EXT_SSCCFG,
 
        /** Maximum index of Hart extension */
        SBI_HART_EXT_MAX,
index a0ab0c64003549d1bb0e2fa1e2ddee1d46297377..3d1369441c05750d6ea08b8ceae1a18e081560b7 100644 (file)
@@ -95,11 +95,16 @@ static void mstatus_init(struct sbi_scratch *scratch)
                mstateen_val |= SMSTATEEN0_HSENVCFG;
 
                if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMAIA))
-                       mstateen_val |= (SMSTATEEN0_AIA | SMSTATEEN0_SVSLCT |
-                                       SMSTATEEN0_IMSIC);
+                       mstateen_val |= (SMSTATEEN0_AIA | SMSTATEEN0_IMSIC);
                else
-                       mstateen_val &= ~(SMSTATEEN0_AIA | SMSTATEEN0_SVSLCT |
-                                       SMSTATEEN0_IMSIC);
+                       mstateen_val &= ~(SMSTATEEN0_AIA | SMSTATEEN0_IMSIC);
+
+               if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMAIA) ||
+                   sbi_hart_has_extension(scratch, SBI_HART_EXT_SMCSRIND))
+                       mstateen_val |= (SMSTATEEN0_SVSLCT);
+               else
+                       mstateen_val &= ~(SMSTATEEN0_SVSLCT);
+
                csr_write(CSR_MSTATEEN0, mstateen_val);
 #if __riscv_xlen == 32
                csr_write(CSR_MSTATEEN0H, mstateen_val >> 32);
@@ -129,6 +134,7 @@ static void mstatus_init(struct sbi_scratch *scratch)
                __set_menvcfg_ext(SBI_HART_EXT_SVPBMT, ENVCFG_PBMTE)
 #endif
                __set_menvcfg_ext(SBI_HART_EXT_SSTC, ENVCFG_STCE)
+               __set_menvcfg_ext(SBI_HART_EXT_SMCDELEG, ENVCFG_CDE);
 
 #undef __set_menvcfg_ext
 
@@ -658,6 +664,8 @@ const struct sbi_hart_ext_data sbi_hart_ext[] = {
        __SBI_HART_EXT_DATA(zicbom, SBI_HART_EXT_ZICBOM),
        __SBI_HART_EXT_DATA(svpbmt, SBI_HART_EXT_SVPBMT),
        __SBI_HART_EXT_DATA(sdtrig, SBI_HART_EXT_SDTRIG),
+       __SBI_HART_EXT_DATA(smcsrind, SBI_HART_EXT_SMCSRIND),
+       __SBI_HART_EXT_DATA(smcdeleg, SBI_HART_EXT_SMCDELEG),
 };
 
 /**