[PATCH] riscv: add sbi v0.2 or later support

add rfence and ipi extension for sbi v0.2 or later. sbi_ipi add support for sbi v0.2 or later. This can make sbi_ipi break through the limit that the number of cores needs to be less than or equal to xlen
Signed-off-by: Xiang W merlew4n6@gmail.com --- arch/riscv/Kconfig | 2 +- arch/riscv/include/asm/sbi.h | 16 +++++++- arch/riscv/lib/sbi.c | 71 +++++++++++++++++++++++++++++++++++- arch/riscv/lib/sbi_ipi.c | 8 +++- 4 files changed, 91 insertions(+), 6 deletions(-)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index ebc4bef220..1f534f6f77 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -212,7 +212,7 @@ config ANDES_PLICSW
config SMP bool "Symmetric Multi-Processing" - depends on SBI_V01 || !RISCV_SMODE + depends on SBI || !RISCV_SMODE help This enables support for systems with more than one CPU. If you say N here, U-Boot will run on single and multiprocessor diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index 81fcfe0b36..5c4df101f5 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -135,11 +135,12 @@ struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0, unsigned long arg3, unsigned long arg4, unsigned long arg5);
-#ifdef CONFIG_SBI_V01 void sbi_console_putchar(int ch); int sbi_console_getchar(void); void sbi_clear_ipi(void); void sbi_shutdown(void); + +#ifdef CONFIG_SBI_V01 void sbi_send_ipi(const unsigned long *hart_mask); void sbi_remote_fence_i(const unsigned long *hart_mask); void sbi_remote_sfence_vma(const unsigned long *hart_mask, @@ -149,7 +150,18 @@ void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, unsigned long start, unsigned long size, unsigned long asid); -#endif +#else /* CONFIG_SBI_V01 */ +void sbi_send_ipi(unsigned long hart_mask, unsigned long hart_mask_base); +void sbi_remote_fence_i(unsigned long hart_mask, unsigned long hart_mask_base); +void sbi_remote_sfence_vma(unsigned long hart_mask, unsigned long hart_mask_base, + unsigned long start, + unsigned long size); +void sbi_remote_sfence_vma_asid(unsigned long hart_mask, unsigned long hart_mask_base, + unsigned long start, + unsigned long size, + unsigned long asid); +#endif /* CONFIG_SBI_V01 */ + void sbi_set_timer(uint64_t stime_value); long sbi_get_spec_version(void); int sbi_get_impl_id(void); diff --git a/arch/riscv/lib/sbi.c b/arch/riscv/lib/sbi.c index 8724e3a460..0daf43ceec 100644 --- a/arch/riscv/lib/sbi.c +++ b/arch/riscv/lib/sbi.c @@ -204,8 +204,6 @@ void sbi_srst_reset(unsigned long type, unsigned long reason) 0, 0, 0, 0); }
-#ifdef CONFIG_SBI_V01 - /** * sbi_console_putchar() - Writes given character to the console device. * @ch: The data to be written to the console. @@ -251,6 +249,7 @@ void sbi_shutdown(void) sbi_ecall(SBI_EXT_0_1_SHUTDOWN, 0, 0, 0, 0, 0, 0, 0); }
+#ifdef CONFIG_SBI_V01 /** * sbi_send_ipi() - Send an IPI to any hart. * @hart_mask: A cpu mask containing all the target harts. @@ -313,4 +312,72 @@ void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, (unsigned long)hart_mask, start, size, asid, 0, 0); }
+#else /* CONFIG_SBI_V01 */ + +/** + * sbi_send_ipi() - Send an IPI to any hart. + * @hart_mask: A cpu mask containing the target harts. + * @hart_mask_base: The hartid represented by the nth bit in hart_mask is hart_mask_base+n + * + * Return: None + */ +void sbi_send_ipi(unsigned long hart_mask, unsigned long hart_mask_base) +{ + sbi_ecall(SBI_EXT_SEND_IPI, SBI_FID_SEND_IPI, hart_mask, + hart_mask_base, 0, 0, 0, 0); +} + +/** + * sbi_remote_fence_i() - Execute FENCE.I instruction on given remote harts. + * @hart_mask: A cpu mask containing the target harts. + * @hart_mask_base: The hartid represented by the nth bit in hart_mask is hart_mask_base+n + * + * Return: None + */ +void sbi_remote_fence_i(unsigned long hart_mask, unsigned long hart_mask_base) +{ + sbi_ecall(SBI_EXT_REMOTE_FENCE_I, SBI_FID_REMOTE_FENCE_I, + hart_mask, hart_mask_base, 0, 0, 0, 0); +} + +/** + * sbi_remote_sfence_vma() - Execute SFENCE.VMA instructions on given remote + * harts for the specified virtual address range. + * @hart_mask: A cpu mask containing the target harts. + * @hart_mask_base: The hartid represented by the nth bit in hart_mask is hart_mask_base+n + * @start: Start of the virtual address + * @size: Total size of the virtual address range. + * + * Return: None + */ +void sbi_remote_sfence_vma(unsigned long hart_mask, unsigned long hart_mask_base, + unsigned long start, + unsigned long size) +{ + sbi_ecall(SBI_EXT_REMOTE_SFENCE_VMA, SBI_FID_REMOTE_SFENCE_VMA, + hart_mask, hart_mask_base, start, size, 0, 0); +} + +/** + * sbi_remote_sfence_vma_asid() - Execute SFENCE.VMA instructions on given + * remote harts for a virtual address range belonging to a specific ASID. + * + * @hart_mask: A cpu mask containing the target harts. + * @hart_mask_base: The hartid represented by the nth bit in hart_mask is hart_mask_base+n + * @start: Start of the virtual address + * @size: Total size of the virtual address range. + * @asid: The value of address space identifier (ASID). + * + * Return: None + */ +void sbi_remote_sfence_vma_asid(unsigned long hart_mask, unsigned long hart_mask_base, + unsigned long start, + unsigned long size, + unsigned long asid) +{ + sbi_ecall(SBI_EXT_REMOTE_SFENCE_VMA_ASID, + SBI_FID_REMOTE_SFENCE_VMA_ASID, + hart_mask, hart_mask_base, start, size, asid, 0); +} + #endif /* CONFIG_SBI_V01 */ diff --git a/arch/riscv/lib/sbi_ipi.c b/arch/riscv/lib/sbi_ipi.c index d02e2b4c48..724a10ae6e 100644 --- a/arch/riscv/lib/sbi_ipi.c +++ b/arch/riscv/lib/sbi_ipi.c @@ -15,11 +15,17 @@ int riscv_init_ipi(void)
int riscv_send_ipi(int hart) { +#ifdef CONFIG_SBI_V01 +#if CONFIG_NR_CPUS > BITS_PER_LONG +#error "SBI v0.1 cannot support too many harts" +#endif ulong mask;
mask = 1UL << hart; sbi_send_ipi(&mask); - +#else + sbi_send_ipi(1, hart); +#endif return 0; }
participants (1)
-
merle w