summaryrefslogtreecommitdiff
path: root/release/src/shared/boot.S
blob: ed99304c99aac23af9fe0d077c6e89cc1c381a83 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
/*
 * BCM947XX Boot code for standalone apps.
 *
 * Code should be position-independent until it copies itself to SDRAM.
 *
 * Copyright 2005, Broadcom Corporation
 * All Rights Reserved.
 * 
 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
 *
 * $Id: boot.S,v 1.1.1.3 2005/03/07 07:31:12 kanki Exp $
 */

#include "mipsinc.h"
#include "sbconfig.h"
#include "sbchipc.h"

	.text
	LEAF(startup)
	.set	noreorder

       	# XXX: the following code snipet sets clk frequency to 200M
        # correct pll clk freq to real speed in the 5350 case.
        # It is Ugly...but

	li      t0,KSEG1ADDR(SB_ENUM_BASE)      # Is there a chipcommon core?
	lw      t1,(SBCONFIGOFF + SBIDHIGH)(t0)
	and     t1,t1,SBIDH_CC_MASK
	srl     t1,t1,SBIDH_CC_SHIFT
	bne     t1,SB_CC,_move_ahead
	nop
        li      a2,KSEG1ADDR(SB_ENUM_BASE)
        li      a3, 0x5350            # 5350 ChipID
        ll      t1, 0(a2)             # ChipID register
        andi    t1, 0x0ffff             # chip id is bit 0-15
        bne     a3, t1, _move_ahead   # if not 5350 then skip
        nop
        li      a3, 0x311
        ll      t1, 0x90(a2)
        beq     a3, t1, _move_ahead   # move ahead if clk freq set correctly
        nop
        sw      a3, 0x90(a2)          # set control N1 to select 6
        li      t1, 0x1
        sw      t1, 0x80(a2)          # set WatchDog Reset
_move_ahead:
        nop


	/* Check if we booted from SDRAM */
	bal	1f
	nop
1:	li	t0,PHYSADDR_MASK
	and	t0,t0,ra
	li	t1,SB_FLASH1
	bge	t0,t1,inflash
	nop

	/* Call draminit to size memory */
	jal	board_draminit
	nop
	b	setsp
	nop

inflash:
	/* Is this chipc rev 11 or 12 and an Atmel serial flash? */
	li	t0,KSEG1ADDR(SB_ENUM_BASE)
	lw	t1,(SBCONFIGOFF + SBIDHIGH)(t0)
	and	t2,t1,SBIDH_CC_MASK
	srl	t2,t2,SBIDH_CC_SHIFT
	bne	t2,SB_CC,checkcon		/* Not chipc */
	nop
	lw	t0,CC_CAPABILITIES(t0)
	and	t0,t0,CAP_FLASH_MASK
	beq	t0,SFLASH_AT,switchkseg0
	nop

checkcon:
	/* Check if the caches are already on */
	mfc0	t0,C0_CONFIG
	and	t0,CONF_CM_CMASK
	beq	t0,CONF_CM_UNCACHED,initcaches
	nop

	b	switchkseg0
	nop

initcaches:
	/* Turn on the caches in the CP0 register */
	mfc0	t0,C0_DIAGNOSTIC
	or	t0,0xc0000000		/* Enable both I$ and D$ */
	mtc0	t0,C0_DIAGNOSTIC


1:	/* Get cache sizes */
	.set	mips32
	mfc0	s0,C0_CONFIG,1
	.set	mips0

	li	s1,CONF1_DL_MASK
	and	s1,s0
	beq	s1,zero,nodc
	nop

	srl	s1,CONF1_DL_SHIFT
	li	t0,CONF1_DL_BASE
	sll	s1,t0,s1		/* s1 has D$ cache line size */

	li	s2,CONF1_DA_MASK
	and	s2,s0
	srl	s2,CONF1_DA_SHIFT
	addiu	s2,CONF1_DA_BASE	/* s2 now has D$ associativity */

	li	t0,CONF1_DS_MASK
	and	t0,s0
	srl	t0,CONF1_DS_SHIFT
	li	s3,CONF1_DS_BASE
	sll	s3,s3,t0		/* s3 has D$ sets per way */

	multu	s2,s3			/* sets/way * associativity */
	mflo	t0			/* total cache lines */

	multu	s1,t0			/* D$ linesize * lines */
	mflo	s2			/* s2 is now D$ size in bytes */

	/* Initilize the D$: */
	mtc0	zero,C0_TAGLO
	mtc0	zero,C0_TAGHI

	li	t0,KSEG0		/* Just an address for the first $ line */
	addu	t1,t0,s2		/*  + size of cache == end */

	.set	mips3
1:	cache	Index_Store_Tag_D,0(t0)
	.set	mips0
	bne	t0,t1,1b
	addu	t0,s1

nodc:
	/* Now we get to do it all again for the I$ */

	li	t0,CONF1_IL_MASK
	and	t0,s0
	beq	t0,zero,noic
	nop

	srl	t0,CONF1_IL_SHIFT
	li	s3,CONF1_IL_BASE
	sll	s3,t0			/* s3 has I$ cache line size */

	li	t0,CONF1_IA_MASK
	and	t0,s0
	srl	t0,CONF1_IA_SHIFT
	addiu	s4,t0,CONF1_IA_BASE	/* s4 now has I$ associativity */

	li	t0,CONF1_IS_MASK
	and	t0,s0
	srl	t0,CONF1_IS_SHIFT
	li	s5,CONF1_IS_BASE
	sll	s5,t0			/* s5 has I$ sets per way */

	multu	s4,s5			/* sets/way * associativity */
	mflo	t0			/* s4 is not total cache lines */

	multu	s3,t0			/* I$ linesize * lines */
	mflo	s4			/* s4 is cache size in bytes */

	/* Initilize the I$: */
	mtc0	zero,C0_TAGLO
	mtc0	zero,C0_TAGHI

	li	t0,KSEG0		/* Just an address for the first $ line */
	addu	t1,t0,s4		/*  + size of cache == end */

	.set	mips3
1:	cache	Index_Store_Tag_I,0(t0)
	.set	mips0
	bne	t0,t1,1b
	addu	t0,s1

noic:	
	/* Caches initialized, change cacheability */
	mfc0	t0,C0_CONFIG
	and	t0,~CONF_CM_CMASK
	or	t0,CONF_CM_CACHABLE_NONCOHERENT
	mtc0	t0,C0_CONFIG
	nop

switchkseg0:
	/* And now jump to KSEG0 */
	li	t0,KSEG1ADDR(SB_FLASH1)
	la	t1,text_start
	la	t2,initdram
	sub	t0,t0,t1
	add	t2,t2,t0
	and	t2,PHYSADDR_MASK
	or	t2,KSEG0
	jr	t2
	nop

initdram:
	/* Initialize SDRAM */
	li	t0,KSEG0ADDR(SB_FLASH1)
	la	t1,text_start
	la	t2,board_draminit
	sub	t0,t0,t1
	add	t2,t2,t0
	jalr	t2
	nop

	/* v0 now contains memory size in bytes */

	/* Copy self to SDRAM */
#ifdef	CONFIG_XIP
	la	a0,text_end
	la	a1,data_start
	la	a2,input_data
#else
	li	a0,KSEG0ADDR(SB_FLASH1)
	la	a1,text_start
	and	a1,PHYSADDR_MASK
	or	a1, KSEG1
	la	a2,input_data
	and	a2,PHYSADDR_MASK
	or	a2, KSEG1
#endif
1:	lw	t0,0(a0)
	sw	t0,0(a1)
	add	a0,4
	add	a1,4
	blt	a1,a2,1b
	nop

setsp:
	/* Set up stack pointer */
	or	v0,KSEG0
	sub	sp,v0,4

	/* Clear BSS */	
	la	a0,bss_start
	la	a1,bss_end
1:	sw	zero,0(a0)
	addi	a0,a0,4
	blt	a0,a1,1b
	nop

	/* Setup trap handlers */
	li	t0,KSEG0ADDR(SB_FLASH1)
	la	t1,text_start
	la	t2,trap_init
	sub	t0,t0,t1
	add	t2,t2,t0
	jalr	t2
	nop

	/* Jump to C */
	la	t0,c_main
	jal	t0
	move	a0,ra

	/* In case c_main returns */
theend:	nop
	nop
	.set	mips32
	wait
	.set	mips0
	nop
	nop
	b	theend
	nop

	/* Black hole for traps with BEV on */
	.org	0x380
bevtrap: nop
	nop
	.set	mips32
	wait
	.set	mips0
	nop
	nop
	b	bevtrap
	nop

	/* Record the size of the binary */
	.org	BISZ_OFFSET
	.word	BISZ_MAGIC
	.word	text_start
	.word	text_end
	.word	data_start
	.word	data_end
	.word	bss_start
	.word	bss_end

	/* Embedded NVRAM */
	.balign	0x400	
	.globl	embedded_nvram
embedded_nvram:
	.fill	0x100,4,~(0x48534c46)
	
	.set reorder
	END(startup)