ebb_handler.S 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. /*
  2. * Copyright 2014, Michael Ellerman, IBM Corp.
  3. * Licensed under GPLv2.
  4. */
  5. #include <ppc-asm.h>
  6. #include "reg.h"
  7. /* ppc-asm.h defines most of the reg aliases, but not r1/r2. */
  8. #define r1 1
  9. #define r2 2
  10. #define RFEBB .long 0x4c000924
  11. /* Stack layout:
  12. *
  13. * ^
  14. * User stack |
  15. * Back chain ------+ <- r1 <-------+
  16. * ... |
  17. * Red zone / ABI Gap |
  18. * ... |
  19. * vr63 <+ |
  20. * vr0 | |
  21. * VSCR | |
  22. * FSCR | |
  23. * r31 | Save area |
  24. * r0 | |
  25. * XER | |
  26. * CTR | |
  27. * LR | |
  28. * CCR <+ |
  29. * ... <+ |
  30. * LR | Caller frame |
  31. * CCR | |
  32. * Back chain <+ <- updated r1 --------+
  33. *
  34. */
  35. #if defined(_CALL_ELF) && _CALL_ELF == 2
  36. #define ABIGAP 512
  37. #else
  38. #define ABIGAP 288
  39. #endif
  40. #define NR_GPR 32
  41. #define NR_SPR 6
  42. #define NR_VSR 64
  43. #define SAVE_AREA ((NR_GPR + NR_SPR) * 8 + (NR_VSR * 16))
  44. #define CALLER_FRAME 112
  45. #define STACK_FRAME (ABIGAP + SAVE_AREA + CALLER_FRAME)
  46. #define CCR_SAVE (CALLER_FRAME)
  47. #define LR_SAVE (CCR_SAVE + 8)
  48. #define CTR_SAVE (LR_SAVE + 8)
  49. #define XER_SAVE (CTR_SAVE + 8)
  50. #define GPR_SAVE(n) (XER_SAVE + 8 + (8 * n))
  51. #define FSCR_SAVE (GPR_SAVE(31) + 8)
  52. #define VSCR_SAVE (FSCR_SAVE + 8)
  53. #define VSR_SAVE(n) (VSCR_SAVE + 8 + (16 * n))
  54. #define SAVE_GPR(n) std n,GPR_SAVE(n)(r1)
  55. #define REST_GPR(n) ld n,GPR_SAVE(n)(r1)
  56. #define TRASH_GPR(n) lis n,0xaaaa
  57. #define SAVE_VSR(n, b) li b, VSR_SAVE(n); stxvd2x n,b,r1
  58. #define LOAD_VSR(n, b) li b, VSR_SAVE(n); lxvd2x n,b,r1
  59. #define LOAD_REG_IMMEDIATE(reg,expr) \
  60. lis reg,(expr)@highest; \
  61. ori reg,reg,(expr)@higher; \
  62. rldicr reg,reg,32,31; \
  63. oris reg,reg,(expr)@h; \
  64. ori reg,reg,(expr)@l;
  65. #if defined(_CALL_ELF) && _CALL_ELF == 2
  66. #define ENTRY_POINT(name) \
  67. .type FUNC_NAME(name),@function; \
  68. .globl FUNC_NAME(name); \
  69. FUNC_NAME(name):
  70. #define RESTORE_TOC(name) \
  71. /* Restore our TOC pointer using our entry point */ \
  72. LOAD_REG_IMMEDIATE(r12, name) \
  73. 0: addis r2,r12,(.TOC.-0b)@ha; \
  74. addi r2,r2,(.TOC.-0b)@l;
  75. #else
  76. #define ENTRY_POINT(name) FUNC_START(name)
  77. #define RESTORE_TOC(name) \
  78. /* Restore our TOC pointer via our opd entry */ \
  79. LOAD_REG_IMMEDIATE(r2, name) \
  80. ld r2,8(r2);
  81. #endif
  82. .text
  83. ENTRY_POINT(ebb_handler)
  84. stdu r1,-STACK_FRAME(r1)
  85. SAVE_GPR(0)
  86. mflr r0
  87. std r0,LR_SAVE(r1)
  88. mfcr r0
  89. std r0,CCR_SAVE(r1)
  90. mfctr r0
  91. std r0,CTR_SAVE(r1)
  92. mfxer r0
  93. std r0,XER_SAVE(r1)
  94. SAVE_GPR(2)
  95. SAVE_GPR(3)
  96. SAVE_GPR(4)
  97. SAVE_GPR(5)
  98. SAVE_GPR(6)
  99. SAVE_GPR(7)
  100. SAVE_GPR(8)
  101. SAVE_GPR(9)
  102. SAVE_GPR(10)
  103. SAVE_GPR(11)
  104. SAVE_GPR(12)
  105. SAVE_GPR(13)
  106. SAVE_GPR(14)
  107. SAVE_GPR(15)
  108. SAVE_GPR(16)
  109. SAVE_GPR(17)
  110. SAVE_GPR(18)
  111. SAVE_GPR(19)
  112. SAVE_GPR(20)
  113. SAVE_GPR(21)
  114. SAVE_GPR(22)
  115. SAVE_GPR(23)
  116. SAVE_GPR(24)
  117. SAVE_GPR(25)
  118. SAVE_GPR(26)
  119. SAVE_GPR(27)
  120. SAVE_GPR(28)
  121. SAVE_GPR(29)
  122. SAVE_GPR(30)
  123. SAVE_GPR(31)
  124. SAVE_VSR(0, r3)
  125. mffs f0
  126. stfd f0, FSCR_SAVE(r1)
  127. mfvscr f0
  128. stfd f0, VSCR_SAVE(r1)
  129. SAVE_VSR(1, r3)
  130. SAVE_VSR(2, r3)
  131. SAVE_VSR(3, r3)
  132. SAVE_VSR(4, r3)
  133. SAVE_VSR(5, r3)
  134. SAVE_VSR(6, r3)
  135. SAVE_VSR(7, r3)
  136. SAVE_VSR(8, r3)
  137. SAVE_VSR(9, r3)
  138. SAVE_VSR(10, r3)
  139. SAVE_VSR(11, r3)
  140. SAVE_VSR(12, r3)
  141. SAVE_VSR(13, r3)
  142. SAVE_VSR(14, r3)
  143. SAVE_VSR(15, r3)
  144. SAVE_VSR(16, r3)
  145. SAVE_VSR(17, r3)
  146. SAVE_VSR(18, r3)
  147. SAVE_VSR(19, r3)
  148. SAVE_VSR(20, r3)
  149. SAVE_VSR(21, r3)
  150. SAVE_VSR(22, r3)
  151. SAVE_VSR(23, r3)
  152. SAVE_VSR(24, r3)
  153. SAVE_VSR(25, r3)
  154. SAVE_VSR(26, r3)
  155. SAVE_VSR(27, r3)
  156. SAVE_VSR(28, r3)
  157. SAVE_VSR(29, r3)
  158. SAVE_VSR(30, r3)
  159. SAVE_VSR(31, r3)
  160. SAVE_VSR(32, r3)
  161. SAVE_VSR(33, r3)
  162. SAVE_VSR(34, r3)
  163. SAVE_VSR(35, r3)
  164. SAVE_VSR(36, r3)
  165. SAVE_VSR(37, r3)
  166. SAVE_VSR(38, r3)
  167. SAVE_VSR(39, r3)
  168. SAVE_VSR(40, r3)
  169. SAVE_VSR(41, r3)
  170. SAVE_VSR(42, r3)
  171. SAVE_VSR(43, r3)
  172. SAVE_VSR(44, r3)
  173. SAVE_VSR(45, r3)
  174. SAVE_VSR(46, r3)
  175. SAVE_VSR(47, r3)
  176. SAVE_VSR(48, r3)
  177. SAVE_VSR(49, r3)
  178. SAVE_VSR(50, r3)
  179. SAVE_VSR(51, r3)
  180. SAVE_VSR(52, r3)
  181. SAVE_VSR(53, r3)
  182. SAVE_VSR(54, r3)
  183. SAVE_VSR(55, r3)
  184. SAVE_VSR(56, r3)
  185. SAVE_VSR(57, r3)
  186. SAVE_VSR(58, r3)
  187. SAVE_VSR(59, r3)
  188. SAVE_VSR(60, r3)
  189. SAVE_VSR(61, r3)
  190. SAVE_VSR(62, r3)
  191. SAVE_VSR(63, r3)
  192. TRASH_GPR(2)
  193. TRASH_GPR(3)
  194. TRASH_GPR(4)
  195. TRASH_GPR(5)
  196. TRASH_GPR(6)
  197. TRASH_GPR(7)
  198. TRASH_GPR(8)
  199. TRASH_GPR(9)
  200. TRASH_GPR(10)
  201. TRASH_GPR(11)
  202. TRASH_GPR(12)
  203. TRASH_GPR(14)
  204. TRASH_GPR(15)
  205. TRASH_GPR(16)
  206. TRASH_GPR(17)
  207. TRASH_GPR(18)
  208. TRASH_GPR(19)
  209. TRASH_GPR(20)
  210. TRASH_GPR(21)
  211. TRASH_GPR(22)
  212. TRASH_GPR(23)
  213. TRASH_GPR(24)
  214. TRASH_GPR(25)
  215. TRASH_GPR(26)
  216. TRASH_GPR(27)
  217. TRASH_GPR(28)
  218. TRASH_GPR(29)
  219. TRASH_GPR(30)
  220. TRASH_GPR(31)
  221. RESTORE_TOC(ebb_handler)
  222. /*
  223. * r13 is our TLS pointer. We leave whatever value was in there when the
  224. * EBB fired. That seems to be OK because once set the TLS pointer is not
  225. * changed - but presumably that could change in future.
  226. */
  227. bl ebb_hook
  228. nop
  229. /* r2 may be changed here but we don't care */
  230. lfd f0, FSCR_SAVE(r1)
  231. mtfsf 0xff,f0
  232. lfd f0, VSCR_SAVE(r1)
  233. mtvscr f0
  234. LOAD_VSR(0, r3)
  235. LOAD_VSR(1, r3)
  236. LOAD_VSR(2, r3)
  237. LOAD_VSR(3, r3)
  238. LOAD_VSR(4, r3)
  239. LOAD_VSR(5, r3)
  240. LOAD_VSR(6, r3)
  241. LOAD_VSR(7, r3)
  242. LOAD_VSR(8, r3)
  243. LOAD_VSR(9, r3)
  244. LOAD_VSR(10, r3)
  245. LOAD_VSR(11, r3)
  246. LOAD_VSR(12, r3)
  247. LOAD_VSR(13, r3)
  248. LOAD_VSR(14, r3)
  249. LOAD_VSR(15, r3)
  250. LOAD_VSR(16, r3)
  251. LOAD_VSR(17, r3)
  252. LOAD_VSR(18, r3)
  253. LOAD_VSR(19, r3)
  254. LOAD_VSR(20, r3)
  255. LOAD_VSR(21, r3)
  256. LOAD_VSR(22, r3)
  257. LOAD_VSR(23, r3)
  258. LOAD_VSR(24, r3)
  259. LOAD_VSR(25, r3)
  260. LOAD_VSR(26, r3)
  261. LOAD_VSR(27, r3)
  262. LOAD_VSR(28, r3)
  263. LOAD_VSR(29, r3)
  264. LOAD_VSR(30, r3)
  265. LOAD_VSR(31, r3)
  266. LOAD_VSR(32, r3)
  267. LOAD_VSR(33, r3)
  268. LOAD_VSR(34, r3)
  269. LOAD_VSR(35, r3)
  270. LOAD_VSR(36, r3)
  271. LOAD_VSR(37, r3)
  272. LOAD_VSR(38, r3)
  273. LOAD_VSR(39, r3)
  274. LOAD_VSR(40, r3)
  275. LOAD_VSR(41, r3)
  276. LOAD_VSR(42, r3)
  277. LOAD_VSR(43, r3)
  278. LOAD_VSR(44, r3)
  279. LOAD_VSR(45, r3)
  280. LOAD_VSR(46, r3)
  281. LOAD_VSR(47, r3)
  282. LOAD_VSR(48, r3)
  283. LOAD_VSR(49, r3)
  284. LOAD_VSR(50, r3)
  285. LOAD_VSR(51, r3)
  286. LOAD_VSR(52, r3)
  287. LOAD_VSR(53, r3)
  288. LOAD_VSR(54, r3)
  289. LOAD_VSR(55, r3)
  290. LOAD_VSR(56, r3)
  291. LOAD_VSR(57, r3)
  292. LOAD_VSR(58, r3)
  293. LOAD_VSR(59, r3)
  294. LOAD_VSR(60, r3)
  295. LOAD_VSR(61, r3)
  296. LOAD_VSR(62, r3)
  297. LOAD_VSR(63, r3)
  298. ld r0,XER_SAVE(r1)
  299. mtxer r0
  300. ld r0,CTR_SAVE(r1)
  301. mtctr r0
  302. ld r0,LR_SAVE(r1)
  303. mtlr r0
  304. ld r0,CCR_SAVE(r1)
  305. mtcr r0
  306. REST_GPR(0)
  307. REST_GPR(2)
  308. REST_GPR(3)
  309. REST_GPR(4)
  310. REST_GPR(5)
  311. REST_GPR(6)
  312. REST_GPR(7)
  313. REST_GPR(8)
  314. REST_GPR(9)
  315. REST_GPR(10)
  316. REST_GPR(11)
  317. REST_GPR(12)
  318. REST_GPR(13)
  319. REST_GPR(14)
  320. REST_GPR(15)
  321. REST_GPR(16)
  322. REST_GPR(17)
  323. REST_GPR(18)
  324. REST_GPR(19)
  325. REST_GPR(20)
  326. REST_GPR(21)
  327. REST_GPR(22)
  328. REST_GPR(23)
  329. REST_GPR(24)
  330. REST_GPR(25)
  331. REST_GPR(26)
  332. REST_GPR(27)
  333. REST_GPR(28)
  334. REST_GPR(29)
  335. REST_GPR(30)
  336. REST_GPR(31)
  337. addi r1,r1,STACK_FRAME
  338. RFEBB
  339. FUNC_END(ebb_handler)