summaryrefslogtreecommitdiff
path: root/lib/sbi/sbi_hart.c
diff options
context:
space:
mode:
authorAnup Patel <anup.patel@wdc.com>2020-08-18 10:58:08 +0300
committerAnup Patel <anup@brainfault.org>2020-09-01 07:58:28 +0300
commit74d1db706293f42f5a4e87c907978339b2d0993d (patch)
tree304eca12e33cb98ed1759eca70b41a0c2a8518f3 /lib/sbi/sbi_hart.c
parent7b0b289887380d2e71210f12b5ce0f3afc011b35 (diff)
downloadopensbi-74d1db706293f42f5a4e87c907978339b2d0993d.tar.xz
lib: sbi: Improve PMP CSR detection and progamming
As-per latest RISC-V privilege spec up to 64 PMP entries are supported. Implementations may implement zero, 16, or 64 PMP CSRs. All PMP CSR fields are WARL and may be hardwired to zero. This patch improves PMP CSR detection and progamming considering above facts. Signed-off-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Atish Patra <atish.patra@wdc.com>
Diffstat (limited to 'lib/sbi/sbi_hart.c')
-rw-r--r--lib/sbi/sbi_hart.c72
1 files changed, 48 insertions, 24 deletions
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index 80ed86a..8f31d58 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -340,31 +340,55 @@ static void hart_detect_features(struct sbi_scratch *scratch)
hfeatures->features = 0;
hfeatures->pmp_count = 0;
- /* Detect if hart supports PMP feature */
-#define __detect_pmp(__pmp_csr) \
- val = csr_read_allowed(__pmp_csr, (ulong)&trap); \
- if (!trap.cause) { \
- csr_write_allowed(__pmp_csr, (ulong)&trap, val);\
- if (!trap.cause) \
- hfeatures->pmp_count++; \
+#define __check_csr(__csr, __rdonly, __wrval, __field, __skip) \
+ val = csr_read_allowed(__csr, (ulong)&trap); \
+ if (!trap.cause) { \
+ if (__rdonly) { \
+ (hfeatures->__field)++; \
+ } else { \
+ csr_write_allowed(__csr, (ulong)&trap, __wrval);\
+ if (!trap.cause) { \
+ if (csr_swap(__csr, val) == __wrval) \
+ (hfeatures->__field)++; \
+ else \
+ goto __skip; \
+ } else { \
+ goto __skip; \
+ } \
+ } \
+ } else { \
+ goto __skip; \
}
- __detect_pmp(CSR_PMPADDR0);
- __detect_pmp(CSR_PMPADDR1);
- __detect_pmp(CSR_PMPADDR2);
- __detect_pmp(CSR_PMPADDR3);
- __detect_pmp(CSR_PMPADDR4);
- __detect_pmp(CSR_PMPADDR5);
- __detect_pmp(CSR_PMPADDR6);
- __detect_pmp(CSR_PMPADDR7);
- __detect_pmp(CSR_PMPADDR8);
- __detect_pmp(CSR_PMPADDR9);
- __detect_pmp(CSR_PMPADDR10);
- __detect_pmp(CSR_PMPADDR11);
- __detect_pmp(CSR_PMPADDR12);
- __detect_pmp(CSR_PMPADDR13);
- __detect_pmp(CSR_PMPADDR14);
- __detect_pmp(CSR_PMPADDR15);
-#undef __detect_pmp
+#define __check_csr_2(__csr, __rdonly, __wrval, __field, __skip) \
+ __check_csr(__csr + 0, __rdonly, __wrval, __field, __skip) \
+ __check_csr(__csr + 1, __rdonly, __wrval, __field, __skip)
+#define __check_csr_4(__csr, __rdonly, __wrval, __field, __skip) \
+ __check_csr_2(__csr + 0, __rdonly, __wrval, __field, __skip) \
+ __check_csr_2(__csr + 2, __rdonly, __wrval, __field, __skip)
+#define __check_csr_8(__csr, __rdonly, __wrval, __field, __skip) \
+ __check_csr_4(__csr + 0, __rdonly, __wrval, __field, __skip) \
+ __check_csr_4(__csr + 4, __rdonly, __wrval, __field, __skip)
+#define __check_csr_16(__csr, __rdonly, __wrval, __field, __skip) \
+ __check_csr_8(__csr + 0, __rdonly, __wrval, __field, __skip) \
+ __check_csr_8(__csr + 8, __rdonly, __wrval, __field, __skip)
+#define __check_csr_32(__csr, __rdonly, __wrval, __field, __skip) \
+ __check_csr_16(__csr + 0, __rdonly, __wrval, __field, __skip) \
+ __check_csr_16(__csr + 16, __rdonly, __wrval, __field, __skip)
+#define __check_csr_64(__csr, __rdonly, __wrval, __field, __skip) \
+ __check_csr_32(__csr + 0, __rdonly, __wrval, __field, __skip) \
+ __check_csr_32(__csr + 32, __rdonly, __wrval, __field, __skip)
+
+ /* Detect number of PMP regions */
+ __check_csr_64(CSR_PMPADDR0, 0, PMP_ADDR_MASK, pmp_count, __pmp_skip);
+__pmp_skip:
+
+#undef __check_csr_64
+#undef __check_csr_32
+#undef __check_csr_16
+#undef __check_csr_8
+#undef __check_csr_4
+#undef __check_csr_2
+#undef __check_csr
/* Detect if hart supports SCOUNTEREN feature */
trap.cause = 0;