[PATCH v2 3/9] lib: sbi: Add wait operations in some initialization functions

Xiang W wxjstz at 126.com
Fri Jun 20 21:22:51 PDT 2025


Many initialization functions need to wait for coldboot HART to
complete some initialization work before other HART can continue
to execute. This patch adds wait operations to these functions.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_dbtr.c    | 3 +++
 lib/sbi/sbi_fwft.c    | 3 +++
 lib/sbi/sbi_hart.c    | 3 +++
 lib/sbi/sbi_ipi.c     | 3 +++
 lib/sbi/sbi_irqchip.c | 5 ++++-
 lib/sbi/sbi_pmu.c     | 3 +++
 lib/sbi/sbi_sse.c     | 3 +++
 lib/sbi/sbi_timer.c   | 3 +++
 lib/sbi/sbi_tlb.c     | 3 +++
 9 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/lib/sbi/sbi_dbtr.c b/lib/sbi/sbi_dbtr.c
index a832c7f1..dcf24ce5 100644
--- a/lib/sbi/sbi_dbtr.c
+++ b/lib/sbi/sbi_dbtr.c
@@ -140,15 +140,18 @@ int sbi_dbtr_init(struct sbi_scratch *scratch, bool coldboot)
 	unsigned long val;
 	int i;
 	struct sbi_dbtr_hart_triggers_state *hart_state = NULL;
+	static atomic_t sync_a = ATOMIC_INITIALIZER(0);
 
 	if (!sbi_hart_has_extension(scratch, SBI_HART_EXT_SDTRIG))
 		return SBI_SUCCESS;
 
+	sbi_wait_for_boot_hart_first(coldboot, &sync_a);
 	if (coldboot) {
 		hart_state_ptr_offset = sbi_scratch_alloc_type_offset(void *);
 		if (!hart_state_ptr_offset)
 			return SBI_ENOMEM;
 	}
+	sbi_signal_boot_hart_first_done(coldboot, &sync_a);
 
 	hart_state = dbtr_get_hart_state_ptr(scratch);
 	if (!hart_state) {
diff --git a/lib/sbi/sbi_fwft.c b/lib/sbi/sbi_fwft.c
index a2aefb9a..612d2f2b 100644
--- a/lib/sbi/sbi_fwft.c
+++ b/lib/sbi/sbi_fwft.c
@@ -406,12 +406,15 @@ int sbi_fwft_init(struct sbi_scratch *scratch, bool cold_boot)
 {
 	int i;
 	struct fwft_hart_state *fhs;
+	static atomic_t sync_a = ATOMIC_INITIALIZER(0);
 
+	sbi_wait_for_boot_hart_first(cold_boot, &sync_a);
 	if (cold_boot) {
 		fwft_ptr_offset = sbi_scratch_alloc_type_offset(void *);
 		if (!fwft_ptr_offset)
 			return SBI_ENOMEM;
 	}
+	sbi_signal_boot_hart_first_done(cold_boot, &sync_a);
 
 	fhs = fwft_get_hart_state_ptr(scratch);
 	if (!fhs) {
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index 61d3b26b..86eedce3 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -1047,6 +1047,7 @@ int sbi_hart_reinit(struct sbi_scratch *scratch)
 int sbi_hart_init(struct sbi_scratch *scratch, bool cold_boot)
 {
 	int rc;
+	static atomic_t sync_a = ATOMIC_INITIALIZER(0);
 
 	/*
 	 * Clear mip CSR before proceeding with init to avoid any spurious
@@ -1054,6 +1055,7 @@ int sbi_hart_init(struct sbi_scratch *scratch, bool cold_boot)
 	 */
 	csr_write(CSR_MIP, 0);
 
+	sbi_wait_for_boot_hart_first(cold_boot, &sync_a);
 	if (cold_boot) {
 		if (misa_extension('H'))
 			sbi_hart_expected_trap = &__sbi_expected_trap_hext;
@@ -1063,6 +1065,7 @@ int sbi_hart_init(struct sbi_scratch *scratch, bool cold_boot)
 		if (!hart_features_offset)
 			return SBI_ENOMEM;
 	}
+	sbi_signal_boot_hart_first_done(cold_boot, &sync_a);
 
 	rc = hart_detect_features(scratch);
 	if (rc)
diff --git a/lib/sbi/sbi_ipi.c b/lib/sbi/sbi_ipi.c
index 2de459b0..8aeb1e8b 100644
--- a/lib/sbi/sbi_ipi.c
+++ b/lib/sbi/sbi_ipi.c
@@ -317,7 +317,9 @@ int sbi_ipi_init(struct sbi_scratch *scratch, bool cold_boot)
 {
 	int ret;
 	struct sbi_ipi_data *ipi_data;
+	static atomic_t sync_a = ATOMIC_INITIALIZER(0);
 
+	sbi_wait_for_boot_hart_first(cold_boot, &sync_a);
 	if (cold_boot) {
 		ipi_data_off = sbi_scratch_alloc_offset(sizeof(*ipi_data));
 		if (!ipi_data_off)
@@ -342,6 +344,7 @@ int sbi_ipi_init(struct sbi_scratch *scratch, bool cold_boot)
 		    SBI_IPI_EVENT_MAX <= ipi_halt_event)
 			return SBI_ENOSPC;
 	}
+	sbi_signal_boot_hart_first_done(cold_boot, &sync_a);
 
 	ipi_data = sbi_scratch_offset_ptr(scratch, ipi_data_off);
 	ipi_data->ipi_type = 0x00;
diff --git a/lib/sbi/sbi_irqchip.c b/lib/sbi/sbi_irqchip.c
index 0594e05a..18818c22 100644
--- a/lib/sbi/sbi_irqchip.c
+++ b/lib/sbi/sbi_irqchip.c
@@ -6,7 +6,7 @@
  * Authors:
  *   Anup Patel <apatel at ventanamicro.com>
  */
-
+#include <sbi/sbi_hart.h>
 #include <sbi/sbi_irqchip.h>
 #include <sbi/sbi_list.h>
 #include <sbi/sbi_platform.h>
@@ -38,12 +38,15 @@ int sbi_irqchip_init(struct sbi_scratch *scratch, bool cold_boot)
 	int rc;
 	const struct sbi_platform *plat = sbi_platform_ptr(scratch);
 	struct sbi_irqchip_device *dev;
+	static atomic_t sync_a = ATOMIC_INITIALIZER(0);
 
+	sbi_wait_for_boot_hart_first(cold_boot, &sync_a);
 	if (cold_boot) {
 		rc = sbi_platform_irqchip_init(plat);
 		if (rc)
 			return rc;
 	}
+	sbi_signal_boot_hart_first_done(cold_boot, &sync_a);
 
 	sbi_list_for_each_entry(dev, &irqchip_list, node) {
 		if (!dev->warm_init)
diff --git a/lib/sbi/sbi_pmu.c b/lib/sbi/sbi_pmu.c
index 07a5c544..842858da 100644
--- a/lib/sbi/sbi_pmu.c
+++ b/lib/sbi/sbi_pmu.c
@@ -1150,7 +1150,9 @@ int sbi_pmu_init(struct sbi_scratch *scratch, bool cold_boot)
 	struct sbi_pmu_hart_state *phs;
 	const struct sbi_platform *plat;
 	int rc;
+	static atomic_t sync_a = ATOMIC_INITIALIZER(0);
 
+	sbi_wait_for_boot_hart_first(cold_boot, &sync_a);
 	if (cold_boot) {
 		hw_event_map = sbi_calloc(sizeof(*hw_event_map),
 					  SBI_PMU_HW_EVENT_MAX);
@@ -1185,6 +1187,7 @@ int sbi_pmu_init(struct sbi_scratch *scratch, bool cold_boot)
 		if (sbi_pmu_irq_bit() >= 0)
 			sbi_sse_add_event(SBI_SSE_EVENT_LOCAL_PMU_OVERFLOW, &pmu_sse_cb_ops);
 	}
+	sbi_signal_boot_hart_first_done(cold_boot, &sync_a);
 
 	phs = pmu_get_hart_state_ptr(scratch);
 	if (!phs) {
diff --git a/lib/sbi/sbi_sse.c b/lib/sbi/sbi_sse.c
index 986b7701..63572633 100644
--- a/lib/sbi/sbi_sse.c
+++ b/lib/sbi/sbi_sse.c
@@ -1214,7 +1214,9 @@ int sbi_sse_init(struct sbi_scratch *scratch, bool cold_boot)
 	void *sse_inject_mem;
 	struct sse_hart_state *shs;
 	struct sbi_fifo *sse_inject_q;
+	static atomic_t sync_a = ATOMIC_INITIALIZER(0);
 
+	sbi_wait_for_boot_hart_first(cold_boot, &sync_a);
 	if (cold_boot) {
 		sse_event_count_init();
 
@@ -1249,6 +1251,7 @@ int sbi_sse_init(struct sbi_scratch *scratch, bool cold_boot)
 		}
 		sse_ipi_inject_event = ret;
 	}
+	sbi_signal_boot_hart_first_done(cold_boot, &sync_a);
 
 	shs = sse_get_hart_state_ptr(scratch);
 	if (!shs) {
diff --git a/lib/sbi/sbi_timer.c b/lib/sbi/sbi_timer.c
index 4088a597..d14e53ab 100644
--- a/lib/sbi/sbi_timer.c
+++ b/lib/sbi/sbi_timer.c
@@ -179,7 +179,9 @@ int sbi_timer_init(struct sbi_scratch *scratch, bool cold_boot)
 	u64 *time_delta;
 	const struct sbi_platform *plat = sbi_platform_ptr(scratch);
 	int ret;
+	static atomic_t sync_a = ATOMIC_INITIALIZER(0);
 
+	sbi_wait_for_boot_hart_first(cold_boot, &sync_a);
 	if (cold_boot) {
 		time_delta_off = sbi_scratch_alloc_offset(sizeof(*time_delta));
 		if (!time_delta_off)
@@ -195,6 +197,7 @@ int sbi_timer_init(struct sbi_scratch *scratch, bool cold_boot)
 		if (!time_delta_off)
 			return SBI_ENOMEM;
 	}
+	sbi_signal_boot_hart_first_done(cold_boot, &sync_a);
 
 	time_delta = sbi_scratch_offset_ptr(scratch, time_delta_off);
 	*time_delta = 0;
diff --git a/lib/sbi/sbi_tlb.c b/lib/sbi/sbi_tlb.c
index 01b31f4e..69cc2dfd 100644
--- a/lib/sbi/sbi_tlb.c
+++ b/lib/sbi/sbi_tlb.c
@@ -419,7 +419,9 @@ int sbi_tlb_init(struct sbi_scratch *scratch, bool cold_boot)
 	atomic_t *tlb_sync;
 	struct sbi_fifo *tlb_q;
 	const struct sbi_platform *plat = sbi_platform_ptr(scratch);
+	static atomic_t sync_a = ATOMIC_INITIALIZER(0);
 
+	sbi_wait_for_boot_hart_first(cold_boot, &sync_a);
 	if (cold_boot) {
 		tlb_sync_off = sbi_scratch_alloc_offset(sizeof(*tlb_sync));
 		if (!tlb_sync_off)
@@ -452,6 +454,7 @@ int sbi_tlb_init(struct sbi_scratch *scratch, bool cold_boot)
 		if (SBI_IPI_EVENT_MAX <= tlb_event)
 			return SBI_ENOSPC;
 	}
+	sbi_signal_boot_hart_first_done(cold_boot, &sync_a);
 
 	tlb_sync = sbi_scratch_offset_ptr(scratch, tlb_sync_off);
 	tlb_q = sbi_scratch_offset_ptr(scratch, tlb_fifo_off);
-- 
2.47.2




More information about the opensbi mailing list