]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
riscv: Introduce AVAILABLE_HARTS
authorRick Chen <rick@andestech.com>
Wed, 21 Sep 2022 06:34:54 +0000 (14:34 +0800)
committerLeo Yu-Chi Liang <ycliang@andestech.com>
Mon, 26 Sep 2022 06:29:13 +0000 (14:29 +0800)
In SMP all harts will register themself in available_hart
during start up. Then main hart will send IPI to other harts
according to this variables. But this mechanism may not
guarantee that all other harts can jump to next stage.

When main hart is sending IPI to other hart according to
available_harts, but other harts maybe still not finish the
registration. Then the SMP booting will miss some harts finally.
So let it become an option and it will be enabled by default.

Please refer to the discussion:
https://www.mail-archive.com/u-boot@lists.denx.de/msg449997.html

Signed-off-by: Rick Chen <rick@andestech.com>
Reviewed-by: Leo Yu-Chi Liang <ycliang@andestech.com>
arch/riscv/Kconfig
arch/riscv/cpu/cpu.c
arch/riscv/cpu/start.S
arch/riscv/include/asm/global_data.h
arch/riscv/lib/asm-offsets.c
arch/riscv/lib/smp.c

index c042506a644a9c95dc14a88df96320b33416f8e9..32a90b83b5a74a3a18a7639f831cb132476b5153 100644 (file)
@@ -276,6 +276,13 @@ config SPL_XIP
          rely on lock variables (for example hart_lottery and available_harts_lock),
          this affects only SPL, other stages should proceed as non-XIP.
 
+config AVAILABLE_HARTS
+       bool "Send IPI by available harts"
+       default y
+       help
+         By default, IPI sending mechanism will depend on available_harts.
+         If disable this, it will send IPI by CPUs node numbers of device tree.
+
 config SHOW_REGS
        bool "Show registers on unhandled exception"
 
index 0f323b26b3f896fad99fb1cf8ac3e937c2eeb9e4..52ab02519f8bf5659e79eb9447c5f330a7ca3e1f 100644 (file)
 #if !CONFIG_IS_ENABLED(XIP)
 u32 hart_lottery __section(".data") = 0;
 
+#ifdef CONFIG_AVAILABLE_HARTS
 /*
  * The main hart running U-Boot has acquired available_harts_lock until it has
  * finished initialization of global data.
  */
 u32 available_harts_lock = 1;
 #endif
+#endif
 
 static inline bool supports_extension(char ext)
 {
index de9d078da144c30bd1f1cd644f96db0d02d17662..4687bca3c996618a3ac40a027af8b22a186519af 100644 (file)
@@ -153,21 +153,23 @@ call_harts_early_init:
        SREG    tp, GD_BOOT_HART(gp)
 
 #if !CONFIG_IS_ENABLED(XIP)
+#ifdef CONFIG_AVAILABLE_HARTS
        la      t0, available_harts_lock
        amoswap.w.rl zero, zero, 0(t0)
+#endif
 
 wait_for_gd_init:
-       la      t0, available_harts_lock
-       li      t1, 1
-1:     amoswap.w.aq t1, t1, 0(t0)
-       bnez    t1, 1b
-
        /*
         * Set the global data pointer only when gd_t has been initialized.
         * This was already set by arch_setup_gd on the boot hart, but all other
         * harts' global data pointers gets set here.
         */
        mv      gp, s0
+#ifdef CONFIG_AVAILABLE_HARTS
+       la      t0, available_harts_lock
+       li      t1, 1
+1:     amoswap.w.aq t1, t1, 0(t0)
+       bnez    t1, 1b
 
        /* register available harts in the available_harts mask */
        li      t1, 1
@@ -177,6 +179,7 @@ wait_for_gd_init:
        SREG    t2, GD_AVAILABLE_HARTS(gp)
 
        amoswap.w.rl zero, zero, 0(t0)
+#endif
 
        /*
         * Continue on hart lottery winner, others branch to
index b3c79e176017bba80c5eca7930bf48eef498969d..858594a1911f68b35ecee54930c5d29303e8cfe8 100644 (file)
@@ -28,8 +28,10 @@ struct arch_global_data {
        struct ipi_data ipi[CONFIG_NR_CPUS];
 #endif
 #if !CONFIG_IS_ENABLED(XIP)
+#ifdef CONFIG_AVAILABLE_HARTS
        ulong available_harts;
 #endif
+#endif
 };
 
 #include <asm-generic/global_data.h>
index c4f48c83735474e234e0c85170c39557970dbdd5..452dfcea97f76aed3536944fd4dc48d6d13d9e5d 100644 (file)
@@ -17,7 +17,9 @@ int main(void)
        DEFINE(GD_BOOT_HART, offsetof(gd_t, arch.boot_hart));
        DEFINE(GD_FIRMWARE_FDT_ADDR, offsetof(gd_t, arch.firmware_fdt_addr));
 #if !CONFIG_IS_ENABLED(XIP)
+#ifdef CONFIG_AVAILABLE_HARTS
        DEFINE(GD_AVAILABLE_HARTS, offsetof(gd_t, arch.available_harts));
+#endif
 #endif
 
        return 0;
index f8b756291f3565213f9c5daebdcfa4b18f3fefc2..c0f65af1916261a6b895f653cf180ece67dbcea5 100644 (file)
@@ -46,9 +46,11 @@ static int send_ipi_many(struct ipi_data *ipi, int wait)
                }
 
 #if !CONFIG_IS_ENABLED(XIP)
+#ifdef CONFIG_AVAILABLE_HARTS
                /* skip if hart is not available */
                if (!(gd->arch.available_harts & (1 << reg)))
                        continue;
+#endif
 #endif
 
                gd->arch.ipi[reg].addr = ipi->addr;