mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2026-07-27 00:11:30 +01:00
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:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user