summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnup Patel <[email protected]>2026-06-13 18:51:28 +0530
committerAnup Patel <[email protected]>2026-07-21 11:50:46 +0530
commitc504877ed00bd7c38168a6574db25562e3615a38 (patch)
treeeb2838cdbf6958b214d1481dc7761f4e92efb50e
parent110f28518a15e84498bcc6337242160c500857fe (diff)
lib: sbi: Move trap delegation setup to sbi_trap.c
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 <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Anup Patel <[email protected]>
-rw-r--r--include/sbi/sbi_trap.h2
-rw-r--r--lib/sbi/sbi_hart.c46
-rw-r--r--lib/sbi/sbi_init.c8
-rw-r--r--lib/sbi/sbi_trap.c47
4 files changed, 57 insertions, 46 deletions
diff --git a/include/sbi/sbi_trap.h b/include/sbi/sbi_trap.h
index 281366e7..04c420a0 100644
--- a/include/sbi/sbi_trap.h
+++ b/include/sbi/sbi_trap.h
@@ -350,6 +350,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);
+}