mirror of
https://github.com/torvalds/linux.git
synced 2026-04-19 15:24:02 -04:00
When system returns from exception with ertn instruction, PC comes from LOONGARCH_CSR_ERA, and CSR.CRMD comes LOONGARCH_CSR_PRMD. Here save CSR register CSR.ERA and CSR.PRMD into stack, and then restore them from stack. So it can be modified by exception handlers in future. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
66 lines
1.5 KiB
ArmAsm
66 lines
1.5 KiB
ArmAsm
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
#include "processor.h"
|
|
|
|
/* address of refill exception should be 4K aligned */
|
|
.balign 4096
|
|
.global handle_tlb_refill
|
|
handle_tlb_refill:
|
|
csrwr t0, LOONGARCH_CSR_TLBRSAVE
|
|
csrrd t0, LOONGARCH_CSR_PGD
|
|
lddir t0, t0, 3
|
|
lddir t0, t0, 1
|
|
ldpte t0, 0
|
|
ldpte t0, 1
|
|
tlbfill
|
|
csrrd t0, LOONGARCH_CSR_TLBRSAVE
|
|
ertn
|
|
|
|
/*
|
|
* save and restore all gprs except base register,
|
|
* and default value of base register is sp ($r3).
|
|
*/
|
|
.macro save_gprs base
|
|
.irp n,1,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
|
|
st.d $r\n, \base, 8 * \n
|
|
.endr
|
|
.endm
|
|
|
|
.macro restore_gprs base
|
|
.irp n,1,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
|
|
ld.d $r\n, \base, 8 * \n
|
|
.endr
|
|
.endm
|
|
|
|
/* address of general exception should be 4K aligned */
|
|
.balign 4096
|
|
.global handle_exception
|
|
handle_exception:
|
|
csrwr sp, LOONGARCH_CSR_KS0
|
|
csrrd sp, LOONGARCH_CSR_KS1
|
|
addi.d sp, sp, -EXREGS_SIZE
|
|
|
|
save_gprs sp
|
|
/* save sp register to stack */
|
|
csrrd t0, LOONGARCH_CSR_KS0
|
|
st.d t0, sp, 3 * 8
|
|
|
|
csrrd t0, LOONGARCH_CSR_ERA
|
|
st.d t0, sp, PC_OFFSET_EXREGS
|
|
csrrd t0, LOONGARCH_CSR_ESTAT
|
|
st.d t0, sp, ESTAT_OFFSET_EXREGS
|
|
csrrd t0, LOONGARCH_CSR_BADV
|
|
st.d t0, sp, BADV_OFFSET_EXREGS
|
|
csrrd t0, LOONGARCH_CSR_PRMD
|
|
st.d t0, sp, PRMD_OFFSET_EXREGS
|
|
|
|
or a0, sp, zero
|
|
bl route_exception
|
|
ld.d t0, sp, PC_OFFSET_EXREGS
|
|
csrwr t0, LOONGARCH_CSR_ERA
|
|
ld.d t0, sp, PRMD_OFFSET_EXREGS
|
|
csrwr t0, LOONGARCH_CSR_PRMD
|
|
restore_gprs sp
|
|
csrrd sp, LOONGARCH_CSR_KS0
|
|
ertn
|