riscv: isr.S: optimize FP regs save/restore decision
Rely on mstatus rather than thread->base.user_options since it is always up to date (updated by z_riscv_switch) to simplify the code and be SMP proof. Also carry over SF_INIT to the mstatus being restored in case it was changed in the mean time. Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
This commit is contained in:
parent
ce8dabfe9e
commit
69d06a901c
1 changed files with 30 additions and 28 deletions
|
@ -135,14 +135,6 @@ SECTION_FUNC(exception.entry, __irq_wrapper)
|
||||||
addi sp, sp, -__z_arch_esf_t_SIZEOF
|
addi sp, sp, -__z_arch_esf_t_SIZEOF
|
||||||
DO_CALLER_SAVED(sr) ;
|
DO_CALLER_SAVED(sr) ;
|
||||||
|
|
||||||
/* Save MEPC register */
|
|
||||||
csrr t0, mepc
|
|
||||||
sr t0, __z_arch_esf_t_mepc_OFFSET(sp)
|
|
||||||
|
|
||||||
/* Save MSTATUS register */
|
|
||||||
csrr t0, mstatus
|
|
||||||
sr t0, __z_arch_esf_t_mstatus_OFFSET(sp)
|
|
||||||
|
|
||||||
#ifdef CONFIG_USERSPACE
|
#ifdef CONFIG_USERSPACE
|
||||||
/*
|
/*
|
||||||
* The scratch register now contains either the user mode stack
|
* The scratch register now contains either the user mode stack
|
||||||
|
@ -163,12 +155,18 @@ SECTION_FUNC(exception.entry, __irq_wrapper)
|
||||||
sw zero, 0(t0)
|
sw zero, 0(t0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Save MEPC register */
|
||||||
|
csrr t0, mepc
|
||||||
|
sr t0, __z_arch_esf_t_mepc_OFFSET(sp)
|
||||||
|
|
||||||
|
/* Save MSTATUS register */
|
||||||
|
csrr t4, mstatus
|
||||||
|
sr t4, __z_arch_esf_t_mstatus_OFFSET(sp)
|
||||||
|
|
||||||
#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)
|
#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)
|
||||||
/* Assess whether floating-point registers need to be saved. */
|
/* Assess whether floating-point registers need to be saved. */
|
||||||
la t0, _kernel
|
li t1, MSTATUS_FS_INIT
|
||||||
lr t0, _kernel_offset_to_current(t0)
|
and t0, t4, t1
|
||||||
lb t0, _thread_offset_to_user_options(t0)
|
|
||||||
andi t0, t0, K_FP_REGS
|
|
||||||
beqz t0, skip_store_fp_caller_saved
|
beqz t0, skip_store_fp_caller_saved
|
||||||
DO_FP_CALLER_SAVED(fsr, sp)
|
DO_FP_CALLER_SAVED(fsr, sp)
|
||||||
skip_store_fp_caller_saved:
|
skip_store_fp_caller_saved:
|
||||||
|
@ -457,28 +455,32 @@ no_reschedule:
|
||||||
jal ra, __soc_restore_context
|
jal ra, __soc_restore_context
|
||||||
#endif /* CONFIG_RISCV_SOC_CONTEXT_SAVE */
|
#endif /* CONFIG_RISCV_SOC_CONTEXT_SAVE */
|
||||||
|
|
||||||
#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)
|
|
||||||
/*
|
|
||||||
* Determine if we need to restore floating-point registers. This needs
|
|
||||||
* to happen before restoring integer registers to avoid stomping on
|
|
||||||
* t0.
|
|
||||||
*/
|
|
||||||
la t0, _kernel
|
|
||||||
lr t0, _kernel_offset_to_current(t0)
|
|
||||||
lb t0, _thread_offset_to_user_options(t0)
|
|
||||||
andi t0, t0, K_FP_REGS
|
|
||||||
beqz t0, skip_load_fp_caller_saved
|
|
||||||
DO_FP_CALLER_SAVED(flr, sp)
|
|
||||||
skip_load_fp_caller_saved:
|
|
||||||
#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */
|
|
||||||
|
|
||||||
/* Restore MEPC register */
|
/* Restore MEPC register */
|
||||||
lr t0, __z_arch_esf_t_mepc_OFFSET(sp)
|
lr t0, __z_arch_esf_t_mepc_OFFSET(sp)
|
||||||
csrw mepc, t0
|
csrw mepc, t0
|
||||||
|
|
||||||
/* Restore MSTATUS register */
|
/* Restore MSTATUS register */
|
||||||
lr t4, __z_arch_esf_t_mstatus_OFFSET(sp)
|
lr t4, __z_arch_esf_t_mstatus_OFFSET(sp)
|
||||||
csrw mstatus, t4
|
csrrw t5, mstatus, t4
|
||||||
|
|
||||||
|
#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)
|
||||||
|
/*
|
||||||
|
* Determine if we need to restore FP regs based on the previous
|
||||||
|
* (before the csr above) mstatus value available in t5.
|
||||||
|
*/
|
||||||
|
li t1, MSTATUS_FS_INIT
|
||||||
|
and t0, t5, t1
|
||||||
|
beqz t0, no_fp
|
||||||
|
|
||||||
|
/* make sure FP is enabled in the restored mstatus */
|
||||||
|
csrs mstatus, t1
|
||||||
|
DO_FP_CALLER_SAVED(flr, sp)
|
||||||
|
j 1f
|
||||||
|
|
||||||
|
no_fp: /* make sure this is reflected in the restored mstatus */
|
||||||
|
csrc mstatus, t1
|
||||||
|
1:
|
||||||
|
#endif /* CONFIG_FPU && CONFIG_FPU_SHARING */
|
||||||
|
|
||||||
#ifdef CONFIG_USERSPACE
|
#ifdef CONFIG_USERSPACE
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue