Commit d62589d5fd006f73fcbf1371081d5604478f925a
1 parent
c12b5a3210
Exists in
master
and in
54 other branches
Initial revision
Showing 1 changed file with 305 additions and 0 deletions Side-by-side Diff
include/ppc_asm.tmpl
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 | +/* | |
25 | + * This file contains all the macros and symbols which define | |
26 | + * a PowerPC assembly language environment. | |
27 | + */ | |
28 | +#ifndef __PPC_ASM_TMPL__ | |
29 | +#define __PPC_ASM_TMPL__ | |
30 | + | |
31 | +/*************************************************************************** | |
32 | + * | |
33 | + * These definitions simplify the ugly declarations necessary for GOT | |
34 | + * definitions. | |
35 | + * | |
36 | + * Stolen from prepboot/bootldr.h, (C) 1998 Gabriel Paubert, paubert@iram.es | |
37 | + * | |
38 | + * Uses r14 to access the GOT | |
39 | + */ | |
40 | + | |
41 | +#define START_GOT \ | |
42 | + .section ".got2","aw"; \ | |
43 | +.LCTOC1 = .+32768 | |
44 | + | |
45 | +#define END_GOT \ | |
46 | + .text | |
47 | + | |
48 | +#define GET_GOT \ | |
49 | + bl 1f ; \ | |
50 | + .text 2 ; \ | |
51 | +0: .long .LCTOC1-1f ; \ | |
52 | + .text ; \ | |
53 | +1: mflr r14 ; \ | |
54 | + lwz r0,0b-1b(r14) ; \ | |
55 | + add r14,r0,r14 ; | |
56 | + | |
57 | +#define GOT_ENTRY(NAME) .L_ ## NAME = . - .LCTOC1 ; .long NAME | |
58 | + | |
59 | +#define GOT(NAME) .L_ ## NAME (r14) | |
60 | + | |
61 | + | |
62 | +/*************************************************************************** | |
63 | + * Register names | |
64 | + */ | |
65 | +#define r0 0 | |
66 | +#define r1 1 | |
67 | +#define r2 2 | |
68 | +#define r3 3 | |
69 | +#define r4 4 | |
70 | +#define r5 5 | |
71 | +#define r6 6 | |
72 | +#define r7 7 | |
73 | +#define r8 8 | |
74 | +#define r9 9 | |
75 | +#define r10 10 | |
76 | +#define r11 11 | |
77 | +#define r12 12 | |
78 | +#define r13 13 | |
79 | +#define r14 14 | |
80 | +#define r15 15 | |
81 | +#define r16 16 | |
82 | +#define r17 17 | |
83 | +#define r18 18 | |
84 | +#define r19 19 | |
85 | +#define r20 20 | |
86 | +#define r21 21 | |
87 | +#define r22 22 | |
88 | +#define r23 23 | |
89 | +#define r24 24 | |
90 | +#define r25 25 | |
91 | +#define r26 26 | |
92 | +#define r27 27 | |
93 | +#define r28 28 | |
94 | +#define r29 29 | |
95 | +#define r30 30 | |
96 | +#define r31 31 | |
97 | + | |
98 | + | |
99 | +#if defined(CONFIG_8xx) || defined(CONFIG_MPC824X) | |
100 | + | |
101 | +/* Some special registers */ | |
102 | + | |
103 | +#define ICR 148 /* Interrupt Cause Register (37-44) */ | |
104 | +#define DER 149 | |
105 | +#define COUNTA 150 /* Breakpoint Counter (37-44) */ | |
106 | +#define COUNTB 151 /* Breakpoint Counter (37-44) */ | |
107 | +#define LCTRL1 156 /* Load/Store Support (37-40) */ | |
108 | +#define LCTRL2 157 /* Load/Store Support (37-41) */ | |
109 | +#define ICTRL 158 | |
110 | + | |
111 | +#endif /* CONFIG_8xx, CONFIG_MPC824X */ | |
112 | + | |
113 | +#if defined(CONFIG_8xx) | |
114 | + | |
115 | +/* Registers in the processor's internal memory map that we use. | |
116 | +*/ | |
117 | +#define SYPCR 0x00000004 | |
118 | +#define BR0 0x00000100 | |
119 | +#define OR0 0x00000104 | |
120 | +#define BR1 0x00000108 | |
121 | +#define OR1 0x0000010c | |
122 | +#define BR2 0x00000110 | |
123 | +#define OR2 0x00000114 | |
124 | +#define BR3 0x00000118 | |
125 | +#define OR3 0x0000011c | |
126 | +#define BR4 0x00000120 | |
127 | +#define OR4 0x00000124 | |
128 | + | |
129 | +#define MAR 0x00000164 | |
130 | +#define MCR 0x00000168 | |
131 | +#define MAMR 0x00000170 | |
132 | +#define MBMR 0x00000174 | |
133 | +#define MSTAT 0x00000178 | |
134 | +#define MPTPR 0x0000017a | |
135 | +#define MDR 0x0000017c | |
136 | + | |
137 | +#define TBSCR 0x00000200 | |
138 | +#define TBREFF0 0x00000204 | |
139 | + | |
140 | +#define PLPRCR 0x00000284 | |
141 | + | |
142 | +#elif defined(CONFIG_8260) | |
143 | + | |
144 | +#define HID2 1011 | |
145 | + | |
146 | +#define HID0_IFEM (1<<7) | |
147 | + | |
148 | +#define HID0_ICE_BITPOS 16 | |
149 | +#define HID0_DCE_BITPOS 17 | |
150 | + | |
151 | +#define IM_REGBASE 0x10000 | |
152 | +#define IM_SYPCR (IM_REGBASE+0x0004) | |
153 | +#define IM_SWSR (IM_REGBASE+0x000e) | |
154 | +#define IM_BR0 (IM_REGBASE+0x0100) | |
155 | +#define IM_OR0 (IM_REGBASE+0x0104) | |
156 | +#define IM_BR1 (IM_REGBASE+0x0108) | |
157 | +#define IM_OR1 (IM_REGBASE+0x010c) | |
158 | +#define IM_BR2 (IM_REGBASE+0x0110) | |
159 | +#define IM_OR2 (IM_REGBASE+0x0114) | |
160 | +#define IM_MPTPR (IM_REGBASE+0x0184) | |
161 | +#define IM_PSDMR (IM_REGBASE+0x0190) | |
162 | +#define IM_PSRT (IM_REGBASE+0x019c) | |
163 | +#define IM_IMMR (IM_REGBASE+0x01a8) | |
164 | +#define IM_SCCR (IM_REGBASE+0x0c80) | |
165 | + | |
166 | +#endif | |
167 | + | |
168 | +#define curptr r2 | |
169 | + | |
170 | +#define SYNC \ | |
171 | + sync; \ | |
172 | + isync | |
173 | + | |
174 | +/* | |
175 | + * Macros for storing registers into and loading registers from | |
176 | + * exception frames. | |
177 | + */ | |
178 | +#define SAVE_GPR(n, base) stw n,GPR0+4*(n)(base) | |
179 | +#define SAVE_2GPRS(n, base) SAVE_GPR(n, base); SAVE_GPR(n+1, base) | |
180 | +#define SAVE_4GPRS(n, base) SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base) | |
181 | +#define SAVE_8GPRS(n, base) SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base) | |
182 | +#define SAVE_10GPRS(n, base) SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base) | |
183 | +#define REST_GPR(n, base) lwz n,GPR0+4*(n)(base) | |
184 | +#define REST_2GPRS(n, base) REST_GPR(n, base); REST_GPR(n+1, base) | |
185 | +#define REST_4GPRS(n, base) REST_2GPRS(n, base); REST_2GPRS(n+2, base) | |
186 | +#define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base) | |
187 | +#define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base) | |
188 | + | |
189 | +/* | |
190 | + * GCC sometimes accesses words at negative offsets from the stack | |
191 | + * pointer, although the SysV ABI says it shouldn't. To cope with | |
192 | + * this, we leave this much untouched space on the stack on exception | |
193 | + * entry. | |
194 | + */ | |
195 | +#define STACK_UNDERHEAD 64 | |
196 | + | |
197 | +/* | |
198 | + * Exception entry code. This code runs with address translation | |
199 | + * turned off, i.e. using physical addresses. | |
200 | + * We assume sprg3 has the physical address of the current | |
201 | + * task's thread_struct. | |
202 | + */ | |
203 | +#define EXCEPTION_PROLOG \ | |
204 | + mtspr SPRG0,r20; \ | |
205 | + mtspr SPRG1,r21; \ | |
206 | + mfcr r20; \ | |
207 | + subi r21,r1,INT_FRAME_SIZE+STACK_UNDERHEAD; /* alloc exc. frame */\ | |
208 | + stw r20,_CCR(r21); /* save registers */ \ | |
209 | + stw r22,GPR22(r21); \ | |
210 | + stw r23,GPR23(r21); \ | |
211 | + mfspr r20,SPRG0; \ | |
212 | + stw r20,GPR20(r21); \ | |
213 | + mfspr r22,SPRG1; \ | |
214 | + stw r22,GPR21(r21); \ | |
215 | + mflr r20; \ | |
216 | + stw r20,_LINK(r21); \ | |
217 | + mfctr r22; \ | |
218 | + stw r22,_CTR(r21); \ | |
219 | + mfspr r20,XER; \ | |
220 | + stw r20,_XER(r21); \ | |
221 | + mfspr r22,SRR0; \ | |
222 | + mfspr r23,SRR1; \ | |
223 | + stw r0,GPR0(r21); \ | |
224 | + stw r1,GPR1(r21); \ | |
225 | + stw r2,GPR2(r21); \ | |
226 | + stw r1,0(r21); \ | |
227 | + mr r1,r21; /* set new kernel sp */ \ | |
228 | + SAVE_4GPRS(3, r21); | |
229 | +/* | |
230 | + * Note: code which follows this uses cr0.eq (set if from kernel), | |
231 | + * r21, r22 (SRR0), and r23 (SRR1). | |
232 | + */ | |
233 | + | |
234 | +/* | |
235 | + * Critical exception entry code. This is just like the other exception | |
236 | + * code except that it uses SRR2 and SRR3 instead of SRR0 and SRR1. | |
237 | + */ | |
238 | +#define CRITICAL_EXCEPTION_PROLOG \ | |
239 | + mtspr SPRG0,r20; \ | |
240 | + mtspr SPRG1,r21; \ | |
241 | + mfcr r20; \ | |
242 | + subi r21,r1,INT_FRAME_SIZE+STACK_UNDERHEAD; /* alloc exc. frame */\ | |
243 | + stw r20,_CCR(r21); /* save registers */ \ | |
244 | + stw r22,GPR22(r21); \ | |
245 | + stw r23,GPR23(r21); \ | |
246 | + mfspr r20,SPRG0; \ | |
247 | + stw r20,GPR20(r21); \ | |
248 | + mfspr r22,SPRG1; \ | |
249 | + stw r22,GPR21(r21); \ | |
250 | + mflr r20; \ | |
251 | + stw r20,_LINK(r21); \ | |
252 | + mfctr r22; \ | |
253 | + stw r22,_CTR(r21); \ | |
254 | + mfspr r20,XER; \ | |
255 | + stw r20,_XER(r21); \ | |
256 | + mfspr r22,990; /* SRR2 */ \ | |
257 | + mfspr r23,991; /* SRR3 */ \ | |
258 | + stw r0,GPR0(r21); \ | |
259 | + stw r1,GPR1(r21); \ | |
260 | + stw r2,GPR2(r21); \ | |
261 | + stw r1,0(r21); \ | |
262 | + mr r1,r21; /* set new kernel sp */ \ | |
263 | + SAVE_4GPRS(3, r21); | |
264 | +/* | |
265 | + * Note: code which follows this uses cr0.eq (set if from kernel), | |
266 | + * r21, r22 (SRR2), and r23 (SRR3). | |
267 | + */ | |
268 | + | |
269 | +/* | |
270 | + * Exception vectors. | |
271 | + * | |
272 | + * The data words for `hdlr' and `int_return' are initialized with | |
273 | + * OFFSET values only; they must be relocated first before they can | |
274 | + * be used! | |
275 | + */ | |
276 | +#define STD_EXCEPTION(n, label, hdlr) \ | |
277 | + . = n; \ | |
278 | +label: \ | |
279 | + EXCEPTION_PROLOG; \ | |
280 | + lwz r3,GOT(transfer_to_handler); \ | |
281 | + mtlr r3; \ | |
282 | + addi r3,r1,STACK_FRAME_OVERHEAD; \ | |
283 | + li r20,MSR_KERNEL; \ | |
284 | + rlwimi r20,r23,0,25,25; \ | |
285 | + blrl ; \ | |
286 | +.L_ ## label : \ | |
287 | + .long hdlr - _start + EXC_OFF_SYS_RESET; \ | |
288 | + .long int_return - _start + EXC_OFF_SYS_RESET | |
289 | + | |
290 | + | |
291 | +#define CRIT_EXCEPTION(n, label, hdlr) \ | |
292 | + . = n; \ | |
293 | +label: \ | |
294 | + CRITICAL_EXCEPTION_PROLOG; \ | |
295 | + lwz r3,GOT(transfer_to_handler); \ | |
296 | + mtlr r3; \ | |
297 | + addi r3,r1,STACK_FRAME_OVERHEAD; \ | |
298 | + li r20,MSR_KERNEL; \ | |
299 | + rlwimi r20,r23,0,25,25; \ | |
300 | + blrl ; \ | |
301 | +.L_ ## label : \ | |
302 | + .long hdlr - _start + EXC_OFF_SYS_RESET; \ | |
303 | + .long crit_return - _start + EXC_OFF_SYS_RESET | |
304 | + | |
305 | +#endif /* __PPC_ASM_TMPL__ */ |