ppc_asm.tmpl 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  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_8xx)
  99. /* Registers in the processor's internal memory map that we use.
  100. */
  101. #define SYPCR 0x00000004
  102. #define BR0 0x00000100
  103. #define OR0 0x00000104
  104. #define BR1 0x00000108
  105. #define OR1 0x0000010c
  106. #define BR2 0x00000110
  107. #define OR2 0x00000114
  108. #define BR3 0x00000118
  109. #define OR3 0x0000011c
  110. #define BR4 0x00000120
  111. #define OR4 0x00000124
  112. #define MAR 0x00000164
  113. #define MCR 0x00000168
  114. #define MAMR 0x00000170
  115. #define MBMR 0x00000174
  116. #define MSTAT 0x00000178
  117. #define MPTPR 0x0000017a
  118. #define MDR 0x0000017c
  119. #define TBSCR 0x00000200
  120. #define TBREFF0 0x00000204
  121. #define PLPRCR 0x00000284
  122. #elif defined(CONFIG_8260)
  123. #define HID2 1011
  124. #define HID0_IFEM (1<<7)
  125. #define HID0_ICE_BITPOS 16
  126. #define HID0_DCE_BITPOS 17
  127. #define IM_REGBASE 0x10000
  128. #define IM_SYPCR (IM_REGBASE+0x0004)
  129. #define IM_SWSR (IM_REGBASE+0x000e)
  130. #define IM_BR0 (IM_REGBASE+0x0100)
  131. #define IM_OR0 (IM_REGBASE+0x0104)
  132. #define IM_BR1 (IM_REGBASE+0x0108)
  133. #define IM_OR1 (IM_REGBASE+0x010c)
  134. #define IM_BR2 (IM_REGBASE+0x0110)
  135. #define IM_OR2 (IM_REGBASE+0x0114)
  136. #define IM_MPTPR (IM_REGBASE+0x0184)
  137. #define IM_PSDMR (IM_REGBASE+0x0190)
  138. #define IM_PSRT (IM_REGBASE+0x019c)
  139. #define IM_IMMR (IM_REGBASE+0x01a8)
  140. #define IM_SCCR (IM_REGBASE+0x0c80)
  141. #endif
  142. #define curptr r2
  143. #define SYNC \
  144. sync; \
  145. isync
  146. /*
  147. * Macros for storing registers into and loading registers from
  148. * exception frames.
  149. */
  150. #define SAVE_GPR(n, base) stw n,GPR0+4*(n)(base)
  151. #define SAVE_2GPRS(n, base) SAVE_GPR(n, base); SAVE_GPR(n+1, base)
  152. #define SAVE_4GPRS(n, base) SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base)
  153. #define SAVE_8GPRS(n, base) SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base)
  154. #define SAVE_10GPRS(n, base) SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base)
  155. #define REST_GPR(n, base) lwz n,GPR0+4*(n)(base)
  156. #define REST_2GPRS(n, base) REST_GPR(n, base); REST_GPR(n+1, base)
  157. #define REST_4GPRS(n, base) REST_2GPRS(n, base); REST_2GPRS(n+2, base)
  158. #define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base)
  159. #define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base)
  160. /*
  161. * GCC sometimes accesses words at negative offsets from the stack
  162. * pointer, although the SysV ABI says it shouldn't. To cope with
  163. * this, we leave this much untouched space on the stack on exception
  164. * entry.
  165. */
  166. #define STACK_UNDERHEAD 64
  167. /*
  168. * Exception entry code. This code runs with address translation
  169. * turned off, i.e. using physical addresses.
  170. * We assume sprg3 has the physical address of the current
  171. * task's thread_struct.
  172. */
  173. #define EXCEPTION_PROLOG \
  174. mtspr SPRG0,r20; \
  175. mtspr SPRG1,r21; \
  176. mfcr r20; \
  177. subi r21,r1,INT_FRAME_SIZE+STACK_UNDERHEAD; /* alloc exc. frame */\
  178. stw r20,_CCR(r21); /* save registers */ \
  179. stw r22,GPR22(r21); \
  180. stw r23,GPR23(r21); \
  181. mfspr r20,SPRG0; \
  182. stw r20,GPR20(r21); \
  183. mfspr r22,SPRG1; \
  184. stw r22,GPR21(r21); \
  185. mflr r20; \
  186. stw r20,_LINK(r21); \
  187. mfctr r22; \
  188. stw r22,_CTR(r21); \
  189. mfspr r20,XER; \
  190. stw r20,_XER(r21); \
  191. mfspr r22,SRR0; \
  192. mfspr r23,SRR1; \
  193. stw r0,GPR0(r21); \
  194. stw r1,GPR1(r21); \
  195. stw r2,GPR2(r21); \
  196. stw r1,0(r21); \
  197. mr r1,r21; /* set new kernel sp */ \
  198. SAVE_4GPRS(3, r21);
  199. /*
  200. * Note: code which follows this uses cr0.eq (set if from kernel),
  201. * r21, r22 (SRR0), and r23 (SRR1).
  202. */
  203. /*
  204. * Critical exception entry code. This is just like the other exception
  205. * code except that it uses SRR2 and SRR3 instead of SRR0 and SRR1.
  206. */
  207. #define CRITICAL_EXCEPTION_PROLOG \
  208. mtspr SPRG0,r20; \
  209. mtspr SPRG1,r21; \
  210. mfcr r20; \
  211. subi r21,r1,INT_FRAME_SIZE+STACK_UNDERHEAD; /* alloc exc. frame */\
  212. stw r20,_CCR(r21); /* save registers */ \
  213. stw r22,GPR22(r21); \
  214. stw r23,GPR23(r21); \
  215. mfspr r20,SPRG0; \
  216. stw r20,GPR20(r21); \
  217. mfspr r22,SPRG1; \
  218. stw r22,GPR21(r21); \
  219. mflr r20; \
  220. stw r20,_LINK(r21); \
  221. mfctr r22; \
  222. stw r22,_CTR(r21); \
  223. mfspr r20,XER; \
  224. stw r20,_XER(r21); \
  225. mfspr r22,990; /* SRR2 */ \
  226. mfspr r23,991; /* SRR3 */ \
  227. stw r0,GPR0(r21); \
  228. stw r1,GPR1(r21); \
  229. stw r2,GPR2(r21); \
  230. stw r1,0(r21); \
  231. mr r1,r21; /* set new kernel sp */ \
  232. SAVE_4GPRS(3, r21);
  233. /*
  234. * Note: code which follows this uses cr0.eq (set if from kernel),
  235. * r21, r22 (SRR2), and r23 (SRR3).
  236. */
  237. /*
  238. * Exception vectors.
  239. *
  240. * The data words for `hdlr' and `int_return' are initialized with
  241. * OFFSET values only; they must be relocated first before they can
  242. * be used!
  243. */
  244. #define STD_EXCEPTION(n, label, hdlr) \
  245. . = n; \
  246. label: \
  247. EXCEPTION_PROLOG; \
  248. lwz r3,GOT(transfer_to_handler); \
  249. mtlr r3; \
  250. addi r3,r1,STACK_FRAME_OVERHEAD; \
  251. li r20,MSR_KERNEL; \
  252. rlwimi r20,r23,0,25,25; \
  253. blrl ; \
  254. .L_ ## label : \
  255. .long hdlr - _start + EXC_OFF_SYS_RESET; \
  256. .long int_return - _start + EXC_OFF_SYS_RESET
  257. #define CRIT_EXCEPTION(n, label, hdlr) \
  258. . = n; \
  259. label: \
  260. CRITICAL_EXCEPTION_PROLOG; \
  261. lwz r3,GOT(transfer_to_handler); \
  262. mtlr r3; \
  263. addi r3,r1,STACK_FRAME_OVERHEAD; \
  264. li r20,MSR_KERNEL; \
  265. rlwimi r20,r23,0,25,25; \
  266. blrl ; \
  267. .L_ ## label : \
  268. .long hdlr - _start + EXC_OFF_SYS_RESET; \
  269. .long crit_return - _start + EXC_OFF_SYS_RESET
  270. #endif /* __PPC_ASM_TMPL__ */