xref: /linux/arch/loongarch/kernel/lbt.S (revision e742bd199092e4991b559ca63d565457b519153a)
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)
93EXPORT_SYMBOL_GPL(_save_lbt_context)
94
95/*
96 * a0: scr
97 * a1: eflag
98 */
99SYM_FUNC_START(_restore_lbt_context)
100	EX	ld.d	t1, a0, (0 * SCR_REG_WIDTH)	# restore scr
101	movgr2scr	$scr0, t1
102	EX	ld.d	t1, a0, (1 * SCR_REG_WIDTH)
103	movgr2scr	$scr1, t1
104	EX	ld.d	t1, a0, (2 * SCR_REG_WIDTH)
105	movgr2scr	$scr2, t1
106	EX	ld.d	t1, a0, (3 * SCR_REG_WIDTH)
107	movgr2scr	$scr3, t1
108
109	EX 	ld.w	t1, a1, 0			# restore eflags
110	x86mtflag	t1, 0x3f
111	li.w		a0, 0			# success
112	jr		ra
113SYM_FUNC_END(_restore_lbt_context)
114EXPORT_SYMBOL_GPL(_restore_lbt_context)
115
116/*
117 * a0: ftop
118 */
119SYM_FUNC_START(_save_ftop_context)
120	x86mftop	t1
121	st.w		t1, a0, 0
122	li.w		a0, 0			# success
123	jr		ra
124SYM_FUNC_END(_save_ftop_context)
125EXPORT_SYMBOL_GPL(_save_ftop_context)
126
127/*
128 * a0: ftop
129 */
130SYM_FUNC_START(_restore_ftop_context)
131	ld.w		t1, a0, 0
132	andi		t1, t1, 0x7
133	la.pcrel	a0, 1f
134	alsl.d		a0, t1, a0, 3
135	jr		a0
1361:
137	x86mttop	0
138	b	2f
139	x86mttop	1
140	b	2f
141	x86mttop	2
142	b	2f
143	x86mttop	3
144	b	2f
145	x86mttop	4
146	b	2f
147	x86mttop	5
148	b	2f
149	x86mttop	6
150	b	2f
151	x86mttop	7
1522:
153	li.w		a0, 0			# success
154	jr		ra
155SYM_FUNC_END(_restore_ftop_context)
156EXPORT_SYMBOL_GPL(_restore_ftop_context)
157
158.L_lbt_fault:
159	li.w		a0, -EFAULT		# failure
160	jr		ra
161
162STACK_FRAME_NON_STANDARD _restore_ftop_context
163