Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright 2014, Michael Ellerman, IBM Corp.
0004  */
0005 
0006 #include <ppc-asm.h>
0007 #include "reg.h"
0008 
0009 
0010 /* ppc-asm.h defines most of the reg aliases, but not r1/r2. */
0011 #define r1 1
0012 #define r2 2
0013 
0014 #define RFEBB   .long 0x4c000924
0015 
0016 /* Stack layout:
0017  *
0018  *                   ^
0019  *  User stack       |
0020  *  Back chain ------+  <- r1       <-------+
0021  *  ...                     |
0022  *  Red zone / ABI Gap              |
0023  *  ...                     |
0024  *  vr63    <+              |
0025  *  vr0      |              |
0026  *  VSCR     |              |
0027  *  FSCR     |              |
0028  *  r31      | Save area            |
0029  *  r0       |              |
0030  *  XER      |              |
0031  *  CTR      |              |
0032  *  LR       |              |
0033  *  CCR     <+              |
0034  *  ...     <+              |
0035  *  LR       | Caller frame         |
0036  *  CCR      |              |
0037  *  Back chain  <+  <- updated r1   --------+
0038  *
0039  */
0040 
0041 #if defined(_CALL_ELF) && _CALL_ELF == 2
0042 #define ABIGAP      512
0043 #else
0044 #define ABIGAP      288
0045 #endif
0046 
0047 #define NR_GPR      32
0048 #define NR_SPR      6
0049 #define NR_VSR      64
0050 
0051 #define SAVE_AREA   ((NR_GPR + NR_SPR) * 8 + (NR_VSR * 16))
0052 #define CALLER_FRAME    112
0053 
0054 #define STACK_FRAME (ABIGAP + SAVE_AREA + CALLER_FRAME)
0055 
0056 #define CCR_SAVE    (CALLER_FRAME)
0057 #define LR_SAVE     (CCR_SAVE + 8)
0058 #define CTR_SAVE    (LR_SAVE  + 8)
0059 #define XER_SAVE    (CTR_SAVE + 8)
0060 #define GPR_SAVE(n) (XER_SAVE + 8 + (8 * n))
0061 #define FSCR_SAVE   (GPR_SAVE(31) + 8)
0062 #define VSCR_SAVE   (FSCR_SAVE + 8)
0063 #define VSR_SAVE(n) (VSCR_SAVE + 8 + (16 * n))
0064 
0065 #define SAVE_GPR(n) std n,GPR_SAVE(n)(r1)
0066 #define REST_GPR(n) ld  n,GPR_SAVE(n)(r1)
0067 #define TRASH_GPR(n)    lis n,0xaaaa
0068 
0069 #define SAVE_VSR(n, b)  li b, VSR_SAVE(n); stxvd2x n,b,r1
0070 #define LOAD_VSR(n, b)  li b, VSR_SAVE(n); lxvd2x  n,b,r1
0071 
0072 #define LOAD_REG_IMMEDIATE(reg,expr)    \
0073     lis     reg,(expr)@highest; \
0074     ori     reg,reg,(expr)@higher;  \
0075     rldicr  reg,reg,32,31;      \
0076     oris    reg,reg,(expr)@h;   \
0077     ori     reg,reg,(expr)@l;
0078 
0079 
0080 #if defined(_CALL_ELF) && _CALL_ELF == 2
0081 #define ENTRY_POINT(name) \
0082     .type FUNC_NAME(name),@function; \
0083     .globl FUNC_NAME(name); \
0084     FUNC_NAME(name):
0085 
0086 #define RESTORE_TOC(name)   \
0087     /* Restore our TOC pointer using our entry point */ \
0088     LOAD_REG_IMMEDIATE(r12, name)               \
0089 0:  addis   r2,r12,(.TOC.-0b)@ha;               \
0090     addi    r2,r2,(.TOC.-0b)@l;
0091 
0092 #else
0093 #define ENTRY_POINT(name) FUNC_START(name)
0094 #define RESTORE_TOC(name)   \
0095     /* Restore our TOC pointer via our opd entry */ \
0096     LOAD_REG_IMMEDIATE(r2, name)            \
0097     ld      r2,8(r2);
0098 #endif
0099 
0100     .text
0101 
0102 ENTRY_POINT(ebb_handler)
0103     stdu    r1,-STACK_FRAME(r1)
0104     SAVE_GPR(0)
0105     mflr    r0
0106     std     r0,LR_SAVE(r1)
0107     mfcr    r0
0108     std     r0,CCR_SAVE(r1)
0109     mfctr   r0
0110     std     r0,CTR_SAVE(r1)
0111     mfxer   r0
0112     std     r0,XER_SAVE(r1)
0113     SAVE_GPR(2)
0114     SAVE_GPR(3)
0115     SAVE_GPR(4)
0116     SAVE_GPR(5)
0117     SAVE_GPR(6)
0118     SAVE_GPR(7)
0119     SAVE_GPR(8)
0120     SAVE_GPR(9)
0121     SAVE_GPR(10)
0122     SAVE_GPR(11)
0123     SAVE_GPR(12)
0124     SAVE_GPR(13)
0125     SAVE_GPR(14)
0126     SAVE_GPR(15)
0127     SAVE_GPR(16)
0128     SAVE_GPR(17)
0129     SAVE_GPR(18)
0130     SAVE_GPR(19)
0131     SAVE_GPR(20)
0132     SAVE_GPR(21)
0133     SAVE_GPR(22)
0134     SAVE_GPR(23)
0135     SAVE_GPR(24)
0136     SAVE_GPR(25)
0137     SAVE_GPR(26)
0138     SAVE_GPR(27)
0139     SAVE_GPR(28)
0140     SAVE_GPR(29)
0141     SAVE_GPR(30)
0142     SAVE_GPR(31)
0143     SAVE_VSR(0, r3)
0144     mffs     f0
0145     stfd     f0, FSCR_SAVE(r1)
0146     mfvscr   f0
0147     stfd     f0, VSCR_SAVE(r1)
0148     SAVE_VSR(1,  r3)
0149     SAVE_VSR(2,  r3)
0150     SAVE_VSR(3,  r3)
0151     SAVE_VSR(4,  r3)
0152     SAVE_VSR(5,  r3)
0153     SAVE_VSR(6,  r3)
0154     SAVE_VSR(7,  r3)
0155     SAVE_VSR(8,  r3)
0156     SAVE_VSR(9,  r3)
0157     SAVE_VSR(10, r3)
0158     SAVE_VSR(11, r3)
0159     SAVE_VSR(12, r3)
0160     SAVE_VSR(13, r3)
0161     SAVE_VSR(14, r3)
0162     SAVE_VSR(15, r3)
0163     SAVE_VSR(16, r3)
0164     SAVE_VSR(17, r3)
0165     SAVE_VSR(18, r3)
0166     SAVE_VSR(19, r3)
0167     SAVE_VSR(20, r3)
0168     SAVE_VSR(21, r3)
0169     SAVE_VSR(22, r3)
0170     SAVE_VSR(23, r3)
0171     SAVE_VSR(24, r3)
0172     SAVE_VSR(25, r3)
0173     SAVE_VSR(26, r3)
0174     SAVE_VSR(27, r3)
0175     SAVE_VSR(28, r3)
0176     SAVE_VSR(29, r3)
0177     SAVE_VSR(30, r3)
0178     SAVE_VSR(31, r3)
0179     SAVE_VSR(32, r3)
0180     SAVE_VSR(33, r3)
0181     SAVE_VSR(34, r3)
0182     SAVE_VSR(35, r3)
0183     SAVE_VSR(36, r3)
0184     SAVE_VSR(37, r3)
0185     SAVE_VSR(38, r3)
0186     SAVE_VSR(39, r3)
0187     SAVE_VSR(40, r3)
0188     SAVE_VSR(41, r3)
0189     SAVE_VSR(42, r3)
0190     SAVE_VSR(43, r3)
0191     SAVE_VSR(44, r3)
0192     SAVE_VSR(45, r3)
0193     SAVE_VSR(46, r3)
0194     SAVE_VSR(47, r3)
0195     SAVE_VSR(48, r3)
0196     SAVE_VSR(49, r3)
0197     SAVE_VSR(50, r3)
0198     SAVE_VSR(51, r3)
0199     SAVE_VSR(52, r3)
0200     SAVE_VSR(53, r3)
0201     SAVE_VSR(54, r3)
0202     SAVE_VSR(55, r3)
0203     SAVE_VSR(56, r3)
0204     SAVE_VSR(57, r3)
0205     SAVE_VSR(58, r3)
0206     SAVE_VSR(59, r3)
0207     SAVE_VSR(60, r3)
0208     SAVE_VSR(61, r3)
0209     SAVE_VSR(62, r3)
0210     SAVE_VSR(63, r3)
0211 
0212     TRASH_GPR(2)
0213     TRASH_GPR(3)
0214     TRASH_GPR(4)
0215     TRASH_GPR(5)
0216     TRASH_GPR(6)
0217     TRASH_GPR(7)
0218     TRASH_GPR(8)
0219     TRASH_GPR(9)
0220     TRASH_GPR(10)
0221     TRASH_GPR(11)
0222     TRASH_GPR(12)
0223     TRASH_GPR(14)
0224     TRASH_GPR(15)
0225     TRASH_GPR(16)
0226     TRASH_GPR(17)
0227     TRASH_GPR(18)
0228     TRASH_GPR(19)
0229     TRASH_GPR(20)
0230     TRASH_GPR(21)
0231     TRASH_GPR(22)
0232     TRASH_GPR(23)
0233     TRASH_GPR(24)
0234     TRASH_GPR(25)
0235     TRASH_GPR(26)
0236     TRASH_GPR(27)
0237     TRASH_GPR(28)
0238     TRASH_GPR(29)
0239     TRASH_GPR(30)
0240     TRASH_GPR(31)
0241 
0242     RESTORE_TOC(ebb_handler)
0243 
0244     /*
0245      * r13 is our TLS pointer. We leave whatever value was in there when the
0246      * EBB fired. That seems to be OK because once set the TLS pointer is not
0247      * changed - but presumably that could change in future.
0248      */
0249 
0250     bl      ebb_hook
0251     nop
0252 
0253     /* r2 may be changed here but we don't care */
0254 
0255     lfd      f0, FSCR_SAVE(r1)
0256     mtfsf    0xff,f0
0257     lfd      f0, VSCR_SAVE(r1)
0258     mtvscr   f0
0259     LOAD_VSR(0, r3)
0260     LOAD_VSR(1,  r3)
0261     LOAD_VSR(2,  r3)
0262     LOAD_VSR(3,  r3)
0263     LOAD_VSR(4,  r3)
0264     LOAD_VSR(5,  r3)
0265     LOAD_VSR(6,  r3)
0266     LOAD_VSR(7,  r3)
0267     LOAD_VSR(8,  r3)
0268     LOAD_VSR(9,  r3)
0269     LOAD_VSR(10, r3)
0270     LOAD_VSR(11, r3)
0271     LOAD_VSR(12, r3)
0272     LOAD_VSR(13, r3)
0273     LOAD_VSR(14, r3)
0274     LOAD_VSR(15, r3)
0275     LOAD_VSR(16, r3)
0276     LOAD_VSR(17, r3)
0277     LOAD_VSR(18, r3)
0278     LOAD_VSR(19, r3)
0279     LOAD_VSR(20, r3)
0280     LOAD_VSR(21, r3)
0281     LOAD_VSR(22, r3)
0282     LOAD_VSR(23, r3)
0283     LOAD_VSR(24, r3)
0284     LOAD_VSR(25, r3)
0285     LOAD_VSR(26, r3)
0286     LOAD_VSR(27, r3)
0287     LOAD_VSR(28, r3)
0288     LOAD_VSR(29, r3)
0289     LOAD_VSR(30, r3)
0290     LOAD_VSR(31, r3)
0291     LOAD_VSR(32, r3)
0292     LOAD_VSR(33, r3)
0293     LOAD_VSR(34, r3)
0294     LOAD_VSR(35, r3)
0295     LOAD_VSR(36, r3)
0296     LOAD_VSR(37, r3)
0297     LOAD_VSR(38, r3)
0298     LOAD_VSR(39, r3)
0299     LOAD_VSR(40, r3)
0300     LOAD_VSR(41, r3)
0301     LOAD_VSR(42, r3)
0302     LOAD_VSR(43, r3)
0303     LOAD_VSR(44, r3)
0304     LOAD_VSR(45, r3)
0305     LOAD_VSR(46, r3)
0306     LOAD_VSR(47, r3)
0307     LOAD_VSR(48, r3)
0308     LOAD_VSR(49, r3)
0309     LOAD_VSR(50, r3)
0310     LOAD_VSR(51, r3)
0311     LOAD_VSR(52, r3)
0312     LOAD_VSR(53, r3)
0313     LOAD_VSR(54, r3)
0314     LOAD_VSR(55, r3)
0315     LOAD_VSR(56, r3)
0316     LOAD_VSR(57, r3)
0317     LOAD_VSR(58, r3)
0318     LOAD_VSR(59, r3)
0319     LOAD_VSR(60, r3)
0320     LOAD_VSR(61, r3)
0321     LOAD_VSR(62, r3)
0322     LOAD_VSR(63, r3)
0323 
0324     ld      r0,XER_SAVE(r1)
0325     mtxer   r0
0326     ld      r0,CTR_SAVE(r1)
0327     mtctr   r0
0328     ld      r0,LR_SAVE(r1)
0329     mtlr    r0
0330     ld      r0,CCR_SAVE(r1)
0331     mtcr    r0
0332     REST_GPR(0)
0333     REST_GPR(2)
0334     REST_GPR(3)
0335     REST_GPR(4)
0336     REST_GPR(5)
0337     REST_GPR(6)
0338     REST_GPR(7)
0339     REST_GPR(8)
0340     REST_GPR(9)
0341     REST_GPR(10)
0342     REST_GPR(11)
0343     REST_GPR(12)
0344     REST_GPR(13)
0345     REST_GPR(14)
0346     REST_GPR(15)
0347     REST_GPR(16)
0348     REST_GPR(17)
0349     REST_GPR(18)
0350     REST_GPR(19)
0351     REST_GPR(20)
0352     REST_GPR(21)
0353     REST_GPR(22)
0354     REST_GPR(23)
0355     REST_GPR(24)
0356     REST_GPR(25)
0357     REST_GPR(26)
0358     REST_GPR(27)
0359     REST_GPR(28)
0360     REST_GPR(29)
0361     REST_GPR(30)
0362     REST_GPR(31)
0363     addi    r1,r1,STACK_FRAME
0364     RFEBB
0365 FUNC_END(ebb_handler)