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);
|
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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user