[PATCH] firmware: fw_base: Optimize trap handler for RV32 systems

Anup Patel Anup.Patel at wdc.com
Tue Dec 1 11:29:36 EST 2020



> -----Original Message-----
> From: Alistair Francis <Alistair.Francis at wdc.com>
> Sent: 01 December 2020 07:27
> To: Atish Patra <Atish.Patra at wdc.com>; Anup Patel
> <Anup.Patel at wdc.com>
> Cc: anup at brainfault.org; opensbi at lists.infradead.org
> Subject: Re: [PATCH] firmware: fw_base: Optimize trap handler for RV32
> systems
> 
> On Sun, 2020-11-22 at 12:02 +0530, Anup Patel wrote:
> > On RV32 systems, we have two CSRs for M-mode status (MSTATUS and
> > MSTATUSH) when H-extension is implemented. This means we have to
> > save/restore MSTATUSH for RV32 systems only when H-extension is
> > implemented. The current _trap_handler() has extra instructions
> > (roughly 10) to conditional save/restore of MSTATUSH CSR.
> >
> > These extra instructions in RV32 _trap_handler() can be avoided if we
> > create separate low-level trap handler for RV32 systems having
> > H-extension. This patch optimizes low-level trap handler for RV32
> > systems accordingly.
> >
> > Signed-off-by: Anup Patel <anup.patel at wdc.com>
> 
> Reviewed-by: Alistair Francis <alistair.francis at wdc.com>
> 
> Alistair
> 
> > ---
> >  firmware/fw_base.S | 87 ++++++++++++++++++++++++++++++++++++--
> ------
> > --
> >  1 file changed, 68 insertions(+), 19 deletions(-)
> >
> > diff --git a/firmware/fw_base.S b/firmware/fw_base.S index
> > 1d9b375..fb504e8 100644
> > --- a/firmware/fw_base.S
> > +++ b/firmware/fw_base.S
> > @@ -413,6 +413,14 @@ _start_warm:
> >
> >         /* Setup trap handler */
> >         la      a4, _trap_handler
> > +#if __riscv_xlen == 32
> > +       csrr    a5, CSR_MISA
> > +       srli    a5, a5, ('H' - 'A')
> > +       andi    a5, a5, 0x1
> > +       beq     a5, zero, _skip_trap_handler_rv32_hyp
> > +       la      a4, _trap_handler_rv32_hyp
> > +_skip_trap_handler_rv32_hyp:
> > +#endif
> >         csrw    CSR_MTVEC, a4
> >
> >         /* Initialize SBI runtime */
> > @@ -476,10 +484,7 @@ fw_platform_init:
> >         add     a0, a1, zero
> >         ret
> >
> > -       .section .entry, "ax", %progbits
> > -       .align 3
> > -       .globl _trap_handler
> > -_trap_handler:
> > +.macro TRAP_SAVE_AND_SETUP_SP_T0
> >         /* Swap TP and MSCRATCH */
> >         csrrw   tp, CSR_MSCRATCH, tp
> >
> > @@ -519,23 +524,23 @@ _trap_handler:
> >
> >         /* Swap TP and MSCRATCH */
> >         csrrw   tp, CSR_MSCRATCH, tp
> > +.endm
> >
> > +.macro TRAP_SAVE_MEPC_MSTATUS have_mstatush
> >         /* Save MEPC and MSTATUS CSRs */
> >         csrr    t0, CSR_MEPC
> >         REG_S   t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)
> >         csrr    t0, CSR_MSTATUS
> >         REG_S   t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp)
> > -       REG_S   zero, SBI_TRAP_REGS_OFFSET(mstatusH)(sp)
> > -#if __riscv_xlen == 32
> > -       csrr    t0, CSR_MISA
> > -       srli    t0, t0, ('H' - 'A')
> > -       andi    t0, t0, 0x1
> > -       beq     t0, zero, _skip_mstatush_save
> > +       .if \have_mstatush
> >         csrr    t0, CSR_MSTATUSH
> >         REG_S   t0, SBI_TRAP_REGS_OFFSET(mstatusH)(sp)
> > -_skip_mstatush_save:
> > -#endif
> > +       .else
> > +       REG_S   zero, SBI_TRAP_REGS_OFFSET(mstatusH)(sp)
> > +       .endif
> > +.endm
> >
> > +.macro TRAP_SAVE_GENERAL_REGS_EXCEPT_SP_T0
> >         /* Save all general regisers except SP and T0 */
> >         REG_S   zero, SBI_TRAP_REGS_OFFSET(zero)(sp)
> >         REG_S   ra, SBI_TRAP_REGS_OFFSET(ra)(sp) @@ -567,11 +572,15 @@
> > _skip_mstatush_save:
> >         REG_S   t4, SBI_TRAP_REGS_OFFSET(t4)(sp)
> >         REG_S   t5, SBI_TRAP_REGS_OFFSET(t5)(sp)
> >         REG_S   t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
> > +.endm
> >
> > +.macro TRAP_CALL_C_ROUTINE
> >         /* Call C routine */
> >         add     a0, sp, zero
> >         call    sbi_trap_handler
> > +.endm
> >
> > +.macro TRAP_RESTORE_GENERAL_REGS_EXCEPT_SP_T0
> >         /* Restore all general regisers except SP and T0 */
> >         REG_L   ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
> >         REG_L   gp, SBI_TRAP_REGS_OFFSET(gp)(sp) @@ -602,30 +611,70 @@
> > _skip_mstatush_save:
> >         REG_L   t4, SBI_TRAP_REGS_OFFSET(t4)(sp)
> >         REG_L   t5, SBI_TRAP_REGS_OFFSET(t5)(sp)
> >         REG_L   t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
> > +.endm
> >
> > +.macro TRAP_RESTORE_MEPC_MSTATUS have_mstatush
> >         /* Restore MEPC and MSTATUS CSRs */
> >         REG_L   t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)
> >         csrw    CSR_MEPC, t0
> >         REG_L   t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp)
> >         csrw    CSR_MSTATUS, t0
> > -#if __riscv_xlen == 32
> > -       csrr    t0, CSR_MISA
> > -       srli    t0, t0, ('H' - 'A')
> > -       andi    t0, t0, 0x1
> > -       beq     t0, zero, _skip_mstatush_restore
> > +       .if \have_mstatush
> >         REG_L   t0, SBI_TRAP_REGS_OFFSET(mstatusH)(sp)
> >         csrw    CSR_MSTATUSH, t0
> > -_skip_mstatush_restore:
> > -#endif
> > +       .endif
> > +.endm
> >
> > +.macro TRAP_RESTORE_SP_T0
> >         /* Restore T0 */
> >         REG_L   t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
> >
> >         /* Restore SP */
> >         REG_L   sp, SBI_TRAP_REGS_OFFSET(sp)(sp)
> > +.endm
> > +
> > +       .section .entry, "ax", %progbits
> > +       .align 3
> > +       .globl _trap_handler
> > +_trap_handler:
> > +       TRAP_SAVE_AND_SETUP_SP_T0
> > +
> > +       TRAP_SAVE_MEPC_MSTATUS 0
> > +
> > +       TRAP_SAVE_GENERAL_REGS_EXCEPT_SP_T0
> > +
> > +       TRAP_CALL_C_ROUTINE
> > +
> > +       TRAP_RESTORE_GENERAL_REGS_EXCEPT_SP_T0
> > +
> > +       TRAP_RESTORE_MEPC_MSTATUS 0
> > +
> > +       TRAP_RESTORE_SP_T0
> >
> >         mret
> >
> > +#if __riscv_xlen == 32
> > +       .section .entry, "ax", %progbits
> > +       .align 3
> > +       .globl _trap_handler_rv32_hyp
> > +_trap_handler_rv32_hyp:
> > +       TRAP_SAVE_AND_SETUP_SP_T0
> > +
> > +       TRAP_SAVE_MEPC_MSTATUS 1
> > +
> > +       TRAP_SAVE_GENERAL_REGS_EXCEPT_SP_T0
> > +
> > +       TRAP_CALL_C_ROUTINE
> > +
> > +       TRAP_RESTORE_GENERAL_REGS_EXCEPT_SP_T0
> > +
> > +       TRAP_RESTORE_MEPC_MSTATUS 1
> > +
> > +       TRAP_RESTORE_SP_T0
> > +
> > +       mret
> > +#endif
> > +
> >         .section .entry, "ax", %progbits
> >         .align 3
> >         .globl _reset_regs

Applied this patch to the riscv/opensbi repo

Regards,
Anup


More information about the opensbi mailing list