[PATCH v2 1/9] lib: sbi: Implement synchronisation and wait between multiple HARTs
Xiang W
wxjstz at 126.com
Fri Jun 20 21:22:49 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 | 4 ++++
lib/sbi/sbi_hart.c | 29 +++++++++++++++++++++++++++++
2 files changed, 33 insertions(+)
diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h
index dfbe8e4c..d0b08dca 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,8 @@ 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_sync_and_wait_all_harts(atomic_t *a);
#endif
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index 054a405c..61d3b26b 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -1145,3 +1145,32 @@ 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_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