[PATCH v2] firmware: fw_base: Improve exception stack setup in trap handler
Atish Patra
atishp at atishpatra.org
Wed Aug 12 13:50:54 EDT 2020
On Wed, Aug 12, 2020 at 6:27 AM Anup Patel <anup.patel at wdc.com> wrote:
>
> Currently, the low-level trap handler (i.e. _trap_handler()) uses
> branch instructions to conditionally setup exception stack based
> on which mode trap occured.
>
> This patch implements exception stack setup using xor instructions
> which is faster with same number of instructions due to lack of
> branch instructions.
>
> The new exception stack setup approach can be best described by the
> following pseudocode:
>
> Came_From_M_Mode = ((MSTATUS.MPP < PRV_M) ? 1 : 0) - 1;
> Exception_Stack = TP ^ (Came_From_M_Mode & (SP ^ TP))
>
> Came_From_M_Mode = 0 ==> Exception_Stack = TP
> Came_From_M_Mode = -1 ==> Exception_Stack = SP
>
> Signed-off-by: Anup Patel <anup.patel at wdc.com>
> ---
> Changes since v1:
> - Don't assume that 0b10 privilege mode will never be used
> - Use AND operation in-place of MUL operation
> ---
> firmware/fw_base.S | 47 +++++++++++++++++++++-------------------------
> 1 file changed, 21 insertions(+), 26 deletions(-)
>
> diff --git a/firmware/fw_base.S b/firmware/fw_base.S
> index b66ac41..0271d9a 100644
> --- a/firmware/fw_base.S
> +++ b/firmware/fw_base.S
> @@ -490,35 +490,30 @@ _trap_handler:
> /* Save T0 in scratch space */
> REG_S t0, SBI_SCRATCH_TMP0_OFFSET(tp)
>
> - /* Check which mode we came from */
> + /*
> + * Set T0 to appropriate exception stack
> + *
> + * Came_From_M_Mode = ((MSTATUS.MPP < PRV_M) ? 1 : 0) - 1;
> + * Exception_Stack = TP ^ (Came_From_M_Mode & (SP ^ TP))
> + *
> + * Came_From_M_Mode = 0 ==> Exception_Stack = TP
> + * Came_From_M_Mode = -1 ==> Exception_Stack = SP
> + */
> csrr t0, CSR_MSTATUS
> srl t0, t0, MSTATUS_MPP_SHIFT
> and t0, t0, PRV_M
> - xori t0, t0, PRV_M
> - beq t0, zero, _trap_handler_m_mode
> -
> - /* We came from S-mode or U-mode */
> -_trap_handler_s_mode:
> - /* Set T0 to original SP */
> - add t0, sp, zero
> -
> - /* Setup exception stack */
> - add sp, tp, -(SBI_TRAP_REGS_SIZE)
> -
> - /* Jump to code common for all modes */
> - j _trap_handler_all_mode
> -
> - /* We came from M-mode */
> -_trap_handler_m_mode:
> - /* Set T0 to original SP */
> - add t0, sp, zero
> -
> - /* Re-use current SP as exception stack */
> - add sp, sp, -(SBI_TRAP_REGS_SIZE)
> -
> -_trap_handler_all_mode:
> - /* Save original SP (from T0) on stack */
> - REG_S t0, SBI_TRAP_REGS_OFFSET(sp)(sp)
> + slti t0, t0, PRV_M
> + add t0, t0, -1
> + xor sp, sp, tp
> + and t0, t0, sp
> + xor sp, sp, tp
> + xor t0, tp, t0
> +
> + /* Save original SP on exception stack */
> + REG_S sp, (SBI_TRAP_REGS_OFFSET(sp) - SBI_TRAP_REGS_SIZE)(t0)
> +
> + /* Set SP to exception stack and make room for trap registers */
> + add sp, t0, -(SBI_TRAP_REGS_SIZE)
>
> /* Restore T0 from scratch space */
> REG_L t0, SBI_SCRATCH_TMP0_OFFSET(tp)
> --
> 2.25.1
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi
Looks good to me.
Reviewed-by: Atish Patra <atish.patra at wdc.com>
--
Regards,
Atish
More information about the opensbi
mailing list