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