diff options
author | Atish Patra <atish.patra@wdc.com> | 2020-05-10 02:47:27 +0300 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2020-05-10 07:32:49 +0300 |
commit | 6a053f6e6cb4db8a291239e882e9a778c2738e0a (patch) | |
tree | d4f6d52c7b486c51860c5a9eb9f96d5d176bef87 | |
parent | 79d0fadb0681acbba55bb6b4afcd3c2e6f725928 (diff) | |
download | opensbi-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.h | 1 | ||||
-rw-r--r-- | lib/sbi/sbi_hart.c | 23 |
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); |