diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h index c77ffd2..90161f0 100644 --- a/include/sbi/sbi_hart.h +++ b/include/sbi/sbi_hart.h @@ -16,7 +16,7 @@ struct sbi_scratch; int sbi_hart_init(struct sbi_scratch *scratch, u32 hartid); -void sbi_hart_pmp_dump(void); +void sbi_hart_pmp_dump(struct sbi_scratch *scratch); void __attribute__((noreturn)) sbi_hart_hang(void); diff --git a/include/sbi/sbi_platform.h b/include/sbi/sbi_platform.h index 57b8e6b..39dfb49 100644 --- a/include/sbi/sbi_platform.h +++ b/include/sbi/sbi_platform.h @@ -13,10 +13,19 @@ #include enum sbi_platform_features { - SBI_PLATFORM_HAS_MMIO_TIMER_VALUE = (1 << 0), - SBI_PLATFORM_HAS_HART_HOTPLUG = (1 << 1), + SBI_PLATFORM_HAS_MMIO_TIMER_VALUE = (1 << 0), + SBI_PLATFORM_HAS_HART_HOTPLUG = (1 << 1), + SBI_PLATFORM_HAS_PMP = (1 << 2), + SBI_PLATFORM_HAS_SCOUNTEREN = (1 << 3), + SBI_PLATFORM_HAS_MCOUNTEREN = (1 << 4), }; +#define SBI_PLATFORM_DEFAULT_FEATURES \ + (SBI_PLATFORM_HAS_MMIO_TIMER_VALUE | \ + SBI_PLATFORM_HAS_PMP | \ + SBI_PLATFORM_HAS_SCOUNTEREN | \ + SBI_PLATFORM_HAS_MCOUNTEREN) + struct sbi_platform { char name[64]; u64 features; @@ -48,17 +57,20 @@ struct sbi_platform { int (*system_shutdown)(u32 type); } __attribute__((packed)); -#define sbi_platform_ptr(__s) \ -((struct sbi_platform *)((__s)->platform_addr)) - -#define sbi_platform_thishart_ptr() \ -((struct sbi_platform *)(sbi_scratch_thishart_ptr()->platform_addr)) - +#define sbi_platform_ptr(__s) \ + ((struct sbi_platform *)((__s)->platform_addr)) +#define sbi_platform_thishart_ptr() \ + ((struct sbi_platform *)(sbi_scratch_thishart_ptr()->platform_addr)) #define sbi_platform_has_mmio_timer_value(__p) \ -((__p)->features & SBI_PLATFORM_HAS_MMIO_TIMER_VALUE) - + ((__p)->features & SBI_PLATFORM_HAS_MMIO_TIMER_VALUE) #define sbi_platform_has_hart_hotplug(__p) \ -((__p)->features & SBI_PLATFORM_HAS_HART_HOTPLUG) + ((__p)->features & SBI_PLATFORM_HAS_HART_HOTPLUG) +#define sbi_platform_has_pmp(__p) \ + ((__p)->features & SBI_PLATFORM_HAS_PMP) +#define sbi_platform_has_scounteren(__p) \ + ((__p)->features & SBI_PLATFORM_HAS_SCOUNTEREN) +#define sbi_platform_has_mcounteren(__p) \ + ((__p)->features & SBI_PLATFORM_HAS_MCOUNTEREN) static inline const char *sbi_platform_name(struct sbi_platform *plat) { diff --git a/lib/sbi_hart.c b/lib/sbi_hart.c index a375ecf..26d435b 100644 --- a/lib/sbi_hart.c +++ b/lib/sbi_hart.c @@ -17,16 +17,20 @@ #include #include -static int mstatus_init(u32 hartid) +static void mstatus_init(struct sbi_scratch *scratch, u32 hartid) { + struct sbi_platform *plat = sbi_platform_ptr(scratch); + /* Enable FPU */ if (misa_extension('D') || misa_extension('F')) csr_write(mstatus, MSTATUS_FS); /* Enable user/supervisor use of perf counters */ - if (misa_extension('S')) + if (misa_extension('S') && + sbi_platform_has_scounteren(plat)) csr_write(scounteren, -1); - csr_write(mcounteren, -1); + if (sbi_platform_has_mcounteren(plat)) + csr_write(mcounteren, -1); /* Disable all interrupts */ csr_write(mie, 0); @@ -34,8 +38,6 @@ static int mstatus_init(u32 hartid) /* Disable S-mode paging */ if (misa_extension('S')) csr_write(sptbr, 0); - - return 0; } #ifdef __riscv_flen @@ -111,10 +113,14 @@ unsigned long log2roundup(unsigned long x) return ret; } -void sbi_hart_pmp_dump(void) +void sbi_hart_pmp_dump(struct sbi_scratch *scratch) { - unsigned int i; + struct sbi_platform *plat = sbi_platform_ptr(scratch); unsigned long prot, addr, size, l2l; + unsigned int i; + + if (!sbi_platform_has_pmp(plat)) + return; for (i = 0; i < PMP_COUNT; i++) { pmp_get(i, &prot, &addr, &l2l); @@ -149,6 +155,9 @@ static int pmp_init(struct sbi_scratch *scratch, u32 hartid) ulong prot, addr, log2size; struct sbi_platform *plat = sbi_platform_ptr(scratch); + if (!sbi_platform_has_pmp(plat)) + return 0; + fw_size_log2 = log2roundup(scratch->fw_size); fw_start = scratch->fw_start & ~((1UL << fw_size_log2) - 1UL); @@ -172,9 +181,7 @@ int sbi_hart_init(struct sbi_scratch *scratch, u32 hartid) { int rc; - rc = mstatus_init(hartid); - if (rc) - return rc; + mstatus_init(scratch, hartid); rc = fp_init(hartid); if (rc) diff --git a/lib/sbi_init.c b/lib/sbi_init.c index 82384b3..3e7bda3 100644 --- a/lib/sbi_init.c +++ b/lib/sbi_init.c @@ -91,7 +91,7 @@ static void __attribute__((noreturn)) init_coldboot(struct sbi_scratch *scratch, sbi_ecall_version_major(), sbi_ecall_version_minor()); sbi_printf("\n"); - sbi_hart_pmp_dump(); + sbi_hart_pmp_dump(scratch); sbi_hart_mark_available(hartid); diff --git a/platform/qemu/sifive_u/platform.c b/platform/qemu/sifive_u/platform.c index a4a401e..d916825 100644 --- a/platform/qemu/sifive_u/platform.c +++ b/platform/qemu/sifive_u/platform.c @@ -88,7 +88,7 @@ static int sifive_u_system_down(u32 type) struct sbi_platform platform = { .name = STRINGIFY(PLAT_NAME), - .features = SBI_PLATFORM_HAS_MMIO_TIMER_VALUE, + .features = SBI_PLATFORM_DEFAULT_FEATURES, .hart_count = PLAT_HART_COUNT, .hart_stack_size = PLAT_HART_STACK_SIZE, .pmp_region_count = sifive_u_pmp_region_count, diff --git a/platform/qemu/virt/platform.c b/platform/qemu/virt/platform.c index e59cdfd..fe91fc8 100644 --- a/platform/qemu/virt/platform.c +++ b/platform/qemu/virt/platform.c @@ -86,7 +86,7 @@ static int virt_system_down(u32 type) struct sbi_platform platform = { .name = STRINGIFY(PLAT_NAME), - .features = SBI_PLATFORM_HAS_MMIO_TIMER_VALUE, + .features = SBI_PLATFORM_DEFAULT_FEATURES, .hart_count = PLAT_HART_COUNT, .hart_stack_size = PLAT_HART_STACK_SIZE, .pmp_region_count = virt_pmp_region_count, diff --git a/platform/sifive/hifive_u540/platform.c b/platform/sifive/hifive_u540/platform.c index 5b1c989..46613e6 100644 --- a/platform/sifive/hifive_u540/platform.c +++ b/platform/sifive/hifive_u540/platform.c @@ -105,7 +105,7 @@ static int sifive_u_system_down(u32 type) struct sbi_platform platform = { .name = STRINGIFY(PLAT_NAME), - .features = SBI_PLATFORM_HAS_MMIO_TIMER_VALUE, + .features = SBI_PLATFORM_DEFAULT_FEATURES; .hart_count = PLAT_HART_COUNT, .hart_stack_size = PLAT_HART_STACK_SIZE, .pmp_region_count = sifive_u_pmp_region_count,