ec4858da8175d20182941d4711f8117e282a5ff3
[coreboot.git] / src / arch / ppc / include / ppc_asm.tmpl
1 /*
2  * (C) Copyright 2000
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., 51 Franklin St, Fifth Floor, Boston,
21  * MA 02110-1301 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  * FP register names
100  */
101 #define fr0     0
102 #define fr1     1
103 #define fr2     2
104 #define fr3     3
105 #define fr4     4
106 #define fr5     5
107 #define fr6     6
108 #define fr7     7
109 #define fr8     8
110 #define fr9     9
111 #define fr10    10
112 #define fr11    11
113 #define fr12    12
114 #define fr13    13
115 #define fr14    14
116 #define fr15    15
117 #define fr16    16
118 #define fr17    17
119 #define fr18    18
120 #define fr19    19
121 #define fr20    20
122 #define fr21    21
123 #define fr22    22
124 #define fr23    23
125 #define fr24    24
126 #define fr25    25
127 #define fr26    26
128 #define fr27    27
129 #define fr28    28
130 #define fr29    29
131 #define fr30    30
132 #define fr31    31
133
134 /* Some special registers */
135
136 #define TBRU    269     /* Time base Upper/Lower (Reading) */
137 #define TBRL    268
138 #define TBWU    284     /* Time base Upper/Lower (Writing) */
139 #define TBWL    285
140 #define XER     1
141 #define LR      8
142 #define CTR     9
143 #define HID0    1008    /* Hardware Implementation */
144 #define PVR     287     /* Processor Version */
145 #define SDR1    25      /* MMU hash base register */
146 #define DAR     19      /* Data Address Register */
147 #define SPR0    272     /* Supervisor Private Registers */
148 #define SPRG0   272
149 #define SPR1    273
150 #define SPRG1   273
151 #define SPR2    274
152 #define SPRG2   274
153 #define SPR3    275
154 #define SPRG3   275
155 #define DSISR   18
156 #define SRR0    26      /* Saved Registers (exception) */
157 #define SRR1    27
158 #define DEC     22      /* Decrementer */
159 #define EAR     282     /* External Address Register */
160 #define ICR     148     /* Interrupt Cause Register (37-44) */
161 #define DER     149
162 #define COUNTA  150     /* Breakpoint Counter       (37-44) */
163 #define COUNTB  151     /* Breakpoint Counter       (37-44) */
164 #define LCTRL1  156     /* Load/Store Support       (37-40) */
165 #define LCTRL2  157     /* Load/Store Support       (37-41) */
166 #define ICTRL   158
167
168 /* Registers in the processor's internal memory map that we use.
169 */
170 #define IMMR    0xff000000
171
172 #define SYPCR   0x00000004
173 #define BR0     0x00000100
174 #define OR0     0x00000104
175 #define BR1     0x00000108
176 #define OR1     0x0000010c
177 #define BR2     0x00000110
178 #define OR2     0x00000114
179 #define BR3     0x00000118
180 #define OR3     0x0000011c
181 #define BR4     0x00000120
182 #define OR4     0x00000124
183
184 #define MAR     0x00000164
185 #define MCR     0x00000168
186 #define MAMR    0x00000170
187 #define MBMR    0x00000174
188 #define MSTAT   0x00000178
189 #define MPTPR   0x0000017a
190 #define MDR     0x0000017c
191
192 #define TBSCR   0x00000200
193 #define TBREFF0 0x00000204
194
195 #define PLPRCR  0x00000284
196
197 #define curptr r2
198
199 #define SYNC \
200         sync; \
201         isync
202
203 /*
204  * Macros for storing registers into and loading registers from
205  * exception frames.
206  */
207 #define SAVE_GPR(n, base)       stw     n,GPR0+4*(n)(base)
208 #define SAVE_2GPRS(n, base)     SAVE_GPR(n, base); SAVE_GPR(n+1, base)
209 #define SAVE_4GPRS(n, base)     SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base)
210 #define SAVE_8GPRS(n, base)     SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base)
211 #define SAVE_10GPRS(n, base)    SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base)
212 #define REST_GPR(n, base)       lwz     n,GPR0+4*(n)(base)
213 #define REST_2GPRS(n, base)     REST_GPR(n, base); REST_GPR(n+1, base)
214 #define REST_4GPRS(n, base)     REST_2GPRS(n, base); REST_2GPRS(n+2, base)
215 #define REST_8GPRS(n, base)     REST_4GPRS(n, base); REST_4GPRS(n+4, base)
216 #define REST_10GPRS(n, base)    REST_8GPRS(n, base); REST_2GPRS(n+8, base)
217
218 /*
219  * GCC sometimes accesses words at negative offsets from the stack
220  * pointer, although the SysV ABI says it shouldn't.  To cope with
221  * this, we leave this much untouched space on the stack on exception
222  * entry.
223  */
224 #define STACK_UNDERHEAD 64
225
226 #if 0   /* we don't use virtual addresses in PPCBOOT */
227 #define tophys(rd,rs,rt)        addis   rd,rs,-KERNELBASE@h
228 #define tovirt(rd,rs,rt)        addis   rd,rs,KERNELBASE@h
229 #else
230 #define tophys(rd,rs,rt)        mr      rd,rs
231 #define tovirt(rd,rs,rt)        mr      rd,rs
232 #endif
233
234 /*
235  * Exception entry code.  This code runs with address translation
236  * turned off, i.e. using physical addresses.
237  * We assume sprg3 has the physical address of the current
238  * task's thread_struct.
239  */
240 #define EXCEPTION_PROLOG        \
241         mtspr   SPRG0,r20;      \
242         mtspr   SPRG1,r21;      \
243         mfcr    r20;            \
244         tophys(r21,r1,r21);             /* use tophys(kernel sp) otherwise */ \
245         subi    r21,r21,INT_FRAME_SIZE+STACK_UNDERHEAD; /* alloc exc. frame */\
246 1:      stw     r20,_CCR(r21);          /* save registers */ \
247         stw     r22,GPR22(r21); \
248         stw     r23,GPR23(r21); \
249         mfspr   r20,SPRG0;      \
250         stw     r20,GPR20(r21); \
251         mfspr   r22,SPRG1;      \
252         stw     r22,GPR21(r21); \
253         mflr    r20;            \
254         stw     r20,_LINK(r21); \
255         mfctr   r22;            \
256         stw     r22,_CTR(r21);  \
257         mfspr   r20,XER;        \
258         stw     r20,_XER(r21);  \
259         mfspr   r22,SRR0;       \
260         mfspr   r23,SRR1;       \
261         stw     r0,GPR0(r21);   \
262         stw     r1,GPR1(r21);   \
263         stw     r2,GPR2(r21);   \
264         stw     r1,0(r21);      \
265         tovirt(r1,r21,r1);              /* set new kernel sp */ \
266         SAVE_4GPRS(3, r21);
267 /*
268  * Note: code which follows this uses cr0.eq (set if from kernel),
269  * r21, r22 (SRR0), and r23 (SRR1).
270  */
271
272 /*
273  * Exception vectors.
274  *
275  * The data words for `hdlr' and `int_return' are initialized with
276  * OFFSET values only; they must be relocated first before they can
277  * be used!
278  */
279 #define STD_EXCEPTION(n, label, hdlr)                   \
280         . = n;                                          \
281 label:                                                  \
282         EXCEPTION_PROLOG;                               \
283         lwz     r3,GOT(transfer_to_handler);            \
284         mtlr    r3;                                     \
285         addi    r3,r1,STACK_FRAME_OVERHEAD;             \
286         li      r20,MSR_KERNEL;                         \
287         blrl    ;                                       \
288 .L_ ## label :                                          \
289         .long   hdlr - _start + EXC_OFF_SYS_RESET;      \
290         .long   int_return - _start + EXC_OFF_SYS_RESET
291
292
293 #endif  /* __PPC_ASM_TMPL__ */