xref: /linux/arch/loongarch/kernel/lbt.S (revision 24168c5e6dfbdd5b414f048f47f75d64533296ca)
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Author: Qi Hu <huqi@loongson.cn>
4 *         Huacai Chen <chenhuacai@loongson.cn>
5 *
6 * Copyright (C) 2020-2023 Loongson Technology Corporation Limited
7 */
8#include <asm/asm.h>
9#include <asm/asmmacro.h>
10#include <asm/asm-extable.h>
11#include <asm/asm-offsets.h>
12#include <asm/errno.h>
13#include <asm/regdef.h>
14#include <asm/unwind_hints.h>
15
16#define SCR_REG_WIDTH 8
17
18	.macro	EX insn, reg, src, offs
19.ex\@:	\insn	\reg, \src, \offs
20	_asm_extable .ex\@, .L_lbt_fault
21	.endm
22
23/*
24 * Save a thread's lbt context.
25 */
26SYM_FUNC_START(_save_lbt)
27	movscr2gr	t1, $scr0		# save scr
28	stptr.d		t1, a0, THREAD_SCR0
29	movscr2gr	t1, $scr1
30	stptr.d		t1, a0, THREAD_SCR1
31	movscr2gr	t1, $scr2
32	stptr.d		t1, a0, THREAD_SCR2
33	movscr2gr	t1, $scr3
34	stptr.d		t1, a0, THREAD_SCR3
35
36	x86mfflag	t1, 0x3f		# save eflags
37	stptr.d		t1, a0, THREAD_EFLAGS
38	jr		ra
39SYM_FUNC_END(_save_lbt)
40EXPORT_SYMBOL(_save_lbt)
41
42/*
43 * Restore a thread's lbt context.
44 */
45SYM_FUNC_START(_restore_lbt)
46	ldptr.d		t1, a0, THREAD_SCR0	# restore scr
47	movgr2scr	$scr0, t1
48	ldptr.d		t1, a0, THREAD_SCR1
49	movgr2scr	$scr1, t1
50	ldptr.d		t1, a0, THREAD_SCR2
51	movgr2scr	$scr2, t1
52	ldptr.d		t1, a0, THREAD_SCR3
53	movgr2scr	$scr3, t1
54
55	ldptr.d		t1, a0, THREAD_EFLAGS	# restore eflags
56	x86mtflag	t1, 0x3f
57	jr		ra
58SYM_FUNC_END(_restore_lbt)
59EXPORT_SYMBOL(_restore_lbt)
60
61/*
62 * Load scr/eflag with zero.
63 */
64SYM_FUNC_START(_init_lbt)
65	movgr2scr	$scr0, zero
66	movgr2scr	$scr1, zero
67	movgr2scr	$scr2, zero
68	movgr2scr	$scr3, zero
69
70	x86mtflag	zero, 0x3f
71	jr		ra
72SYM_FUNC_END(_init_lbt)
73
74/*
75 * a0: scr
76 * a1: eflag
77 */
78SYM_FUNC_START(_save_lbt_context)
79	movscr2gr	t1, $scr0		# save scr
80	EX	st.d	t1, a0, (0 * SCR_REG_WIDTH)
81	movscr2gr	t1, $scr1
82	EX	st.d	t1, a0, (1 * SCR_REG_WIDTH)
83	movscr2gr	t1, $scr2
84	EX	st.d	t1, a0, (2 * SCR_REG_WIDTH)
85	movscr2gr	t1, $scr3
86	EX	st.d	t1, a0, (3 * SCR_REG_WIDTH)
87
88	x86mfflag	t1, 0x3f		# save eflags
89	EX 	st.w	t1, a1, 0
90	li.w		a0, 0			# success
91	jr		ra
92SYM_FUNC_END(_save_lbt_context)
93
94/*
95 * a0: scr
96 * a1: eflag
97 */
98SYM_FUNC_START(_restore_lbt_context)
99	EX	ld.d	t1, a0, (0 * SCR_REG_WIDTH)	# restore scr
100	movgr2scr	$scr0, t1
101	EX	ld.d	t1, a0, (1 * SCR_REG_WIDTH)
102	movgr2scr	$scr1, t1
103	EX	ld.d	t1, a0, (2 * SCR_REG_WIDTH)
104	movgr2scr	$scr2, t1
105	EX	ld.d	t1, a0, (3 * SCR_REG_WIDTH)
106	movgr2scr	$scr3, t1
107
108	EX 	ld.w	t1, a1, 0			# restore eflags
109	x86mtflag	t1, 0x3f
110	li.w		a0, 0			# success
111	jr		ra
112SYM_FUNC_END(_restore_lbt_context)
113
114/*
115 * a0: ftop
116 */
117SYM_FUNC_START(_save_ftop_context)
118	x86mftop	t1
119	st.w		t1, a0, 0
120	li.w		a0, 0			# success
121	jr		ra
122SYM_FUNC_END(_save_ftop_context)
123
124/*
125 * a0: ftop
126 */
127SYM_FUNC_START(_restore_ftop_context)
128	ld.w		t1, a0, 0
129	andi		t1, t1, 0x7
130	la.pcrel	a0, 1f
131	alsl.d		a0, t1, a0, 3
132	jr		a0
1331:
134	x86mttop	0
135	b	2f
136	x86mttop	1
137	b	2f
138	x86mttop	2
139	b	2f
140	x86mttop	3
141	b	2f
142	x86mttop	4
143	b	2f
144	x86mttop	5
145	b	2f
146	x86mttop	6
147	b	2f
148	x86mttop	7
1492:
150	li.w		a0, 0			# success
151	jr		ra
152SYM_FUNC_END(_restore_ftop_context)
153
154.L_lbt_fault:
155	li.w		a0, -EFAULT		# failure
156	jr		ra
157
158STACK_FRAME_NON_STANDARD _restore_ftop_context
159