]> git.proxmox.com Git - mirror_qemu.git/blob - linux-user/ppc/vdso.S
Merge tag 'pull-tcg-20231114' of https://gitlab.com/rth7680/qemu into staging
[mirror_qemu.git] / linux-user / ppc / vdso.S
1 /*
2 * PowerPC linux replacement vdso.
3 *
4 * Copyright 2023 Linaro, Ltd.
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
9 #include <asm/unistd.h>
10 #include <asm/errno.h>
11
12 #ifndef _ARCH_PPC64
13 # define TARGET_ABI32
14 #endif
15 #include "vdso-asmoffset.h"
16
17
18 .text
19
20 .macro endf name
21 .globl \name
22 .size \name, .-\name
23 /* For PPC64, functions have special linkage; we export pointers. */
24 #ifndef _ARCH_PPC64
25 .type \name, @function
26 #endif
27 .endm
28
29 .macro raw_syscall nr
30 addi 0, 0, \nr
31 sc
32 .endm
33
34 .macro vdso_syscall name, nr
35 \name:
36 raw_syscall \nr
37 blr
38 endf \name
39 .endm
40
41 .cfi_startproc
42
43 vdso_syscall __kernel_gettimeofday, __NR_gettimeofday
44 vdso_syscall __kernel_clock_gettime, __NR_clock_gettime
45 vdso_syscall __kernel_clock_getres, __NR_clock_getres
46 vdso_syscall __kernel_getcpu, __NR_getcpu
47 vdso_syscall __kernel_time, __NR_time
48
49 #ifdef __NR_clock_gettime64
50 vdso_syscall __kernel_clock_gettime64, __NR_clock_gettime64
51 #endif
52
53 __kernel_sync_dicache:
54 /* qemu does not need to flush caches */
55 blr
56 endf __kernel_sync_dicache
57
58 .cfi_endproc
59
60 /*
61 * TODO: __kernel_get_tbfreq
62 * This is probably a constant for QEMU.
63 */
64
65 /*
66 * Start the unwind info at least one instruction before the signal
67 * trampoline, because the unwinder will assume we are returning
68 * after a call site.
69 */
70
71 .cfi_startproc simple
72 .cfi_signal_frame
73
74 #ifdef _ARCH_PPC64
75 # define __kernel_sigtramp_rt __kernel_sigtramp_rt64
76 # define sizeof_reg 8
77 #else
78 # define __kernel_sigtramp_rt __kernel_sigtramp_rt32
79 # define sizeof_reg 4
80 #endif
81 #define sizeof_freg 8
82 #define sizeof_vreg 16
83
84 .cfi_def_cfa 1, SIGNAL_FRAMESIZE + offsetof_rt_sigframe_mcontext
85
86 /* Return address */
87 .cfi_return_column 67
88 .cfi_offset 67, 32 * sizeof_reg /* nip */
89
90 /* Integer registers */
91 .cfi_offset 0, 0 * sizeof_reg
92 .cfi_offset 1, 1 * sizeof_reg
93 .cfi_offset 2, 2 * sizeof_reg
94 .cfi_offset 3, 3 * sizeof_reg
95 .cfi_offset 4, 4 * sizeof_reg
96 .cfi_offset 5, 5 * sizeof_reg
97 .cfi_offset 6, 6 * sizeof_reg
98 .cfi_offset 7, 7 * sizeof_reg
99 .cfi_offset 8, 8 * sizeof_reg
100 .cfi_offset 9, 9 * sizeof_reg
101 .cfi_offset 10, 10 * sizeof_reg
102 .cfi_offset 11, 11 * sizeof_reg
103 .cfi_offset 12, 12 * sizeof_reg
104 .cfi_offset 13, 13 * sizeof_reg
105 .cfi_offset 14, 14 * sizeof_reg
106 .cfi_offset 15, 15 * sizeof_reg
107 .cfi_offset 16, 16 * sizeof_reg
108 .cfi_offset 17, 17 * sizeof_reg
109 .cfi_offset 18, 18 * sizeof_reg
110 .cfi_offset 19, 19 * sizeof_reg
111 .cfi_offset 20, 20 * sizeof_reg
112 .cfi_offset 21, 21 * sizeof_reg
113 .cfi_offset 22, 22 * sizeof_reg
114 .cfi_offset 23, 23 * sizeof_reg
115 .cfi_offset 24, 24 * sizeof_reg
116 .cfi_offset 25, 25 * sizeof_reg
117 .cfi_offset 26, 26 * sizeof_reg
118 .cfi_offset 27, 27 * sizeof_reg
119 .cfi_offset 28, 28 * sizeof_reg
120 .cfi_offset 29, 29 * sizeof_reg
121 .cfi_offset 30, 30 * sizeof_reg
122 .cfi_offset 31, 31 * sizeof_reg
123 .cfi_offset 65, 36 * sizeof_reg /* lr */
124 .cfi_offset 70, 38 * sizeof_reg /* ccr */
125
126 /* Floating point registers */
127 .cfi_offset 32, offsetof_mcontext_fregs
128 .cfi_offset 33, offsetof_mcontext_fregs + 1 * sizeof_freg
129 .cfi_offset 34, offsetof_mcontext_fregs + 2 * sizeof_freg
130 .cfi_offset 35, offsetof_mcontext_fregs + 3 * sizeof_freg
131 .cfi_offset 36, offsetof_mcontext_fregs + 4 * sizeof_freg
132 .cfi_offset 37, offsetof_mcontext_fregs + 5 * sizeof_freg
133 .cfi_offset 38, offsetof_mcontext_fregs + 6 * sizeof_freg
134 .cfi_offset 39, offsetof_mcontext_fregs + 7 * sizeof_freg
135 .cfi_offset 40, offsetof_mcontext_fregs + 8 * sizeof_freg
136 .cfi_offset 41, offsetof_mcontext_fregs + 9 * sizeof_freg
137 .cfi_offset 42, offsetof_mcontext_fregs + 10 * sizeof_freg
138 .cfi_offset 43, offsetof_mcontext_fregs + 11 * sizeof_freg
139 .cfi_offset 44, offsetof_mcontext_fregs + 12 * sizeof_freg
140 .cfi_offset 45, offsetof_mcontext_fregs + 13 * sizeof_freg
141 .cfi_offset 46, offsetof_mcontext_fregs + 14 * sizeof_freg
142 .cfi_offset 47, offsetof_mcontext_fregs + 15 * sizeof_freg
143 .cfi_offset 48, offsetof_mcontext_fregs + 16 * sizeof_freg
144 .cfi_offset 49, offsetof_mcontext_fregs + 17 * sizeof_freg
145 .cfi_offset 50, offsetof_mcontext_fregs + 18 * sizeof_freg
146 .cfi_offset 51, offsetof_mcontext_fregs + 19 * sizeof_freg
147 .cfi_offset 52, offsetof_mcontext_fregs + 20 * sizeof_freg
148 .cfi_offset 53, offsetof_mcontext_fregs + 21 * sizeof_freg
149 .cfi_offset 54, offsetof_mcontext_fregs + 22 * sizeof_freg
150 .cfi_offset 55, offsetof_mcontext_fregs + 23 * sizeof_freg
151 .cfi_offset 56, offsetof_mcontext_fregs + 24 * sizeof_freg
152 .cfi_offset 57, offsetof_mcontext_fregs + 25 * sizeof_freg
153 .cfi_offset 58, offsetof_mcontext_fregs + 26 * sizeof_freg
154 .cfi_offset 59, offsetof_mcontext_fregs + 27 * sizeof_freg
155 .cfi_offset 60, offsetof_mcontext_fregs + 28 * sizeof_freg
156 .cfi_offset 61, offsetof_mcontext_fregs + 29 * sizeof_freg
157 .cfi_offset 62, offsetof_mcontext_fregs + 30 * sizeof_freg
158 .cfi_offset 63, offsetof_mcontext_fregs + 31 * sizeof_freg
159
160 /*
161 * Unlike the kernel, unconditionally represent the Altivec/VSX regs.
162 * The space within the stack frame is always available, and most of
163 * our supported processors have them enabled. The only complication
164 * for PPC64 is the misalignment, so that we have to use indirection.
165 */
166 .macro save_vreg_ofs reg, ofs
167 #ifdef _ARCH_PPC64
168 /*
169 * vreg = *(cfa + offsetof(v_regs)) + ofs
170 *
171 * The CFA is input to the expression on the stack, so:
172 * DW_CFA_expression reg, length (7),
173 * DW_OP_plus_uconst (0x23), vreg_ptr, DW_OP_deref (0x06),
174 * DW_OP_plus_uconst (0x23), ofs
175 */
176 .cfi_escape 0x10, 77 + \reg, 7, 0x23, (offsetof_mcontext_vregs_ptr & 0x7f) + 0x80, offsetof_mcontext_vregs_ptr >> 7, 0x06, 0x23, (\ofs & 0x7f) | 0x80, \ofs >> 7
177 #else
178 .cfi_offset 77 + \reg, offsetof_mcontext_vregs + \ofs
179 #endif
180 .endm
181
182 .macro save_vreg reg
183 save_vreg_ofs \reg, (\reg * sizeof_vreg)
184 .endm
185
186 save_vreg 0
187 save_vreg 1
188 save_vreg 2
189 save_vreg 3
190 save_vreg 4
191 save_vreg 5
192 save_vreg 6
193 save_vreg 7
194 save_vreg 8
195 save_vreg 9
196 save_vreg 10
197 save_vreg 11
198 save_vreg 12
199 save_vreg 13
200 save_vreg 14
201 save_vreg 15
202 save_vreg 16
203 save_vreg 17
204 save_vreg 18
205 save_vreg 19
206 save_vreg 20
207 save_vreg 21
208 save_vreg 22
209 save_vreg 23
210 save_vreg 24
211 save_vreg 25
212 save_vreg 26
213 save_vreg 27
214 save_vreg 28
215 save_vreg 29
216 save_vreg 30
217 save_vreg 31
218 save_vreg 32
219 save_vreg_ofs 33, (32 * sizeof_vreg + 12)
220
221 nop
222
223 __kernel_sigtramp_rt:
224 raw_syscall __NR_rt_sigreturn
225 endf __kernel_sigtramp_rt
226
227 #ifndef _ARCH_PPC64
228 /*
229 * The non-rt sigreturn has the same layout at a different offset.
230 * Move the CFA and leave all othe other descriptions the same.
231 */
232 .cfi_def_cfa 1, SIGNAL_FRAMESIZE + offsetof_sigframe_mcontext
233 nop
234 __kernel_sigtramp32:
235 raw_syscall __NR_sigreturn
236 endf __kernel_sigtramp32
237 #endif
238
239 .cfi_endproc