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) \ 89 0: 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 102 ENTRY_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 365 FUNC_END(ebb_handler)
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.