summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAtish Patra <atish.patra@wdc.com>2020-05-10 02:47:27 +0300
committerAnup Patel <anup@brainfault.org>2020-05-10 07:32:49 +0300
commit6a053f6e6cb4db8a291239e882e9a778c2738e0a (patch)
treed4f6d52c7b486c51860c5a9eb9f96d5d176bef87
parent79d0fadb0681acbba55bb6b4afcd3c2e6f725928 (diff)
downloadopensbi-6a053f6e6cb4db8a291239e882e9a778c2738e0a.tar.xz
lib: Add support for hart specific features
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>
-rw-r--r--include/sbi/sbi_hart.h1
-rw-r--r--lib/sbi/sbi_hart.c23
2 files changed, 24 insertions, 0 deletions
diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h
index 6a2ba4e..e285bdf 100644
--- a/include/sbi/sbi_hart.h
+++ b/include/sbi/sbi_hart.h
@@ -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);
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index b789900..cf3e9fb 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -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);