ppc_asm.tmpl 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. /* SPDX-License-Identifier: GPL-2.0+ */
  2. /*
  3. * (C) Copyright 2000-2002
  4. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  5. */
  6. /*
  7. * This file contains all the macros and symbols which define
  8. * a PowerPC assembly language environment.
  9. */
  10. #ifndef __PPC_ASM_TMPL__
  11. #define __PPC_ASM_TMPL__
  12. #include <config.h>
  13. /***************************************************************************
  14. *
  15. * These definitions simplify the ugly declarations necessary for GOT
  16. * definitions.
  17. *
  18. * Stolen from prepboot/bootldr.h, (C) 1998 Gabriel Paubert, paubert@iram.es
  19. *
  20. * Uses r12 to access the GOT
  21. */
  22. #define START_GOT \
  23. .section ".got2","aw"; \
  24. .LCTOC1 = .+32768
  25. #define END_GOT \
  26. .text
  27. #define GET_GOT \
  28. bl 1f ; \
  29. .text 2 ; \
  30. 0: .long .LCTOC1-1f ; \
  31. .text ; \
  32. 1: mflr r12 ; \
  33. lwz r0,0b-1b(r12) ; \
  34. add r12,r0,r12 ;
  35. #define GOT_ENTRY(NAME) .L_ ## NAME = . - .LCTOC1 ; .long NAME
  36. #define GOT(NAME) .L_ ## NAME (r12)
  37. /***************************************************************************
  38. * Register names
  39. */
  40. #define r0 0
  41. #define r1 1
  42. #define r2 2
  43. #define r3 3
  44. #define r4 4
  45. #define r5 5
  46. #define r6 6
  47. #define r7 7
  48. #define r8 8
  49. #define r9 9
  50. #define r10 10
  51. #define r11 11
  52. #define r12 12
  53. #define r13 13
  54. #define r14 14
  55. #define r15 15
  56. #define r16 16
  57. #define r17 17
  58. #define r18 18
  59. #define r19 19
  60. #define r20 20
  61. #define r21 21
  62. #define r22 22
  63. #define r23 23
  64. #define r24 24
  65. #define r25 25
  66. #define r26 26
  67. #define r27 27
  68. #define r28 28
  69. #define r29 29
  70. #define r30 30
  71. #define r31 31
  72. #if defined(CONFIG_MPC8xx)
  73. /* Some special registers */
  74. #define ICR 148 /* Interrupt Cause Register (37-44) */
  75. #define DER 149
  76. #define COUNTA 150 /* Breakpoint Counter (37-44) */
  77. #define COUNTB 151 /* Breakpoint Counter (37-44) */
  78. #define LCTRL1 156 /* Load/Store Support (37-40) */
  79. #define LCTRL2 157 /* Load/Store Support (37-41) */
  80. #define ICTRL 158
  81. #endif /* CONFIG_MPC8xx */
  82. #if defined(CONFIG_MPC8xx)
  83. /* Registers in the processor's internal memory map that we use.
  84. */
  85. #define SYPCR 0x00000004
  86. #define BR0 0x00000100
  87. #define OR0 0x00000104
  88. #define BR1 0x00000108
  89. #define OR1 0x0000010c
  90. #define BR2 0x00000110
  91. #define OR2 0x00000114
  92. #define BR3 0x00000118
  93. #define OR3 0x0000011c
  94. #define BR4 0x00000120
  95. #define OR4 0x00000124
  96. #define MAR 0x00000164
  97. #define MCR 0x00000168
  98. #define MAMR 0x00000170
  99. #define MBMR 0x00000174
  100. #define MSTAT 0x00000178
  101. #define MPTPR 0x0000017a
  102. #define MDR 0x0000017c
  103. #define TBSCR 0x00000200
  104. #define TBREFF0 0x00000204
  105. #define PLPRCR 0x00000284
  106. #endif
  107. #define curptr r2
  108. #define SYNC \
  109. sync; \
  110. isync
  111. /*
  112. * Macros for storing registers into and loading registers from
  113. * exception frames.
  114. */
  115. #define SAVE_GPR(n, base) stw n,GPR0+4*(n)(base)
  116. #define SAVE_2GPRS(n, base) SAVE_GPR(n, base); SAVE_GPR(n+1, base)
  117. #define SAVE_4GPRS(n, base) SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base)
  118. #define SAVE_8GPRS(n, base) SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base)
  119. #define SAVE_10GPRS(n, base) SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base)
  120. #define REST_GPR(n, base) lwz n,GPR0+4*(n)(base)
  121. #define REST_2GPRS(n, base) REST_GPR(n, base); REST_GPR(n+1, base)
  122. #define REST_4GPRS(n, base) REST_2GPRS(n, base); REST_2GPRS(n+2, base)
  123. #define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base)
  124. #define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base)
  125. /*
  126. * GCC sometimes accesses words at negative offsets from the stack
  127. * pointer, although the SysV ABI says it shouldn't. To cope with
  128. * this, we leave this much untouched space on the stack on exception
  129. * entry.
  130. */
  131. #define STACK_UNDERHEAD 64
  132. /*
  133. * Exception entry code. This code runs with address translation
  134. * turned off, i.e. using physical addresses.
  135. * We assume sprg3 has the physical address of the current
  136. * task's thread_struct.
  137. */
  138. #define EXCEPTION_PROLOG(reg1, reg2) \
  139. mtspr SPRG0,r20; \
  140. mtspr SPRG1,r21; \
  141. mfcr r20; \
  142. subi r21,r1,INT_FRAME_SIZE+STACK_UNDERHEAD; /* alloc exc. frame */\
  143. stw r20,_CCR(r21); /* save registers */ \
  144. stw r22,GPR22(r21); \
  145. stw r23,GPR23(r21); \
  146. mfspr r20,SPRG0; \
  147. stw r20,GPR20(r21); \
  148. mfspr r22,SPRG1; \
  149. stw r22,GPR21(r21); \
  150. mflr r20; \
  151. stw r20,_LINK(r21); \
  152. mfctr r22; \
  153. stw r22,_CTR(r21); \
  154. mfspr r20,XER; \
  155. stw r20,_XER(r21); \
  156. mfspr r20, DAR_DEAR; \
  157. stw r20,_DAR(r21); \
  158. mfspr r22,reg1; \
  159. mfspr r23,reg2; \
  160. stw r0,GPR0(r21); \
  161. stw r1,GPR1(r21); \
  162. stw r2,GPR2(r21); \
  163. stw r1,0(r21); \
  164. mr r1,r21; /* set new kernel sp */ \
  165. SAVE_4GPRS(3, r21);
  166. /*
  167. * Note: code which follows this uses cr0.eq (set if from kernel),
  168. * r21, r22 (SRR0), and r23 (SRR1).
  169. */
  170. /*
  171. * Exception vectors.
  172. *
  173. * The data words for `hdlr' and `int_return' are initialized with
  174. * OFFSET values only; they must be relocated first before they can
  175. * be used!
  176. */
  177. #define COPY_EE(d, s) rlwimi d,s,0,16,16
  178. #define NOCOPY(d, s)
  179. #ifdef CONFIG_E500
  180. #define EXC_XFER_TEMPLATE(n, label, hdlr, msr, copyee) \
  181. stw r22,_NIP(r21); \
  182. stw r23,_MSR(r21); \
  183. li r23,n; \
  184. stw r23,TRAP(r21); \
  185. li r20,msr; \
  186. copyee(r20,r23); \
  187. rlwimi r20,r23,0,25,25; \
  188. mtmsr r20; \
  189. bl 1f; \
  190. 1: mflr r23; \
  191. addis r23,r23,(hdlr - 1b)@ha; \
  192. addi r23,r23,(hdlr - 1b)@l; \
  193. b transfer_to_handler
  194. #define STD_EXCEPTION(n, label, hdlr) \
  195. .align 4; \
  196. label: \
  197. EXCEPTION_PROLOG(SRR0, SRR1); \
  198. addi r3,r1,STACK_FRAME_OVERHEAD; \
  199. EXC_XFER_TEMPLATE(n, label, hdlr, MSR_KERNEL, NOCOPY) \
  200. #define CRIT_EXCEPTION(n, label, hdlr) \
  201. .align 4; \
  202. label: \
  203. EXCEPTION_PROLOG(CSRR0, CSRR1); \
  204. addi r3,r1,STACK_FRAME_OVERHEAD; \
  205. EXC_XFER_TEMPLATE(n, label, hdlr, \
  206. MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE), NOCOPY) \
  207. #define MCK_EXCEPTION(n, label, hdlr) \
  208. .align 4; \
  209. label: \
  210. EXCEPTION_PROLOG(MCSRR0, MCSRR1); \
  211. addi r3,r1,STACK_FRAME_OVERHEAD; \
  212. EXC_XFER_TEMPLATE(n, label, hdlr, \
  213. MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE), NOCOPY) \
  214. #else /* !E500 */
  215. #define EXC_XFER_TEMPLATE(label, hdlr, msr, copyee) \
  216. bl 1f; \
  217. 1: mflr r20; \
  218. lwz r20,(.L_ ## label)-1b+8(r20); \
  219. mtlr r20; \
  220. li r20,msr; \
  221. copyee(r20,r23); \
  222. rlwimi r20,r23,0,25,25; \
  223. blrl; \
  224. .L_ ## label : \
  225. .long hdlr - _start + _START_OFFSET; \
  226. .long int_return - _start + _START_OFFSET; \
  227. .long transfer_to_handler - _start + _START_OFFSET
  228. #define STD_EXCEPTION(n, label, hdlr) \
  229. . = n; \
  230. label: \
  231. EXCEPTION_PROLOG(SRR0, SRR1); \
  232. addi r3,r1,STACK_FRAME_OVERHEAD; \
  233. EXC_XFER_TEMPLATE(label, hdlr, MSR_KERNEL, NOCOPY) \
  234. #define CRIT_EXCEPTION(n, label, hdlr) \
  235. . = n; \
  236. label: \
  237. EXCEPTION_PROLOG(CSRR0, CSRR1); \
  238. addi r3,r1,STACK_FRAME_OVERHEAD; \
  239. EXC_XFER_TEMPLATE(label, hdlr, \
  240. MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE), NOCOPY) \
  241. #define MCK_EXCEPTION(n, label, hdlr) \
  242. . = n; \
  243. label: \
  244. EXCEPTION_PROLOG(MCSRR0, MCSRR1); \
  245. addi r3,r1,STACK_FRAME_OVERHEAD; \
  246. EXC_XFER_TEMPLATE(label, hdlr, \
  247. MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE), NOCOPY) \
  248. #endif /* !E500 */
  249. #endif /* __PPC_ASM_TMPL__ */