[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