1 /* *********************************************************************
2 * SB1250 Board Support Package
4 * CPU initialization File: bcmcore_cpuinit.S
6 * This module contains code to initialize the CPU cores.
8 * Note: all the routines in this module rely on registers only,
9 * since DRAM may not be active yet.
11 * Author: Mitch Lichtenberg (mpl@broadcom.com)
13 *********************************************************************
15 * XX Copyright 2000,2001
16 * Broadcom Corporation. All rights reserved.
18 * BROADCOM PROPRIETARY AND CONFIDENTIAL
20 * This software is furnished under license and may be used and
21 * copied only in accordance with the license.
22 ********************************************************************* */
25 #include "exception.h"
26 #include "bsp_config.h"
27 #include "mipsmacros.h"
28 #include "cpu_config.h" /* for ERET and HAZARD */
36 /* *********************************************************************
38 ********************************************************************* */
40 #define R_CPU_CP0INIT _TBLIDX(0)
41 #define R_CPU_L1CINIT _TBLIDX(1)
42 #define R_CPU_SETLEDS _TBLIDX(2)
44 #define SETLEDS1(a,b,c,d) \
45 li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \
46 CALLINIT_KSEG1(cpuinit_table,R_CPU_SETLEDS)
47 #define SETLEDS(a,b,c,d) \
48 li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \
49 CALLINIT_KSEG0(cpuinit_table,R_CPU_SETLEDS)
52 _LONG_ bcmcore_cp0_init # [ 0 ] R_CPU_CP0INIT
53 _LONG_ bcmcore_l1cache_init # [ 1 ] R_CPU_L1CINIT
54 _LONG_ board_setleds # [ 2 ] R_CPU_SETLEDS
57 /* *********************************************************************
60 * Initialize an BCMCORE CPU's CP0 registers
70 ********************************************************************* */
73 LEAF(bcmcore_cp0_init)
77 mtc0 zero,C0_WATCHLO # Watch registers.
79 mtc0 zero,C0_CAUSE # must clear before writing SR
81 mfc0 v0,C0_SR # Get status register
82 and v0,M_SR_SR # preserve soft reset
86 or v0,M_SR_BEV # exceptions to boot vector
88 mtc0 v0,C0_SR # set up the status register
92 bne v0,0x00029000,1f # Broadcom BCM330X
95 or v0,0x80000000 # Enable icache
96 or v0,0x40000000 # Enable dcache
99 1: bne v0,0x00019700,2f # 74k core
104 2: mtc0 zero,C0_COUNT
107 # This is probably not the right init value for C0_COMPARE,
108 # but it seems to be necessary for the sim model right now.
116 # Initialize all the TLB entries to some invalid value
119 mtc0 zero,C0_TLBHI # TLB entry (high half)
122 mtc0 zero,C0_TLBLO0 /* tlblo0 = invalid */
124 mtc0 zero,C0_TLBLO1 /* tlblo1 = invalid */
126 mtc0 zero,C0_PGMASK /* 4K pages */
129 li t0,K1BASE /* tlbhi = impossible vpn */
133 srl t1,S_CFG_MMUSIZE /* index */
141 addu t0,0x2000 /* inc vpn */
152 END(bcmcore_cp0_init)
155 /* *********************************************************************
158 * Do initialization of the Broadcom core
165 ********************************************************************* */
168 LEAF(bcmcore_cpuinit)
172 SETLEDS1('C','P','U','I')
173 CALLINIT_KSEG1(cpuinit_table,R_CPU_CP0INIT)
175 SETLEDS1('L','1','C','I')
176 CALLINIT_KSEG1(cpuinit_table,R_CPU_L1CINIT)
184 /* *********************************************************************
187 * Dummy handler for routines we don't need to implement, like
188 * the multiprocessor stuff
198 ********************************************************************* */
207 /* *********************************************************************
210 * This routine is called when someone soft-exits to CFE. We
211 * reinitialize any CP0 stuff here.
218 ********************************************************************* */
220 LEAF(bcmcore_cpurestart)
224 END(bcmcore_cpurestart)
227 /* *********************************************************************
230 * Perform various cache operations on a BCM Core
233 * a0 - flag bits (CFE_CACHE_xxx)
240 ********************************************************************* */
242 LEAF(bcmcore_cacheops)
249 * With no flags, we flush L1D and invalid L1I
253 li v1,CFE_CACHE_FLUSH_D | CFE_CACHE_INVAL_I
257 * Flush the D-Cache, since the program we loaded is "data".
260 and a0,v1,CFE_CACHE_FLUSH_D | CFE_CACHE_INVAL_D | CFE_CACHE_FLUSH_RANGE | CFE_CACHE_INVAL_RANGE
262 jal bcmcore_l1cache_flush_d
266 * Invalidate the I-Cache, so that addresses in the program
267 * region will miss and need to be filled from the data we
268 * just flushed above.
271 and a0,v1,CFE_CACHE_INVAL_I
273 jal bcmcore_l1cache_inval_i
279 END(bcmcore_cacheops)
283 /* *********************************************************************
286 * This is the TLB exception handler for the bcmcore
288 * Note: only K0 and K1 are available to us at this time.
295 ********************************************************************* */
298 LEAF(bcmcore_tlbhandler)
308 * This requires a bit of explanation: We only support 256KB
309 * of mapped space for the boot program. This space will be
310 * mapped from 0x2000_0000 to 0x2004_0000 to some physical
311 * memory allocated by the firmware. This is 64 pages
314 * We know our BadVPN2 will be in the range
315 * 0x100000 to 0x1001F0, since the memory is mapped from
316 * 0x2000_0000 to 0x2004_0000. BadVPN2 plus the four bits
317 * of zeroes at the end are bits 31..9
319 * We also want to place the PTEbase on something other than
320 * a 16MB boundary. Each entry is 16 bytes, and there
321 * are 64 entries, so we need only 10 bits to address
322 * the entire table (it can therefore be aligned on a
325 * To make this work, we'll shift PTEbase to the right, leaving
326 * the bottom ten bits for the page number, as:
328 * Bits 31..10: PTEbase
330 * Bits 3..0: 16 bytes for table entry
333 * PTEbase gets shifted right 13 bits.
334 * BadVPN gets masked at 6 bits (mask is 0x3F0)
335 * The bottom 4 bits are zero.
337 * To range check the address, we can shift the Bad VPN
338 * right by 9 bits, and check for values of 0x1000 and
344 * This part range checks the VPN2 field in the
345 * context register. We only handle
346 * VPN2s in the range 0x100000 to 0x1001F0
350 mfc0 k0,C0_CTEXT # Get context
351 sra k0,8 # keep hi part
352 and k0,0x1FFF # of VPN2
353 li k1,0x1000 # 0x1000 is ok
356 li k1,0x1001 # 0x1001 is ok
360 li k0,XTYPE_TLBFILL # all other bits are not
364 1: mfc0 k0,C0_CTEXT # Get context
365 sra k0,13 # Shift PTEbase
366 li k1,0x3FF # Generate mask to kill
367 not k1 # BadVPN2 bits
368 and k0,k1 # keep only PTEBase part.
370 mfc0 k1,C0_CTEXT # Get Context
371 and k1,0x3F0 # Keep only BadVPN2 bits
372 or k1,k0 # Replace PTEBase
374 ld k0,0(k1) # Load entrylo0
375 ld k1,8(k1) # Load entrylo1
376 mtc0 k0,C0_TLBLO0 # and write to CP0
378 tlbwr # put it in the TLB
385 END(bcmcore_tlbhandler)
388 /* *********************************************************************
390 ********************************************************************* */