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