[PATCH 1/2] lib: sbi: Move trap delegation setup to sbi_trap.c
Anup Patel
anup.patel at oss.qualcomm.com
Sat Jun 13 06:21:28 PDT 2026
Currently, the trap delegation setup is part of sbi_hart.c and
called via sbi_hart_init() whereas the per-hart trap (aka exception
and interrupt) handling is part of sbi_trap.c.
Move trap delegation init to sbi_trap.c and call it via new
sbi_trap_init() from both cold boot and warm boot path. This
way trap delegation setup is in same place as trap handling.
Signed-off-by: Anup Patel <anup.patel at oss.qualcomm.com>
---
include/sbi/sbi_trap.h | 2 ++
lib/sbi/sbi_hart.c | 46 -----------------------------------------
lib/sbi/sbi_init.c | 8 +++++++
lib/sbi/sbi_trap.c | 47 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 57 insertions(+), 46 deletions(-)
diff --git a/include/sbi/sbi_trap.h b/include/sbi/sbi_trap.h
index 091a2446..8d2a6346 100644
--- a/include/sbi/sbi_trap.h
+++ b/include/sbi/sbi_trap.h
@@ -291,6 +291,8 @@ struct sbi_trap_context *sbi_trap_handler(struct sbi_trap_context *tcntx);
struct sbi_trap_context *sbi_trap_rnmi_handler(struct sbi_trap_context *tcntx);
+int sbi_trap_init(struct sbi_scratch *scratch, bool cold_boot);
+
#endif
#endif
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index 21713816..bee88557 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -211,48 +211,6 @@ static int fp_init(struct sbi_scratch *scratch)
return 0;
}
-static int delegate_traps(struct sbi_scratch *scratch)
-{
- const struct sbi_platform *plat = sbi_platform_ptr(scratch);
- unsigned long interrupts, exceptions;
-
- if (!misa_extension('S'))
- /* No delegation possible as mideleg does not exist */
- return 0;
-
- /* Send M-mode interrupts and most exceptions to S-mode */
- interrupts = MIP_SSIP | MIP_STIP | MIP_SEIP;
- interrupts |= sbi_pmu_irq_mask();
-
- exceptions = (1U << CAUSE_MISALIGNED_FETCH) | (1U << CAUSE_BREAKPOINT) |
- (1U << CAUSE_USER_ECALL);
- if (sbi_platform_has_mfaults_delegation(plat))
- exceptions |= (1U << CAUSE_FETCH_PAGE_FAULT) |
- (1U << CAUSE_LOAD_PAGE_FAULT) |
- (1U << CAUSE_STORE_PAGE_FAULT) |
- (1U << CAUSE_SW_CHECK_EXCP);
-
- /*
- * If hypervisor extension available then we only handle hypervisor
- * calls (i.e. ecalls from HS-mode) in M-mode.
- *
- * The HS-mode will additionally handle supervisor calls (i.e. ecalls
- * from VS-mode), Guest page faults and Virtual interrupts.
- */
- if (misa_extension('H')) {
- exceptions |= (1U << CAUSE_VIRTUAL_SUPERVISOR_ECALL);
- exceptions |= (1U << CAUSE_FETCH_GUEST_PAGE_FAULT);
- exceptions |= (1U << CAUSE_LOAD_GUEST_PAGE_FAULT);
- exceptions |= (1U << CAUSE_VIRTUAL_INST_FAULT);
- exceptions |= (1U << CAUSE_STORE_GUEST_PAGE_FAULT);
- }
-
- csr_write(CSR_MIDELEG, interrupts);
- csr_write(CSR_MEDELEG, exceptions);
-
- return 0;
-}
-
void sbi_hart_delegation_dump(struct sbi_scratch *scratch,
const char *prefix, const char *suffix)
{
@@ -773,10 +731,6 @@ int sbi_hart_init(struct sbi_scratch *scratch, bool cold_boot)
return rc;
}
- rc = delegate_traps(scratch);
- if (rc)
- return rc;
-
return sbi_hart_reinit(scratch);
}
diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
index 658fe37f..9bb1a37e 100644
--- a/lib/sbi/sbi_init.c
+++ b/lib/sbi/sbi_init.c
@@ -309,6 +309,10 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
__stack_chk_guard = guard_val;
}
+ rc = sbi_trap_init(scratch, true);
+ if (rc)
+ sbi_hart_hang();
+
rc = sbi_timer_init(scratch, true);
if (rc)
sbi_hart_hang();
@@ -466,6 +470,10 @@ static void __noreturn init_warm_startup(struct sbi_scratch *scratch,
if (rc)
sbi_hart_hang();
+ rc = sbi_trap_init(scratch, false);
+ if (rc)
+ sbi_hart_hang();
+
rc = sbi_timer_init(scratch, false);
if (rc)
sbi_hart_hang();
diff --git a/lib/sbi/sbi_trap.c b/lib/sbi/sbi_trap.c
index 1e55b885..16774fd2 100644
--- a/lib/sbi/sbi_trap.c
+++ b/lib/sbi/sbi_trap.c
@@ -414,3 +414,50 @@ struct sbi_trap_context *sbi_trap_rnmi_handler(struct sbi_trap_context *tcntx)
/* Never returns */
return tcntx;
}
+
+static int delegate_traps(struct sbi_scratch *scratch)
+{
+ const struct sbi_platform *plat = sbi_platform_ptr(scratch);
+ unsigned long interrupts, exceptions;
+
+ if (!misa_extension('S'))
+ /* No delegation possible as mideleg does not exist */
+ return 0;
+
+ /* Send M-mode interrupts and most exceptions to S-mode */
+ interrupts = MIP_SSIP | MIP_STIP | MIP_SEIP;
+ interrupts |= sbi_pmu_irq_mask();
+
+ exceptions = (1U << CAUSE_MISALIGNED_FETCH) | (1U << CAUSE_BREAKPOINT) |
+ (1U << CAUSE_USER_ECALL);
+ if (sbi_platform_has_mfaults_delegation(plat))
+ exceptions |= (1U << CAUSE_FETCH_PAGE_FAULT) |
+ (1U << CAUSE_LOAD_PAGE_FAULT) |
+ (1U << CAUSE_STORE_PAGE_FAULT) |
+ (1U << CAUSE_SW_CHECK_EXCP);
+
+ /*
+ * If hypervisor extension available then we only handle hypervisor
+ * calls (i.e. ecalls from HS-mode) in M-mode.
+ *
+ * The HS-mode will additionally handle supervisor calls (i.e. ecalls
+ * from VS-mode), Guest page faults and Virtual interrupts.
+ */
+ if (misa_extension('H')) {
+ exceptions |= (1U << CAUSE_VIRTUAL_SUPERVISOR_ECALL);
+ exceptions |= (1U << CAUSE_FETCH_GUEST_PAGE_FAULT);
+ exceptions |= (1U << CAUSE_LOAD_GUEST_PAGE_FAULT);
+ exceptions |= (1U << CAUSE_VIRTUAL_INST_FAULT);
+ exceptions |= (1U << CAUSE_STORE_GUEST_PAGE_FAULT);
+ }
+
+ csr_write(CSR_MIDELEG, interrupts);
+ csr_write(CSR_MEDELEG, exceptions);
+
+ return 0;
+}
+
+int sbi_trap_init(struct sbi_scratch *scratch, bool cold_boot)
+{
+ return delegate_traps(scratch);
+}
--
2.43.0
More information about the opensbi
mailing list