1/*  *********************************************************************
2    *  SB1250 Board Support Package
3    *
4    *  L1C initialization			File: bcmcore_l1cache.S
5    *
6    *  This module contains code for various CPU cache operations
7    *
8    *  Note: the init 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
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 "sbmips32.h"
51#include "bsp_config.h"
52
53
54		.text
55
56		.set push
57		.set mips32
58
59/*  *********************************************************************
60    *  Macros
61    ********************************************************************* */
62
63
64#define BCMCORE_CACHELINE_SIZE  16
65
66#define L1CACHEOP(cachename,op) ((cachename) | ((op) << 2))
67
68#define L1C_OP_IDXINVAL     0
69#define L1C_OP_IDXLOADTAG   1
70#define L1C_OP_IDXWBINV	    1	/* for the DCache */
71#define L1C_OP_IDXSTORETAG  2
72#define L1C_OP_IMPLRSVD     3
73#define L1C_OP_HITINVAL     4
74#define L1C_OP_FILL         5	/* for the ICache */
75#define L1C_OP_HITWBINVAL   5	/* for the DCache */
76#define L1C_OP_HITWRITEBACK 6
77#define L1C_OP_FETCHLOCK    7
78
79#define L1C_I		    0
80#define L1C_D		    1
81
82
83/*  *********************************************************************
84    *  BCMCORE_L1CACHE_INIT()
85    *
86    *  Initialize the L1 Cache
87    *
88    *  Input parameters:
89    *  	   nothing
90    *
91    *  Return value:
92    *  	   nothing
93    *
94    *  Registers used:
95    *  	   t0,t1,t2
96    ********************************************************************* */
97
98LEAF(bcmcore_l1cache_init)
99
100	/*
101	 * Size the icache
102	 */
103
104		mfc0	t0,C0_CONFIG,1
105
106	/*
107	 * Sets Per Way = 64 << CFG_IS
108	 */
109
110		li	t2,M_CFG_IS
111		and	t2,t0
112		srl	t2,S_CFG_IS
113		li	t1,64
114		sll	t1,t2
115
116	/*
117	 * Associativity = 1 + CFG_IA
118	 */
119
120		li	t2,M_CFG_IA
121		and	t2,t0
122		srl	t2,S_CFG_IA
123		addiu	t2,1
124
125	/*
126	 * Associativity * Sets Per Way
127	 */
128
129		multu	t1,t2
130		mflo	t1
131
132	/*
133	 * Line Size = 2 << CFG_IL
134	 */
135
136		li	t2,M_CFG_IL
137		and	t2,t0
138		srl	t2,S_CFG_IL
139		li	t0,2
140		sll	t2,t0,t2
141
142	/*
143	 * Instruction Cache Size =
144	 * Associativity * Line Size * Sets Per Way
145	 */
146
147		multu	t1,t2
148		mflo	t0
149
150	/*
151	 * Zero the icache
152	 */
153
154		mtc0	zero,C0_TAGLO
155		mtc0	zero,C0_TAGHI
156		li	t1,K0BASE
1571:		sub	t0,t0,t2
158		cache	Index_Store_Tag_I,0(t1)
159		add	t1,t2
160		bne	t0,zero,1b
161
162	/*
163	 * Size the dcache
164	 */
165
166		mfc0	t0,C0_CONFIG,1
167
168	/*
169	 * Sets Per Way = 64 << CFG_DS
170	 */
171
172		li	t2,M_CFG_DS
173		and	t2,t0
174		srl	t2,S_CFG_DS
175		li	t1,64
176		sll	t1,t2
177
178
179	/*
180	 * Associativity = 1 + CFG_DA
181	 */
182
183		li	t2,M_CFG_DA
184		and	t2,t0
185		srl	t2,S_CFG_DA
186		addiu	t2,1
187
188	/*
189	 * Associativity * Sets Per Way
190	 */
191
192		multu	t1,t2
193		mflo	t1
194
195	/*
196	 * Line Size = 2 << CFG_DL
197	 */
198
199		li	t2,M_CFG_DL
200		and	t2,t0
201		srl	t2,S_CFG_DL
202		li	t0,2
203		sll	t2,t0,t2
204
205	/*
206	 * Data Cache Size =
207	 * Associativity * Line Size * Sets Per Way
208	 */
209
210		multu	t1,t2
211		mflo	t0
212
213	/*
214	 * Zero the dcache
215	 */
216
217		mtc0	zero,C0_TAGLO
218		mtc0	zero,C0_TAGHI
219		li	t1,K0BASE
2201:		sub	t0,t0,t2
221		cache	Index_Store_Tag_D,0(t1)
222		add	t1,t2
223		bne	t0,zero,1b
224
225		jr	ra
226
227END(bcmcore_l1cache_init)
228
229/*  *********************************************************************
230    *  BCMCORE_L1CACHE_INVAL_I()
231    *
232    *  Invalidate the entire ICache
233    *
234    *  Input parameters:
235    *  	   nothing
236    *
237    *  Return value:
238    *  	   nothing
239    *
240    *  Registers used:
241    *  	   t0,t1,t2
242    ********************************************************************* */
243
244LEAF(bcmcore_l1cache_inval_i)
245
246	/*
247	 * Size the icache
248	 */
249
250		mfc0	t0,C0_CONFIG,1
251
252	/*
253	 * Sets Per Way = 64 << CFG_IS
254	 */
255
256		li	t2,M_CFG_IS
257		and	t2,t0
258		srl	t2,S_CFG_IS
259		li	t1,64
260		sll	t1,t2
261
262	/*
263	 * Associativity = 1 + CFG_IA
264	 */
265
266		li	t2,M_CFG_IA
267		and	t2,t0
268		srl	t2,S_CFG_IA
269		addiu	t2,1
270
271	/*
272	 * Associativity * Sets Per Way
273	 */
274
275		multu	t1,t2
276		mflo	t1
277
278	/*
279	 * Line Size = 2 << CFG_IL
280	 */
281
282		li	t2,M_CFG_IL
283		and	t2,t0
284		srl	t2,S_CFG_IL
285		li	t0,2
286		sll	t2,t0,t2
287
288	/*
289	 * Instruction Cache Size =
290	 * Associativity * Line Size * Sets Per Way
291	 */
292
293		multu	t1,t2
294		mflo	t0
295
296	/*
297	 * Invalidate the icache
298	 */
299
300		mtc0	zero,C0_TAGLO
301		mtc0	zero,C0_TAGHI
302		li	t1,K0BASE
3031:		sub	t0,t0,t2
304		cache	Index_Invalidate_I,0(t1)
305		add	t1,t2
306		bne	t0,zero,1b
307
308		j	ra
309
310END(bcmcore_l1cache_inval_i)
311
312/*  *********************************************************************
313    *  BCMCORE_L1CACHE_FLUSH_D()
314    *
315    *  Flush the entire DCache
316    *
317    *  Input parameters:
318    *  	   nothing
319    *
320    *  Return value:
321    *  	   nothing
322    *
323    *  Registers used:
324    *  	   t0,t1,t2,t3
325    ********************************************************************* */
326
327LEAF(bcmcore_l1cache_flush_d)
328
329	/*
330	 * Size the dcache
331	 */
332
333		mfc0	t0,C0_CONFIG,1
334
335	/*
336	 * Sets Per Way = 64 << CFG_DS
337	 */
338
339		li	t2,M_CFG_DS
340		and	t2,t0
341		srl	t2,S_CFG_DS
342		li	t1,64
343		sll	t1,t2
344
345
346	/*
347	 * Associativity = 1 + CFG_DA
348	 */
349
350		li	t2,M_CFG_DA
351		and	t2,t0
352		srl	t2,S_CFG_DA
353		addiu	t2,1
354
355	/*
356	 * Associativity * Sets Per Way
357	 */
358
359		multu	t1,t2
360		mflo	t1
361
362	/*
363	 * Line Size = 2 << CFG_DL
364	 */
365
366		li	t2,M_CFG_DL
367		and	t2,t0
368		srl	t2,S_CFG_DL
369		li	t0,2
370		sll	t2,t0,t2
371
372	/*
373	 * Data Cache Size =
374	 * Associativity * Line Size * Sets Per Way
375	 */
376
377		multu	t1,t2
378		mflo	t0
379
380	/*
381	 * Flush the dcache
382	 */
383
384		mtc0	zero,C0_TAGLO
385		mtc0	zero,C0_TAGHI
386		li	t1,K0BASE
3871:		sub	t0,t0,t2
388#ifdef BCM4710
389		/* HNBU PR2795: out-of-order write workaround */
390		li	t3,0xb8000f90
391		lw	t3,0(t3)
392#endif
393		cache	Index_Writeback_Inv_D,0(t1)
394		add	t1,t2
395		bne	t0,zero,1b
396
397		j	ra
398
399END(bcmcore_l1cache_flush_d)
400
401
402		.set	noreorder
403		.set	noat
404
405#define LINESIZE BCMCORE_CACHELINE_SIZE
406
407/*  *********************************************************************
408    *  BCMCORE_SYNC_RANGE(start, length)
409    *
410    *  Make memory range consistent with L1 DCache
411    *
412    *  Input parameters:
413    *  	   a0 - base address
414    *  	   a1 - length
415    *
416    *  Return value:
417    *  	   nothing
418    *
419    *  Registers used:
420    *  	   a0, a1, t0, t1
421    ********************************************************************* */
422
423LEAF(bcmcore_sync_range)
424
425		beq	a1,zero,2f
426
427	/*
428	 * At least one line.  Compute aligned start and limit.
429	 */
430		li	t0,~(LINESIZE-1)
431		add	a1,a0,a1
432		and	a0,a0,t0
433		addi	a1,a1,LINESIZE-1
434		and	a1,a1,t0
435		addi	a0,a0,LINESIZE
436
437	/*
438	 * This and the lw below are workarounds for HND PR2795 apparently.
439	 */
440		li	t0,0xb8000f90	/* must be uncached */
441
442	/*
443	 * Flush the lines in L1 D
444	 */
4451:		lw	t1,0(t0)
446		cache	L1CACHEOP(L1C_D,L1C_OP_HITWBINVAL),-LINESIZE(a0)
447		bne	a0,a1,1b
448		addi	a0,a0,LINESIZE
449
4502:		j	ra
451		nop
452
453END(bcmcore_sync_range)
454
455
456/*  *********************************************************************
457    *  BCMCORE_INVAL_RANGE(start, length)
458    *
459    *  Flush a memory range from the L1 DCache
460    *
461    *  Input parameters:
462    *  	   a0 - base address
463    *  	   a1 - length
464    *
465    *  Return value:
466    *  	   nothing
467    *
468    *  Registers used:
469    *  	   a0,a1,t0
470    *
471    ********************************************************************* */
472
473LEAF(bcmcore_inval_range)
474
475		beq	a1,zero,2f
476
477	/*
478	 * At least one line.  Compute aligned start and limit.
479	 */
480		li	t0,~(LINESIZE-1)
481		add	a1,a0,a1
482		and	a0,a0,t0
483		addi	a1,a1,LINESIZE-1
484		and	a1,a1,t0
485		addi	a0,a0,LINESIZE
486
487	/*
488	 * Invalidate the lines in L1 D
489	 */
4901:		cache	L1CACHEOP(L1C_D,L1C_OP_HITINVAL),-LINESIZE(a0)
491		bne	a0,a1,1b
492		addi	a0,a0,LINESIZE
493
4942:		j	ra
495		nop
496
497END(bcmcore_inval_range)
498
499
500		.set pop
501
502/*  *********************************************************************
503    *  End
504    ********************************************************************* */
505
506