Linux 6.7-rc7
[linux-modified.git] / arch / loongarch / kernel / lbt.S
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  */
25 SYM_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
38 SYM_FUNC_END(_save_lbt)
39 EXPORT_SYMBOL(_save_lbt)
40
41 /*
42  * Restore a thread's lbt context.
43  */
44 SYM_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
57 SYM_FUNC_END(_restore_lbt)
58 EXPORT_SYMBOL(_restore_lbt)
59
60 /*
61  * Load scr/eflag with zero.
62  */
63 SYM_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
71 SYM_FUNC_END(_init_lbt)
72
73 /*
74  * a0: scr
75  * a1: eflag
76  */
77 SYM_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
91 SYM_FUNC_END(_save_lbt_context)
92
93 /*
94  * a0: scr
95  * a1: eflag
96  */
97 SYM_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
111 SYM_FUNC_END(_restore_lbt_context)
112
113 /*
114  * a0: ftop
115  */
116 SYM_FUNC_START(_save_ftop_context)
117         x86mftop        t1
118         st.w            t1, a0, 0
119         li.w            a0, 0                   # success
120         jr              ra
121 SYM_FUNC_END(_save_ftop_context)
122
123 /*
124  * a0: ftop
125  */
126 SYM_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
132 1:
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
148 2:
149         li.w            a0, 0                   # success
150         jr              ra
151 SYM_FUNC_END(_restore_ftop_context)
152
153 .L_lbt_fault:
154         li.w            a0, -EFAULT             # failure
155         jr              ra