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