1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 4 * 5 * Derived from MIPS: 6 * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle 7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 8 * Copyright (C) 2002, 2007 Maciej W. Rozycki 9 * Copyright (C) 2001, 2012 MIPS Technologies, Inc. All rights reserved. 10 */ 11#include <asm/asm.h> 12#include <asm/asmmacro.h> 13#include <asm/loongarch.h> 14#include <asm/regdef.h> 15#include <asm/fpregdef.h> 16#include <asm/stackframe.h> 17#include <asm/thread_info.h> 18 19 .section .cpuidle.text, "ax" 20 .align 5 21SYM_FUNC_START(__arch_cpu_idle) 22 /* start of idle interrupt region */ 23 ori t0, zero, CSR_CRMD_IE 24 /* idle instruction needs irq enabled */ 25 csrxchg t0, t0, LOONGARCH_CSR_CRMD 26 /* 27 * If an interrupt lands here; between enabling interrupts above and 28 * going idle on the next instruction, we must *NOT* go idle since the 29 * interrupt could have set TIF_NEED_RESCHED or caused an timer to need 30 * reprogramming. Fall through -- see handle_vint() below -- and have 31 * the idle loop take care of things. 32 */ 33 idle 0 34 /* end of idle interrupt region */ 35idle_exit: 36 jr ra 37SYM_FUNC_END(__arch_cpu_idle) 38 .previous 39 40SYM_CODE_START(handle_vint) 41 UNWIND_HINT_UNDEFINED 42 BACKUP_T0T1 43 SAVE_ALL 44 la_abs t1, idle_exit 45 LONG_L t0, sp, PT_ERA 46 /* 3 instructions idle interrupt region */ 47 ori t0, t0, 0b1100 48 bne t0, t1, 1f 49 LONG_S t0, sp, PT_ERA 501: move a0, sp 51 move a1, sp 52 la_abs t0, do_vint 53 jirl ra, t0, 0 54 RESTORE_ALL_AND_RET 55SYM_CODE_END(handle_vint) 56 57SYM_CODE_START(except_vec_cex) 58 UNWIND_HINT_UNDEFINED 59 b cache_parity_error 60SYM_CODE_END(except_vec_cex) 61 62 .macro build_prep_badv 63 csrrd t0, LOONGARCH_CSR_BADV 64 PTR_S t0, sp, PT_BVADDR 65 .endm 66 67 .macro build_prep_fcsr 68 movfcsr2gr a1, fcsr0 69 .endm 70 71 .macro build_prep_none 72 .endm 73 74 .macro BUILD_HANDLER exception handler prep 75 .align 5 76 SYM_CODE_START(handle_\exception) 77 UNWIND_HINT_UNDEFINED 78 666: 79 BACKUP_T0T1 80 SAVE_ALL 81 build_prep_\prep 82 move a0, sp 83 la_abs t0, do_\handler 84 jirl ra, t0, 0 85 668: 86 RESTORE_ALL_AND_RET 87 SYM_CODE_END(handle_\exception) 88 .pushsection ".data", "aw", %progbits 89 SYM_DATA(unwind_hint_\exception, .word 668b - 666b) 90 .popsection 91 .endm 92 93 BUILD_HANDLER ade ade badv 94 BUILD_HANDLER ale ale badv 95 BUILD_HANDLER bce bce none 96 BUILD_HANDLER bp bp none 97 BUILD_HANDLER fpe fpe fcsr 98 BUILD_HANDLER fpu fpu none 99 BUILD_HANDLER lsx lsx none 100 BUILD_HANDLER lasx lasx none 101 BUILD_HANDLER lbt lbt none 102 BUILD_HANDLER ri ri none 103 BUILD_HANDLER watch watch none 104 BUILD_HANDLER reserved reserved none /* others */ 105 106SYM_CODE_START(handle_sys) 107 UNWIND_HINT_UNDEFINED 108 la_abs t0, handle_syscall 109 jr t0 110SYM_CODE_END(handle_sys) 111