riscv: Clear pending IPIs on initialization
authorSean Anderson <seanga2@gmail.com>
Mon, 21 Sep 2020 11:51:38 +0000 (07:51 -0400)
committerAndes <uboot@andestech.com>
Wed, 30 Sep 2020 00:54:52 +0000 (08:54 +0800)
Even though we no longer call smp_function if an IPI was not sent by
U-Boot, we still need to clear any IPIs which were pending from the
execution environment. Otherwise, secondary harts will busy-wait in
secondary_hart_loop, instead of relaxing.

Along with the previous commit ("riscv: Use a valid bit to ignore
already-pending IPIs"), this fixes SMP booting on the Kendryte K210.

Signed-off-by: Sean Anderson <seanga2@gmail.com>
Reviewed-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Rick Chen <rick@andestech.com>
arch/riscv/cpu/cpu.c

index bfa2d4a..85592f5 100644 (file)
@@ -72,6 +72,17 @@ static int riscv_cpu_probe(void)
        return 0;
 }
 
+/*
+ * This is called on secondary harts just after the IPI is init'd. Currently
+ * there's nothing to do, since we just need to clear any existing IPIs, and
+ * that is handled by the sending of an ipi itself.
+ */
+#if CONFIG_IS_ENABLED(SMP)
+static void dummy_pending_ipi_clear(ulong hart, ulong arg0, ulong arg1)
+{
+}
+#endif
+
 int arch_cpu_init_dm(void)
 {
        int ret;
@@ -111,6 +122,15 @@ int arch_cpu_init_dm(void)
        ret = riscv_init_ipi();
        if (ret)
                return ret;
+
+       /*
+        * Clear all pending IPIs on secondary harts. We don't do anything on
+        * the boot hart, since we never send an IPI to ourselves, and no
+        * interrupts are enabled
+        */
+       ret = smp_call_function((ulong)dummy_pending_ipi_clear, 0, 0, 0);
+       if (ret)
+               return ret;
 #endif
 
        return 0;