diff options
author | Atish Patra <atish.patra@wdc.com> | 2020-05-10 02:47:32 +0300 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2020-05-10 08:00:47 +0300 |
commit | 22c4334f5c27c11cebeeba0a4426d26fcdb37327 (patch) | |
tree | dd73845419a7fc260d05bbdff8d00a63be11eb03 | |
parent | 1f235ec47f85ba90916493c7eb1378b5427a66b5 (diff) | |
download | opensbi-22c4334f5c27c11cebeeba0a4426d26fcdb37327.tar.xz |
lib: Add hart features in boot time print
We have now clear distinction between platform and hart features.
Modify the boot print messages to print hart specific features in
a string format.
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 | 4 | ||||
-rw-r--r-- | lib/sbi/sbi_hart.c | 77 | ||||
-rw-r--r-- | lib/sbi/sbi_init.c | 8 |
3 files changed, 89 insertions, 0 deletions
diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h index beb61b6..cdcd865 100644 --- a/include/sbi/sbi_hart.h +++ b/include/sbi/sbi_hart.h @@ -22,6 +22,9 @@ enum sbi_hart_features { SBI_HART_HAS_MCOUNTEREN = (1 << 2), /** HART has timer csr implementation in hardware */ SBI_HART_HAS_TIME = (1 << 3), + + /** Last index of Hart features*/ + SBI_HART_HAS_LAST_FEATURE = SBI_HART_HAS_TIME, }; struct sbi_scratch; @@ -40,6 +43,7 @@ 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); +int sbi_hart_get_features_str(u32 hartid, char *features_str, int nfstr); void __attribute__((noreturn)) sbi_hart_hang(void); diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c index 181cea4..28cfeaa 100644 --- a/lib/sbi/sbi_hart.c +++ b/lib/sbi/sbi_hart.c @@ -18,6 +18,7 @@ #include <sbi/sbi_hart.h> #include <sbi/sbi_math.h> #include <sbi/sbi_platform.h> +#include <sbi/sbi_string.h> extern void __sbi_expected_trap(void); extern void __sbi_expected_trap_hext(void); @@ -223,6 +224,82 @@ bool sbi_hart_has_feature(u32 hartid, unsigned long feature) return false; } +unsigned long sbi_hart_get_features(u32 hartid) +{ + unsigned long *hart_features; + struct sbi_scratch *scratch; + + scratch = sbi_hartid_to_scratch(hartid); + hart_features = sbi_scratch_offset_ptr(scratch, hart_features_offset); + + return *hart_features; +} + +static inline char *sbi_hart_feature_id2string(unsigned long feature) +{ + char *fstr = NULL; + + if (!feature) + return NULL; + + switch (feature) { + case SBI_HART_HAS_PMP: + fstr = "pmp"; + break; + case SBI_HART_HAS_SCOUNTEREN: + fstr = "scountern"; + break; + case SBI_HART_HAS_MCOUNTEREN: + fstr = "mcounteren"; + break; + case SBI_HART_HAS_TIME: + fstr = "time"; + break; + default: + break; + } + + return fstr; +} + +/** + * Get the hart features in string format + * + * @param hartid Hart ID of the hart whose feature list is requested + * @param features_str pointer to a char array where the features string will be + * updated + * @param nfstr length of the features_str. The feature string will be truncated + * if nfstr is not long enough. + * @return the features value currently set for the given platform + */ +int sbi_hart_get_features_str(u32 hartid, char *features_str, int nfstr) +{ + unsigned long features, feat = 1UL; + char *temp; + int offset = 0; + + if (!features_str || !nfstr) + return SBI_EINVAL; + + features = sbi_hart_get_features(hartid); + + do { + if (features & feat) { + temp = sbi_hart_feature_id2string(feat); + if (temp) { + sbi_snprintf(features_str + offset, nfstr, + "%s,", temp); + offset = offset + sbi_strlen(temp) + 1; + } + } + feat = feat << 1; + } while (feat <= SBI_HART_HAS_LAST_FEATURE); + + features_str[offset - 1] = '\0'; + + return 0; +} + static void sbi_hart_set_feature(u32 hartid, unsigned long feature) { unsigned long *hart_features; diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c index 2924784..f892582 100644 --- a/lib/sbi/sbi_init.c +++ b/lib/sbi/sbi_init.c @@ -73,6 +73,14 @@ static void sbi_boot_prints(struct sbi_scratch *scratch, u32 hartid) /* Boot HART details */ sbi_printf("Boot HART ID : %u\n", hartid); sbi_printf("Boot HART ISA : %s\n", str); + + sbi_memset(features, 0, max_fstr_len); + ret = sbi_hart_get_features_str(hartid, features, max_fstr_len); + if (!ret) + sbi_printf("BOOT HART Features : %s\n", features); + else + sbi_printf("BOOT HART Features : %s\n", "none"); + /* Firmware details */ sbi_printf("Firmware Base : 0x%lx\n", scratch->fw_start); sbi_printf("Firmware Size : %d KB\n", |