lib: Add support for hart specific features
authorAtish Patra <atish.patra@wdc.com>
Sat, 9 May 2020 23:47:27 +0000 (16:47 -0700)
committerAnup Patel <anup@brainfault.org>
Sun, 10 May 2020 04:32:49 +0000 (10:02 +0530)
There may be some features which are hart specific rather than a platform
specific feature. Add a framework to support that.

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
lib/sbi/sbi_hart.c

index 6a2ba4e..e285bdf 100644 (file)
@@ -26,6 +26,7 @@ void sbi_hart_delegation_dump(struct sbi_scratch *scratch);
 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);
 
 void __attribute__((noreturn)) sbi_hart_hang(void);
 
index b789900..cf3e9fb 100644 (file)
@@ -22,6 +22,7 @@ extern void __sbi_expected_trap(void);
 extern void __sbi_expected_trap_hext(void);
 
 void (*sbi_hart_expected_trap)(void) = &__sbi_expected_trap;
+static unsigned long hart_features_offset;
 
 static void mstatus_init(struct sbi_scratch *scratch, u32 hartid)
 {
@@ -209,14 +210,36 @@ static int pmp_init(struct sbi_scratch *scratch, u32 hartid)
        return 0;
 }
 
+bool sbi_hart_has_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);
+
+       if (*hart_features & feature)
+               return true;
+       else
+               return false;
+}
+
 int sbi_hart_init(struct sbi_scratch *scratch, u32 hartid, bool cold_boot)
 {
        int rc;
+       unsigned long *hart_features;
 
        if (cold_boot) {
                if (misa_extension('H'))
                        sbi_hart_expected_trap = &__sbi_expected_trap_hext;
+               hart_features_offset = sbi_scratch_alloc_offset(
+                                                       sizeof(hart_features),
+                                                       "HART_FEATURES");
+               if (!hart_features_offset)
+                       return SBI_ENOMEM;
        }
+       hart_features = sbi_scratch_offset_ptr(scratch, hart_features_offset);
+       *hart_features = 0;
 
        mstatus_init(scratch, hartid);