[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