diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/sbi/riscv_asm.c | 186 | ||||
-rw-r--r-- | lib/sbi/sbi_hart.c | 72 |
2 files changed, 114 insertions, 144 deletions
diff --git a/lib/sbi/riscv_asm.c b/lib/sbi/riscv_asm.c index 6dfebd9..799123f 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 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; |