1f50a7f3dSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */
23752e453SMichael Ellerman/*
33752e453SMichael Ellerman * Copyright 2014, Michael Ellerman, IBM Corp.
43752e453SMichael Ellerman */
53752e453SMichael Ellerman
63752e453SMichael Ellerman#include <ppc-asm.h>
73752e453SMichael Ellerman#include "reg.h"
83752e453SMichael Ellerman
93752e453SMichael Ellerman
103752e453SMichael Ellerman/* ppc-asm.h defines most of the reg aliases, but not r1/r2. */
113752e453SMichael Ellerman#define r1 1
123752e453SMichael Ellerman#define r2 2
133752e453SMichael Ellerman
143752e453SMichael Ellerman#define RFEBB   .long 0x4c000924
153752e453SMichael Ellerman
163752e453SMichael Ellerman/* Stack layout:
173752e453SMichael Ellerman *
183752e453SMichael Ellerman *                   ^
193752e453SMichael Ellerman *  User stack       |
203752e453SMichael Ellerman *  Back chain ------+	<- r1		<-------+
213752e453SMichael Ellerman *  ...						|
223752e453SMichael Ellerman *  Red zone / ABI Gap				|
233752e453SMichael Ellerman *  ...						|
243752e453SMichael Ellerman *  vr63	<+				|
253752e453SMichael Ellerman *  vr0		 |				|
263752e453SMichael Ellerman *  VSCR	 |				|
273752e453SMichael Ellerman *  FSCR	 |				|
283752e453SMichael Ellerman *  r31		 | Save area			|
293752e453SMichael Ellerman *  r0		 |				|
303752e453SMichael Ellerman *  XER		 |				|
313752e453SMichael Ellerman *  CTR		 |				|
323752e453SMichael Ellerman *  LR		 |				|
333752e453SMichael Ellerman *  CCR		<+				|
343752e453SMichael Ellerman *  ...		<+				|
353752e453SMichael Ellerman *  LR		 | Caller frame			|
363752e453SMichael Ellerman *  CCR		 |				|
373752e453SMichael Ellerman *  Back chain	<+	<- updated r1	--------+
383752e453SMichael Ellerman *
393752e453SMichael Ellerman */
403752e453SMichael Ellerman
413752e453SMichael Ellerman#if defined(_CALL_ELF) && _CALL_ELF == 2
423752e453SMichael Ellerman#define ABIGAP		512
433752e453SMichael Ellerman#else
443752e453SMichael Ellerman#define ABIGAP		288
453752e453SMichael Ellerman#endif
463752e453SMichael Ellerman
473752e453SMichael Ellerman#define NR_GPR		32
483752e453SMichael Ellerman#define NR_SPR		6
493752e453SMichael Ellerman#define NR_VSR		64
503752e453SMichael Ellerman
513752e453SMichael Ellerman#define SAVE_AREA	((NR_GPR + NR_SPR) * 8 + (NR_VSR * 16))
523752e453SMichael Ellerman#define CALLER_FRAME	112
533752e453SMichael Ellerman
543752e453SMichael Ellerman#define STACK_FRAME	(ABIGAP + SAVE_AREA + CALLER_FRAME)
553752e453SMichael Ellerman
563752e453SMichael Ellerman#define CCR_SAVE	(CALLER_FRAME)
573752e453SMichael Ellerman#define LR_SAVE		(CCR_SAVE + 8)
583752e453SMichael Ellerman#define CTR_SAVE	(LR_SAVE  + 8)
593752e453SMichael Ellerman#define XER_SAVE	(CTR_SAVE + 8)
603752e453SMichael Ellerman#define GPR_SAVE(n)	(XER_SAVE + 8 + (8 * n))
613752e453SMichael Ellerman#define FSCR_SAVE	(GPR_SAVE(31) + 8)
623752e453SMichael Ellerman#define VSCR_SAVE	(FSCR_SAVE + 8)
633752e453SMichael Ellerman#define VSR_SAVE(n)	(VSCR_SAVE + 8 + (16 * n))
643752e453SMichael Ellerman
653752e453SMichael Ellerman#define SAVE_GPR(n)	std n,GPR_SAVE(n)(r1)
663752e453SMichael Ellerman#define REST_GPR(n)	ld  n,GPR_SAVE(n)(r1)
673752e453SMichael Ellerman#define TRASH_GPR(n)	lis n,0xaaaa
683752e453SMichael Ellerman
693752e453SMichael Ellerman#define SAVE_VSR(n, b)	li b, VSR_SAVE(n); stxvd2x n,b,r1
703752e453SMichael Ellerman#define LOAD_VSR(n, b)	li b, VSR_SAVE(n); lxvd2x  n,b,r1
713752e453SMichael Ellerman
723752e453SMichael Ellerman#define LOAD_REG_IMMEDIATE(reg,expr)	\
733752e453SMichael Ellerman	lis     reg,(expr)@highest;	\
743752e453SMichael Ellerman	ori     reg,reg,(expr)@higher;	\
753752e453SMichael Ellerman	rldicr  reg,reg,32,31;		\
763752e453SMichael Ellerman	oris    reg,reg,(expr)@h;	\
773752e453SMichael Ellerman	ori     reg,reg,(expr)@l;
783752e453SMichael Ellerman
793752e453SMichael Ellerman
803752e453SMichael Ellerman#if defined(_CALL_ELF) && _CALL_ELF == 2
813752e453SMichael Ellerman#define ENTRY_POINT(name) \
823752e453SMichael Ellerman	.type FUNC_NAME(name),@function; \
833752e453SMichael Ellerman	.globl FUNC_NAME(name); \
843752e453SMichael Ellerman	FUNC_NAME(name):
853752e453SMichael Ellerman
863752e453SMichael Ellerman#define RESTORE_TOC(name)	\
873752e453SMichael Ellerman	/* Restore our TOC pointer using our entry point */	\
883752e453SMichael Ellerman	LOAD_REG_IMMEDIATE(r12, name)				\
893752e453SMichael Ellerman0:	addis	r2,r12,(.TOC.-0b)@ha;				\
903752e453SMichael Ellerman	addi	r2,r2,(.TOC.-0b)@l;
913752e453SMichael Ellerman
923752e453SMichael Ellerman#else
933752e453SMichael Ellerman#define ENTRY_POINT(name) FUNC_START(name)
943752e453SMichael Ellerman#define RESTORE_TOC(name)	\
953752e453SMichael Ellerman	/* Restore our TOC pointer via our opd entry */	\
963752e453SMichael Ellerman	LOAD_REG_IMMEDIATE(r2, name)			\
973752e453SMichael Ellerman	ld      r2,8(r2);
983752e453SMichael Ellerman#endif
993752e453SMichael Ellerman
1003752e453SMichael Ellerman    .text
1013752e453SMichael Ellerman
1023752e453SMichael EllermanENTRY_POINT(ebb_handler)
1033752e453SMichael Ellerman    stdu    r1,-STACK_FRAME(r1)
1043752e453SMichael Ellerman    SAVE_GPR(0)
1053752e453SMichael Ellerman    mflr    r0
1063752e453SMichael Ellerman    std     r0,LR_SAVE(r1)
1073752e453SMichael Ellerman    mfcr    r0
1083752e453SMichael Ellerman    std     r0,CCR_SAVE(r1)
1093752e453SMichael Ellerman    mfctr   r0
1103752e453SMichael Ellerman    std     r0,CTR_SAVE(r1)
1113752e453SMichael Ellerman    mfxer   r0
1123752e453SMichael Ellerman    std     r0,XER_SAVE(r1)
1133752e453SMichael Ellerman    SAVE_GPR(2)
1143752e453SMichael Ellerman    SAVE_GPR(3)
1153752e453SMichael Ellerman    SAVE_GPR(4)
1163752e453SMichael Ellerman    SAVE_GPR(5)
1173752e453SMichael Ellerman    SAVE_GPR(6)
1183752e453SMichael Ellerman    SAVE_GPR(7)
1193752e453SMichael Ellerman    SAVE_GPR(8)
1203752e453SMichael Ellerman    SAVE_GPR(9)
1213752e453SMichael Ellerman    SAVE_GPR(10)
1223752e453SMichael Ellerman    SAVE_GPR(11)
1233752e453SMichael Ellerman    SAVE_GPR(12)
1243752e453SMichael Ellerman    SAVE_GPR(13)
1253752e453SMichael Ellerman    SAVE_GPR(14)
1263752e453SMichael Ellerman    SAVE_GPR(15)
1273752e453SMichael Ellerman    SAVE_GPR(16)
1283752e453SMichael Ellerman    SAVE_GPR(17)
1293752e453SMichael Ellerman    SAVE_GPR(18)
1303752e453SMichael Ellerman    SAVE_GPR(19)
1313752e453SMichael Ellerman    SAVE_GPR(20)
1323752e453SMichael Ellerman    SAVE_GPR(21)
1333752e453SMichael Ellerman    SAVE_GPR(22)
1343752e453SMichael Ellerman    SAVE_GPR(23)
1353752e453SMichael Ellerman    SAVE_GPR(24)
1363752e453SMichael Ellerman    SAVE_GPR(25)
1373752e453SMichael Ellerman    SAVE_GPR(26)
1383752e453SMichael Ellerman    SAVE_GPR(27)
1393752e453SMichael Ellerman    SAVE_GPR(28)
1403752e453SMichael Ellerman    SAVE_GPR(29)
1413752e453SMichael Ellerman    SAVE_GPR(30)
1423752e453SMichael Ellerman    SAVE_GPR(31)
1433752e453SMichael Ellerman    SAVE_VSR(0, r3)
1443752e453SMichael Ellerman    mffs     f0
1453752e453SMichael Ellerman    stfd     f0, FSCR_SAVE(r1)
1463752e453SMichael Ellerman    mfvscr   f0
1473752e453SMichael Ellerman    stfd     f0, VSCR_SAVE(r1)
1483752e453SMichael Ellerman    SAVE_VSR(1,  r3)
1493752e453SMichael Ellerman    SAVE_VSR(2,  r3)
1503752e453SMichael Ellerman    SAVE_VSR(3,  r3)
1513752e453SMichael Ellerman    SAVE_VSR(4,  r3)
1523752e453SMichael Ellerman    SAVE_VSR(5,  r3)
1533752e453SMichael Ellerman    SAVE_VSR(6,  r3)
1543752e453SMichael Ellerman    SAVE_VSR(7,  r3)
1553752e453SMichael Ellerman    SAVE_VSR(8,  r3)
1563752e453SMichael Ellerman    SAVE_VSR(9,  r3)
1573752e453SMichael Ellerman    SAVE_VSR(10, r3)
1583752e453SMichael Ellerman    SAVE_VSR(11, r3)
1593752e453SMichael Ellerman    SAVE_VSR(12, r3)
1603752e453SMichael Ellerman    SAVE_VSR(13, r3)
1613752e453SMichael Ellerman    SAVE_VSR(14, r3)
1623752e453SMichael Ellerman    SAVE_VSR(15, r3)
1633752e453SMichael Ellerman    SAVE_VSR(16, r3)
1643752e453SMichael Ellerman    SAVE_VSR(17, r3)
1653752e453SMichael Ellerman    SAVE_VSR(18, r3)
1663752e453SMichael Ellerman    SAVE_VSR(19, r3)
1673752e453SMichael Ellerman    SAVE_VSR(20, r3)
1683752e453SMichael Ellerman    SAVE_VSR(21, r3)
1693752e453SMichael Ellerman    SAVE_VSR(22, r3)
1703752e453SMichael Ellerman    SAVE_VSR(23, r3)
1713752e453SMichael Ellerman    SAVE_VSR(24, r3)
1723752e453SMichael Ellerman    SAVE_VSR(25, r3)
1733752e453SMichael Ellerman    SAVE_VSR(26, r3)
1743752e453SMichael Ellerman    SAVE_VSR(27, r3)
1753752e453SMichael Ellerman    SAVE_VSR(28, r3)
1763752e453SMichael Ellerman    SAVE_VSR(29, r3)
1773752e453SMichael Ellerman    SAVE_VSR(30, r3)
1783752e453SMichael Ellerman    SAVE_VSR(31, r3)
1793752e453SMichael Ellerman    SAVE_VSR(32, r3)
1803752e453SMichael Ellerman    SAVE_VSR(33, r3)
1813752e453SMichael Ellerman    SAVE_VSR(34, r3)
1823752e453SMichael Ellerman    SAVE_VSR(35, r3)
1833752e453SMichael Ellerman    SAVE_VSR(36, r3)
1843752e453SMichael Ellerman    SAVE_VSR(37, r3)
1853752e453SMichael Ellerman    SAVE_VSR(38, r3)
1863752e453SMichael Ellerman    SAVE_VSR(39, r3)
1873752e453SMichael Ellerman    SAVE_VSR(40, r3)
1883752e453SMichael Ellerman    SAVE_VSR(41, r3)
1893752e453SMichael Ellerman    SAVE_VSR(42, r3)
1903752e453SMichael Ellerman    SAVE_VSR(43, r3)
1913752e453SMichael Ellerman    SAVE_VSR(44, r3)
1923752e453SMichael Ellerman    SAVE_VSR(45, r3)
1933752e453SMichael Ellerman    SAVE_VSR(46, r3)
1943752e453SMichael Ellerman    SAVE_VSR(47, r3)
1953752e453SMichael Ellerman    SAVE_VSR(48, r3)
1963752e453SMichael Ellerman    SAVE_VSR(49, r3)
1973752e453SMichael Ellerman    SAVE_VSR(50, r3)
1983752e453SMichael Ellerman    SAVE_VSR(51, r3)
1993752e453SMichael Ellerman    SAVE_VSR(52, r3)
2003752e453SMichael Ellerman    SAVE_VSR(53, r3)
2013752e453SMichael Ellerman    SAVE_VSR(54, r3)
2023752e453SMichael Ellerman    SAVE_VSR(55, r3)
2033752e453SMichael Ellerman    SAVE_VSR(56, r3)
2043752e453SMichael Ellerman    SAVE_VSR(57, r3)
2053752e453SMichael Ellerman    SAVE_VSR(58, r3)
2063752e453SMichael Ellerman    SAVE_VSR(59, r3)
2073752e453SMichael Ellerman    SAVE_VSR(60, r3)
2083752e453SMichael Ellerman    SAVE_VSR(61, r3)
2093752e453SMichael Ellerman    SAVE_VSR(62, r3)
2103752e453SMichael Ellerman    SAVE_VSR(63, r3)
2113752e453SMichael Ellerman
2123752e453SMichael Ellerman    TRASH_GPR(2)
2133752e453SMichael Ellerman    TRASH_GPR(3)
2143752e453SMichael Ellerman    TRASH_GPR(4)
2153752e453SMichael Ellerman    TRASH_GPR(5)
2163752e453SMichael Ellerman    TRASH_GPR(6)
2173752e453SMichael Ellerman    TRASH_GPR(7)
2183752e453SMichael Ellerman    TRASH_GPR(8)
2193752e453SMichael Ellerman    TRASH_GPR(9)
2203752e453SMichael Ellerman    TRASH_GPR(10)
2213752e453SMichael Ellerman    TRASH_GPR(11)
2223752e453SMichael Ellerman    TRASH_GPR(12)
2233752e453SMichael Ellerman    TRASH_GPR(14)
2243752e453SMichael Ellerman    TRASH_GPR(15)
2253752e453SMichael Ellerman    TRASH_GPR(16)
2263752e453SMichael Ellerman    TRASH_GPR(17)
2273752e453SMichael Ellerman    TRASH_GPR(18)
2283752e453SMichael Ellerman    TRASH_GPR(19)
2293752e453SMichael Ellerman    TRASH_GPR(20)
2303752e453SMichael Ellerman    TRASH_GPR(21)
2313752e453SMichael Ellerman    TRASH_GPR(22)
2323752e453SMichael Ellerman    TRASH_GPR(23)
2333752e453SMichael Ellerman    TRASH_GPR(24)
2343752e453SMichael Ellerman    TRASH_GPR(25)
2353752e453SMichael Ellerman    TRASH_GPR(26)
2363752e453SMichael Ellerman    TRASH_GPR(27)
2373752e453SMichael Ellerman    TRASH_GPR(28)
2383752e453SMichael Ellerman    TRASH_GPR(29)
2393752e453SMichael Ellerman    TRASH_GPR(30)
2403752e453SMichael Ellerman    TRASH_GPR(31)
2413752e453SMichael Ellerman
2423752e453SMichael Ellerman    RESTORE_TOC(ebb_handler)
2433752e453SMichael Ellerman
2443752e453SMichael Ellerman    /*
2453752e453SMichael Ellerman     * r13 is our TLS pointer. We leave whatever value was in there when the
2463752e453SMichael Ellerman     * EBB fired. That seems to be OK because once set the TLS pointer is not
2473752e453SMichael Ellerman     * changed - but presumably that could change in future.
2483752e453SMichael Ellerman     */
2493752e453SMichael Ellerman
2503752e453SMichael Ellerman    bl      ebb_hook
2513752e453SMichael Ellerman    nop
2523752e453SMichael Ellerman
2533752e453SMichael Ellerman    /* r2 may be changed here but we don't care */
2543752e453SMichael Ellerman
2553752e453SMichael Ellerman    lfd      f0, FSCR_SAVE(r1)
2563752e453SMichael Ellerman    mtfsf    0xff,f0
2573752e453SMichael Ellerman    lfd      f0, VSCR_SAVE(r1)
2583752e453SMichael Ellerman    mtvscr   f0
2593752e453SMichael Ellerman    LOAD_VSR(0, r3)
2603752e453SMichael Ellerman    LOAD_VSR(1,  r3)
2613752e453SMichael Ellerman    LOAD_VSR(2,  r3)
2623752e453SMichael Ellerman    LOAD_VSR(3,  r3)
2633752e453SMichael Ellerman    LOAD_VSR(4,  r3)
2643752e453SMichael Ellerman    LOAD_VSR(5,  r3)
2653752e453SMichael Ellerman    LOAD_VSR(6,  r3)
2663752e453SMichael Ellerman    LOAD_VSR(7,  r3)
2673752e453SMichael Ellerman    LOAD_VSR(8,  r3)
2683752e453SMichael Ellerman    LOAD_VSR(9,  r3)
2693752e453SMichael Ellerman    LOAD_VSR(10, r3)
2703752e453SMichael Ellerman    LOAD_VSR(11, r3)
2713752e453SMichael Ellerman    LOAD_VSR(12, r3)
2723752e453SMichael Ellerman    LOAD_VSR(13, r3)
2733752e453SMichael Ellerman    LOAD_VSR(14, r3)
2743752e453SMichael Ellerman    LOAD_VSR(15, r3)
2753752e453SMichael Ellerman    LOAD_VSR(16, r3)
2763752e453SMichael Ellerman    LOAD_VSR(17, r3)
2773752e453SMichael Ellerman    LOAD_VSR(18, r3)
2783752e453SMichael Ellerman    LOAD_VSR(19, r3)
2793752e453SMichael Ellerman    LOAD_VSR(20, r3)
2803752e453SMichael Ellerman    LOAD_VSR(21, r3)
2813752e453SMichael Ellerman    LOAD_VSR(22, r3)
2823752e453SMichael Ellerman    LOAD_VSR(23, r3)
2833752e453SMichael Ellerman    LOAD_VSR(24, r3)
2843752e453SMichael Ellerman    LOAD_VSR(25, r3)
2853752e453SMichael Ellerman    LOAD_VSR(26, r3)
2863752e453SMichael Ellerman    LOAD_VSR(27, r3)
2873752e453SMichael Ellerman    LOAD_VSR(28, r3)
2883752e453SMichael Ellerman    LOAD_VSR(29, r3)
2893752e453SMichael Ellerman    LOAD_VSR(30, r3)
2903752e453SMichael Ellerman    LOAD_VSR(31, r3)
2913752e453SMichael Ellerman    LOAD_VSR(32, r3)
2923752e453SMichael Ellerman    LOAD_VSR(33, r3)
2933752e453SMichael Ellerman    LOAD_VSR(34, r3)
2943752e453SMichael Ellerman    LOAD_VSR(35, r3)
2953752e453SMichael Ellerman    LOAD_VSR(36, r3)
2963752e453SMichael Ellerman    LOAD_VSR(37, r3)
2973752e453SMichael Ellerman    LOAD_VSR(38, r3)
2983752e453SMichael Ellerman    LOAD_VSR(39, r3)
2993752e453SMichael Ellerman    LOAD_VSR(40, r3)
3003752e453SMichael Ellerman    LOAD_VSR(41, r3)
3013752e453SMichael Ellerman    LOAD_VSR(42, r3)
3023752e453SMichael Ellerman    LOAD_VSR(43, r3)
3033752e453SMichael Ellerman    LOAD_VSR(44, r3)
3043752e453SMichael Ellerman    LOAD_VSR(45, r3)
3053752e453SMichael Ellerman    LOAD_VSR(46, r3)
3063752e453SMichael Ellerman    LOAD_VSR(47, r3)
3073752e453SMichael Ellerman    LOAD_VSR(48, r3)
3083752e453SMichael Ellerman    LOAD_VSR(49, r3)
3093752e453SMichael Ellerman    LOAD_VSR(50, r3)
3103752e453SMichael Ellerman    LOAD_VSR(51, r3)
3113752e453SMichael Ellerman    LOAD_VSR(52, r3)
3123752e453SMichael Ellerman    LOAD_VSR(53, r3)
3133752e453SMichael Ellerman    LOAD_VSR(54, r3)
3143752e453SMichael Ellerman    LOAD_VSR(55, r3)
3153752e453SMichael Ellerman    LOAD_VSR(56, r3)
3163752e453SMichael Ellerman    LOAD_VSR(57, r3)
3173752e453SMichael Ellerman    LOAD_VSR(58, r3)
3183752e453SMichael Ellerman    LOAD_VSR(59, r3)
3193752e453SMichael Ellerman    LOAD_VSR(60, r3)
3203752e453SMichael Ellerman    LOAD_VSR(61, r3)
3213752e453SMichael Ellerman    LOAD_VSR(62, r3)
3223752e453SMichael Ellerman    LOAD_VSR(63, r3)
3233752e453SMichael Ellerman
3243752e453SMichael Ellerman    ld      r0,XER_SAVE(r1)
3253752e453SMichael Ellerman    mtxer   r0
3263752e453SMichael Ellerman    ld      r0,CTR_SAVE(r1)
3273752e453SMichael Ellerman    mtctr   r0
3283752e453SMichael Ellerman    ld      r0,LR_SAVE(r1)
3293752e453SMichael Ellerman    mtlr    r0
3303752e453SMichael Ellerman    ld      r0,CCR_SAVE(r1)
3313752e453SMichael Ellerman    mtcr    r0
3323752e453SMichael Ellerman    REST_GPR(0)
3333752e453SMichael Ellerman    REST_GPR(2)
3343752e453SMichael Ellerman    REST_GPR(3)
3353752e453SMichael Ellerman    REST_GPR(4)
3363752e453SMichael Ellerman    REST_GPR(5)
3373752e453SMichael Ellerman    REST_GPR(6)
3383752e453SMichael Ellerman    REST_GPR(7)
3393752e453SMichael Ellerman    REST_GPR(8)
3403752e453SMichael Ellerman    REST_GPR(9)
3413752e453SMichael Ellerman    REST_GPR(10)
3423752e453SMichael Ellerman    REST_GPR(11)
3433752e453SMichael Ellerman    REST_GPR(12)
3443752e453SMichael Ellerman    REST_GPR(13)
3453752e453SMichael Ellerman    REST_GPR(14)
3463752e453SMichael Ellerman    REST_GPR(15)
3473752e453SMichael Ellerman    REST_GPR(16)
3483752e453SMichael Ellerman    REST_GPR(17)
3493752e453SMichael Ellerman    REST_GPR(18)
3503752e453SMichael Ellerman    REST_GPR(19)
3513752e453SMichael Ellerman    REST_GPR(20)
3523752e453SMichael Ellerman    REST_GPR(21)
3533752e453SMichael Ellerman    REST_GPR(22)
3543752e453SMichael Ellerman    REST_GPR(23)
3553752e453SMichael Ellerman    REST_GPR(24)
3563752e453SMichael Ellerman    REST_GPR(25)
3573752e453SMichael Ellerman    REST_GPR(26)
3583752e453SMichael Ellerman    REST_GPR(27)
3593752e453SMichael Ellerman    REST_GPR(28)
3603752e453SMichael Ellerman    REST_GPR(29)
3613752e453SMichael Ellerman    REST_GPR(30)
3623752e453SMichael Ellerman    REST_GPR(31)
3633752e453SMichael Ellerman    addi    r1,r1,STACK_FRAME
3643752e453SMichael Ellerman    RFEBB
3653752e453SMichael EllermanFUNC_END(ebb_handler)
366