LoongArch: Add ORC stack unwinder support
[linux-2.6-microblaze.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 #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