summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnup Patel <anup.patel@wdc.com>2020-11-22 09:17:22 +0300
committerAnup Patel <anup@brainfault.org>2020-12-01 14:44:32 +0300
commit2677324f906133db8596de4868df87cb1224f113 (patch)
tree9ba4085aa7bd74ce779051dca067fe427064b6bf
parent548d03e577490f74af8b57706655e5d81c9b94a1 (diff)
downloadopensbi-2677324f906133db8596de4868df87cb1224f113.tar.xz
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>
-rw-r--r--firmware/fw_base.S87
1 files 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