• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/cfe/cfe/arch/mips/common/include/
1/*  *********************************************************************
2    *  Broadcom Common Firmware Environment (CFE)
3    *
4    *  MIPS Macros				File: mipsmacros.h
5    *
6    *  Macros to deal with various mips-related things.
7    *
8    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
9    *
10    *********************************************************************
11    *
12    *  Copyright 2000,2001,2002,2003
13    *  Broadcom Corporation. All rights reserved.
14    *
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.
21    *
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.
25    *
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.
31    *
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    ********************************************************************* */
46
47/*  *********************************************************************
48    *  32/64-bit macros
49    ********************************************************************* */
50
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
76
77
78/*  *********************************************************************
79    *  NORMAL_VECTOR(addr,vecname,vecdest)
80    *  NORMAL_XVECTOR(addr,vecname,vecdest,code)
81    *
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.
85    *
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
91    *
92    *  Return value:
93    *  	   nothing
94    ********************************************************************* */
95
96
97#define NORMAL_VECTOR(addr,vecname,vecdest) \
98       .globl vecname    ;                   \
99       .org   addr       ;                   \
100vecname: b    vecdest    ;                   \
101       nop;
102
103#define NORMAL_XVECTOR(addr,vecname,vecdest,code) \
104       .globl vecname    ;                   \
105       .org   addr       ;                   \
106vecname: b    vecdest    ;                   \
107	 li   k0,code    ;		     \
108       nop;
109
110
111/*  *********************************************************************
112    *  Evil macros for bi-endian support.
113    *
114    *  The magic here is in the instruction encoded as 0x10000014.
115    *
116    *  This instruction in big-endian is:   "b .+0x54"
117    *  this instruction in little-endian is: "bne zero,zero,.+0x44"
118    *
119    *  So, depending on what the system endianness is, it will either
120    *  branch to .+0x54 or not branch at all.
121    *
122    *  the instructions that follow are:
123    *
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)
132    *
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.
138    *
139    *  the instructions at the vectors will either jump to the
140    *  big-endian or little-endian code based on system endianness.
141    *
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.
147    *
148    *  More information about how this works can be found in the
149    *  CFE Manual.
150    ********************************************************************* */
151
152#define __SWAPW(x) ((((x) & 0xFF) << 8) | (((x) & 0xFF00) >> 8))
153
154#define BIENDIAN_VECTOR(addr,vecname,vecdest) \
155       .globl vecname    ;                   \
156       .org   addr       ;                   \
157vecname: .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;
166
167#define BIENDIAN_XVECTOR(addr,vecname,vecdest,code) \
168       .globl vecname    ;                   \
169       .org   addr       ;                   \
170vecname: .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;
180
181
182
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    ********************************************************************* */
189
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
197
198
199
200/*  *********************************************************************
201    *  LOADREL(reg,label)
202    *
203    *  Load the address of a label, but do it in a position-independent
204    *  way.
205    *
206    *  Input parameters:
207    *  	   reg - register to load
208    *  	   label - label whose address to load
209    *
210    *  Return value:
211    *  	   ra is trashed!
212    ********************************************************************* */
213
214#if CFG_EMBEDDED_PIC
215#define LOADREL(reg,label)			\
216	.set noreorder ;			\
217	bal  1f	       ;			\
218	nop	       ;			\
2191:	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		;			\
2281:	nop		;			\
229	.set reorder	;			\
230	la	reg,1b	;			\
231	subu	ra,reg	;			\
232	la	reg,label ;			\
233	addu	reg,ra	;
234#endif
235
236
237
238/*  *********************************************************************
239    *  JUMPREL(reg)
240    *
241    *  Jump relative to the current PC.
242    *
243    *  Input parameters:
244    *  	   reg - contains linked address to fix up
245    *
246    *  Return value:
247    *  	   ra is trashed!
248    ********************************************************************* */
249
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		;			\
2611:	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
274
275/*  *********************************************************************
276    *  CALLINIT_KSEG1(label,table,offset)
277    *  CALLINIT_KSEG0(label,table,offset)
278    *
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.
283    *
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.
288    *
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
293    *
294    *  Return value:
295    *  	   k1,ra is trashed.
296    ********************************************************************* */
297
298
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
314
315/*
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.
321 */
322
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 ;                      \
330123:	jal	k1
331#else
332#define CALLINIT_RELOC CALLINIT_KSEG0
333#endif
334
335
336
337/*  *********************************************************************
338    *  SPIN_LOCK(lock,reg1,reg2)
339    *
340    *  Acquire a spin lock.
341    *
342    *  Input parameters:
343    *  	   lock - symbol (address) of lock to acquire
344    *  	   reg1,reg2 - registers we can use to acquire lock
345    *
346    *  Return value:
347    *  	   nothing (lock acquired)
348    ********************************************************************* */
349
350#define SPIN_LOCK(lock,reg1,reg2)                 \
351        la      reg1,lock ;                       \
3521:	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 ;			  \
358	nop
359
360/*  *********************************************************************
361    *  SPIN_UNLOCK(lock,reg1)
362    *
363    *  Release a spin lock.
364    *
365    *  Input parameters:
366    *  	   lock - symbol (address) of lock to release
367    *  	   reg1 - a register we can use
368    *
369    *  Return value:
370    *  	   nothing (lock released)
371    ********************************************************************* */
372
373
374#define SPIN_UNLOCK(lock,reg1)			 \
375	la	reg1,lock ;			 \
376	sw	zero,0(reg1)
377
378
379/*  *********************************************************************
380    *  SETCCAMODE(treg,mode)
381    *
382    *  Set cacheability mode.  For some of the pass1 workarounds we
383    *  do this alot, so here's a handy macro.
384    *
385    *  Input parameters:
386    *  	   treg - temporary register we can use
387    *  	   mode - new mode (K_CFG_K0COH_xxx)
388    *
389    *  Return value:
390    *  	   nothing
391    ********************************************************************* */
392
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
400
401
402/*  *********************************************************************
403    *  Declare variables
404    ********************************************************************* */
405
406#define DECLARE_LONG(x) \
407                .global x ; \
408x:              _LONG_  0
409
410
411
412
413/*
414 * end
415 */
416