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 | */ |
26 | SYM_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 |
39 | SYM_FUNC_END(_save_lbt) |
40 | EXPORT_SYMBOL(_save_lbt) |
41 | |
42 | /* |
43 | * Restore a thread's lbt context. |
44 | */ |
45 | SYM_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 |
58 | SYM_FUNC_END(_restore_lbt) |
59 | EXPORT_SYMBOL(_restore_lbt) |
60 | |
61 | /* |
62 | * Load scr/eflag with zero. |
63 | */ |
64 | SYM_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 |
72 | SYM_FUNC_END(_init_lbt) |
73 | |
74 | /* |
75 | * a0: scr |
76 | * a1: eflag |
77 | */ |
78 | SYM_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 |
92 | SYM_FUNC_END(_save_lbt_context) |
93 | |
94 | /* |
95 | * a0: scr |
96 | * a1: eflag |
97 | */ |
98 | SYM_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 |
112 | SYM_FUNC_END(_restore_lbt_context) |
113 | |
114 | /* |
115 | * a0: ftop |
116 | */ |
117 | SYM_FUNC_START(_save_ftop_context) |
118 | x86mftop t1 |
119 | st.w t1, a0, 0 |
120 | li.w a0, 0 # success |
121 | jr ra |
122 | SYM_FUNC_END(_save_ftop_context) |
123 | |
124 | /* |
125 | * a0: ftop |
126 | */ |
127 | SYM_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 |
133 | 1: |
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 |
149 | 2: |
150 | li.w a0, 0 # success |
151 | jr ra |
152 | SYM_FUNC_END(_restore_ftop_context) |
153 | |
154 | .L_lbt_fault: |
155 | li.w a0, -EFAULT # failure |
156 | jr ra |
157 | |
158 | STACK_FRAME_NON_STANDARD _restore_ftop_context |
159 | |