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 <anup.patel@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260613132129.2135128-2-anup.patel@oss.qualcomm.com
Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
Anup Patel
2026-07-21 11:50:46 +05:30
committed by Anup Patel
parent 110f28518a
commit c504877ed0
4 changed files with 57 additions and 46 deletions
+2
View File
@@ -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); 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
#endif #endif
-46
View File
@@ -211,48 +211,6 @@ static int fp_init(struct sbi_scratch *scratch)
return 0; 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, void sbi_hart_delegation_dump(struct sbi_scratch *scratch,
const char *prefix, const char *suffix) const char *prefix, const char *suffix)
{ {
@@ -773,10 +731,6 @@ int sbi_hart_init(struct sbi_scratch *scratch, bool cold_boot)
return rc; return rc;
} }
rc = delegate_traps(scratch);
if (rc)
return rc;
return sbi_hart_reinit(scratch); return sbi_hart_reinit(scratch);
} }
+8
View File
@@ -309,6 +309,10 @@ static void __noreturn init_coldboot(struct sbi_scratch *scratch, u32 hartid)
__stack_chk_guard = guard_val; __stack_chk_guard = guard_val;
} }
rc = sbi_trap_init(scratch, true);
if (rc)
sbi_hart_hang();
rc = sbi_timer_init(scratch, true); rc = sbi_timer_init(scratch, true);
if (rc) if (rc)
sbi_hart_hang(); sbi_hart_hang();
@@ -466,6 +470,10 @@ static void __noreturn init_warm_startup(struct sbi_scratch *scratch,
if (rc) if (rc)
sbi_hart_hang(); sbi_hart_hang();
rc = sbi_trap_init(scratch, false);
if (rc)
sbi_hart_hang();
rc = sbi_timer_init(scratch, false); rc = sbi_timer_init(scratch, false);
if (rc) if (rc)
sbi_hart_hang(); sbi_hart_hang();
+47
View File
@@ -414,3 +414,50 @@ struct sbi_trap_context *sbi_trap_rnmi_handler(struct sbi_trap_context *tcntx)
/* Never returns */ /* Never returns */
return tcntx; 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);
}