xref: /openbmc/linux/arch/loongarch/kernel/genex.S (revision fd5e9fccbd504c5179ab57ff695c610bca8809d6)
10603839bSHuacai Chen/* SPDX-License-Identifier: GPL-2.0 */
20603839bSHuacai Chen/*
30603839bSHuacai Chen * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
40603839bSHuacai Chen *
50603839bSHuacai Chen * Derived from MIPS:
60603839bSHuacai Chen * Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle
70603839bSHuacai Chen * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
80603839bSHuacai Chen * Copyright (C) 2002, 2007  Maciej W. Rozycki
90603839bSHuacai Chen * Copyright (C) 2001, 2012 MIPS Technologies, Inc.  All rights reserved.
100603839bSHuacai Chen */
110603839bSHuacai Chen#include <asm/asm.h>
120603839bSHuacai Chen#include <asm/asmmacro.h>
130603839bSHuacai Chen#include <asm/loongarch.h>
140603839bSHuacai Chen#include <asm/regdef.h>
150603839bSHuacai Chen#include <asm/fpregdef.h>
160603839bSHuacai Chen#include <asm/stackframe.h>
170603839bSHuacai Chen#include <asm/thread_info.h>
180603839bSHuacai Chen
190603839bSHuacai Chen	.align	5
200603839bSHuacai ChenSYM_FUNC_START(__arch_cpu_idle)
21*1dfcc04eSMarco Crivellari	/* start of idle interrupt region */
22*1dfcc04eSMarco Crivellari	ori	t0, zero, CSR_CRMD_IE
23*1dfcc04eSMarco Crivellari	/* idle instruction needs irq enabled */
24*1dfcc04eSMarco Crivellari	csrxchg	t0, t0, LOONGARCH_CSR_CRMD
25*1dfcc04eSMarco Crivellari	/*
26*1dfcc04eSMarco Crivellari	 * If an interrupt lands here; between enabling interrupts above and
27*1dfcc04eSMarco Crivellari	 * going idle on the next instruction, we must *NOT* go idle since the
28*1dfcc04eSMarco Crivellari	 * interrupt could have set TIF_NEED_RESCHED or caused an timer to need
29*1dfcc04eSMarco Crivellari	 * reprogramming. Fall through -- see handle_vint() below -- and have
30*1dfcc04eSMarco Crivellari	 * the idle loop take care of things.
31*1dfcc04eSMarco Crivellari	 */
320603839bSHuacai Chen	idle	0
33*1dfcc04eSMarco Crivellari	/* end of idle interrupt region */
3407b48069SWANG Xuerui1:	jr	ra
350603839bSHuacai ChenSYM_FUNC_END(__arch_cpu_idle)
360603839bSHuacai Chen
3700c2ca84STiezhu YangSYM_CODE_START(handle_vint)
380603839bSHuacai Chen	BACKUP_T0T1
390603839bSHuacai Chen	SAVE_ALL
40*1dfcc04eSMarco Crivellari	la_abs	t1, 1b
410603839bSHuacai Chen	LONG_L	t0, sp, PT_ERA
42*1dfcc04eSMarco Crivellari	/* 3 instructions idle interrupt region */
43*1dfcc04eSMarco Crivellari	ori	t0, t0, 0b1100
440603839bSHuacai Chen	bne	t0, t1, 1f
450603839bSHuacai Chen	LONG_S	t0, sp, PT_ERA
460603839bSHuacai Chen1:	move	a0, sp
470603839bSHuacai Chen	move	a1, sp
48396233c6SYouling Tang	la_abs	t0, do_vint
490603839bSHuacai Chen	jirl	ra, t0, 0
500603839bSHuacai Chen	RESTORE_ALL_AND_RET
5100c2ca84STiezhu YangSYM_CODE_END(handle_vint)
520603839bSHuacai Chen
5300c2ca84STiezhu YangSYM_CODE_START(except_vec_cex)
540603839bSHuacai Chen	b	cache_parity_error
5500c2ca84STiezhu YangSYM_CODE_END(except_vec_cex)
560603839bSHuacai Chen
570603839bSHuacai Chen	.macro	build_prep_badv
580603839bSHuacai Chen	csrrd	t0, LOONGARCH_CSR_BADV
590603839bSHuacai Chen	PTR_S	t0, sp, PT_BVADDR
600603839bSHuacai Chen	.endm
610603839bSHuacai Chen
620603839bSHuacai Chen	.macro	build_prep_fcsr
630603839bSHuacai Chen	movfcsr2gr	a1, fcsr0
640603839bSHuacai Chen	.endm
650603839bSHuacai Chen
660603839bSHuacai Chen	.macro	build_prep_none
670603839bSHuacai Chen	.endm
680603839bSHuacai Chen
690603839bSHuacai Chen	.macro	BUILD_HANDLER exception handler prep
700603839bSHuacai Chen	.align	5
7100c2ca84STiezhu Yang	SYM_CODE_START(handle_\exception)
72dc74a9e8SJinyang He	666:
730603839bSHuacai Chen	BACKUP_T0T1
740603839bSHuacai Chen	SAVE_ALL
750603839bSHuacai Chen	build_prep_\prep
760603839bSHuacai Chen	move	a0, sp
77396233c6SYouling Tang	la_abs	t0, do_\handler
780603839bSHuacai Chen	jirl	ra, t0, 0
79dc74a9e8SJinyang He	668:
800603839bSHuacai Chen	RESTORE_ALL_AND_RET
8100c2ca84STiezhu Yang	SYM_CODE_END(handle_\exception)
82dc74a9e8SJinyang He	SYM_DATA(unwind_hint_\exception, .word 668b - 666b)
830603839bSHuacai Chen	.endm
840603839bSHuacai Chen
850603839bSHuacai Chen	BUILD_HANDLER ade ade badv
860603839bSHuacai Chen	BUILD_HANDLER ale ale badv
87c23e7f01SWANG Xuerui	BUILD_HANDLER bce bce none
880603839bSHuacai Chen	BUILD_HANDLER bp bp none
890603839bSHuacai Chen	BUILD_HANDLER fpe fpe fcsr
900603839bSHuacai Chen	BUILD_HANDLER fpu fpu none
910603839bSHuacai Chen	BUILD_HANDLER lsx lsx none
920603839bSHuacai Chen	BUILD_HANDLER lasx lasx none
930603839bSHuacai Chen	BUILD_HANDLER lbt lbt none
940603839bSHuacai Chen	BUILD_HANDLER ri ri none
950603839bSHuacai Chen	BUILD_HANDLER watch watch none
960603839bSHuacai Chen	BUILD_HANDLER reserved reserved none	/* others */
970603839bSHuacai Chen
9800c2ca84STiezhu YangSYM_CODE_START(handle_sys)
99396233c6SYouling Tang	la_abs	t0, handle_syscall
10007b48069SWANG Xuerui	jr	t0
10100c2ca84STiezhu YangSYM_CODE_END(handle_sys)
102