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

source code of linux/arch/loongarch/kernel/lbt.S