366 lines · plain
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 112#define r2 213 14#define RFEBB .long 0x4c00092415 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 == 242#define ABIGAP 51243#else44#define ABIGAP 28845#endif46 47#define NR_GPR 3248#define NR_SPR 649#define NR_VSR 6450 51#define SAVE_AREA ((NR_GPR + NR_SPR) * 8 + (NR_VSR * 16))52#define CALLER_FRAME 11253 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,0xaaaa68 69#define SAVE_VSR(n, b) li b, VSR_SAVE(n); stxvd2x n,b,r170#define LOAD_VSR(n, b) li b, VSR_SAVE(n); lxvd2x n,b,r171 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 == 281#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#else93#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#endif99 100 .text101 102ENTRY_POINT(ebb_handler)103 stdu r1,-STACK_FRAME(r1)104 SAVE_GPR(0)105 mflr r0106 std r0,LR_SAVE(r1)107 mfcr r0108 std r0,CCR_SAVE(r1)109 mfctr r0110 std r0,CTR_SAVE(r1)111 mfxer r0112 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 f0145 stfd f0, FSCR_SAVE(r1)146 mfvscr f0147 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 the246 * EBB fired. That seems to be OK because once set the TLS pointer is not247 * changed - but presumably that could change in future.248 */249 250 bl ebb_hook251 nop252 253 /* r2 may be changed here but we don't care */254 255 lfd f0, FSCR_SAVE(r1)256 mtfsf 0xff,f0257 lfd f0, VSCR_SAVE(r1)258 mtvscr f0259 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 r0326 ld r0,CTR_SAVE(r1)327 mtctr r0328 ld r0,LR_SAVE(r1)329 mtlr r0330 ld r0,CCR_SAVE(r1)331 mtcr r0332 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_FRAME364 RFEBB365FUNC_END(ebb_handler)366