[PATCH 03/12] lib: sbi: Implement synchronisation and wait between multiple HARTs

Xiang W wxjstz at 126.com
Wed Jun 11 05:12:20 PDT 2025


Implemented sbi_sync_and_wait_all_harts to synchronize and wait for
all HARTs to complete their tasks before proceeding.

Introduced sbi_wait_for_boot_hart_first and
sbi_signal_boot_hart_first_done to ensure that the coldboot HART
completes its initialization before other HARTs start executing.

Added sbi_wait_for_non_boot_harts and sbi_signal_non_boot_harts_done
to coordinate the execution of non-coldboot HARTs, ensuring they finish
their tasks before the coldboot HART continues.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 include/sbi/sbi_hart.h |  6 ++++
 lib/sbi/sbi_hart.c     | 62 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+)

diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h
index dfbe8e4c..b7664dfa 100644
--- a/include/sbi/sbi_hart.h
+++ b/include/sbi/sbi_hart.h
@@ -12,6 +12,7 @@
 
 #include <sbi/sbi_types.h>
 #include <sbi/sbi_bitops.h>
+#include <sbi/riscv_atomic.h>
 
 /** Possible privileged specification versions of a hart */
 enum sbi_hart_priv_versions {
@@ -167,5 +168,10 @@ void __attribute__((noreturn))
 sbi_hart_switch_mode(unsigned long arg0, unsigned long arg1,
 		     unsigned long next_addr, unsigned long next_mode,
 		     bool next_virt);
+void sbi_wait_for_boot_hart_first(bool cold_boot, atomic_t *a);
+void sbi_signal_boot_hart_first_done(bool cold_boot, atomic_t *a);
+void sbi_wait_for_non_boot_harts(bool cold_boot, atomic_t *a);
+void sbi_signal_non_boot_harts_done(bool cold_boot, atomic_t *a);
+void sbi_sync_and_wait_all_harts(atomic_t *a);
 
 #endif
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index 74ccdd84..04f04721 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -1135,3 +1135,65 @@ sbi_hart_switch_mode(unsigned long arg0, unsigned long arg1,
 	__asm__ __volatile__("mret" : : "r"(a0), "r"(a1));
 	__builtin_unreachable();
 }
+
+void sbi_wait_for_boot_hart_first(bool cold_boot, atomic_t *a)
+{
+	if (cold_boot)
+		return;
+	while (!atomic_read(a))
+		cpu_relax();
+}
+
+void sbi_signal_boot_hart_first_done(bool cold_boot, atomic_t *a)
+{
+	if (!cold_boot)
+		return;
+	atomic_write(a, 1);
+}
+
+void sbi_wait_for_non_boot_harts(bool cold_boot, atomic_t *a)
+{
+	long val;
+	u32 hart_count;
+	if (!cold_boot)
+		return;
+
+	hart_count = sbi_platform_hart_count(sbi_platform_thishart_ptr());
+	do {
+		val = atomic_read(a);
+		if (val >= hart_count)
+			return;
+	} while(atomic_cmpxchg(a, val, val + 1) != val);
+
+	while (atomic_read(a) < hart_count)
+		cpu_relax();
+}
+
+void sbi_signal_non_boot_harts_done(bool cold_boot, atomic_t *a)
+{
+	long val;
+	u32 hart_count;
+	if (cold_boot)
+		return;
+
+	hart_count = sbi_platform_hart_count(sbi_platform_thishart_ptr());
+	do {
+		val = atomic_read(a);
+		if (val >= hart_count)
+			return;
+	} while (atomic_cmpxchg(a, val, val + 1) != val);
+}
+
+void sbi_sync_and_wait_all_harts(atomic_t *a)
+{
+	long val;
+	u32 hart_count = sbi_platform_hart_count(sbi_platform_thishart_ptr());
+	do {
+		val = atomic_read(a);
+		if (val >= hart_count)
+			return;
+	} while (atomic_cmpxchg(a, val, val + 1) != val);
+
+	while (atomic_read(a) < hart_count)
+		cpu_relax();
+}
-- 
2.47.2




More information about the opensbi mailing list