GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / cfe / cfe / arch / mips / common / include / mipsmacros.h
blobf020eb8df8429eb2c2dfde634a11216c1a1eac27
1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
3 *
4 * MIPS Macros File: mipsmacros.h
6 * Macros to deal with various mips-related things.
7 *
8 * Author: Mitch Lichtenberg (mpl@broadcom.com)
9 *
10 *********************************************************************
12 * Copyright 2000,2001,2002,2003
13 * Broadcom Corporation. All rights reserved.
15 * This software is furnished under license and may be used and
16 * copied only in accordance with the following terms and
17 * conditions. Subject to these conditions, you may download,
18 * copy, install, use, modify and distribute modified or unmodified
19 * copies of this software in source and/or binary form. No title
20 * or ownership is transferred hereby.
22 * 1) Any source code used, modified or distributed must reproduce
23 * and retain this copyright notice and list of conditions
24 * as they appear in the source file.
26 * 2) No right is granted to use any trade name, trademark, or
27 * logo of Broadcom Corporation. The "Broadcom Corporation"
28 * name may not be used to endorse or promote products derived
29 * from this software without the prior written permission of
30 * Broadcom Corporation.
32 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
33 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
34 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
35 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
36 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
37 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
38 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
40 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
42 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
43 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
44 * THE POSSIBILITY OF SUCH DAMAGE.
45 ********************************************************************* */
47 /* *********************************************************************
48 * 32/64-bit macros
49 ********************************************************************* */
51 #ifdef __long64
52 #define _VECT_ .dword
53 #define _LONG_ .dword
54 #define SR sd
55 #define LR ld
56 #define ADD dadd
57 #define SUB dsub
58 #define MFC0 dmfc0
59 #define MTC0 dmtc0
60 #define REGSIZE 8
61 #define BPWSIZE 3 /* bits per word size */
62 #define _TBLIDX(x) ((x)*REGSIZE)
63 #else
64 #define _VECT_ .word
65 #define _LONG_ .word
66 #define SR sw
67 #define LR lw
68 #define ADD add
69 #define SUB sub
70 #define MFC0 mfc0
71 #define MTC0 mtc0
72 #define REGSIZE 4
73 #define BPWSIZE 2
74 #define _TBLIDX(x) ((x)*REGSIZE)
75 #endif
78 /* *********************************************************************
79 * NORMAL_VECTOR(addr,vecname,vecdest)
80 * NORMAL_XVECTOR(addr,vecname,vecdest,code)
82 * Declare a trap or dispatch vector. There are two flavors,
83 * DECLARE_XVECTOR sets up an indentifying code in k0 before
84 * jumping to the dispatch routine.
86 * Input parameters:
87 * addr - vector address
88 * vecname - for label at that address
89 * vecdest - destination (place vector jumps to)
90 * code - code to place in k0 before jumping
92 * Return value:
93 * nothing
94 ********************************************************************* */
97 #define NORMAL_VECTOR(addr,vecname,vecdest) \
98 .globl vecname ; \
99 .org addr ; \
100 vecname: b vecdest ; \
101 nop;
103 #define NORMAL_XVECTOR(addr,vecname,vecdest,code) \
104 .globl vecname ; \
105 .org addr ; \
106 vecname: b vecdest ; \
107 li k0,code ; \
108 nop;
111 /* *********************************************************************
112 * Evil macros for bi-endian support.
114 * The magic here is in the instruction encoded as 0x10000014.
116 * This instruction in big-endian is: "b .+0x54"
117 * this instruction in little-endian is: "bne zero,zero,.+0x44"
119 * So, depending on what the system endianness is, it will either
120 * branch to .+0x54 or not branch at all.
122 * the instructions that follow are:
124 * 0x10000014 "magic branch" (either-endian)
125 * 0x00000000 nop (bds) (either-endian)
126 * 0xD0BF1A3C lui k0,0xBFD0 (little-endian)
127 * 0xxxxx5A27 addu k0,vector (little-endian)
128 * 0x08004003 jr k0 (little-endian)
129 * 0x00000000 nop (bds) (little-endian)
130 * ... space up to offset 0x54
131 * ......... b vecaddr (big-endian)
133 * The idea is that the big-endian firmware is first, from 0..1MB
134 * in the flash, and the little-endian firmware is second,
135 * from 1..2MB in the flash. The little-endian firmware is
136 * set to load at BFD00000, so that its initial routines will
137 * work until relocation is completed.
139 * the instructions at the vectors will either jump to the
140 * big-endian or little-endian code based on system endianness.
142 * The ROM is built by compiling CFE twice, first with
143 * CFG_BIENDIAN=1 and CFG_LITTLE=0 (big-endian) and again
144 * with CFG_BIENDIAN=1 and CFG_LITTLE=1. The resulting
145 * cfe.bin files are located at 0xBFC00000 and 0xBFD00000
146 * for big and little-endian versions, respectively.
148 * More information about how this works can be found in the
149 * CFE Manual.
150 ********************************************************************* */
152 #define __SWAPW(x) ((((x) & 0xFF) << 8) | (((x) & 0xFF00) >> 8))
154 #define BIENDIAN_VECTOR(addr,vecname,vecdest) \
155 .globl vecname ; \
156 .org addr ; \
157 vecname: .word 0x10000014 ; \
158 .word 0 ; \
159 .word ((__SWAPW(BIENDIAN_LE_BASE >> 16)) << 16) | 0x1A3C ; \
160 .word (0x00005A27 | (((addr) & 0xFF) << 24) | (((addr) & 0xFF00) << 8)) ; \
161 .word 0x08004003 ; \
162 .word 0 ; \
163 .org ((addr) + 0x54) ; \
164 b vecdest ; \
165 nop;
167 #define BIENDIAN_XVECTOR(addr,vecname,vecdest,code) \
168 .globl vecname ; \
169 .org addr ; \
170 vecname: .word 0x10000014 ; \
171 .word 0 ; \
172 .word ((__SWAPW(BIENDIAN_LE_BASE >> 16)) << 16) | 0x1A3C ; \
173 .word (0x00005A27 | (((addr) & 0xFF) << 24) | (((addr) & 0xFF00) << 8)) ; \
174 .word 0x08004003 ; \
175 .word 0 ; \
176 .org ((addr) + 0x54) ; \
177 b vecdest ; \
178 li k0,code ; \
179 nop;
183 /* *********************************************************************
184 * Declare the right versions of DECLARE_VECTOR and
185 * DECLARE_XVECTOR depending on how we're building stuff.
186 * Generally, we only use the biendian version if we're building
187 * as CFG_BIENDIAN=1 and we're doing the big-endian MIPS version.
188 ********************************************************************* */
190 #if CFG_BIENDIAN && defined(__MIPSEB)
191 #define DECLARE_VECTOR BIENDIAN_VECTOR
192 #define DECLARE_XVECTOR BIENDIAN_XVECTOR
193 #else
194 #define DECLARE_VECTOR NORMAL_VECTOR
195 #define DECLARE_XVECTOR NORMAL_XVECTOR
196 #endif
200 /* *********************************************************************
201 * LOADREL(reg,label)
203 * Load the address of a label, but do it in a position-independent
204 * way.
206 * Input parameters:
207 * reg - register to load
208 * label - label whose address to load
210 * Return value:
211 * ra is trashed!
212 ********************************************************************* */
214 #if CFG_EMBEDDED_PIC
215 #define LOADREL(reg,label) \
216 .set noreorder ; \
217 bal 1f ; \
218 nop ; \
219 1: nop ; \
220 .set reorder ; \
221 la reg,label-1b ; \
222 addu reg,ra
223 #else
224 #define LOADREL(reg,label) \
225 .set noreorder ; \
226 bal 1f ; \
227 nop ; \
228 1: nop ; \
229 .set reorder ; \
230 la reg,1b ; \
231 subu ra,reg ; \
232 la reg,label ; \
233 addu reg,ra ;
234 #endif
238 /* *********************************************************************
239 * JUMPREL(reg)
241 * Jump relative to the current PC.
243 * Input parameters:
244 * reg - contains linked address to fix up
246 * Return value:
247 * ra is trashed!
248 ********************************************************************* */
250 #if CFG_EMBEDDED_PIC
251 #define JUMPREL1(reg) \
252 or reg,K1BASE ; \
253 jalr reg
254 #define JUMPREL(reg) \
255 jalr reg
256 #else
257 #define __JUMPREL(reg) \
258 .set noreorder ; \
259 bal 1f ; \
260 nop ; \
261 1: nop ; \
262 addu ra,reg ; \
263 la reg,1b ; \
264 subu reg,ra,reg ; \
265 .set reorder
266 #define JUMPREL1(reg) \
267 __JUMPREL(reg) ; \
268 or reg,K1BASE ; \
269 jalr reg
270 #define JUMPREL(reg) \
271 __JUMPREL(reg) ; \
272 jalr reg
273 #endif
275 /* *********************************************************************
276 * CALLINIT_KSEG1(label,table,offset)
277 * CALLINIT_KSEG0(label,table,offset)
279 * Call an initialization routine (usually in another module).
280 * If initialization routine lives in KSEG1 it may need
281 * special fixing if using the cached version of CFE (this is
282 * the default case). CFE is linked at a KSEG0 address.
284 * Embedded PIC is especially tricky, since the "la"
285 * instruction expands to calculations involving GP.
286 * In that case, use our table of offsets to
287 * load the routine address from a table in memory.
289 * Input parameters:
290 * label - routine to call if we can call directly
291 * table - symbol name of table containing routine addresses
292 * offset - offset within the above table
294 * Return value:
295 * k1,ra is trashed.
296 ********************************************************************* */
299 #define CALLINIT_KSEG0(table,tableoffset) \
300 LOADREL(k1,table) ; \
301 LR k1,tableoffset(k1) ; \
302 JUMPREL(k1)
303 #if CFG_RUNFROMKSEG0
304 /* Cached PIC code - call indirect through table */
305 #define CALLINIT_KSEG1(table,tableoffset) \
306 LOADREL(k1,table) ; \
307 or k1,K1BASE ; \
308 LR k1,tableoffset(k1) ; \
309 JUMPREL1(k1)
310 #else
311 /* Uncached PIC code - call indirect through table, always same KSEG */
312 #define CALLINIT_KSEG1 CALLINIT_KSEG0
313 #endif
316 * CALLINIT_RELOC is used once CFE's relocation is complete and
317 * the "mem_textreloc" variable is set up. (yes, this is nasty.)
318 * If 'gp' is set, we can presume that we've relocated
319 * and it's safe to read "mem_textreloc", otherwise use the
320 * address as-is from the table.
323 #if CFG_EMBEDDED_PIC
324 #define CALLINIT_RELOC(table,tableoffset) \
325 LOADREL(k1,table) ; \
326 LR k1,tableoffset(k1) ; \
327 beq gp,zero,123f ; \
328 LR k0,mem_textreloc ; \
329 ADD k1,k1,k0 ; \
330 123: jal k1
331 #else
332 #define CALLINIT_RELOC CALLINIT_KSEG0
333 #endif
337 /* *********************************************************************
338 * SPIN_LOCK(lock,reg1,reg2)
340 * Acquire a spin lock.
342 * Input parameters:
343 * lock - symbol (address) of lock to acquire
344 * reg1,reg2 - registers we can use to acquire lock
346 * Return value:
347 * nothing (lock acquired)
348 ********************************************************************* */
350 #define SPIN_LOCK(lock,reg1,reg2) \
351 la reg1,lock ; \
352 1: sync ; \
353 ll reg2,0(reg1) ; \
354 bne reg2,zero,1b ; \
355 li reg2,1 ; \
356 sc reg2,0(reg1) ; \
357 beq reg2,zero,1b ; \
360 /* *********************************************************************
361 * SPIN_UNLOCK(lock,reg1)
363 * Release a spin lock.
365 * Input parameters:
366 * lock - symbol (address) of lock to release
367 * reg1 - a register we can use
369 * Return value:
370 * nothing (lock released)
371 ********************************************************************* */
374 #define SPIN_UNLOCK(lock,reg1) \
375 la reg1,lock ; \
376 sw zero,0(reg1)
379 /* *********************************************************************
380 * SETCCAMODE(treg,mode)
382 * Set cacheability mode. For some of the pass1 workarounds we
383 * do this alot, so here's a handy macro.
385 * Input parameters:
386 * treg - temporary register we can use
387 * mode - new mode (K_CFG_K0COH_xxx)
389 * Return value:
390 * nothing
391 ********************************************************************* */
393 #define SETCCAMODE(treg,mode) \
394 mfc0 treg,C0_CONFIG ; \
395 srl treg,treg,3 ; \
396 sll treg,treg,3 ; \
397 or treg,treg,mode ; \
398 mtc0 treg,C0_CONFIG ; \
399 HAZARD
402 /* *********************************************************************
403 * Declare variables
404 ********************************************************************* */
406 #define DECLARE_LONG(x) \
407 .global x ; \
408 x: _LONG_ 0
414 * end