[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