xref: /openbmc/linux/arch/loongarch/kernel/genex.S (revision fd5e9fccbd504c5179ab57ff695c610bca8809d6)
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	.align	5
20SYM_FUNC_START(__arch_cpu_idle)
21	/* start of idle interrupt region */
22	ori	t0, zero, CSR_CRMD_IE
23	/* idle instruction needs irq enabled */
24	csrxchg	t0, t0, LOONGARCH_CSR_CRMD
25	/*
26	 * If an interrupt lands here; between enabling interrupts above and
27	 * going idle on the next instruction, we must *NOT* go idle since the
28	 * interrupt could have set TIF_NEED_RESCHED or caused an timer to need
29	 * reprogramming. Fall through -- see handle_vint() below -- and have
30	 * the idle loop take care of things.
31	 */
32	idle	0
33	/* end of idle interrupt region */
341:	jr	ra
35SYM_FUNC_END(__arch_cpu_idle)
36
37SYM_CODE_START(handle_vint)
38	BACKUP_T0T1
39	SAVE_ALL
40	la_abs	t1, 1b
41	LONG_L	t0, sp, PT_ERA
42	/* 3 instructions idle interrupt region */
43	ori	t0, t0, 0b1100
44	bne	t0, t1, 1f
45	LONG_S	t0, sp, PT_ERA
461:	move	a0, sp
47	move	a1, sp
48	la_abs	t0, do_vint
49	jirl	ra, t0, 0
50	RESTORE_ALL_AND_RET
51SYM_CODE_END(handle_vint)
52
53SYM_CODE_START(except_vec_cex)
54	b	cache_parity_error
55SYM_CODE_END(except_vec_cex)
56
57	.macro	build_prep_badv
58	csrrd	t0, LOONGARCH_CSR_BADV
59	PTR_S	t0, sp, PT_BVADDR
60	.endm
61
62	.macro	build_prep_fcsr
63	movfcsr2gr	a1, fcsr0
64	.endm
65
66	.macro	build_prep_none
67	.endm
68
69	.macro	BUILD_HANDLER exception handler prep
70	.align	5
71	SYM_CODE_START(handle_\exception)
72	666:
73	BACKUP_T0T1
74	SAVE_ALL
75	build_prep_\prep
76	move	a0, sp
77	la_abs	t0, do_\handler
78	jirl	ra, t0, 0
79	668:
80	RESTORE_ALL_AND_RET
81	SYM_CODE_END(handle_\exception)
82	SYM_DATA(unwind_hint_\exception, .word 668b - 666b)
83	.endm
84
85	BUILD_HANDLER ade ade badv
86	BUILD_HANDLER ale ale badv
87	BUILD_HANDLER bce bce none
88	BUILD_HANDLER bp bp none
89	BUILD_HANDLER fpe fpe fcsr
90	BUILD_HANDLER fpu fpu none
91	BUILD_HANDLER lsx lsx none
92	BUILD_HANDLER lasx lasx none
93	BUILD_HANDLER lbt lbt none
94	BUILD_HANDLER ri ri none
95	BUILD_HANDLER watch watch none
96	BUILD_HANDLER reserved reserved none	/* others */
97
98SYM_CODE_START(handle_sys)
99	la_abs	t0, handle_syscall
100	jr	t0
101SYM_CODE_END(handle_sys)
102