diff --git a/include/sbi/riscv_encoding.h b/include/sbi/riscv_encoding.h index 827c86c4..073261fe 100644 --- a/include/sbi/riscv_encoding.h +++ b/include/sbi/riscv_encoding.h @@ -144,7 +144,12 @@ #define PMP_L _UL(0x80) #define PMP_SHIFT 2 -#define PMP_COUNT 16 +#define PMP_COUNT 64 +#if __riscv_xlen == 64 +#define PMP_ADDR_MASK ((_ULL(0x1) << 54) - 1) +#else +#define PMP_ADDR_MASK _UL(0xFFFFFFFF) +#endif #if __riscv_xlen == 64 #define MSTATUS_SD MSTATUS64_SD @@ -263,6 +268,18 @@ #define CSR_PMPCFG1 0x3a1 #define CSR_PMPCFG2 0x3a2 #define CSR_PMPCFG3 0x3a3 +#define CSR_PMPCFG4 0x3a4 +#define CSR_PMPCFG5 0x3a5 +#define CSR_PMPCFG6 0x3a6 +#define CSR_PMPCFG7 0x3a7 +#define CSR_PMPCFG8 0x3a8 +#define CSR_PMPCFG9 0x3a9 +#define CSR_PMPCFG10 0x3aa +#define CSR_PMPCFG11 0x3ab +#define CSR_PMPCFG12 0x3ac +#define CSR_PMPCFG13 0x3ad +#define CSR_PMPCFG14 0x3ae +#define CSR_PMPCFG15 0x3af #define CSR_PMPADDR0 0x3b0 #define CSR_PMPADDR1 0x3b1 #define CSR_PMPADDR2 0x3b2 @@ -279,6 +296,54 @@ #define CSR_PMPADDR13 0x3bd #define CSR_PMPADDR14 0x3be #define CSR_PMPADDR15 0x3bf +#define CSR_PMPADDR16 0x3c0 +#define CSR_PMPADDR17 0x3c1 +#define CSR_PMPADDR18 0x3c2 +#define CSR_PMPADDR19 0x3c3 +#define CSR_PMPADDR20 0x3c4 +#define CSR_PMPADDR21 0x3c5 +#define CSR_PMPADDR22 0x3c6 +#define CSR_PMPADDR23 0x3c7 +#define CSR_PMPADDR24 0x3c8 +#define CSR_PMPADDR25 0x3c9 +#define CSR_PMPADDR26 0x3ca +#define CSR_PMPADDR27 0x3cb +#define CSR_PMPADDR28 0x3cc +#define CSR_PMPADDR29 0x3cd +#define CSR_PMPADDR30 0x3ce +#define CSR_PMPADDR31 0x3cf +#define CSR_PMPADDR32 0x3d0 +#define CSR_PMPADDR33 0x3d1 +#define CSR_PMPADDR34 0x3d2 +#define CSR_PMPADDR35 0x3d3 +#define CSR_PMPADDR36 0x3d4 +#define CSR_PMPADDR37 0x3d5 +#define CSR_PMPADDR38 0x3d6 +#define CSR_PMPADDR39 0x3d7 +#define CSR_PMPADDR40 0x3d8 +#define CSR_PMPADDR41 0x3d9 +#define CSR_PMPADDR42 0x3da +#define CSR_PMPADDR43 0x3db +#define CSR_PMPADDR44 0x3dc +#define CSR_PMPADDR45 0x3dd +#define CSR_PMPADDR46 0x3de +#define CSR_PMPADDR47 0x3df +#define CSR_PMPADDR48 0x3e0 +#define CSR_PMPADDR49 0x3e1 +#define CSR_PMPADDR50 0x3e2 +#define CSR_PMPADDR51 0x3e3 +#define CSR_PMPADDR52 0x3e4 +#define CSR_PMPADDR53 0x3e5 +#define CSR_PMPADDR54 0x3e6 +#define CSR_PMPADDR55 0x3e7 +#define CSR_PMPADDR56 0x3e8 +#define CSR_PMPADDR57 0x3e9 +#define CSR_PMPADDR58 0x3ea +#define CSR_PMPADDR59 0x3eb +#define CSR_PMPADDR60 0x3ec +#define CSR_PMPADDR61 0x3ed +#define CSR_PMPADDR62 0x3ee +#define CSR_PMPADDR63 0x3ef #define CSR_TSELECT 0x7a0 #define CSR_TDATA1 0x7a1 #define CSR_TDATA2 0x7a2 diff --git a/lib/sbi/riscv_asm.c b/lib/sbi/riscv_asm.c index 6dfebd91..799123fa 100644 --- a/lib/sbi/riscv_asm.c +++ b/lib/sbi/riscv_asm.c @@ -90,142 +90,88 @@ void misa_string(int xlen, char *out, unsigned int out_sz) unsigned long csr_read_num(int csr_num) { +#define switchcase_csr_read(__csr_num, __val) \ + case __csr_num: \ + __val = csr_read(__csr_num); \ + break; +#define switchcase_csr_read_2(__csr_num, __val) \ + switchcase_csr_read(__csr_num + 0, __val) \ + switchcase_csr_read(__csr_num + 1, __val) +#define switchcase_csr_read_4(__csr_num, __val) \ + switchcase_csr_read_2(__csr_num + 0, __val) \ + switchcase_csr_read_2(__csr_num + 2, __val) +#define switchcase_csr_read_8(__csr_num, __val) \ + switchcase_csr_read_4(__csr_num + 0, __val) \ + switchcase_csr_read_4(__csr_num + 4, __val) +#define switchcase_csr_read_16(__csr_num, __val) \ + switchcase_csr_read_8(__csr_num + 0, __val) \ + switchcase_csr_read_8(__csr_num + 8, __val) +#define switchcase_csr_read_32(__csr_num, __val) \ + switchcase_csr_read_16(__csr_num + 0, __val) \ + switchcase_csr_read_16(__csr_num + 16, __val) +#define switchcase_csr_read_64(__csr_num, __val) \ + switchcase_csr_read_32(__csr_num + 0, __val) \ + switchcase_csr_read_32(__csr_num + 32, __val) + unsigned long ret = 0; switch (csr_num) { - case CSR_PMPCFG0: - ret = csr_read(CSR_PMPCFG0); - break; - case CSR_PMPCFG1: - ret = csr_read(CSR_PMPCFG1); - break; - case CSR_PMPCFG2: - ret = csr_read(CSR_PMPCFG2); - break; - case CSR_PMPCFG3: - ret = csr_read(CSR_PMPCFG3); - break; - case CSR_PMPADDR0: - ret = csr_read(CSR_PMPADDR0); - break; - case CSR_PMPADDR1: - ret = csr_read(CSR_PMPADDR1); - break; - case CSR_PMPADDR2: - ret = csr_read(CSR_PMPADDR2); - break; - case CSR_PMPADDR3: - ret = csr_read(CSR_PMPADDR3); - break; - case CSR_PMPADDR4: - ret = csr_read(CSR_PMPADDR4); - break; - case CSR_PMPADDR5: - ret = csr_read(CSR_PMPADDR5); - break; - case CSR_PMPADDR6: - ret = csr_read(CSR_PMPADDR6); - break; - case CSR_PMPADDR7: - ret = csr_read(CSR_PMPADDR7); - break; - case CSR_PMPADDR8: - ret = csr_read(CSR_PMPADDR8); - break; - case CSR_PMPADDR9: - ret = csr_read(CSR_PMPADDR9); - break; - case CSR_PMPADDR10: - ret = csr_read(CSR_PMPADDR10); - break; - case CSR_PMPADDR11: - ret = csr_read(CSR_PMPADDR11); - break; - case CSR_PMPADDR12: - ret = csr_read(CSR_PMPADDR12); - break; - case CSR_PMPADDR13: - ret = csr_read(CSR_PMPADDR13); - break; - case CSR_PMPADDR14: - ret = csr_read(CSR_PMPADDR14); - break; - case CSR_PMPADDR15: - ret = csr_read(CSR_PMPADDR15); - break; + switchcase_csr_read_16(CSR_PMPCFG0, ret) + switchcase_csr_read_64(CSR_PMPADDR0, ret) default: break; }; return ret; + +#undef switchcase_csr_read_64 +#undef switchcase_csr_read_32 +#undef switchcase_csr_read_16 +#undef switchcase_csr_read_8 +#undef switchcase_csr_read_4 +#undef switchcase_csr_read_2 +#undef switchcase_csr_read } void csr_write_num(int csr_num, unsigned long val) { +#define switchcase_csr_write(__csr_num, __val) \ + case __csr_num: \ + csr_write(__csr_num, __val); \ + break; +#define switchcase_csr_write_2(__csr_num, __val) \ + switchcase_csr_write(__csr_num + 0, __val) \ + switchcase_csr_write(__csr_num + 1, __val) +#define switchcase_csr_write_4(__csr_num, __val) \ + switchcase_csr_write_2(__csr_num + 0, __val) \ + switchcase_csr_write_2(__csr_num + 2, __val) +#define switchcase_csr_write_8(__csr_num, __val) \ + switchcase_csr_write_4(__csr_num + 0, __val) \ + switchcase_csr_write_4(__csr_num + 4, __val) +#define switchcase_csr_write_16(__csr_num, __val) \ + switchcase_csr_write_8(__csr_num + 0, __val) \ + switchcase_csr_write_8(__csr_num + 8, __val) +#define switchcase_csr_write_32(__csr_num, __val) \ + switchcase_csr_write_16(__csr_num + 0, __val) \ + switchcase_csr_write_16(__csr_num + 16, __val) +#define switchcase_csr_write_64(__csr_num, __val) \ + switchcase_csr_write_32(__csr_num + 0, __val) \ + switchcase_csr_write_32(__csr_num + 32, __val) + switch (csr_num) { - case CSR_PMPCFG0: - csr_write(CSR_PMPCFG0, val); - break; - case CSR_PMPCFG1: - csr_write(CSR_PMPCFG1, val); - break; - case CSR_PMPCFG2: - csr_write(CSR_PMPCFG2, val); - break; - case CSR_PMPCFG3: - csr_write(CSR_PMPCFG3, val); - break; - case CSR_PMPADDR0: - csr_write(CSR_PMPADDR0, val); - break; - case CSR_PMPADDR1: - csr_write(CSR_PMPADDR1, val); - break; - case CSR_PMPADDR2: - csr_write(CSR_PMPADDR2, val); - break; - case CSR_PMPADDR3: - csr_write(CSR_PMPADDR3, val); - break; - case CSR_PMPADDR4: - csr_write(CSR_PMPADDR4, val); - break; - case CSR_PMPADDR5: - csr_write(CSR_PMPADDR5, val); - break; - case CSR_PMPADDR6: - csr_write(CSR_PMPADDR6, val); - break; - case CSR_PMPADDR7: - csr_write(CSR_PMPADDR7, val); - break; - case CSR_PMPADDR8: - csr_write(CSR_PMPADDR8, val); - break; - case CSR_PMPADDR9: - csr_write(CSR_PMPADDR9, val); - break; - case CSR_PMPADDR10: - csr_write(CSR_PMPADDR10, val); - break; - case CSR_PMPADDR11: - csr_write(CSR_PMPADDR11, val); - break; - case CSR_PMPADDR12: - csr_write(CSR_PMPADDR12, val); - break; - case CSR_PMPADDR13: - csr_write(CSR_PMPADDR13, val); - break; - case CSR_PMPADDR14: - csr_write(CSR_PMPADDR14, val); - break; - case CSR_PMPADDR15: - csr_write(CSR_PMPADDR15, val); - break; + switchcase_csr_write_16(CSR_PMPCFG0, val) + switchcase_csr_write_64(CSR_PMPADDR0, val) default: break; }; + +#undef switchcase_csr_write_64 +#undef switchcase_csr_write_32 +#undef switchcase_csr_write_16 +#undef switchcase_csr_write_8 +#undef switchcase_csr_write_4 +#undef switchcase_csr_write_2 +#undef switchcase_csr_write } static unsigned long ctz(unsigned long x) diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c index 80ed86a9..8f31d588 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;