ppc_asm.tmpl 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /*
  2. * (C) Copyright 2000-2002
  3. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. /*
  24. * This file contains all the macros and symbols which define
  25. * a PowerPC assembly language environment.
  26. */
  27. #ifndef __PPC_ASM_TMPL__
  28. #define __PPC_ASM_TMPL__
  29. /***************************************************************************
  30. *
  31. * These definitions simplify the ugly declarations necessary for GOT
  32. * definitions.
  33. *
  34. * Stolen from prepboot/bootldr.h, (C) 1998 Gabriel Paubert, paubert@iram.es
  35. *
  36. * Uses r14 to access the GOT
  37. */
  38. #define START_GOT \
  39. .section ".got2","aw"; \
  40. .LCTOC1 = .+32768
  41. #define END_GOT \
  42. .text
  43. #define GET_GOT \
  44. bl 1f ; \
  45. .text 2 ; \
  46. 0: .long .LCTOC1-1f ; \
  47. .text ; \
  48. 1: mflr r14 ; \
  49. lwz r0,0b-1b(r14) ; \
  50. add r14,r0,r14 ;
  51. #define GOT_ENTRY(NAME) .L_ ## NAME = . - .LCTOC1 ; .long NAME
  52. #define GOT(NAME) .L_ ## NAME (r14)
  53. /***************************************************************************
  54. * Register names
  55. */
  56. #define r0 0
  57. #define r1 1
  58. #define r2 2
  59. #define r3 3
  60. #define r4 4
  61. #define r5 5
  62. #define r6 6
  63. #define r7 7
  64. #define r8 8
  65. #define r9 9
  66. #define r10 10
  67. #define r11 11
  68. #define r12 12
  69. #define r13 13
  70. #define r14 14
  71. #define r15 15
  72. #define r16 16
  73. #define r17 17
  74. #define r18 18
  75. #define r19 19
  76. #define r20 20
  77. #define r21 21
  78. #define r22 22
  79. #define r23 23
  80. #define r24 24
  81. #define r25 25
  82. #define r26 26
  83. #define r27 27
  84. #define r28 28
  85. #define r29 29
  86. #define r30 30
  87. #define r31 31
  88. #if defined(CONFIG_8xx) || defined(CONFIG_MPC824X)
  89. /* Some special registers */
  90. #define ICR 148 /* Interrupt Cause Register (37-44) */
  91. #define DER 149
  92. #define COUNTA 150 /* Breakpoint Counter (37-44) */
  93. #define COUNTB 151 /* Breakpoint Counter (37-44) */
  94. #define LCTRL1 156 /* Load/Store Support (37-40) */
  95. #define LCTRL2 157 /* Load/Store Support (37-41) */
  96. #define ICTRL 158
  97. #endif /* CONFIG_8xx, CONFIG_MPC824X */
  98. #if defined(CONFIG_5xx)
  99. /* Some special purpose registers */
  100. #define DER 149 /* Debug Enable Register */
  101. #define COUNTA 150 /* Breakpoint Counter */
  102. #define COUNTB 151 /* Breakpoint Counter */
  103. #define LCTRL1 156 /* Load/Store Support */
  104. #define LCTRL2 157 /* Load/Store Support */
  105. #define ICTRL 158 /* I-Bus Support Control Register */
  106. #define EID 81
  107. #endif /* CONFIG_5xx */
  108. #if defined(CONFIG_8xx)
  109. /* Registers in the processor's internal memory map that we use.
  110. */
  111. #define SYPCR 0x00000004
  112. #define BR0 0x00000100
  113. #define OR0 0x00000104
  114. #define BR1 0x00000108
  115. #define OR1 0x0000010c
  116. #define BR2 0x00000110
  117. #define OR2 0x00000114
  118. #define BR3 0x00000118
  119. #define OR3 0x0000011c
  120. #define BR4 0x00000120
  121. #define OR4 0x00000124
  122. #define MAR 0x00000164
  123. #define MCR 0x00000168
  124. #define MAMR 0x00000170
  125. #define MBMR 0x00000174
  126. #define MSTAT 0x00000178
  127. #define MPTPR 0x0000017a
  128. #define MDR 0x0000017c
  129. #define TBSCR 0x00000200
  130. #define TBREFF0 0x00000204
  131. #define PLPRCR 0x00000284
  132. #elif defined(CONFIG_8260)
  133. #define HID2 1011
  134. #define HID0_IFEM (1<<7)
  135. #define HID0_ICE_BITPOS 16
  136. #define HID0_DCE_BITPOS 17
  137. #define IM_REGBASE 0x10000
  138. #define IM_SYPCR (IM_REGBASE+0x0004)
  139. #define IM_SWSR (IM_REGBASE+0x000e)
  140. #define IM_BR0 (IM_REGBASE+0x0100)
  141. #define IM_OR0 (IM_REGBASE+0x0104)
  142. #define IM_BR1 (IM_REGBASE+0x0108)
  143. #define IM_OR1 (IM_REGBASE+0x010c)
  144. #define IM_BR2 (IM_REGBASE+0x0110)
  145. #define IM_OR2 (IM_REGBASE+0x0114)
  146. #define IM_MPTPR (IM_REGBASE+0x0184)
  147. #define IM_PSDMR (IM_REGBASE+0x0190)
  148. #define IM_PSRT (IM_REGBASE+0x019c)
  149. #define IM_IMMR (IM_REGBASE+0x01a8)
  150. #define IM_SCCR (IM_REGBASE+0x0c80)
  151. #elif defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC8220)
  152. #define HID0_ICE_BITPOS 16
  153. #define HID0_DCE_BITPOS 17
  154. #endif
  155. #define curptr r2
  156. #define SYNC \
  157. sync; \
  158. isync
  159. /*
  160. * Macros for storing registers into and loading registers from
  161. * exception frames.
  162. */
  163. #define SAVE_GPR(n, base) stw n,GPR0+4*(n)(base)
  164. #define SAVE_2GPRS(n, base) SAVE_GPR(n, base); SAVE_GPR(n+1, base)
  165. #define SAVE_4GPRS(n, base) SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base)
  166. #define SAVE_8GPRS(n, base) SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base)
  167. #define SAVE_10GPRS(n, base) SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base)
  168. #define REST_GPR(n, base) lwz n,GPR0+4*(n)(base)
  169. #define REST_2GPRS(n, base) REST_GPR(n, base); REST_GPR(n+1, base)
  170. #define REST_4GPRS(n, base) REST_2GPRS(n, base); REST_2GPRS(n+2, base)
  171. #define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base)
  172. #define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base)
  173. /*
  174. * GCC sometimes accesses words at negative offsets from the stack
  175. * pointer, although the SysV ABI says it shouldn't. To cope with
  176. * this, we leave this much untouched space on the stack on exception
  177. * entry.
  178. */
  179. #define STACK_UNDERHEAD 64
  180. /*
  181. * Exception entry code. This code runs with address translation
  182. * turned off, i.e. using physical addresses.
  183. * We assume sprg3 has the physical address of the current
  184. * task's thread_struct.
  185. */
  186. #define EXCEPTION_PROLOG(reg1, reg2) \
  187. mtspr SPRG0,r20; \
  188. mtspr SPRG1,r21; \
  189. mfcr r20; \
  190. subi r21,r1,INT_FRAME_SIZE+STACK_UNDERHEAD; /* alloc exc. frame */\
  191. stw r20,_CCR(r21); /* save registers */ \
  192. stw r22,GPR22(r21); \
  193. stw r23,GPR23(r21); \
  194. mfspr r20,SPRG0; \
  195. stw r20,GPR20(r21); \
  196. mfspr r22,SPRG1; \
  197. stw r22,GPR21(r21); \
  198. mflr r20; \
  199. stw r20,_LINK(r21); \
  200. mfctr r22; \
  201. stw r22,_CTR(r21); \
  202. mfspr r20,XER; \
  203. stw r20,_XER(r21); \
  204. mfspr r20, DAR_DEAR; \
  205. stw r20,_DAR(r21); \
  206. mfspr r22,reg1; \
  207. mfspr r23,reg2; \
  208. stw r0,GPR0(r21); \
  209. stw r1,GPR1(r21); \
  210. stw r2,GPR2(r21); \
  211. stw r1,0(r21); \
  212. mr r1,r21; /* set new kernel sp */ \
  213. SAVE_4GPRS(3, r21);
  214. /*
  215. * Note: code which follows this uses cr0.eq (set if from kernel),
  216. * r21, r22 (SRR0), and r23 (SRR1).
  217. */
  218. /*
  219. * Exception vectors.
  220. *
  221. * The data words for `hdlr' and `int_return' are initialized with
  222. * OFFSET values only; they must be relocated first before they can
  223. * be used!
  224. */
  225. #define STD_EXCEPTION(n, label, hdlr) \
  226. . = n; \
  227. label: \
  228. EXCEPTION_PROLOG(SRR0, SRR1); \
  229. lwz r3,GOT(transfer_to_handler); \
  230. mtlr r3; \
  231. addi r3,r1,STACK_FRAME_OVERHEAD; \
  232. li r20,MSR_KERNEL; \
  233. rlwimi r20,r23,0,25,25; \
  234. blrl; \
  235. .L_ ## label : \
  236. .long hdlr - _start + _START_OFFSET; \
  237. .long int_return - _start + _START_OFFSET
  238. #define CRIT_EXCEPTION(n, label, hdlr) \
  239. . = n; \
  240. label: \
  241. EXCEPTION_PROLOG(CSRR0, CSRR1); \
  242. lwz r3,GOT(transfer_to_handler); \
  243. mtlr r3; \
  244. addi r3,r1,STACK_FRAME_OVERHEAD; \
  245. li r20,(MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)); \
  246. rlwimi r20,r23,0,25,25; \
  247. blrl; \
  248. .L_ ## label : \
  249. .long hdlr - _start + _START_OFFSET; \
  250. .long crit_return - _start + _START_OFFSET
  251. #define MCK_EXCEPTION(n, label, hdlr) \
  252. . = n; \
  253. label: \
  254. EXCEPTION_PROLOG(MCSRR0, MCSRR1); \
  255. lwz r3,GOT(transfer_to_handler); \
  256. mtlr r3; \
  257. addi r3,r1,STACK_FRAME_OVERHEAD; \
  258. li r20,(MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)); \
  259. rlwimi r20,r23,0,25,25; \
  260. blrl; \
  261. .L_ ## label : \
  262. .long hdlr - _start + _START_OFFSET; \
  263. .long mck_return - _start + _START_OFFSET
  264. #endif /* __PPC_ASM_TMPL__ */