[PATCH v2 5/9] lib: sbi: Initialize as much as possible on non-coldboot HART
Xiang W
wxjstz at 126.com
Fri Jun 20 21:22:53 PDT 2025
Separate sbi_hsm_hart_wait from sbi_hsm_init to allow the secondary
Hart to perform more initialization.
Signed-off-by: Xiang W <wxjstz at 126.com>
---
include/sbi/sbi_hsm.h | 3 ++-
lib/sbi/sbi_hsm.c | 49 ++++++++++++++++++-------------------------
lib/sbi/sbi_init.c | 15 ++++++-------
3 files changed, 28 insertions(+), 39 deletions(-)
diff --git a/include/sbi/sbi_hsm.h b/include/sbi/sbi_hsm.h
index 38f90516..3be08654 100644
--- a/include/sbi/sbi_hsm.h
+++ b/include/sbi/sbi_hsm.h
@@ -63,7 +63,8 @@ const struct sbi_hsm_device *sbi_hsm_get_device(void);
void sbi_hsm_set_device(const struct sbi_hsm_device *dev);
-int sbi_hsm_init(struct sbi_scratch *scratch, bool cold_boot);
+int sbi_hsm_init(struct sbi_scratch *scratch);
+void sbi_hsm_hart_wait(struct sbi_scratch *scratch);
void __noreturn sbi_hsm_exit(struct sbi_scratch *scratch);
int sbi_hsm_hart_start(struct sbi_scratch *scratch,
diff --git a/lib/sbi/sbi_hsm.c b/lib/sbi/sbi_hsm.c
index 557ab131..f32212d8 100644
--- a/lib/sbi/sbi_hsm.c
+++ b/lib/sbi/sbi_hsm.c
@@ -159,7 +159,7 @@ void __noreturn sbi_hsm_hart_start_finish(struct sbi_scratch *scratch,
sbi_hart_switch_mode(hartid, next_arg1, next_addr, next_mode, false);
}
-static void sbi_hsm_hart_wait(struct sbi_scratch *scratch)
+void sbi_hsm_hart_wait(struct sbi_scratch *scratch)
{
unsigned long saved_mie;
struct sbi_hsm_data *hdata = sbi_scratch_offset_ptr(scratch,
@@ -183,14 +183,10 @@ static void sbi_hsm_hart_wait(struct sbi_scratch *scratch)
wfi();
}
+ sbi_ipi_raw_clear();
/* Restore MIE CSR */
csr_write(CSR_MIE, saved_mie);
-
- /*
- * No need to clear IPI here because the sbi_ipi_init() will
- * clear it for current HART.
- */
}
const struct sbi_hsm_device *sbi_hsm_get_device(void)
@@ -247,34 +243,29 @@ static void hsm_device_hart_resume(void)
hsm_dev->hart_resume();
}
-int sbi_hsm_init(struct sbi_scratch *scratch, bool cold_boot)
+int sbi_hsm_init(struct sbi_scratch *scratch)
{
struct sbi_scratch *rscratch;
struct sbi_hsm_data *hdata;
- if (cold_boot) {
- hart_data_offset = sbi_scratch_alloc_offset(sizeof(*hdata));
- if (!hart_data_offset)
- return SBI_ENOMEM;
-
- /* Initialize hart state data for every hart */
- sbi_for_each_hartindex(i) {
- rscratch = sbi_hartindex_to_scratch(i);
- if (!rscratch)
- continue;
-
- hdata = sbi_scratch_offset_ptr(rscratch,
- hart_data_offset);
- ATOMIC_INIT(&hdata->state,
- (i == current_hartindex()) ?
- SBI_HSM_STATE_START_PENDING :
- SBI_HSM_STATE_STOPPED);
- ATOMIC_INIT(&hdata->start_ticket, 0);
- }
- } else {
- sbi_hsm_hart_wait(scratch);
+ hart_data_offset = sbi_scratch_alloc_offset(sizeof(*hdata));
+ if (!hart_data_offset)
+ return SBI_ENOMEM;
+
+ /* Initialize hart state data for every hart */
+ sbi_for_each_hartindex(i) {
+ rscratch = sbi_hartindex_to_scratch(i);
+ if (!rscratch)
+ continue;
+
+ hdata = sbi_scratch_offset_ptr(rscratch,
+ hart_data_offset);
+ ATOMIC_INIT(&hdata->state,
+ (i == current_hartindex()) ?
+ SBI_HSM_STATE_START_PENDING :
+ SBI_HSM_STATE_STOPPED);
+ ATOMIC_INIT(&hdata->start_ticket, 0);
}
-
return 0;
}
diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
index 4c55b3dc..5c017cda 100644
--- a/lib/sbi/sbi_init.c
+++ b/lib/sbi/sbi_init.c
@@ -223,6 +223,10 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
if (rc)
sbi_hart_hang();
+ rc = sbi_hsm_init(scratch);
+ if (rc)
+ sbi_hart_hang();
+
entry_count_offset = sbi_scratch_alloc_offset(__SIZEOF_POINTER__);
if (!entry_count_offset)
sbi_hart_hang();
@@ -234,10 +238,6 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
count = sbi_scratch_offset_ptr(scratch, entry_count_offset);
(*count)++;
- rc = sbi_hsm_init(scratch, true);
- if (rc)
- sbi_hart_hang();
-
/*
* All non-coldboot HARTs do HSM initialization (i.e. enter HSM state
* machine) at the start of the warmboot path so it is wasteful to
@@ -400,11 +400,6 @@ static void __noreturn init_warm_startup(struct sbi_scratch *scratch,
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();
@@ -457,6 +452,8 @@ static void __noreturn init_warm_startup(struct sbi_scratch *scratch,
if (rc)
sbi_hart_hang();
+ sbi_hsm_hart_wait(scratch);
+
count = sbi_scratch_offset_ptr(scratch, init_count_offset);
(*count)++;
--
2.47.2
More information about the opensbi
mailing list