platform: Move platform features to hart
authorAtish Patra <atish.patra@wdc.com>
Sat, 9 May 2020 23:47:28 +0000 (16:47 -0700)
committerAnup Patel <anup@brainfault.org>
Sun, 10 May 2020 04:35:41 +0000 (10:05 +0530)
PMP & performance counters belong to a hart rather than a platform.
In addition to that, these features enable reading/writing from a
particular csr. Thus, they can be detected and set at runtime rather
than compile time.

Move PMP/MCOUNTEREN/SCOUNTEREN features to hart and detect them at runtime.

Signed-off-by: Atish Patra <atish.patra@wdc.com>
Tested-by: Jonathan Balkind <jbalkind@cs.princeton.edu>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
include/sbi/sbi_hart.h
include/sbi/sbi_platform.h
lib/sbi/sbi_hart.c
lib/utils/fdt/fdt_fixup.c
platform/fpga/ariane/platform.c
platform/fpga/openpiton/platform.c
platform/thead/c910/platform.h

index e285bdf..f7870d9 100644 (file)
 
 #include <sbi/sbi_types.h>
 
+/** Possible feature flags of a hart */
+enum sbi_hart_features {
+       /** Hart has PMP support */
+       SBI_HART_HAS_PMP = (1 << 0),
+       /** Hart has S-mode counter enable */
+       SBI_HART_HAS_SCOUNTEREN = (1 << 1),
+       /** Hart has M-mode counter enable */
+       SBI_HART_HAS_MCOUNTEREN = (1 << 2),
+};
+
 struct sbi_scratch;
 
 int sbi_hart_init(struct sbi_scratch *scratch, u32 hartid, bool cold_boot);
@@ -27,6 +37,7 @@ void sbi_hart_pmp_dump(struct sbi_scratch *scratch);
 int  sbi_hart_pmp_check_addr(struct sbi_scratch *scratch, unsigned long daddr,
                             unsigned long attr);
 bool sbi_hart_has_feature(u32 hartid, unsigned long feature);
+unsigned long sbi_hart_get_features(u32 hartid);
 
 void __attribute__((noreturn)) sbi_hart_hang(void);
 
index 9eaf82e..675d021 100644 (file)
@@ -52,23 +52,15 @@ enum sbi_platform_features {
        SBI_PLATFORM_HAS_TIMER_VALUE = (1 << 0),
        /** Platform has HART hotplug support */
        SBI_PLATFORM_HAS_HART_HOTPLUG = (1 << 1),
-       /** Platform has PMP support */
-       SBI_PLATFORM_HAS_PMP = (1 << 2),
-       /** Platform has S-mode counter enable */
-       SBI_PLATFORM_HAS_SCOUNTEREN = (1 << 3),
-       /** Platform has M-mode counter enable */
-       SBI_PLATFORM_HAS_MCOUNTEREN = (1 << 4),
        /** Platform has fault delegation support */
-       SBI_PLATFORM_HAS_MFAULTS_DELEGATION = (1 << 5),
+       SBI_PLATFORM_HAS_MFAULTS_DELEGATION = (1 << 2),
        /** Platform has custom secondary hart booting support */
-       SBI_PLATFORM_HAS_HART_SECONDARY_BOOT = (1 << 6),
+       SBI_PLATFORM_HAS_HART_SECONDARY_BOOT = (1 << 3),
 };
 
 /** Default feature set for a platform */
 #define SBI_PLATFORM_DEFAULT_FEATURES                                \
-       (SBI_PLATFORM_HAS_TIMER_VALUE | SBI_PLATFORM_HAS_PMP |       \
-        SBI_PLATFORM_HAS_SCOUNTEREN | SBI_PLATFORM_HAS_MCOUNTEREN | \
-        SBI_PLATFORM_HAS_MFAULTS_DELEGATION)
+       (SBI_PLATFORM_HAS_TIMER_VALUE | SBI_PLATFORM_HAS_MFAULTS_DELEGATION)
 
 /** Platform functions */
 struct sbi_platform_operations {
@@ -224,14 +216,6 @@ struct sbi_platform {
 /** Check whether the platform supports HART hotplug */
 #define sbi_platform_has_hart_hotplug(__p) \
        ((__p)->features & SBI_PLATFORM_HAS_HART_HOTPLUG)
-/** Check whether the platform has PMP support */
-#define sbi_platform_has_pmp(__p) ((__p)->features & SBI_PLATFORM_HAS_PMP)
-/** Check whether the platform supports scounteren CSR */
-#define sbi_platform_has_scounteren(__p) \
-       ((__p)->features & SBI_PLATFORM_HAS_SCOUNTEREN)
-/** Check whether the platform supports mcounteren CSR */
-#define sbi_platform_has_mcounteren(__p) \
-       ((__p)->features & SBI_PLATFORM_HAS_MCOUNTEREN)
 /** Check whether the platform supports fault delegation */
 #define sbi_platform_has_mfaults_delegation(__p) \
        ((__p)->features & SBI_PLATFORM_HAS_MFAULTS_DELEGATION)
index cf3e9fb..10972c8 100644 (file)
@@ -13,6 +13,7 @@
 #include <sbi/riscv_fp.h>
 #include <sbi/sbi_bitops.h>
 #include <sbi/sbi_console.h>
+#include <sbi/sbi_csr_detect.h>
 #include <sbi/sbi_error.h>
 #include <sbi/sbi_hart.h>
 #include <sbi/sbi_math.h>
@@ -26,7 +27,6 @@ static unsigned long hart_features_offset;
 
 static void mstatus_init(struct sbi_scratch *scratch, u32 hartid)
 {
-       const struct sbi_platform *plat = sbi_platform_ptr(scratch);
        unsigned long mstatus_val = 0;
 
        /* Enable FPU */
@@ -40,9 +40,10 @@ static void mstatus_init(struct sbi_scratch *scratch, u32 hartid)
        csr_write(CSR_MSTATUS, mstatus_val);
 
        /* Enable user/supervisor use of perf counters */
-       if (misa_extension('S') && sbi_platform_has_scounteren(plat))
+       if (misa_extension('S') &&
+           sbi_hart_has_feature(hartid, SBI_HART_HAS_SCOUNTEREN))
                csr_write(CSR_SCOUNTEREN, -1);
-       if (sbi_platform_has_mcounteren(plat))
+       if (!sbi_hart_has_feature(hartid, SBI_HART_HAS_MCOUNTEREN))
                csr_write(CSR_MCOUNTEREN, -1);
 
        /* Disable all interrupts */
@@ -125,11 +126,10 @@ void sbi_hart_delegation_dump(struct sbi_scratch *scratch)
 
 void sbi_hart_pmp_dump(struct sbi_scratch *scratch)
 {
-       const struct sbi_platform *plat = sbi_platform_ptr(scratch);
        unsigned long prot, addr, size;
        unsigned int i;
 
-       if (!sbi_platform_has_pmp(plat))
+       if (!sbi_hart_has_feature(current_hartid(), SBI_HART_HAS_PMP))
                return;
 
        for (i = 0; i < PMP_COUNT; i++) {
@@ -158,9 +158,8 @@ int sbi_hart_pmp_check_addr(struct sbi_scratch *scratch, unsigned long addr,
                            unsigned long attr)
 {
        unsigned long prot, size, i, tempaddr;
-       const struct sbi_platform *plat = sbi_platform_ptr(scratch);
 
-       if (!sbi_platform_has_pmp(plat))
+       if (!sbi_hart_has_feature(current_hartid(), SBI_HART_HAS_PMP))
                return SBI_OK;
 
        for (i = 0; i < PMP_COUNT; i++) {
@@ -182,7 +181,7 @@ static int pmp_init(struct sbi_scratch *scratch, u32 hartid)
        ulong prot, addr, log2size;
        const struct sbi_platform *plat = sbi_platform_ptr(scratch);
 
-       if (!sbi_platform_has_pmp(plat))
+       if (!sbi_hart_has_feature(current_hartid(), SBI_HART_HAS_PMP))
                return 0;
 
        /* Firmware PMP region to protect OpenSBI firmware */
@@ -224,6 +223,57 @@ bool sbi_hart_has_feature(u32 hartid, unsigned long feature)
                return false;
 }
 
+static void sbi_hart_set_feature(u32 hartid, unsigned long feature)
+{
+       unsigned long *hart_features;
+       struct sbi_scratch *scratch;
+
+       scratch = sbi_hartid_to_scratch(hartid);
+       hart_features = sbi_scratch_offset_ptr(scratch, hart_features_offset);
+
+       *hart_features = *hart_features | feature;
+}
+
+static void sbi_hart_detect_features(u32 hartid)
+{
+       struct sbi_trap_info trap = {0};
+       unsigned long feature = 0;
+       unsigned long csr_val;
+
+       if (hartid != current_hartid())
+               sbi_hart_hang();
+
+       /* Detect if hart supports PMP feature */
+       csr_val = csr_read_allowed(CSR_PMPCFG0, (unsigned long)&trap);
+       if (!trap.cause) {
+               csr_write_allowed(CSR_PMPCFG0, (unsigned long)&trap, csr_val);
+               if (!trap.cause)
+                       feature |= SBI_HART_HAS_PMP;
+       }
+
+       /* Detect if hart supports SCOUNTEREN feature */
+       trap.cause = 0;
+       csr_val = csr_read_allowed(CSR_SCOUNTEREN, (unsigned long)&trap);
+       if (!trap.cause) {
+               csr_write_allowed(CSR_SCOUNTEREN, (unsigned long)&trap,
+                                 csr_val);
+               if (!trap.cause)
+                       feature |= SBI_HART_HAS_SCOUNTEREN;
+       }
+
+       /* Detect if hart supports MCOUNTEREN feature */
+       trap.cause = 0;
+       csr_val = csr_read_allowed(CSR_MCOUNTEREN, (unsigned long)&trap);
+       if (!trap.cause) {
+               csr_write_allowed(CSR_MCOUNTEREN, (unsigned long)&trap,
+                                 csr_val);
+               if (!trap.cause)
+                       feature |= SBI_HART_HAS_MCOUNTEREN;
+       }
+
+       sbi_hart_set_feature(hartid, feature);
+}
+
 int sbi_hart_init(struct sbi_scratch *scratch, u32 hartid, bool cold_boot)
 {
        int rc;
@@ -251,6 +301,8 @@ int sbi_hart_init(struct sbi_scratch *scratch, u32 hartid, bool cold_boot)
        if (rc)
                return rc;
 
+       sbi_hart_detect_features(hartid);
+
        return pmp_init(scratch, hartid);
 }
 
index e209cb6..e69ba1d 100644 (file)
@@ -11,6 +11,7 @@
 #include <sbi/riscv_asm.h>
 #include <sbi/sbi_console.h>
 #include <sbi/sbi_math.h>
+#include <sbi/sbi_hart.h>
 #include <sbi/sbi_platform.h>
 #include <sbi/sbi_scratch.h>
 #include <sbi/sbi_string.h>
@@ -143,7 +144,6 @@ static int fdt_resv_memory_update_node(void *fdt, unsigned long addr,
 int fdt_reserved_memory_fixup(void *fdt)
 {
        struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
-       const struct sbi_platform *plat = sbi_platform_ptr(scratch);
        unsigned long prot, addr, size;
        int parent, i, j;
        int err;
@@ -183,7 +183,7 @@ int fdt_reserved_memory_fixup(void *fdt)
                        return err;
        }
 
-       if (!sbi_platform_has_pmp(plat)) {
+       if (!sbi_hart_has_feature(current_hartid(), SBI_HART_HAS_PMP)) {
                /* update the DT with firmware start & size even if PMP is not
                 * supported. This makes sure that supervisor OS is always
                 * aware of wheren OpenSBI resident memory area.
index 7c76ff8..ad64c74 100644 (file)
@@ -28,8 +28,6 @@
 
 #define SBI_ARIANE_FEATURES    \
        (SBI_PLATFORM_HAS_TIMER_VALUE | \
-        SBI_PLATFORM_HAS_SCOUNTEREN | \
-        SBI_PLATFORM_HAS_MCOUNTEREN | \
         SBI_PLATFORM_HAS_MFAULTS_DELEGATION)
 
 /*
index c549a95..89512e1 100644 (file)
@@ -28,8 +28,6 @@
 
 #define SBI_OPENPITON_FEATURES \
        (SBI_PLATFORM_HAS_TIMER_VALUE | \
-        SBI_PLATFORM_HAS_SCOUNTEREN | \
-        SBI_PLATFORM_HAS_MCOUNTEREN | \
         SBI_PLATFORM_HAS_MFAULTS_DELEGATION)
 
 static struct platform_uart_data uart = {
index 0faf2af..354404e 100644 (file)
@@ -8,9 +8,7 @@
 #define C910_HART_COUNT   16
 
 #define SBI_THEAD_FEATURES     \
-       (SBI_PLATFORM_HAS_SCOUNTEREN | \
-        SBI_PLATFORM_HAS_MCOUNTEREN | \
-        SBI_PLATFORM_HAS_MFAULTS_DELEGATION | \
+        (SBI_PLATFORM_HAS_MFAULTS_DELEGATION | \
         SBI_PLATFORM_HAS_HART_SECONDARY_BOOT)
 
 #define CSR_MCOR         0x7c2