1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright 2014, Michael Ellerman, IBM Corp.
4 */
5
6#include <ppc-asm.h>
7#include "reg.h"
8
9
10/* ppc-asm.h defines most of the reg aliases, but not r1/r2. */
11#define r1 1
12#define r2 2
13
14#define RFEBB .long 0x4c000924
15
16/* Stack layout:
17 *
18 * ^
19 * User stack |
20 * Back chain ------+ <- r1 <-------+
21 * ... |
22 * Red zone / ABI Gap |
23 * ... |
24 * vr63 <+ |
25 * vr0 | |
26 * VSCR | |
27 * FSCR | |
28 * r31 | Save area |
29 * r0 | |
30 * XER | |
31 * CTR | |
32 * LR | |
33 * CCR <+ |
34 * ... <+ |
35 * LR | Caller frame |
36 * CCR | |
37 * Back chain <+ <- updated r1 --------+
38 *
39 */
40
41#if defined(_CALL_ELF) && _CALL_ELF == 2
42#define ABIGAP 512
43#else
44#define ABIGAP 288
45#endif
46
47#define NR_GPR 32
48#define NR_SPR 6
49#define NR_VSR 64
50
51#define SAVE_AREA ((NR_GPR + NR_SPR) * 8 + (NR_VSR * 16))
52#define CALLER_FRAME 112
53
54#define STACK_FRAME (ABIGAP + SAVE_AREA + CALLER_FRAME)
55
56#define CCR_SAVE (CALLER_FRAME)
57#define LR_SAVE (CCR_SAVE + 8)
58#define CTR_SAVE (LR_SAVE + 8)
59#define XER_SAVE (CTR_SAVE + 8)
60#define GPR_SAVE(n) (XER_SAVE + 8 + (8 * n))
61#define FSCR_SAVE (GPR_SAVE(31) + 8)
62#define VSCR_SAVE (FSCR_SAVE + 8)
63#define VSR_SAVE(n) (VSCR_SAVE + 8 + (16 * n))
64
65#define SAVE_GPR(n) std n,GPR_SAVE(n)(r1)
66#define REST_GPR(n) ld n,GPR_SAVE(n)(r1)
67#define TRASH_GPR(n) lis n,0xaaaa
68
69#define SAVE_VSR(n, b) li b, VSR_SAVE(n); stxvd2x n,b,r1
70#define LOAD_VSR(n, b) li b, VSR_SAVE(n); lxvd2x n,b,r1
71
72#define LOAD_REG_IMMEDIATE(reg,expr) \
73 lis reg,(expr)@highest; \
74 ori reg,reg,(expr)@higher; \
75 rldicr reg,reg,32,31; \
76 oris reg,reg,(expr)@h; \
77 ori reg,reg,(expr)@l;
78
79
80#if defined(_CALL_ELF) && _CALL_ELF == 2
81#define ENTRY_POINT(name) \
82 .type FUNC_NAME(name),@function; \
83 .globl FUNC_NAME(name); \
84 FUNC_NAME(name):
85
86#define RESTORE_TOC(name) \
87 /* Restore our TOC pointer using our entry point */ \
88 LOAD_REG_IMMEDIATE(r12, name) \
890: addis r2,r12,(.TOC.-0b)@ha; \
90 addi r2,r2,(.TOC.-0b)@l;
91
92#else
93#define ENTRY_POINT(name) FUNC_START(name)
94#define RESTORE_TOC(name) \
95 /* Restore our TOC pointer via our opd entry */ \
96 LOAD_REG_IMMEDIATE(r2, name) \
97 ld r2,8(r2);
98#endif
99
100 .text
101
102ENTRY_POINT(ebb_handler)
103 stdu r1,-STACK_FRAME(r1)
104 SAVE_GPR(0)
105 mflr r0
106 std r0,LR_SAVE(r1)
107 mfcr r0
108 std r0,CCR_SAVE(r1)
109 mfctr r0
110 std r0,CTR_SAVE(r1)
111 mfxer r0
112 std r0,XER_SAVE(r1)
113 SAVE_GPR(2)
114 SAVE_GPR(3)
115 SAVE_GPR(4)
116 SAVE_GPR(5)
117 SAVE_GPR(6)
118 SAVE_GPR(7)
119 SAVE_GPR(8)
120 SAVE_GPR(9)
121 SAVE_GPR(10)
122 SAVE_GPR(11)
123 SAVE_GPR(12)
124 SAVE_GPR(13)
125 SAVE_GPR(14)
126 SAVE_GPR(15)
127 SAVE_GPR(16)
128 SAVE_GPR(17)
129 SAVE_GPR(18)
130 SAVE_GPR(19)
131 SAVE_GPR(20)
132 SAVE_GPR(21)
133 SAVE_GPR(22)
134 SAVE_GPR(23)
135 SAVE_GPR(24)
136 SAVE_GPR(25)
137 SAVE_GPR(26)
138 SAVE_GPR(27)
139 SAVE_GPR(28)
140 SAVE_GPR(29)
141 SAVE_GPR(30)
142 SAVE_GPR(31)
143 SAVE_VSR(0, r3)
144 mffs f0
145 stfd f0, FSCR_SAVE(r1)
146 mfvscr f0
147 stfd f0, VSCR_SAVE(r1)
148 SAVE_VSR(1, r3)
149 SAVE_VSR(2, r3)
150 SAVE_VSR(3, r3)
151 SAVE_VSR(4, r3)
152 SAVE_VSR(5, r3)
153 SAVE_VSR(6, r3)
154 SAVE_VSR(7, r3)
155 SAVE_VSR(8, r3)
156 SAVE_VSR(9, r3)
157 SAVE_VSR(10, r3)
158 SAVE_VSR(11, r3)
159 SAVE_VSR(12, r3)
160 SAVE_VSR(13, r3)
161 SAVE_VSR(14, r3)
162 SAVE_VSR(15, r3)
163 SAVE_VSR(16, r3)
164 SAVE_VSR(17, r3)
165 SAVE_VSR(18, r3)
166 SAVE_VSR(19, r3)
167 SAVE_VSR(20, r3)
168 SAVE_VSR(21, r3)
169 SAVE_VSR(22, r3)
170 SAVE_VSR(23, r3)
171 SAVE_VSR(24, r3)
172 SAVE_VSR(25, r3)
173 SAVE_VSR(26, r3)
174 SAVE_VSR(27, r3)
175 SAVE_VSR(28, r3)
176 SAVE_VSR(29, r3)
177 SAVE_VSR(30, r3)
178 SAVE_VSR(31, r3)
179 SAVE_VSR(32, r3)
180 SAVE_VSR(33, r3)
181 SAVE_VSR(34, r3)
182 SAVE_VSR(35, r3)
183 SAVE_VSR(36, r3)
184 SAVE_VSR(37, r3)
185 SAVE_VSR(38, r3)
186 SAVE_VSR(39, r3)
187 SAVE_VSR(40, r3)
188 SAVE_VSR(41, r3)
189 SAVE_VSR(42, r3)
190 SAVE_VSR(43, r3)
191 SAVE_VSR(44, r3)
192 SAVE_VSR(45, r3)
193 SAVE_VSR(46, r3)
194 SAVE_VSR(47, r3)
195 SAVE_VSR(48, r3)
196 SAVE_VSR(49, r3)
197 SAVE_VSR(50, r3)
198 SAVE_VSR(51, r3)
199 SAVE_VSR(52, r3)
200 SAVE_VSR(53, r3)
201 SAVE_VSR(54, r3)
202 SAVE_VSR(55, r3)
203 SAVE_VSR(56, r3)
204 SAVE_VSR(57, r3)
205 SAVE_VSR(58, r3)
206 SAVE_VSR(59, r3)
207 SAVE_VSR(60, r3)
208 SAVE_VSR(61, r3)
209 SAVE_VSR(62, r3)
210 SAVE_VSR(63, r3)
211
212 TRASH_GPR(2)
213 TRASH_GPR(3)
214 TRASH_GPR(4)
215 TRASH_GPR(5)
216 TRASH_GPR(6)
217 TRASH_GPR(7)
218 TRASH_GPR(8)
219 TRASH_GPR(9)
220 TRASH_GPR(10)
221 TRASH_GPR(11)
222 TRASH_GPR(12)
223 TRASH_GPR(14)
224 TRASH_GPR(15)
225 TRASH_GPR(16)
226 TRASH_GPR(17)
227 TRASH_GPR(18)
228 TRASH_GPR(19)
229 TRASH_GPR(20)
230 TRASH_GPR(21)
231 TRASH_GPR(22)
232 TRASH_GPR(23)
233 TRASH_GPR(24)
234 TRASH_GPR(25)
235 TRASH_GPR(26)
236 TRASH_GPR(27)
237 TRASH_GPR(28)
238 TRASH_GPR(29)
239 TRASH_GPR(30)
240 TRASH_GPR(31)
241
242 RESTORE_TOC(ebb_handler)
243
244 /*
245 * r13 is our TLS pointer. We leave whatever value was in there when the
246 * EBB fired. That seems to be OK because once set the TLS pointer is not
247 * changed - but presumably that could change in future.
248 */
249
250 bl ebb_hook
251 nop
252
253 /* r2 may be changed here but we don't care */
254
255 lfd f0, FSCR_SAVE(r1)
256 mtfsf 0xff,f0
257 lfd f0, VSCR_SAVE(r1)
258 mtvscr f0
259 LOAD_VSR(0, r3)
260 LOAD_VSR(1, r3)
261 LOAD_VSR(2, r3)
262 LOAD_VSR(3, r3)
263 LOAD_VSR(4, r3)
264 LOAD_VSR(5, r3)
265 LOAD_VSR(6, r3)
266 LOAD_VSR(7, r3)
267 LOAD_VSR(8, r3)
268 LOAD_VSR(9, r3)
269 LOAD_VSR(10, r3)
270 LOAD_VSR(11, r3)
271 LOAD_VSR(12, r3)
272 LOAD_VSR(13, r3)
273 LOAD_VSR(14, r3)
274 LOAD_VSR(15, r3)
275 LOAD_VSR(16, r3)
276 LOAD_VSR(17, r3)
277 LOAD_VSR(18, r3)
278 LOAD_VSR(19, r3)
279 LOAD_VSR(20, r3)
280 LOAD_VSR(21, r3)
281 LOAD_VSR(22, r3)
282 LOAD_VSR(23, r3)
283 LOAD_VSR(24, r3)
284 LOAD_VSR(25, r3)
285 LOAD_VSR(26, r3)
286 LOAD_VSR(27, r3)
287 LOAD_VSR(28, r3)
288 LOAD_VSR(29, r3)
289 LOAD_VSR(30, r3)
290 LOAD_VSR(31, r3)
291 LOAD_VSR(32, r3)
292 LOAD_VSR(33, r3)
293 LOAD_VSR(34, r3)
294 LOAD_VSR(35, r3)
295 LOAD_VSR(36, r3)
296 LOAD_VSR(37, r3)
297 LOAD_VSR(38, r3)
298 LOAD_VSR(39, r3)
299 LOAD_VSR(40, r3)
300 LOAD_VSR(41, r3)
301 LOAD_VSR(42, r3)
302 LOAD_VSR(43, r3)
303 LOAD_VSR(44, r3)
304 LOAD_VSR(45, r3)
305 LOAD_VSR(46, r3)
306 LOAD_VSR(47, r3)
307 LOAD_VSR(48, r3)
308 LOAD_VSR(49, r3)
309 LOAD_VSR(50, r3)
310 LOAD_VSR(51, r3)
311 LOAD_VSR(52, r3)
312 LOAD_VSR(53, r3)
313 LOAD_VSR(54, r3)
314 LOAD_VSR(55, r3)
315 LOAD_VSR(56, r3)
316 LOAD_VSR(57, r3)
317 LOAD_VSR(58, r3)
318 LOAD_VSR(59, r3)
319 LOAD_VSR(60, r3)
320 LOAD_VSR(61, r3)
321 LOAD_VSR(62, r3)
322 LOAD_VSR(63, r3)
323
324 ld r0,XER_SAVE(r1)
325 mtxer r0
326 ld r0,CTR_SAVE(r1)
327 mtctr r0
328 ld r0,LR_SAVE(r1)
329 mtlr r0
330 ld r0,CCR_SAVE(r1)
331 mtcr r0
332 REST_GPR(0)
333 REST_GPR(2)
334 REST_GPR(3)
335 REST_GPR(4)
336 REST_GPR(5)
337 REST_GPR(6)
338 REST_GPR(7)
339 REST_GPR(8)
340 REST_GPR(9)
341 REST_GPR(10)
342 REST_GPR(11)
343 REST_GPR(12)
344 REST_GPR(13)
345 REST_GPR(14)
346 REST_GPR(15)
347 REST_GPR(16)
348 REST_GPR(17)
349 REST_GPR(18)
350 REST_GPR(19)
351 REST_GPR(20)
352 REST_GPR(21)
353 REST_GPR(22)
354 REST_GPR(23)
355 REST_GPR(24)
356 REST_GPR(25)
357 REST_GPR(26)
358 REST_GPR(27)
359 REST_GPR(28)
360 REST_GPR(29)
361 REST_GPR(30)
362 REST_GPR(31)
363 addi r1,r1,STACK_FRAME
364 RFEBB
365FUNC_END(ebb_handler)
366

source code of linux/tools/testing/selftests/powerpc/pmu/ebb/ebb_handler.S