firmware: fw_base: Optimize trap handler for RV32 systems

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) for 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@wdc.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
Anup Patel
2020-11-22 11:47:22 +05:30
committed by Anup Patel
parent 548d03e577
commit 2677324f90

View File

@@ -413,6 +413,14 @@ _start_warm:
/* Setup trap handler */ /* Setup trap handler */
la a4, _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 csrw CSR_MTVEC, a4
/* Initialize SBI runtime */ /* Initialize SBI runtime */
@@ -476,10 +484,7 @@ fw_platform_init:
add a0, a1, zero add a0, a1, zero
ret ret
.section .entry, "ax", %progbits .macro TRAP_SAVE_AND_SETUP_SP_T0
.align 3
.globl _trap_handler
_trap_handler:
/* Swap TP and MSCRATCH */ /* Swap TP and MSCRATCH */
csrrw tp, CSR_MSCRATCH, tp csrrw tp, CSR_MSCRATCH, tp
@@ -519,23 +524,23 @@ _trap_handler:
/* Swap TP and MSCRATCH */ /* Swap TP and MSCRATCH */
csrrw tp, CSR_MSCRATCH, tp csrrw tp, CSR_MSCRATCH, tp
.endm
.macro TRAP_SAVE_MEPC_MSTATUS have_mstatush
/* Save MEPC and MSTATUS CSRs */ /* Save MEPC and MSTATUS CSRs */
csrr t0, CSR_MEPC csrr t0, CSR_MEPC
REG_S t0, SBI_TRAP_REGS_OFFSET(mepc)(sp) REG_S t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)
csrr t0, CSR_MSTATUS csrr t0, CSR_MSTATUS
REG_S t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp) REG_S t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp)
REG_S zero, SBI_TRAP_REGS_OFFSET(mstatusH)(sp) .if \have_mstatush
#if __riscv_xlen == 32
csrr t0, CSR_MISA
srli t0, t0, ('H' - 'A')
andi t0, t0, 0x1
beq t0, zero, _skip_mstatush_save
csrr t0, CSR_MSTATUSH csrr t0, CSR_MSTATUSH
REG_S t0, SBI_TRAP_REGS_OFFSET(mstatusH)(sp) REG_S t0, SBI_TRAP_REGS_OFFSET(mstatusH)(sp)
_skip_mstatush_save: .else
#endif 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 */ /* Save all general regisers except SP and T0 */
REG_S zero, SBI_TRAP_REGS_OFFSET(zero)(sp) REG_S zero, SBI_TRAP_REGS_OFFSET(zero)(sp)
REG_S ra, SBI_TRAP_REGS_OFFSET(ra)(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 t4, SBI_TRAP_REGS_OFFSET(t4)(sp)
REG_S t5, SBI_TRAP_REGS_OFFSET(t5)(sp) REG_S t5, SBI_TRAP_REGS_OFFSET(t5)(sp)
REG_S t6, SBI_TRAP_REGS_OFFSET(t6)(sp) REG_S t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
.endm
.macro TRAP_CALL_C_ROUTINE
/* Call C routine */ /* Call C routine */
add a0, sp, zero add a0, sp, zero
call sbi_trap_handler call sbi_trap_handler
.endm
.macro TRAP_RESTORE_GENERAL_REGS_EXCEPT_SP_T0
/* Restore all general regisers except SP and T0 */ /* Restore all general regisers except SP and T0 */
REG_L ra, SBI_TRAP_REGS_OFFSET(ra)(sp) REG_L ra, SBI_TRAP_REGS_OFFSET(ra)(sp)
REG_L gp, SBI_TRAP_REGS_OFFSET(gp)(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 t4, SBI_TRAP_REGS_OFFSET(t4)(sp)
REG_L t5, SBI_TRAP_REGS_OFFSET(t5)(sp) REG_L t5, SBI_TRAP_REGS_OFFSET(t5)(sp)
REG_L t6, SBI_TRAP_REGS_OFFSET(t6)(sp) REG_L t6, SBI_TRAP_REGS_OFFSET(t6)(sp)
.endm
.macro TRAP_RESTORE_MEPC_MSTATUS have_mstatush
/* Restore MEPC and MSTATUS CSRs */ /* Restore MEPC and MSTATUS CSRs */
REG_L t0, SBI_TRAP_REGS_OFFSET(mepc)(sp) REG_L t0, SBI_TRAP_REGS_OFFSET(mepc)(sp)
csrw CSR_MEPC, t0 csrw CSR_MEPC, t0
REG_L t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp) REG_L t0, SBI_TRAP_REGS_OFFSET(mstatus)(sp)
csrw CSR_MSTATUS, t0 csrw CSR_MSTATUS, t0
#if __riscv_xlen == 32 .if \have_mstatush
csrr t0, CSR_MISA
srli t0, t0, ('H' - 'A')
andi t0, t0, 0x1
beq t0, zero, _skip_mstatush_restore
REG_L t0, SBI_TRAP_REGS_OFFSET(mstatusH)(sp) REG_L t0, SBI_TRAP_REGS_OFFSET(mstatusH)(sp)
csrw CSR_MSTATUSH, t0 csrw CSR_MSTATUSH, t0
_skip_mstatush_restore: .endif
#endif .endm
.macro TRAP_RESTORE_SP_T0
/* Restore T0 */ /* Restore T0 */
REG_L t0, SBI_TRAP_REGS_OFFSET(t0)(sp) REG_L t0, SBI_TRAP_REGS_OFFSET(t0)(sp)
/* Restore SP */ /* Restore SP */
REG_L sp, SBI_TRAP_REGS_OFFSET(sp)(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 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 .section .entry, "ax", %progbits
.align 3 .align 3
.globl _reset_regs .globl _reset_regs