1/*  *********************************************************************
2    *  SB1250 Board Support Package
3    *
4    *  CPU initialization			File: sb1_cpuinit.S
5    *
6    *  This module contains code to initialize the CPU cores.
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
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 "cpu_config.h"
53#include "mipsmacros.h"
54
55
56		.text
57		.set mips64
58
59
60/*  *********************************************************************
61    *  Macros
62    ********************************************************************* */
63
64
65/*  *********************************************************************
66    *  SB1_ZERO_INT_REGS
67    *
68    *  Zero all the CPU's integer registers *except* FP, which we're
69    *  using within cpu_init to hold its return address.
70    *
71    *  Input parameters:
72    *  	   nothing
73    *
74    *  Return value:
75    *  	   nothing - all registers (except ra/R31) zero
76    ********************************************************************* */
77
78LEAF(sb1_zero_int_regs)
79
80		.set	noat
81		move	AT,zero
82		.set	at
83
84		move	v0,zero
85		move	v1,zero
86
87		move	a0,zero
88		move	a1,zero
89		move	a2,zero
90		move	a3,zero
91
92		move	t0,zero
93		move	t1,zero
94		move	t2,zero
95		move	t3,zero
96		move	t4,zero
97		move	t5,zero
98		move	t6,zero
99		move	t7,zero
100
101		move	ta0,zero
102		move	ta1,zero
103		move	ta2,zero
104		move	ta3,zero
105
106		move	s0,zero
107		move	s1,zero
108		move	s2,zero
109		move	s3,zero
110		move	s4,zero
111		move	s5,zero
112		move	s6,zero
113		move	s7,zero
114
115		move	t8,zero
116		move	t9,zero
117
118		/* note: do NOT zero k0/k1 here: it's used by VAPI exit. */
119		/* move	k0,zero */
120		/* move	k1,zero */
121
122		/*move	gp,zero*/
123		move	sp,zero
124		/* note: do NOT zero fp here */
125
126		jr	ra
127
128END(sb1_zero_int_regs)
129
130
131/*  *********************************************************************
132    *  SB1_ZERO_FP_REGS()
133    *
134    *  Initialize the CP1 (floating-point) registers
135    *
136    *  Input parameters:
137    *  	   nothing
138    *
139    *  Return value:
140    *  	   nothing
141    ********************************************************************* */
142
143LEAF(sb1_zero_fp_regs)
144
145		mfc0	v0,C0_SR		/* Get old SR_CU1 value */
146		or	v1,v0,M_SR_CU1		/* Turn on coprocessor 1 */
147		or	v1,v1,M_SR_FR		/* in 32-register mode */
148		mtc0	v1,C0_SR
149
150		ssnop				/* wait for mtc0 to finish */
151		ssnop
152		ssnop
153		ssnop
154		ssnop
155		ssnop
156		ssnop
157
158		cfc1	v1,$0			/* get FP impl register */
159		beq	v1,zero,no_fp		/* don't do this if no FP */
160
161		ctc1	zero,$31		/* Exception/status register */
162
163		dmtc1	zero,$f0		/* general data registers */
164		dmtc1	zero,$f1
165		dmtc1	zero,$f2
166		dmtc1	zero,$f3
167		dmtc1	zero,$f4
168		dmtc1	zero,$f5
169		dmtc1	zero,$f6
170		dmtc1	zero,$f7
171		dmtc1	zero,$f8
172		dmtc1	zero,$f9
173		dmtc1	zero,$f10
174		dmtc1	zero,$f11
175		dmtc1	zero,$f12
176		dmtc1	zero,$f13
177		dmtc1	zero,$f14
178		dmtc1	zero,$f15
179		dmtc1	zero,$f16
180		dmtc1	zero,$f17
181		dmtc1	zero,$f18
182		dmtc1	zero,$f19
183		dmtc1	zero,$f20
184		dmtc1	zero,$f21
185		dmtc1	zero,$f22
186		dmtc1	zero,$f23
187		dmtc1	zero,$f24
188		dmtc1	zero,$f25
189		dmtc1	zero,$f26
190		dmtc1	zero,$f27
191		dmtc1	zero,$f28
192		dmtc1	zero,$f29
193		dmtc1	zero,$f30
194		dmtc1	zero,$f31
195
196no_fp:		mtc0	v0,C0_SR		/* restore to original state */
197		j	ra
198
199END(sb1_zero_fp_regs)
200
201/*  *********************************************************************
202    *  SB1_CP0_INIT()
203    *
204    *  Initialize CP0 registers for an SB1 core
205    *
206    *  Input parameters:
207    *  	   nothing
208    *
209    *  Return value:
210    *  	   nothing
211    ********************************************************************* */
212
213LEAF(sb1_cp0_init)
214
215		.set	noreorder
216		mtc0	zero,C0_WATCHLO		# Clear out the watch regs.
217		mtc0	zero,C0_WATCHHI
218
219		mfc0	v0,C0_SR		# Get status register
220		and	v0,M_SR_SR		# preserve soft reset
221		or	v0,M_SR_BEV		# exceptions to boot vector
222
223		mtc0	zero,C0_CAUSE		# must clear before writing SR
224
225		mtc0	v0,C0_SR		# set up the status register
226
227		mfc0	v0,C0_CONFIG		# get current CONFIG register
228		srl	v0,v0,3			# strip out K0 bits
229		sll	v0,v0,3			# k0 bits now zero
230		or	v0,v0,K_CFG_K0COH_COHERENT # K0 is cacheable.
231		mtc0	v0,C0_CONFIG
232
233		mtc0	zero,C0_WATCHLO,0	# Watch registers.
234		mtc0	zero,C0_WATCHHI,0
235		mtc0	zero,C0_WATCHLO,1
236		mtc0	zero,C0_WATCHHI,1
237
238		mtc0	zero,C0_TLBHI		# TLB entry (high half)
239
240	#
241	# This is probably not the right init value for C0_COMPARE,
242	# but it seems to be necessary for the sim model right now.
243	#
244
245		li	v0,-1
246		mtc0	v0,C0_COMPARE
247
248	#
249	# Initialize all the TLB entries to some invalid value
250	#
251
252		mtc0	zero,C0_TLBLO0		/* tlblo0 = invalid */
253		mtc0	zero,C0_TLBLO1		/* tlblo1 = invalid */
254		mtc0	zero,C0_PGMASK
255		li	t0,K1BASE		/* tlbhi  = impossible vpn */
256		li	t1,(K_NTLBENTRIES-1)	/* index */
257
258		.set noreorder
259		nop
2601:		mtc0	t0,C0_TLBHI
261		mtc0	t1,C0_INX
262		addu	t0,0x2000		/* inc vpn */
263		tlbwi
264		bnez	t1,1b
265		subu	t1,1			# BDSLOT
266		.set reorder
267
268#ifdef _SB1250_PASS1_WORKAROUNDS_
269
270		mfc0	t0,C0_PRID
271		andi	t0,0xff
272		addi	t0,-1
273		bnez	t0,1f
274
275       /*
276        * Enable CPU graduation timer for pass1 parts.
277	*/
278		li	t0, (1<<19)
279		mtc0	t0,$23,2
280		ssnop
281		ssnop
282		ssnop
283		ssnop
284		ssnop
285		ssnop
286		ssnop
2871:
288#endif
289
290/*
291 * XXX What other CP0 initialization do I need?
292 */
293#ifdef _DEFEATURE_ECC_
294        li      t0,0x3000       # defeature data errors on both caches
295        mfc0    t1, $23, 2      # get the original value of defeature reg
296        or      t1, t0, t1
297        mtc0    t1, $23, 2
298#endif
299		jr	ra
300
301END(sb1_cp0_init)
302
303
304/*  *********************************************************************
305    *  SB1_CPU_INIT()
306    *
307    *  Initialize an SB1 CPU.
308    *
309    *  Input parameters:
310    *  	   nothing
311    *
312    *  Return value:
313    *  	   nothing
314    *
315    *  Registers used:
316    *  	   all
317    ********************************************************************* */
318
319
320LEAF(sb1_cpu_init)
321
322	#
323	# We are going to call other subroutines from inside this
324	# routine.  Hold onto the return address somewhere else
325	# while we do this.
326	#
327
328		move	fp,ra			# keep our return addr here.
329
330
331	#
332	# First, zero all the registers.
333	#
334		JAL_KSEG1(sb1_zero_int_regs)
335
336	#
337	# CP0 initialization
338	#
339
340		JAL_KSEG1(sb1_cp0_init)
341
342	#
343	# Now do the FP unit
344	#
345
346		JAL_KSEG1(sb1_zero_fp_regs)
347
348		jr	fp
349
350END(sb1_cpu_init)
351
352
353/*  *********************************************************************
354    *  SB1_KSEG0_SWITCH
355    *
356    *  Return to the address of the routine that called us, except
357    *  in K0seg instead of K1seg
358    *
359    *  Input parameters:
360    *  	   nothing - ra is return address
361    *
362    *  Return value:
363    *  	   ra = same return address in K0
364    ********************************************************************* */
365
366sb1_kseg0_switch:
367
368		and	ra,(K0SIZE-1)
369		or	ra,K0BASE
370		jr	ra
371
372
373/*  *********************************************************************
374    *  End
375    ********************************************************************* */
376
377