[PATCH] riscv: cancel the limitation that NR_CPUS is less than or equal to 32
Xiang W
wxjstz at 126.com
Tue Dec 21 16:26:12 CET 2021
Various specifications of riscv allow the number of hart to be
greater than 32. The limit of 32 is determined by
gd->arch.available_harts. We can eliminate this limitation through
bitmaps. Currently, the number of hart is limited to 4095, and 4095
is the limit of the RISC-V Advanced Core Local Interruptor
Specification.
Test on sifive unmatched.
Signed-off-by: Xiang W <wxjstz at 126.com>
---
arch/riscv/Kconfig | 4 ++--
arch/riscv/cpu/start.S | 19 ++++++++++++++-----
arch/riscv/include/asm/global_data.h | 4 +++-
arch/riscv/lib/smp.c | 2 +-
4 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index ba29e70acf..7b9c7f5bca 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -220,8 +220,8 @@ config SPL_SMP
all, single processor machines.
config NR_CPUS
- int "Maximum number of CPUs (2-32)"
- range 2 32
+ int "Maximum number of CPUs (2-4095)"
+ range 2 4095
depends on SMP || SPL_SMP
default 8
help
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
index 76850ec9be..1f97240713 100644
--- a/arch/riscv/cpu/start.S
+++ b/arch/riscv/cpu/start.S
@@ -166,11 +166,20 @@ wait_for_gd_init:
mv gp, s0
/* register available harts in the available_harts mask */
- li t1, 1
- sll t1, t1, tp
- LREG t2, GD_AVAILABLE_HARTS(gp)
- or t2, t2, t1
- SREG t2, GD_AVAILABLE_HARTS(gp)
+ LREG t1, GD_AVAILABLE_HARTS(gp)
+#if defined(CONFIG_ARCH_RV64I)
+ srli t2, tp, 6
+ slli t2, t2, 3
+#elif defined(CONFIG_ARCH_RV32I)
+ srli t2, tp, 5
+ slli t2, t2, 2
+#endif
+ add t1, t1, t2
+ LREG t2, 0(t1)
+ li t3, 1
+ sll t3, t3, tp
+ or t2, t2, t3
+ SREG t2, 0(t1)
amoswap.w.rl zero, zero, 0(t0)
diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h
index 095484a635..6de2ee0b25 100644
--- a/arch/riscv/include/asm/global_data.h
+++ b/arch/riscv/include/asm/global_data.h
@@ -10,9 +10,11 @@
#ifndef __ASM_GBL_DATA_H
#define __ASM_GBL_DATA_H
+#include <config.h>
#include <asm/smp.h>
#include <asm/u-boot.h>
#include <compiler.h>
+#include <linux/bitops.h>
/* Architecture-specific global data */
struct arch_global_data {
@@ -28,7 +30,7 @@ struct arch_global_data {
struct ipi_data ipi[CONFIG_NR_CPUS];
#endif
#ifndef CONFIG_XIP
- ulong available_harts;
+ ulong available_harts[BITS_TO_LONGS(CONFIG_NR_CPUS)];
#endif
};
diff --git a/arch/riscv/lib/smp.c b/arch/riscv/lib/smp.c
index ba992100ad..e8e391fd41 100644
--- a/arch/riscv/lib/smp.c
+++ b/arch/riscv/lib/smp.c
@@ -47,7 +47,7 @@ static int send_ipi_many(struct ipi_data *ipi, int wait)
#ifndef CONFIG_XIP
/* skip if hart is not available */
- if (!(gd->arch.available_harts & (1 << reg)))
+ if (!test_bit(reg, gd->arch.available_harts))
continue;
#endif
--
2.30.2
More information about the U-Boot
mailing list