• 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/cpu/rm5200/src/
1/*  *********************************************************************
2    *  P5064 Board Support Package
3    *
4    *  CPU initialization			File: rm5200_cpuinit.S
5    *
6    *  This module contains code to initialize the CPU.
7    *
8    *  Note: all the routines in this module rely on registers only,
9    *        since DRAM may not be active yet.
10    *
11    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
12    *
13    *********************************************************************
14    *
15    *  Copyright 2000,2001,2002,2003
16    *  Broadcom Corporation. All rights reserved.
17    *
18    *  This software is furnished under license and may be used and
19    *  copied only in accordance with the following terms and
20    *  conditions.  Subject to these conditions, you may download,
21    *  copy, install, use, modify and distribute modified or unmodified
22    *  copies of this software in source and/or binary form.  No title
23    *  or ownership is transferred hereby.
24    *
25    *  1) Any source code used, modified or distributed must reproduce
26    *     and retain this copyright notice and list of conditions
27    *     as they appear in the source file.
28    *
29    *  2) No right is granted to use any trade name, trademark, or
30    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
31    *     name may not be used to endorse or promote products derived
32    *     from this software without the prior written permission of
33    *     Broadcom Corporation.
34    *
35    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
36    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
37    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
38    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
39    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
40    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
41    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
42    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
43    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
44    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
45    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
46    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
47    *     THE POSSIBILITY OF SUCH DAMAGE.
48    ********************************************************************* */
49
50#include "sbmips.h"
51#include "bsp_config.h"
52#include "mipsmacros.h"
53#include "exception.h"
54
55
56		.text
57		.set mips64
58
59
60/*  *********************************************************************
61    *  Macros
62    ********************************************************************* */
63
64#define CFG_BE		0x00008000	/* Big Endian */
65#define CFG_EPMASK	0x0f000000	/* Transmit data pattern */
66#define CFG_EPD		0x00000000	/* D */
67#define NTLBENTRIES 64
68
69/*
70 * Duplicates from cfe_iocb.h -- warning!
71 */
72
73#define CFE_CACHE_FLUSH_D	1
74#define CFE_CACHE_INVAL_I	2
75#define CFE_CACHE_INVAL_D	4
76#define CFE_CACHE_INVAL_L2	8
77#define CFE_CACHE_FLUSH_L2	16
78
79/*  *********************************************************************
80    *  Linkage tables
81    ********************************************************************* */
82
83#define R_CPU_CP0INIT	_TBLIDX(0)
84#define R_CPU_L1CINIT	_TBLIDX(1)
85#define R_CPU_SETLEDS	_TBLIDX(2)
86
87cpuinit_table:
88		_LONG_  rm5200_cp0_init		# [  0] R_CPU_CP0INIT
89		_LONG_  rm5200_l1cache_init	# [  1] R_CPU_L1CINIT
90		_LONG_  board_setleds		# [  2] R_CPU_SETLEDS
91
92#define SETLEDS1(a,b,c,d)                     \
93       li     a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ;    \
94       CALLINIT_KSEG1(cpuinit_table,R_CPU_SETLEDS)
95#define SETLEDS(a,b,c,d)                     \
96       li     a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ;    \
97       CALLINIT_KSEG0(cpuinit_table,R_CPU_SETLEDS)
98
99
100
101/*  *********************************************************************
102    *  RM5200_CP0_INIT
103    *
104    *  Initialize CP0 registers for an RM5200 core.
105    *
106    *  Input parameters:
107    *  	   nothing
108    *
109    *  Return value:
110    *  	   nothing
111    ********************************************************************* */
112
113LEAF(rm5200_cp0_init)
114
115	/*
116	 * Set SR and CAUSE to something sensible.
117	 */
118
119		.set noreorder
120		mfc0	t0,C0_PRID
121		mfc0	v0,C0_SR
122		mtc0	zero,C0_WATCHLO
123		mtc0	zero,C0_WATCHHI
124		li	t1,-1
125		mtc0	t1,C0_COMPARE
126		and	v0,M_SR_SR		# preserve Soft Reset
127		or	v0,M_SR_BEV		# set Boot Exceptions
128		mtc0	zero,C0_CAUSE		# Must clear WP before
129		mtc0	v0,C0_SR		# writing STATUS register.
130		.set reorder
131
132
133		mfc0	t1,C0_CONFIG
134
135		mtc0	zero,C0_WATCHLO
136		mtc0	zero,C0_WATCHHI
137
138	/*
139	 * make KSEG0 cacheable
140	 */
141
142	 	and	t1,~M_CFG_K0COH
143		or	t1,V_CFG_K0COH(K_CFG_K0COH_CACHEABLE)
144
145	/*
146	 * set DDDD rate for CPUs that aren't hardware configured
147 	 */
148
149	 	and	t1,~CFG_EPMASK
150		or	t1,CFG_EPD
151
152#ifdef __MIPSEB
153		or	t1,CFG_BE
154#else
155		and	t1,~CFG_BE
156#endif
157		mtc0	t1,C0_CONFIG
158
159
160	/*
161	 * initialize tlb
162	 */
163	 	mtc0	zero,C0_TLBLO0		/* tlblo0 = invalid */
164		mtc0	zero,C0_TLBLO1		/* tlblo1 = invalid */
165		mtc0	zero,C0_PGMASK
166		li	t8,K1BASE		/* tlbhi  = impossible vpn */
167		li	t9,(NTLBENTRIES-1)	/* index */
168
169
170		.set noreorder
171		nop
1721:		mtc0	t8,C0_TLBHI
173		mtc0	t9,C0_INX
174		addu	t8,0x2000		/* inc vpn */
175		tlbwi
176		bnez	t9,1b
177		subu	t9,1			# BDSLOT
178		.set reorder
179
180		j	ra
181
182END(rm5200_cp0_init)
183
184
185/*  *********************************************************************
186    *  RM5200_NULL_INIT
187    *
188    *  This stub routine is used by initialization functions that
189    *  we leave unimplemented.
190    *
191    *  Input parameters:
192    *  	   nothing
193    *
194    *  Return value:
195    *  	   nothing
196    ********************************************************************* */
197
198LEAF(rm5200_null_init)
199		j	ra
200END(rm5200_null_init)
201
202
203
204/*  *********************************************************************
205    *  RM5200_CPUINIT
206    *
207    *  Initialize the CPU core.
208    *
209    *  Input parameters:
210    *  	   nothing
211    *
212    *  Return value:
213    *  	   nothing
214    ********************************************************************* */
215
216LEAF(rm5200_cpuinit)
217
218		move	k0,ra			/* will be trashing RA */
219
220	/*
221	 * Basic CPU initialization
222	 */
223
224		CALLINIT_KSEG1(cpuinit_table,R_CPU_CP0INIT)
225
226	/*
227	 * CP0 registers
228	 */
229
230
231#------------------------------------------------------------------------------
232
233	/*
234	 * Init the L1 cache.
235	 */
236
237#if CFG_INIT_L1
238		SETLEDS1('L','1','C','I')
239		CALLINIT_KSEG1(cpuinit_table,R_CPU_L1CINIT)
240#endif
241
242	/*
243         * There is no L2 cache.
244         */
245
246		move	ra,k0			/* saved return address */
247		j	ra
248
249
250END(rm5200_cpuinit)
251
252/*  *********************************************************************
253    *  RM5200_CPURESTART
254    *
255    *  'Restart' the CPU (reset things back to some sane state after
256    *  a program returns to the firmware)
257    *
258    *  Input parameters:
259    *  	   nothing
260    *
261    *  Return value:
262    *  	   nothing
263    ********************************************************************* */
264
265LEAF(rm5200_cpurestart)
266
267		move	k0,ra
268
269		CALLINIT_KSEG0(cpuinit_table,R_CPU_CP0INIT)
270
271		LR	v0,cfe_pagetable		# reestablish
272		dsll	v0,v0,13			# see mips_arena.c for this
273		dmtc0	v0,C0_CTEXT			# boot area TLBs
274
275		move	ra,k0
276		j	ra
277
278END(rm5200_cpurestart)
279
280
281LEAF(rm5200_cacheops)
282
283		move	s0,ra
284
285		move	v1,a0
286
287	/*
288	 * With no flags, we flush L1D and invalid L1I
289	 */
290
291		bne	v1,zero,1f
292		li	v1,CFE_CACHE_FLUSH_D | CFE_CACHE_INVAL_I
2931:
294
295	/*
296	 * Flush the D-Cache, since the program we loaded is "data".
297	 */
298
299		and	a0,v1,CFE_CACHE_FLUSH_D
300		beq	a0,zero,1f
301		jal	rm5200_l1cache_flush_d
3021:
303
304	/*
305	 * Invalidate the I-Cache, so that addresses in the program
306	 * region will miss and need to be filled from the data we
307	 * just flushed above.
308	 */
309
310		and	a0,v1,CFE_CACHE_INVAL_I
311		beq	a0,zero,1f
312		jal	rm5200_l1cache_inval_i
3131:
314
315
316		move	ra,s0
317		j	ra
318
319END(rm5200_cacheops)
320
321/*  *********************************************************************
322    *  RM5200_TLBHANDLER
323    *
324    *  This is the TLB exception handler for the RM5200
325    *
326    *  Note: only K0 and K1 are available to us at this time.
327    *
328    *  Input parameters:
329    *  	   nothing
330    *
331    *  Return value:
332    *  	   nothing
333    ********************************************************************* */
334
335
336LEAF(rm5200_tlbhandler)
337                .set    noreorder
338                .set    noat
339
340/*
341 * This requires a bit of explanation:  We only support 256KB
342 * of mapped space for the boot program.  This space will be
343 * mapped from 0x2000_0000 to 0x2004_0000 to some physical
344 * memory allocated by the firmware.  This is 64 pages
345 * of 4KB each.
346 *
347 * We know our BadVPN2 will be in the range
348 * 0x100000 to 0x1001F0, since the memory is mapped from
349 * 0x2000_0000 to 0x2004_0000.  BadVPN2 plus the four bits
350 * of zeroes at the end are bits 31..9
351 *
352 * We also want to place the PTEbase on something other than
353 * a 16MB boundary.  Each entry is 16 bytes, and there
354 * are 64 entries, so we need only 10 bits to address
355 * the entire table (it can therefore be aligned on a
356 * 1KB boundary).
357 *
358 * To make this work, we'll shift PTEbase to the right, leaving
359 * the bottom ten bits for the page number, as:
360 *
361 *    Bits 31..10: PTEbase
362 *    Bits 9..4:   BadVPN
363 *    Bits 3..0:   16 bytes for table entry
364 *
365 * Therefore:
366 *    PTEbase gets shifted right 13 bits.
367 *    BadVPN  gets masked at 6 bits (mask is 0x3F0)
368 *    The bottom 4 bits are zero.
369 *
370 * To range check the address, we can shift the Bad VPN
371 * right by 9 bits, and check for values of 0x1000 and
372 * 0x1001.
373 */
374
375
376	/*
377	 * This part range checks the VPN2 field in the
378	 * context register.  We only handle
379	 * VPN2s in the range 0x100000 to 0x1001F0
380	 */
381		dmfc0	k0,C0_TLBHI
382
383		dmfc0	k0,C0_CTEXT		# Get context
384		dsra	k0,8			# keep hi part
385		and	k0,0x1FFF		# of VPN2
386		li	k1,0x1000		# 0x1000 is ok
387		beq	k0,k1,1f		#
388		nop				# BDSLOT
389		li	k1,0x1001		# 0x1001 is ok
390		beq	k0,k1,1f		#
391		nop				# BDSLOT
392
393		li	k0,XTYPE_TLBFILL	# all other bits are not
394		j	_exc_entry
395		nop				# BDSLOT
396
3971:		dmfc0	k0,C0_CTEXT		# Get context
398		dsra	k0,13			# Shift PTEbase
399		li	k1,0x3FF		# Generate mask to kill
400		not	k1			# BadVPN2 bits
401		and	k0,k1			# keep only PTEBase part.
402
403		dmfc0	k1,C0_CTEXT		# Get Context
404		and	k1,0x3F0		# Keep only BadVPN2 bits
405		or	k1,k0			# Replace PTEBase
406
407		ld	k0,0(k1)		# Load entrylo0
408		ld	k1,8(k1)		# Load entrylo1
409		mtc0	k0,C0_TLBLO0		# and write to CP0
410		mtc0	k1,C0_TLBLO1
411		tlbwr				# put it in the TLB
412		eret
413		nop
414
415		.set	reorder
416		.set	at
417
418END(rm5200_tlbhandler)
419
420/*  *********************************************************************
421    *  End
422    ********************************************************************* */
423