[PATCH 1/2] lib: sbi: Move trap delegation setup to sbi_trap.c
Anup Patel
anup at brainfault.org
Mon Jul 20 23:36:00 PDT 2026
On Sat, Jun 13, 2026 at 6:51 PM Anup Patel <anup.patel at oss.qualcomm.com> wrote:
>
> 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>
Applied this patch to the riscv/opensbi repo.
Thanks,
Anup
> ---
> 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