1/*  *********************************************************************
2    *  SB1250 Board Support Package
3    *
4    *  Exception Handler			File: exception.S
5    *
6    *  Author:  Mitch Lichtenberg
7    *
8    *********************************************************************
9    *
10    *  Copyright 2000,2001,2002,2003
11    *  Broadcom Corporation. All rights reserved.
12    *
13    *  This software is furnished under license and may be used and
14    *  copied only in accordance with the following terms and
15    *  conditions.  Subject to these conditions, you may download,
16    *  copy, install, use, modify and distribute modified or unmodified
17    *  copies of this software in source and/or binary form.  No title
18    *  or ownership is transferred hereby.
19    *
20    *  1) Any source code used, modified or distributed must reproduce
21    *     and retain this copyright notice and list of conditions
22    *     as they appear in the source file.
23    *
24    *  2) No right is granted to use any trade name, trademark, or
25    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
26    *     name may not be used to endorse or promote products derived
27    *     from this software without the prior written permission of
28    *     Broadcom Corporation.
29    *
30    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
31    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
32    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
33    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
34    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
35    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
36    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
38    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
39    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
40    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
41    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
42    *     THE POSSIBILITY OF SUCH DAMAGE.
43    ********************************************************************* */
44
45
46#include "sbmips.h"
47#include "cpu_config.h"		/* for definition of HAZARD and ERET */
48#include "exception.h"
49#include "bsp_config.h"
50#include "mipsmacros.h"
51
52/*  *********************************************************************
53    *  Check some stuff
54    ********************************************************************* */
55
56#if ((CPUCFG_REGS32+CPUCFG_REGS64) != 1)
57#error "You must define exactly ONE of CPUCFG_REGS32,CPUCFG_REGS64 in cpu_config.h"
58#endif
59
60
61/*  *********************************************************************
62    *  Data
63    ********************************************************************* */
64
65                .sdata
66
67		.globl	_exc_vectab
68_exc_vectab:	_LONG_	0		# XTYPE_RESET
69		_LONG_	0		# XTYPE_TLBFILL  (not used)
70		_LONG_	0		# XTYPE_XTLBFILL
71		_LONG_	0		# XTYPE_CACHEERR (not used)
72		_LONG_	0		# XTYPE_EXCEPTION
73		_LONG_	0		# XTYPE_INTERRUPT
74		_LONG_	0		# XTYPE_EJTAG
75
76/*  *********************************************************************
77    *  Common Data
78    ********************************************************************* */
79
80		.bss
81
82
83/*  *********************************************************************
84    *  Code
85    ********************************************************************* */
86
87		.text
88
89#define R_EXC_CERR_TEMPLATE	_TBLIDX(0)
90#define R_EXC_CERR_TEMPLATE_END	_TBLIDX(1)
91
92		.globl	_exc_cerr_htable
93_exc_cerr_htable:
94		_LONG_	_exc_cerr_template
95		_LONG_	_exc_cerr_template_end
96
97
98/*  *********************************************************************
99    *  _exc_cerr_template
100    *
101    *  This is a template routine for our cache error handler.
102    *  We save a couple of registers in our magic save area, then
103    *  dispatch to code elsewhere in CFE.
104    *
105    *  This code is copied right to the vector address, so it has
106    *  to be kept tiny!
107    *
108    *  Input parameters:
109    *  	   nothing - running uncached, all registers trashed
110    *
111    *  Return value:
112    *  	   might return, might not
113    ********************************************************************* */
114
115LEAF(_exc_cerr_template)
116
117	/*
118	 * Magic!  When the cache error handler is running,
119	 * we are in a very special state, running uncached
120	 * and with translations turned off.  We can use offsets
121	 * from r0(zero) to store registers we need to use
122	 * during the error handler.
123	 */
124
125		.set push ; .set noreorder
126
127		SR	k0,CFE_LOCORE_GLOBAL_K0TMP(zero)
128		SR	k1,CFE_LOCORE_GLOBAL_K1TMP(zero)
129		SR	ra,CFE_LOCORE_GLOBAL_RATMP(zero)
130		SR	gp,CFE_LOCORE_GLOBAL_GPTMP(zero)
131
132		LR	k0,CFE_LOCORE_GLOBAL_CERRH(zero)
133		jalr	k0
134		 nop
135
136		LR	k0,CFE_LOCORE_GLOBAL_K0TMP(zero)
137		LR	k1,CFE_LOCORE_GLOBAL_K1TMP(zero)
138		LR	ra,CFE_LOCORE_GLOBAL_RATMP(zero)
139		LR	gp,CFE_LOCORE_GLOBAL_GPTMP(zero)
140		ERET
141
142		.set pop
143
144	/*
145	 * Note: make sure this routine does not exceed 128 bytes
146	 */
147
148_exc_cerr_template_end:
149
150END(_exc_cerr_template)
151
152/*  *********************************************************************
153    *  _exc_setup_locore(cerrh)
154    *
155    *  Set global data into the low-memory region.  We do this in
156    *  assembly language so it's easier to deal with the 32-bit/64-bit
157    *  issues that arise in the "C" code.
158    *
159    *  Input parameters:
160    *  	   a0 - cache error handler
161    *
162    *  Return value:
163    *  	   nothing
164    ********************************************************************* */
165
166LEAF(_exc_setup_locore)
167
168		move	t4,ra
169
170	/*
171	 * Save GP for easy re-use, using uncached writes.
172	 */
173
174		li	t0,PHYS_TO_K1(CFE_LOCORE_GLOBAL_GP)
175		SR	gp,0(t0)
176
177	/*
178	 * Initialize cache error handler pointer.  Make it
179	 * uncached, since cache error handlers should not
180	 * touch the cache.
181	 */
182
183		li	t1,(K0SIZE-1)
184		and	a0,a0,t1		# keep just physical part
185		li	t1,K1BASE
186		or	a0,a0,t1		# make into an uncached address
187
188		li	t0,PHYS_TO_K1(CFE_LOCORE_GLOBAL_CERRH)
189		SR	a0,0(t0)
190
191	/*
192	 * Move the cache error handler into low RAM.
193	 */
194
195		li	t0,PHYS_TO_K1(MIPS_RAM_VEC_CACHEERR)
196
197		la	t1,_exc_cerr_htable
198		LR	t2,R_EXC_CERR_TEMPLATE_END(t1)
199		LR	t1,R_EXC_CERR_TEMPLATE(t1)
200
2011:		lw	t3,0(t1)		# get a word
202		sw	t3,0(t0)		# write a word
203		ADD	t0,4			# next word...
204		ADD	t1,4
205		blt	t1,t2,1b		# till done
206
207	/*
208	 * Now do the whole thing again, but with cached writes.
209	 * Writing uncached makes sure the data is actually in memory,
210	 * and writing cached makes sure we write the same
211	 * stuff again when the cache is evicted.
212	 * This way we don't have to bother with cacheops,
213	 * a bonus on the BCM1250 with its funky L2.
214	 */
215
216		li	t0,PHYS_TO_K0(CFE_LOCORE_GLOBAL_GP)
217		SR	gp,0(t0)
218
219		li	t0,PHYS_TO_K0(CFE_LOCORE_GLOBAL_CERRH)
220		SR	a0,0(t0)
221
222		li	t0,PHYS_TO_K0(MIPS_RAM_VEC_CACHEERR)
223
224		la	t1,_exc_cerr_htable
225		LR	t2,R_EXC_CERR_TEMPLATE_END(t1)
226		LR	t1,R_EXC_CERR_TEMPLATE(t1)
227
2281:		lw	t3,0(t1)		# get a word
229		sw	t3,0(t0)		# write a word
230		ADD	t0,4			# next word...
231		ADD	t1,4
232		blt	t1,t2,1b		# till done
233
234
235	/*
236	 * done!
237	 */
238
239		move	ra,t4
240		j	ra
241
242END(_exc_setup_locore)
243
244
245
246
247/*  *********************************************************************
248    *  _exc_setvector(xtype,addr)
249    *
250    *  Set an exception vector address
251    *
252    *  Input parameters:
253    *  	   xtype - exception vector type
254    *  	   addr - routine address
255    *
256    *  Return value:
257    *  	   nothing
258    ********************************************************************* */
259
260LEAF(_exc_setvector)
261
262		la	v0,_exc_vectab
263		srl	a0,3		/* convert 8-byte index to array index */
264		sll	a0,BPWSIZE	/* convert back to index appropriate for word size */
265		add	v0,a0
266		SR	a1,(v0)
267		j	ra
268
269END(_exc_setvector)
270
271
272/*  *********************************************************************
273    *  _exc_crash_sim()
274    *
275    *  Crash the GDB simulator, causing it to exit.
276    *
277    *  Input parameters:
278    *  	   nothing
279    *
280    *  Return value:
281    *  	   nothing - does not return
282    ********************************************************************* */
283
284
285LEAF(_exc_crash_sim)
286
287		li $2,1
288		li $3,0xdead
289                li $4,0
290                syscall	0xca
2911:		b	1b
292
293END(_exc_crash_sim)
294
295
296/*  *********************************************************************
297    *  _exc_cache_crash_sim()
298    *
299    *  As _exc_crash_sim, but distinguish cache error exception.
300    *
301    *  Input parameters:
302    *  	   nothing
303    *
304    *  Return value:
305    *  	   nothing - does not return
306    ********************************************************************* */
307
308
309LEAF(_exc_cache_crash_sim)
310
311		li $2,1
312		li $3,0xbadc
313                li $4,0
314                syscall	0xca
3151:		b	1b
316
317END(_exc_cache_crash_sim)
318
319
320/*  *********************************************************************
321    *  _exc_restart()
322    *
323    *  Restart the firmware at the boot address
324    *
325    *  Input parameters:
326    *  	   nothing
327    *
328    *  Return value:
329    *  	   nothing
330    ********************************************************************* */
331
332LEAF(_exc_restart)
333
334		li	t0,0xBFC00000		# ROM restart vector
335		jr	t0
336
337END(_exc_restart)
338
339/*  *********************************************************************
340    *  _exc_entry(k0)
341    *
342    *  Main exception entry point.
343    *
344    *  Input parameters:
345    *  	   k0 - exception type
346    *
347    *  Return value:
348    *  	   ...
349    ********************************************************************* */
350
351LEAF(_exc_entry)
352
353		.set noreorder
354		.set noat
355
356		subu	k1,sp,EXCEPTION_SIZE
357		SRL	k1,3
358		SLL	k1,3
359
360                SREG    zero,XGR_ZERO(k1)
361		SREG 	AT,XGR_AT(k1)
362
363		SREG	v0,XGR_V0(k1)
364		SREG	v1,XGR_V1(k1)
365
366		SREG	a0,XGR_A0(k1)
367		SREG	a1,XGR_A1(k1)
368		SREG	a2,XGR_A2(k1)
369		SREG	a3,XGR_A3(k1)
370
371		SREG	t0,XGR_T0(k1)
372		SREG	t1,XGR_T1(k1)
373		SREG	t2,XGR_T2(k1)
374		SREG	t3,XGR_T3(k1)
375		SREG	t4,XGR_T4(k1)
376		SREG	t5,XGR_T5(k1)
377		SREG	t6,XGR_T6(k1)
378		SREG	t7,XGR_T7(k1)
379
380		SREG	s0,XGR_S0(k1)
381		SREG	s1,XGR_S1(k1)
382		SREG	s2,XGR_S2(k1)
383		SREG	s3,XGR_S3(k1)
384		SREG	s4,XGR_S4(k1)
385		SREG	s5,XGR_S5(k1)
386		SREG	s6,XGR_S6(k1)
387		SREG	s7,XGR_S7(k1)
388
389		SREG	t8,XGR_T8(k1)
390		SREG	t9,XGR_T9(k1)
391
392		SREG	gp,XGR_GP(k1)
393		SREG	sp,XGR_SP(k1)
394		SREG	fp,XGR_FP(k1)
395		SREG	ra,XGR_RA(k1)
396
397		mfc0	t0,C0_CAUSE
398		mfc0	t1,C0_SR
399		MFC0	t2,C0_BADVADDR
400		MFC0	t3,C0_EPC
401		mfc0    t4,C0_PRID
402		mflo    t5
403		mfhi    t6
404		SREG	t0,XCP0_CAUSE(k1)
405		SREG	t1,XCP0_SR(k1)
406		SREG	t2,XCP0_VADDR(k1)
407		SREG	t3,XCP0_EPC(k1)
408		SREG	t4,XCP0_PRID(k1)
409		SREG	t5,XGR_LO(k1)
410		SREG	t6,XGR_HI(k1)
411
412#if (CFG_RELOC)
413		la	gp,PHYS_TO_K0(CFE_LOCORE_GLOBAL_GP)
414		LR	gp,0(gp)		# get our GP handle from low memory vector
415#else
416		la	gp,_gp			# Load up GP, not relocated so it's easy
417#endif
418
419		move	a0,k0			# Pass exception type
420		move	a1,k1			# Pass frame to exception handler
421		la	t0,_exc_vectab		# get base of exception vectors
422		srl	k0,3			# convert 8-byte index to array index
423		sll	k0,BPWSIZE		# convert back to index appropriate for word size
424		addu	t0,k0			# get vector address
425		LR	t9,(t0)			# to call handler
426
427		move	sp,k1			# "C" gets fresh stack area
428
429		jalr	t9			# Call exception handler
430		 nop				# use reg 't9' for SVR4 compat
431
432		move    k1, sp
433		LREG  	AT,XGR_AT(k1)
434
435		LREG	t0,XGR_LO(k1)
436		LREG	t1,XGR_HI(k1)
437		mtlo    t0
438		mthi    t1
439
440		LREG	a0,XGR_A0(k1)
441		LREG	a1,XGR_A1(k1)
442		LREG	a2,XGR_A2(k1)
443		LREG	a3,XGR_A3(k1)
444
445		LREG	t0,XGR_T0(k1)
446		LREG	t1,XGR_T1(k1)
447		LREG	t2,XGR_T2(k1)
448		LREG	t3,XGR_T3(k1)
449		LREG	t4,XGR_T4(k1)
450		LREG	t5,XGR_T5(k1)
451		LREG	t6,XGR_T6(k1)
452		LREG	t7,XGR_T7(k1)
453
454		LREG	s0,XGR_S0(k1)
455		LREG	s1,XGR_S1(k1)
456		LREG	s2,XGR_S2(k1)
457		LREG	s3,XGR_S3(k1)
458		LREG	s4,XGR_S4(k1)
459		LREG	s5,XGR_S5(k1)
460		LREG	s6,XGR_S6(k1)
461		LREG	s7,XGR_S7(k1)
462
463		LREG	t8,XGR_T8(k1)
464		LREG	t9,XGR_T9(k1)
465
466		LREG	gp,XGR_GP(k1)
467		LREG	sp,XGR_SP(k1)
468		LREG	fp,XGR_FP(k1)
469		LREG	ra,XGR_RA(k1)
470
471/* do any CP0 cleanup here */
472
473		LREG	v0,XGR_V0(k1)
474		LREG	v1,XGR_V1(k1)
475
476		ERET
477
478		.set at
479		.set reorder
480
481
482END(_exc_entry)
483
484
485/*  *********************************************************************
486    * _exc_clear_sr_exl()
487    *
488    * Clear SR(EXL) and return to caller.
489    *
490    * Input parameters:
491    *	nothing
492    *
493    * Return value:
494    *	nothing
495    ********************************************************************* */
496
497LEAF(_exc_clear_sr_exl)
498
499		mfc0	t0,C0_SR
500		and	t0,t0,~(0x02)	# clear SR(EXL). Bit 1
501		mtc0	t0,C0_SR
502
503		HAZARD
504
505		j	ra
506
507END(_exc_clear_sr_exl)
508
509/*  *********************************************************************
510    * _exc_clear_sr_erl()
511    *
512    * Clear SR(ERL) and return to caller.
513    *
514    * Input parameters:
515    *	nothing
516    *
517    * Return value:
518    *	nothing
519    ********************************************************************* */
520
521LEAF(_exc_clear_sr_erl)
522
523		mfc0	t0,C0_SR
524		and	t0,t0,~(0x04)		# clear SR(ERL). Bit 2
525		mtc0	t0,C0_SR
526
527		HAZARD
528
529		j	ra
530
531END(_exc_clear_sr_erl)
532
533
534/*  *********************************************************************
535    *  End
536    ********************************************************************* */
537
538
539