[PATCH 02/12] lib: sbi: Optimise the boot sequence

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


Originally init_coldboot/init_warm_startup were very similar, and
adding new code needed to be consistent in order. Now merge
init_coldboot/init_warm_startup and rename to init_startup.

Signed-off-by: Xiang W <wxjstz at 126.com>
---
 lib/sbi/sbi_init.c | 275 ++++++++++++++++-----------------------------
 1 file changed, 96 insertions(+), 179 deletions(-)

diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
index a227cb53..a8983f4d 100644
--- a/lib/sbi/sbi_init.c
+++ b/lib/sbi/sbi_init.c
@@ -212,42 +212,69 @@ static void wake_coldboot_harts(struct sbi_scratch *scratch)
 	__smp_store_release(&coldboot_done, 1);
 }
 
+static void __noreturn init_warm_resume(struct sbi_scratch *scratch, u32 hartid)
+{
+	int rc;
+
+	sbi_hsm_hart_resume_start(scratch);
+
+	rc = sbi_hart_reinit(scratch);
+	if (rc)
+		sbi_hart_hang();
+
+	rc = sbi_hart_pmp_configure(scratch);
+	if (rc)
+		sbi_hart_hang();
+
+	sbi_hsm_hart_resume_finish(scratch, hartid);
+}
+
 static unsigned long entry_count_offset;
 static unsigned long init_count_offset;
 
-static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
+static void __noreturn init_startup(struct sbi_scratch *scratch, u32 hartid, bool cold_boot)
 {
 	int rc;
+	int hstate;
 	unsigned long *count;
 	const struct sbi_platform *plat = sbi_platform_ptr(scratch);
 
-	/* Note: This has to be first thing in coldboot init sequence */
-	rc = sbi_scratch_init(scratch);
-	if (rc)
-		sbi_hart_hang();
+	if (cold_boot) {
+		/* Note: This has to be first thing in coldboot init sequence */
+		rc = sbi_scratch_init(scratch);
+		if (rc)
+			sbi_hart_hang();
 
-	/* Note: This has to be second thing in coldboot init sequence */
-	rc = sbi_heap_init(scratch);
-	if (rc)
-		sbi_hart_hang();
+		/* Note: This has to be second thing in coldboot init sequence */
+		rc = sbi_heap_init(scratch);
+		if (rc)
+			sbi_hart_hang();
 
-	/* Note: This has to be the third thing in coldboot init sequence */
-	rc = sbi_domain_init(scratch, hartid);
-	if (rc)
-		sbi_hart_hang();
+		/* Note: This has to be the third thing in coldboot init sequence */
+		rc = sbi_domain_init(scratch, hartid);
+		if (rc)
+			sbi_hart_hang();
 
-	entry_count_offset = sbi_scratch_alloc_offset(__SIZEOF_POINTER__);
-	if (!entry_count_offset)
-		sbi_hart_hang();
+		entry_count_offset = sbi_scratch_alloc_offset(__SIZEOF_POINTER__);
+		init_count_offset = sbi_scratch_alloc_offset(__SIZEOF_POINTER__);
+	} else {
+		wait_for_coldboot(scratch);
 
-	init_count_offset = sbi_scratch_alloc_offset(__SIZEOF_POINTER__);
-	if (!init_count_offset)
+		hstate = sbi_hsm_hart_get_state(sbi_domain_thishart_ptr(), hartid);
+		if (hstate < 0)
+			sbi_hart_hang();
+		if (hstate == SBI_HSM_STATE_SUSPENDED)
+			init_warm_resume(scratch, hartid);
+		sbi_ipi_raw_clear();
+	}
+
+	if (!entry_count_offset || !init_count_offset)
 		sbi_hart_hang();
 
 	count = sbi_scratch_offset_ptr(scratch, entry_count_offset);
 	(*count)++;
 
-	rc = sbi_hsm_init(scratch, true);
+	rc = sbi_hsm_init(scratch, cold_boot);
 	if (rc)
 		sbi_hart_hang();
 
@@ -257,63 +284,65 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
 	 * have these HARTs busy spin in wait_for_coldboot() until coldboot
 	 * path is completed.
 	 */
-	wake_coldboot_harts(scratch);
+	if (cold_boot)
+		wake_coldboot_harts(scratch);
 
-	rc = sbi_platform_early_init(plat, true);
+	rc = sbi_platform_early_init(plat, cold_boot);
 	if (rc)
 		sbi_hart_hang();
 
-	rc = sbi_hart_init(scratch, true);
+	rc = sbi_hart_init(scratch, cold_boot);
 	if (rc)
 		sbi_hart_hang();
 
-	rc = sbi_pmu_init(scratch, true);
+	rc = sbi_pmu_init(scratch, cold_boot);
 	if (rc) {
 		sbi_printf("%s: pmu init failed (error %d)\n",
 			   __func__, rc);
 		sbi_hart_hang();
 	}
 
-	rc = sbi_dbtr_init(scratch, true);
+	rc = sbi_dbtr_init(scratch, cold_boot);
 	if (rc)
 		sbi_hart_hang();
 
-	sbi_boot_print_banner(scratch);
+	if (cold_boot)
+		sbi_boot_print_banner(scratch);
 
-	sbi_double_trap_init(scratch, true);
+	sbi_double_trap_init(scratch, cold_boot);
 
-	rc = sbi_irqchip_init(scratch, true);
+	rc = sbi_irqchip_init(scratch, cold_boot);
 	if (rc) {
 		sbi_printf("%s: irqchip init failed (error %d)\n",
 			   __func__, rc);
 		sbi_hart_hang();
 	}
 
-	rc = sbi_ipi_init(scratch, true);
+	rc = sbi_ipi_init(scratch, cold_boot);
 	if (rc) {
 		sbi_printf("%s: ipi init failed (error %d)\n", __func__, rc);
 		sbi_hart_hang();
 	}
 
-	rc = sbi_tlb_init(scratch, true);
+	rc = sbi_tlb_init(scratch, cold_boot);
 	if (rc) {
 		sbi_printf("%s: tlb init failed (error %d)\n", __func__, rc);
 		sbi_hart_hang();
 	}
 
-	rc = sbi_timer_init(scratch, true);
+	rc = sbi_timer_init(scratch, cold_boot);
 	if (rc) {
 		sbi_printf("%s: timer init failed (error %d)\n", __func__, rc);
 		sbi_hart_hang();
 	}
 
-	rc = sbi_fwft_init(scratch, true);
+	rc = sbi_fwft_init(scratch, cold_boot);
 	if (rc) {
 		sbi_printf("%s: fwft init failed (error %d)\n", __func__, rc);
 		sbi_hart_hang();
 	}
 
-	rc = sbi_mpxy_init(scratch, true);
+	rc = sbi_mpxy_init(scratch, cold_boot);
 	if (rc) {
 		sbi_printf("%s: mpxy init failed (error %d)\n", __func__, rc);
 		sbi_hart_hang();
@@ -324,7 +353,7 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
 	 * Note: Finalize domains before HART PMP configuration so
 	 * that we use correct domain for configuring PMP.
 	 */
-	rc = sbi_domain_finalize(scratch, true);
+	rc = sbi_domain_finalize(scratch, cold_boot);
 	if (rc) {
 		sbi_printf("%s: domain finalize failed (error %d)\n",
 			   __func__, rc);
@@ -336,7 +365,7 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
 	 * domains so that it sees correct domain assignment and PMP
 	 * configuration for FDT fixups.
 	 */
-	rc = sbi_platform_final_init(plat, true);
+	rc = sbi_platform_final_init(plat, cold_boot);
 	if (rc) {
 		sbi_printf("%s: platform final init failed (error %d)\n",
 			   __func__, rc);
@@ -347,40 +376,42 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
 	 * Note: SSE events callbacks can be registered by other drivers so
 	 * sbi_sse_init() needs to be called after all drivers have been probed.
 	 */
-	rc = sbi_sse_init(scratch, true);
+	rc = sbi_sse_init(scratch, cold_boot);
 	if (rc) {
 		sbi_printf("%s: sse init failed (error %d)\n", __func__, rc);
 		sbi_hart_hang();
 	}
 
-	/*
-	 * Note: Ecall initialization should be after platform final
-	 * initialization so that all available platform devices are
-	 * already registered.
-	 */
-	rc = sbi_ecall_init();
-	if (rc) {
-		sbi_printf("%s: ecall init failed (error %d)\n", __func__, rc);
-		sbi_hart_hang();
-	}
-
-	sbi_boot_print_general(scratch);
-
-	sbi_boot_print_domains(scratch);
-
-	sbi_boot_print_hart(scratch, hartid);
-
-	run_all_tests();
-
-	/*
-	 * Note: Startup domains after all initialization are done
-	 * otherwise boot HART of non-root domain can crash.
-	 */
-	rc = sbi_domain_startup(scratch, hartid);
-	if (rc) {
-		sbi_printf("%s: domain startup failed (error %d)\n",
-			   __func__, rc);
-		sbi_hart_hang();
+	if (cold_boot) {
+		/*
+		* Note: Ecall initialization should be after platform final
+		* initialization so that all available platform devices are
+		* already registered.
+		*/
+		rc = sbi_ecall_init();
+		if (rc) {
+			sbi_printf("%s: ecall init failed (error %d)\n", __func__, rc);
+			sbi_hart_hang();
+		}
+
+		sbi_boot_print_general(scratch);
+
+		sbi_boot_print_domains(scratch);
+
+		sbi_boot_print_hart(scratch, hartid);
+
+		run_all_tests();
+
+		/*
+		* Note: Startup domains after all initialization are done
+		* otherwise boot HART of non-root domain can crash.
+		*/
+		rc = sbi_domain_startup(scratch, hartid);
+		if (rc) {
+			sbi_printf("%s: domain startup failed (error %d)\n",
+				__func__, rc);
+			sbi_hart_hang();
+		}
 	}
 
 	/*
@@ -400,118 +431,6 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
 	sbi_hsm_hart_start_finish(scratch, hartid);
 }
 
-static void __noreturn init_warm_startup(struct sbi_scratch *scratch,
-					 u32 hartid)
-{
-	int rc;
-	unsigned long *count;
-	const struct sbi_platform *plat = sbi_platform_ptr(scratch);
-
-	if (!entry_count_offset || !init_count_offset)
-		sbi_hart_hang();
-
-	count = sbi_scratch_offset_ptr(scratch, entry_count_offset);
-	(*count)++;
-
-	/* Note: This has to be first thing in warmboot init sequence */
-	rc = sbi_hsm_init(scratch, false);
-	if (rc)
-		sbi_hart_hang();
-
-	rc = sbi_platform_early_init(plat, false);
-	if (rc)
-		sbi_hart_hang();
-
-	rc = sbi_hart_init(scratch, false);
-	if (rc)
-		sbi_hart_hang();
-
-	rc = sbi_pmu_init(scratch, false);
-	if (rc)
-		sbi_hart_hang();
-
-	rc = sbi_dbtr_init(scratch, false);
-	if (rc)
-		sbi_hart_hang();
-
-	rc = sbi_irqchip_init(scratch, false);
-	if (rc)
-		sbi_hart_hang();
-
-	rc = sbi_ipi_init(scratch, false);
-	if (rc)
-		sbi_hart_hang();
-
-	rc = sbi_tlb_init(scratch, false);
-	if (rc)
-		sbi_hart_hang();
-
-	rc = sbi_timer_init(scratch, false);
-	if (rc)
-		sbi_hart_hang();
-
-	rc = sbi_fwft_init(scratch, false);
-	if (rc)
-		sbi_hart_hang();
-
-	rc = sbi_platform_final_init(plat, false);
-	if (rc)
-		sbi_hart_hang();
-
-	rc = sbi_sse_init(scratch, false);
-	if (rc)
-		sbi_hart_hang();
-
-	/*
-	 * Configure PMP at last because if SMEPMP is detected,
-	 * M-mode access to the S/U space will be rescinded.
-	 */
-	rc = sbi_hart_pmp_configure(scratch);
-	if (rc)
-		sbi_hart_hang();
-
-	count = sbi_scratch_offset_ptr(scratch, init_count_offset);
-	(*count)++;
-
-	sbi_hsm_hart_start_finish(scratch, hartid);
-}
-
-static void __noreturn init_warm_resume(struct sbi_scratch *scratch,
-					u32 hartid)
-{
-	int rc;
-
-	sbi_hsm_hart_resume_start(scratch);
-
-	rc = sbi_hart_reinit(scratch);
-	if (rc)
-		sbi_hart_hang();
-
-	rc = sbi_hart_pmp_configure(scratch);
-	if (rc)
-		sbi_hart_hang();
-
-	sbi_hsm_hart_resume_finish(scratch, hartid);
-}
-
-static void __noreturn init_warmboot(struct sbi_scratch *scratch, u32 hartid)
-{
-	int hstate;
-
-	wait_for_coldboot(scratch);
-
-	hstate = sbi_hsm_hart_get_state(sbi_domain_thishart_ptr(), hartid);
-	if (hstate < 0)
-		sbi_hart_hang();
-
-	if (hstate == SBI_HSM_STATE_SUSPENDED) {
-		init_warm_resume(scratch, hartid);
-	} else {
-		sbi_ipi_raw_clear();
-		init_warm_startup(scratch, hartid);
-	}
-}
-
 static atomic_t coldboot_lottery = ATOMIC_INITIALIZER(0);
 
 /**
@@ -573,10 +492,8 @@ void __noreturn sbi_init(struct sbi_scratch *scratch)
 	if (sbi_platform_nascent_init(plat))
 		sbi_hart_hang();
 
-	if (coldboot)
-		init_coldboot(scratch, hartid);
-	else
-		init_warmboot(scratch, hartid);
+
+	init_startup(scratch, hartid, coldboot);
 }
 
 unsigned long sbi_entry_count(u32 hartindex)
-- 
2.47.2




More information about the opensbi mailing list