1/*  *********************************************************************
2    *  Broadcom Common Firmware Environment (CFE)
3    *
4    *  Verification Test APIs			File: vapi.S
5    *
6    *  This module contains special low-level routines for use
7    *  by verification programs.
8    *
9    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
10    *
11    *********************************************************************
12    *
13    *  Copyright 2000,2001,2002,2003
14    *  Broadcom Corporation. All rights reserved.
15    *
16    *  This software is furnished under license and may be used and
17    *  copied only in accordance with the following terms and
18    *  conditions.  Subject to these conditions, you may download,
19    *  copy, install, use, modify and distribute modified or unmodified
20    *  copies of this software in source and/or binary form.  No title
21    *  or ownership is transferred hereby.
22    *
23    *  1) Any source code used, modified or distributed must reproduce
24    *     and retain this copyright notice and list of conditions
25    *     as they appear in the source file.
26    *
27    *  2) No right is granted to use any trade name, trademark, or
28    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
29    *     name may not be used to endorse or promote products derived
30    *     from this software without the prior written permission of
31    *     Broadcom Corporation.
32    *
33    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
34    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
35    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
36    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
37    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
38    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
39    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
40    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
41    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
42    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
43    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
44    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
45    *     THE POSSIBILITY OF SUCH DAMAGE.
46    ********************************************************************* */
47
48
49#include "sbmips.h"
50#include "bsp_config.h"
51#include "mipsmacros.h"
52
53#if CFG_VAPI
54
55#if CFG_EMBEDDED_PIC
56#error "CFG_VAPI is not compatible with relocatable code"
57#endif
58
59#include "cfe_devfuncs.h"
60
61#include "sb1250_defs.h"
62#include "sb1250_regs.h"
63#include "sb1250_scd.h"
64
65#include "vapi.h"
66
67/*  *********************************************************************
68    *  Constants
69    ********************************************************************* */
70
71#define CALLKSEG1(x) \
72                la       t0,x ; \
73		or	 t0,K1BASE ; \
74		jal	 t0
75
76#ifndef CFG_STACK_SIZE
77#define STACK_SIZE	8192
78#else
79#define STACK_SIZE	((CFG_STACK_SIZE+1023) & ~1023)
80#endif
81
82
83/*Break compile if stack less than 4096.  Vapi_puts() and vapi_dumpgprs()
84   uses high 1/4 of stack and needs between 512 and 1024 bytes */
85#if  !(STACK_SIZE & ~4095)
86#error "To use this module the stack must be at least 4096 bytes"
87#endif
88
89#define REGIDX(x) ((x)*8)
90
91#define SAVE_RA		  REGIDX(0)
92#define	SAVE_GP		  REGIDX(1)
93#define SAVE_AT		  REGIDX(2)
94#define SAVE_T0		  REGIDX(3)
95#define SAVE_T1		  REGIDX(4)
96#define SAVE_T2		  REGIDX(5)
97#define SAVE_T3		  REGIDX(6)
98#define SAVE_A0		  REGIDX(7)
99#define SAVE_A1		  REGIDX(8)
100#define SAVE_A2		  REGIDX(9)
101
102#define SAVE_SIZE	  REGIDX(10)
103
104#define SAVETEMPS(x)				\
105		.set    noat ;                  \
106                la      k0,x ;			\
107		sd	ra,SAVE_RA(k0) ;        \
108		sd	gp,SAVE_GP(k0) ;        \
109		sd	AT,SAVE_AT(k0) ;        \
110		sd	t0,SAVE_T0(k0) ;        \
111		sd	t1,SAVE_T1(k0) ;        \
112		sd	t2,SAVE_T2(k0) ;        \
113		sd	t3,SAVE_T3(k0) ;        \
114		sd	a0,SAVE_A0(k0) ;        \
115		sd	a1,SAVE_A1(k0) ;        \
116		sd	a2,SAVE_A2(k0) ;        \
117                .set    at ;                    \
118		la	gp,_gp
119
120
121#define RESTORETEMPS(x)				\
122		.set    noat ;                  \
123                la      k0,x ;			\
124		ld	ra,SAVE_RA(k0) ;        \
125		ld	gp,SAVE_GP(k0) ;        \
126		ld	AT,SAVE_AT(k0) ;        \
127		ld	t0,SAVE_T0(k0) ;        \
128		ld	t1,SAVE_T1(k0) ;        \
129		ld	t2,SAVE_T2(k0) ;        \
130		ld	t3,SAVE_T3(k0) ;        \
131		ld	a0,SAVE_A0(k0) ;        \
132		ld	a1,SAVE_A1(k0) ;        \
133		ld	a2,SAVE_A2(k0) ;        \
134                .set    at
135
136#define RECPTR t3
137
138#define CHECKPTR(label) \
139		ld      RECPTR,vapi_logptr ; \
140		ld	t0,vapi_logend ; \
141		beq	RECPTR,zero,label ; \
142		bge	RECPTR,t0,label
143
144#define SETRECTYPE(x,id) \
145                ld      RECPTR,vapi_logptr ; \
146                li      t2,(VAPI_CFESEAL | (x)) ; \
147		mfc0	t0,C0_PRID ; \
148		srl	t0,t0,25 ; \
149		and	t0,t0,7 ; \
150		sll	t0,t0,VAPI_PRNUM_SHIFT ; \
151		or      t2,t2,t0 ; \
152                dsll    t2,t2,32 ; \
153                or      t2,id ; \
154                sd      t2,VAPI_REC_SIGNATURE(RECPTR) ; \
155		mfc0    t2,C0_COUNT ; \
156		dsll	t2,t2,32 ; \
157		sd      t2,VAPI_REC_SIZE(RECPTR) ; \
158                sd      ra,VAPI_REC_RA(RECPTR)
159
160
161
162#define SETRECLEN_CONST(len) \
163		ld      t2,VAPI_REC_SIZE(RECPTR) ; \
164		or	t2,len ; \
165                sd      t2,VAPI_REC_SIZE(RECPTR)
166
167#define SETRECLEN_REG(r) \
168		ld      t2,VAPI_REC_SIZE(RECPTR) ; \
169		or	t2,r ; \
170                sd      t2,VAPI_REC_SIZE(RECPTR)
171
172
173/*  *********************************************************************
174    *  Data
175    ********************************************************************* */
176
177                .sdata
178
179		.globl vapi_logstart
180		.globl vapi_logend
181		.globl vapi_logptr
182		.globl vapi_status
183		.globl vapi_logover
184
185vapi_logstart:	.dword 0
186vapi_logend:	.dword 0
187vapi_logptr:	.dword 0
188vapi_status:	.dword -1
189vapi_logover:	.dword 0
190
191		.extern	mem_heapstart
192
193		.bss
194
195		.comm	vapi_regsave,REGIDX(64)
196
197		.text
198
199		.globl	vapi_socregs
200vapi_socregs:
201
202#ifdef _P5064_
203		.word 0, 0
204#else
205#include "sb1250_socregs.inc"
206#endif
207
208		.text
209
210		.extern cfe_warmstart
211
212		.set reorder
213
214
215/*  *********************************************************************
216    *  VAPI_KSEG0_SWITCH
217    *
218    *  Hack the return address so we will come back in KSEG0
219    *
220    *  Input parameters:
221    *  	   nothing
222    *
223    *  Return value:
224    *  	   nothing
225    ********************************************************************* */
226
227LEAF(vapi_kseg0_switch)
228
229		and	ra,(K0SIZE-1)
230		or	ra,K0BASE
231		jr	ra
232
233END(vapi_kseg0_switch)
234
235/*  *********************************************************************
236    *  VAPI_EXIT(status)
237    *
238    *  Return from diagnostic to firmware
239    *
240    *  Input parameters:
241    *  	   a0 - exit status (0=ok, else error)
242    *
243    *  Return value:
244    *  	   does not return
245    ********************************************************************* */
246
247
248LEAF(vapi_exit)
249
250		move	k1,a0
251
252
253/*
254 * Reinitialize the CPU and the caches
255 */
256
257		bal	vapi_kseg1_switch
258		CALLKSEG1(sb1_cpu_init)
259/*
260 * Don't initialize the caches again.  Some diags
261 * leave data in the caches and if we invalidate it
262 * now we won't be able to see what happened.
263 */
264/*		CALLKSEG1(sb1250_l1cache_init) */
265/*		CALLKSEG1(sb1250_l2cache_init) */
266
267#ifdef __long64
268/*
269 * Set back to 64-bit mode.  Don't worry about the hazard
270 * here, it'll be eons before we need to use the KX space.
271 */
272		mfc0	t0,C0_SR
273		or	t0,t0,M_SR_KX
274		mtc0	t0,C0_SR
275#endif
276
277		bal	vapi_kseg0_switch
278
279		li	a0,0x42424242		# 'BBBB'
280		jal	board_setleds
281
282		move	a0,k1
283
284		la	gp,_gp
285		sd	a0,vapi_status
286		LR	sp,mem_heapstart
287		ADD	sp,((CFG_HEAP_SIZE*1024)+STACK_SIZE - 8)
288
289/*
290 * Create a log record for the EXIT status.
291 */
292		ld	t0,vapi_logptr
293		beq	t0,zero,nolog
294
295		SETRECTYPE(VAPI_FMT_EXIT,0)
296		SETRECLEN_CONST(1)
297		sd	a0,VAPI_REC_DATA(RECPTR)
298		add	RECPTR,32
299		sd	RECPTR,vapi_logptr
300nolog:
301		li	a0,0x45454545		# 'EEEE'
302		jal	board_setleds
303
304#if CFG_MULTI_CPUS
305
306	/*
307	 * Restart the other CPU if it was left in RESET.
308	 */
309
310		la	t2,PHYS_TO_K1(A_SCD_SYSTEM_CFG)
311		ld	t0,0(t2)
312		dli	t1,M_SYS_CPU_RESET_1	# Reset mask
313		and	t0,t1			# Test if CPU is in reset
314		beq	t0,zero,1f		# skip if not in reset
315
316		li	a0,1			# Whack the CPU
317		jal	altcpu_cmd_stop		# and put it back in idle
3181:
319#endif
320
321		ld	a0,vapi_status
322		j	cfe_warmstart
323
324END(vapi_exit)
325
326
327
328/*  *********************************************************************
329    *  VAPI_DUMPGPRS()
330    *
331    *  Dump the GPRs to the console
332    *
333    *  Input parameters:
334    *  	   nothing
335    *
336    *  Return value:
337    *  	   nothing
338    *
339    *  Registers used:
340    *  	   k0 - scratch register for CFE
341    ********************************************************************* */
342
343LEAF(vapi_dumpgprs)
344
345		.set	noat
346		la	k0,vapi_regsave
347		sd	$0,REGIDX(0)(k0)
348		sd	$1,REGIDX(1)(k0)
349		sd	$2,REGIDX(2)(k0)
350		sd	$3,REGIDX(3)(k0)
351		sd	$4,REGIDX(4)(k0)
352		sd	$5,REGIDX(5)(k0)
353		sd	$6,REGIDX(6)(k0)
354		sd	$7,REGIDX(7)(k0)
355		sd	$8,REGIDX(8)(k0)
356		sd	$9,REGIDX(9)(k0)
357		sd	$10,REGIDX(10)(k0)
358		sd	$11,REGIDX(11)(k0)
359		sd	$12,REGIDX(12)(k0)
360		sd	$13,REGIDX(13)(k0)
361		sd	$14,REGIDX(14)(k0)
362		sd	$15,REGIDX(15)(k0)
363		sd	$16,REGIDX(16)(k0)
364		sd	$17,REGIDX(17)(k0)
365		sd	$18,REGIDX(18)(k0)
366		sd	$19,REGIDX(19)(k0)
367		sd	$20,REGIDX(20)(k0)
368		sd	$21,REGIDX(21)(k0)
369		sd	$22,REGIDX(22)(k0)
370		sd	$23,REGIDX(23)(k0)
371		sd	$24,REGIDX(24)(k0)
372		sd	$25,REGIDX(25)(k0)
373		sd	$26,REGIDX(26)(k0)	/* k0 */
374		sd	$27,REGIDX(27)(k0)
375		sd	$28,REGIDX(28)(k0)
376		sd	$29,REGIDX(29)(k0)
377		sd	$30,REGIDX(30)(k0)
378		sd	$31,REGIDX(31)(k0)
379		.set    at
380
381# Save some CP0 registers here.
382#define LSAVECP0(cp0,idx) \
383                dmfc0    t0,cp0 ; \
384                sd      t0,REGIDX(idx)(k0)
385
386		LSAVECP0(C0_INX,32)
387		LSAVECP0(C0_RAND,33)
388		LSAVECP0(C0_TLBLO0,34)
389		LSAVECP0(C0_TLBLO1,35)
390		LSAVECP0(C0_CTEXT,36)
391		LSAVECP0(C0_PGMASK,37)
392		LSAVECP0(C0_WIRED,38)
393		LSAVECP0(C0_BADVADDR,39)
394		LSAVECP0(C0_COUNT,40)
395		LSAVECP0(C0_TLBHI,41)
396		LSAVECP0(C0_COMPARE,42)
397		LSAVECP0(C0_SR,43)
398		LSAVECP0(C0_CAUSE,44)
399		LSAVECP0(C0_EPC,45)
400		LSAVECP0(C0_PRID,46)
401		LSAVECP0(C0_CONFIG,47)
402		LSAVECP0(C0_LLADDR,48)
403		LSAVECP0(C0_WATCHLO,49)
404		LSAVECP0(C0_WATCHHI,50)
405		LSAVECP0(C0_XCTEXT,51)
406		LSAVECP0(C0_ECC,52)
407		LSAVECP0(C0_CACHEERR,53)
408		LSAVECP0(C0_TAGLO,54)
409		LSAVECP0(C0_TAGHI,55)
410		LSAVECP0(C0_ERREPC,56)
411
412
413		move	a0,k0			/* pass addr of regs */
414		la	gp,_gp
415		LR	sp,mem_heapstart
416		/*use bottom 1/4 of stack so not to trash top of stack */
417		ADD	sp,((CFG_HEAP_SIZE*1024)+(STACK_SIZE/4) - 8)
418		jal	vapi_dodumpregs		/* dump registers in 'C' */
419
420		.set	noat
421		la	k0,vapi_regsave
422		ld	$1,REGIDX(1)(k0)
423		ld	$2,REGIDX(2)(k0)
424		ld	$3,REGIDX(3)(k0)
425		ld	$4,REGIDX(4)(k0)
426		ld	$5,REGIDX(5)(k0)
427		ld	$6,REGIDX(6)(k0)
428		ld	$7,REGIDX(7)(k0)
429		ld	$8,REGIDX(8)(k0)
430		ld	$9,REGIDX(9)(k0)
431		ld	$10,REGIDX(10)(k0)
432		ld	$11,REGIDX(11)(k0)
433		ld	$12,REGIDX(12)(k0)
434		ld	$13,REGIDX(13)(k0)
435		ld	$14,REGIDX(14)(k0)
436		ld	$15,REGIDX(15)(k0)
437		ld	$16,REGIDX(16)(k0)
438		ld	$17,REGIDX(17)(k0)
439		ld	$18,REGIDX(18)(k0)
440		ld	$19,REGIDX(19)(k0)
441		ld	$20,REGIDX(20)(k0)
442		ld	$21,REGIDX(21)(k0)
443		ld	$22,REGIDX(22)(k0)
444		ld	$23,REGIDX(23)(k0)
445		ld	$24,REGIDX(24)(k0)
446		ld	$25,REGIDX(25)(k0)
447		/*ld	$26,REGIDX(26)(k0)	don't restore k0 */
448		ld	$27,REGIDX(27)(k0)
449		ld	$28,REGIDX(28)(k0)
450		ld	$29,REGIDX(29)(k0)
451		ld	$30,REGIDX(30)(k0)
452		ld	$31,REGIDX(31)(k0)
453		.set    at
454
455		j	ra
456
457END(vapi_dumpgprs)
458
459
460/*  *********************************************************************
461    *  VAPI_SETLOG(start,end)
462    *
463    *  Set the address of the log buffer.  This call is required
464    *  before any data will be stored in the log.
465    *
466    *  Input parameters:
467    *  	   a0 - start of log buffer, 64-bit aligned
468    *  	   a1 - end of log buffer, 64-bit aligned
469    *
470    *  Return value:
471    *  	   nothing
472    *
473    *  Registers used:
474    *  	   k0 - scratch register for CFE
475    ********************************************************************* */
476
477LEAF(vapi_setlog)
478
479		SAVETEMPS(vapi_regsave)
480
481		sd	a0,vapi_logstart
482		sd	a0,vapi_logptr
483		sd	a1,vapi_logend
484		sd	zero,vapi_logover
485
486		RESTORETEMPS(vapi_regsave)
487
488		j	ra
489
490END(vapi_setlog)
491
492/*  *********************************************************************
493    *  VAPI_LOGTRACE(id)
494    *
495    *  Store a the contents of the trace buffer to the log
496    *
497    *  Input parameters:
498    *  	   a0 - low 32 bits are the ID code to store with the entry
499    *  	        in the log.
500    *
501    *  Return value:
502    *  	   nothing
503    *
504    *  Registers used:
505    *  	   k0 - scratch register for CFE
506    ********************************************************************* */
507
508LEAF(vapi_logtrace)
509
510		j	ra
511
512END(vapi_logtrace)
513
514
515/*  *********************************************************************
516    *  VAPI_LOGSINGLE(id,value)
517    *
518    *  Store a single value in the log.
519    *
520    *  Input parameters:
521    *  	   a0 - low 32 bits are the ID code to store with the entry
522    *  	        in the log.
523    *  	   a1 - value to store in the log
524    *
525    *  Return value:
526    *  	   nothing
527    *
528    *  Registers used:
529    *  	   k0 - scratch register for CFE
530    ********************************************************************* */
531
532LEAF(vapi_logsingle)
533
534
535		SAVETEMPS(vapi_regsave)
536
537		CHECKPTR(99f)
538
539		SETRECTYPE(VAPI_FMT_DATA,a0)
540		SETRECLEN_CONST(1)
541
542		sd	a1,VAPI_REC_DATA(RECPTR)
543
544		add	RECPTR,32		# one record
545		sd	RECPTR,vapi_logptr
546
54799:		RESTORETEMPS(vapi_regsave)
548
549		j	ra
550
551END(vapi_logsingle)
552
553/*  *********************************************************************
554    *  VAPI_LOGDATA(id,addr,cnt)
555    *
556    *  Store multiple values in the log
557    *
558    *  Input parameters:
559    *  	   a0 - low 32 bits are the ID code to store with the entry
560    *  	        in the log.
561    *  	   a1 - Address of values to store in the log
562    *      a2 - number of 64-bit values to store in the log
563    *
564    *  Return value:
565    *  	   nothing
566    *
567    *  Registers used:
568    *  	   k0 - scratch register for CFE
569    ********************************************************************* */
570
571LEAF(vapi_logdata)
572
573		SAVETEMPS(vapi_regsave)
574
575		CHECKPTR(99f)
576
577		SETRECTYPE(VAPI_FMT_BUFFER,a0)
578
579		add	t1,RECPTR,VAPI_REC_DATA    # a1 = ptr to data ara
580
581		sd	a1,0(t1)
582		add	t1,8
583
584		move	k0,a2			# counter for words
585
5861:		beq	k0,zero,2f
587		ld	t0,0(a1)
588		sd	t0,0(t1)
589		add	a1,8
590		add	t1,8
591		sub	k0,1
592		b	1b
593
5942:		add	k0,a2,1			 # total number of words
595		SETRECLEN_REG(k0)
596		sll	k0,k0,3			# number of words we wrote
597		add	k0,24			# size of header
598		add	RECPTR,k0
599		sd	RECPTR,vapi_logptr
600
60199:		RESTORETEMPS(vapi_regsave)
602
603		j	ra
604
605END(vapi_logdata)
606
607
608/*  *********************************************************************
609    *  VAPI_SAVESOC(id)
610    *
611    *  Save the SOC registers in the log
612    *
613    *  Input parameters:
614    *  	   a0 - low 32 bits are the ID code to store with the entry
615    *  	        in the log
616    *      a1 - bitmask of SOC agents to save
617    *
618    *  Return value:
619    *  	   nothing
620    *
621    *  Registers used:
622    *  	   k0 - scratch register for CFE
623    ********************************************************************* */
624
625LEAF(vapi_savesoc)
626
627		SAVETEMPS(vapi_regsave)
628
629		CHECKPTR(99f)
630
631		li	t0,VAPI_CFESEAL | VAPI_FMT_SOC
632		dsll	t0,t0,32
633		or	t0,a0
634		mfc0	t1,C0_PRID
635		srl	t1,t1,25
636		and	t1,t1,7
637		sll	t1,t1,VAPI_PRNUM_SHIFT
638		or      t0,t0,t1
639		ld	t1,vapi_logptr
640
641		sd	t0,VAPI_REC_SIGNATURE(t1)
642		mfc0	t0,C0_COUNT
643		dsll	t0,t0,32
644		sd	t0,VAPI_REC_SIZE(t1)
645		sd	ra,VAPI_REC_RA(t1)
646
647		move	a2,zero			# Counts how many we write
648
649		la	t2,vapi_socregs
650
6511:		lw	t0,0(t2)		# get flags
652		beq	t0,zero,2f
653		and	t0,t0,a1		# test flags
654		beq	t0,zero,3f		# skip if no flags set
655
656		lw	t0,4(t2)		# get address of register
657
658		sd	t0,VAPI_REC_DATA(t1)	# store address of register
659		add	t1,8			# next destination addr
660		add	a2,1			# count the words written
661
662		or	t0,K1BASE		# Make K1seg
663		ld	t0,0(t0)		# Read SOC register
664
665		sd	t0,VAPI_REC_DATA(t1)	# Store in log
666		add	t1,8			# next destination addr
667		add	a2,1			# count the words written
668
6693:		add	t2,8			# next reg from table
670
671		b	1b
672
6732:		ld	t0,vapi_logptr		# get original pointer
674		ld	a1,VAPI_REC_SIZE(t0)	# Get C0_COUNT value
675		or	a1,a2			# OR in the record size
676		sd	a1,VAPI_REC_SIZE(t0)	# put the record size back
677
678		add	t1,24			# Account for extra fields in record
679		sd	t1,vapi_logptr		# Update the pointer
680
68199:		RESTORETEMPS(vapi_regsave)
682
683		j	ra
684
685END(vapi_savesoc)
686
687/*  *********************************************************************
688    *  VAPI_LOGGPRS(id)
689    *
690    *  Save the general purpose registers and certain CP0 values
691    *  in the log.
692    *
693    *  Input parameters:
694    *  	   a0 - low 32 bits are the ID code to store with the entry
695    *  	        in the log
696    *
697    *  Return value:
698    *  	   nothing
699    *
700    *  Registers used:
701    *  	   k0 - scratch register for CFE
702    ********************************************************************* */
703
704#define REGLOG(x) (VAPI_REC_DATA+REGIDX(x))
705#define MAXREGS 57
706#define REGLOGMAX REGLOG(MAXREGS)
707
708LEAF(vapi_loggprs)
709
710		SAVETEMPS(vapi_regsave)
711		CHECKPTR(99f)
712
713		.set	noat
714		ld	k0,vapi_logptr
715		sd	$0,REGLOG(0)(k0)
716		sd	$1,REGLOG(1)(k0)
717		sd	$2,REGLOG(2)(k0)
718		sd	$3,REGLOG(3)(k0)
719		sd	$4,REGLOG(4)(k0)
720		sd	$5,REGLOG(5)(k0)
721		sd	$6,REGLOG(6)(k0)
722		sd	$7,REGLOG(7)(k0)
723		sd	$8,REGLOG(8)(k0)
724		sd	$9,REGLOG(9)(k0)
725		sd	$10,REGLOG(10)(k0)
726		sd	$11,REGLOG(11)(k0)
727		sd	$12,REGLOG(12)(k0)
728		sd	$13,REGLOG(13)(k0)
729		sd	$14,REGLOG(14)(k0)
730		sd	$15,REGLOG(15)(k0)
731		sd	$16,REGLOG(16)(k0)
732		sd	$17,REGLOG(17)(k0)
733		sd	$18,REGLOG(18)(k0)
734		sd	$19,REGLOG(19)(k0)
735		sd	$20,REGLOG(20)(k0)
736		sd	$21,REGLOG(21)(k0)
737		sd	$22,REGLOG(22)(k0)
738		sd	$23,REGLOG(23)(k0)
739		sd	$24,REGLOG(24)(k0)
740		sd	$25,REGLOG(25)(k0)
741		sd	$26,REGLOG(26)(k0)
742		sd	$27,REGLOG(27)(k0)
743		sd	$28,REGLOG(28)(k0)
744		sd	$29,REGLOG(29)(k0)
745		sd	$30,REGLOG(30)(k0)
746		sd	$31,REGLOG(31)(k0)
747		.set	at
748
749
750# Save some CP0 registers here.
751#define SAVECP0(cp0,idx) \
752                dmfc0    t0,cp0 ; \
753                sd      t0,REGLOG(idx)(k0)
754
755		SAVECP0(C0_INX,32)
756		SAVECP0(C0_RAND,33)
757		SAVECP0(C0_TLBLO0,34)
758		SAVECP0(C0_TLBLO1,35)
759		SAVECP0(C0_CTEXT,36)
760		SAVECP0(C0_PGMASK,37)
761		SAVECP0(C0_WIRED,38)
762		SAVECP0(C0_BADVADDR,39)
763		SAVECP0(C0_COUNT,40)
764		SAVECP0(C0_TLBHI,41)
765		SAVECP0(C0_COMPARE,42)
766		SAVECP0(C0_SR,43)
767		SAVECP0(C0_CAUSE,44)
768		SAVECP0(C0_EPC,45)
769		SAVECP0(C0_PRID,46)
770		SAVECP0(C0_CONFIG,47)
771		SAVECP0(C0_LLADDR,48)
772		SAVECP0(C0_WATCHLO,49)
773		SAVECP0(C0_WATCHHI,50)
774		SAVECP0(C0_XCTEXT,51)
775		SAVECP0(C0_ECC,52)
776		SAVECP0(C0_CACHEERR,53)
777		SAVECP0(C0_TAGLO,54)
778		SAVECP0(C0_TAGHI,55)
779		SAVECP0(C0_ERREPC,56)
780
781		SETRECTYPE(VAPI_FMT_GPRS,a0)
782		SETRECLEN_CONST(MAXREGS)
783		add	RECPTR,REGLOGMAX
784		sd	RECPTR,vapi_logptr
785
78699:		RESTORETEMPS(vapi_regsave)
787
788		j	ra			# go home
789
790END(vapi_loggprs)
791
792
793/*  *********************************************************************
794    *  VAPI_LOGFPRS(id)
795    *
796    *  Save the floating point unit's registers
797    *  in the log.
798    *
799    *  Input parameters:
800    *  	   a0 - low 32 bits are the ID code to store with the entry
801    *  	        in the log
802    *
803    *  Return value:
804    *  	   nothing
805    *
806    *  Registers used:
807    *  	   k0 - scratch register for CFE
808    ********************************************************************* */
809
810
811#define SAVEFPR(cp1,idx) \
812                dmfc1    t0,cp1 ; \
813                sd      t0,FPREGLOG(idx)(k0)
814#define SAVECP1(cp1,idx) \
815                cfc1    t0,cp1 ; \
816                sd      t0,FPREGLOG(idx)(k0)
817
818#define FPREGLOG(x) (VAPI_REC_DATA+REGIDX(x))
819#define FPMAXREGS 37
820#define FPREGLOGMAX FPREGLOG(FPMAXREGS)
821
822LEAF(vapi_logfprs)
823
824		SAVETEMPS(vapi_regsave)
825		CHECKPTR(99f)
826
827		ld	k0,vapi_logptr
828		SAVEFPR($0,0)
829		SAVEFPR($1,1)
830		SAVEFPR($2,2)
831		SAVEFPR($3,3)
832		SAVEFPR($4,4)
833		SAVEFPR($5,5)
834		SAVEFPR($6,6)
835		SAVEFPR($7,7)
836		SAVEFPR($8,8)
837		SAVEFPR($9,9)
838		SAVEFPR($10,10)
839		SAVEFPR($11,11)
840		SAVEFPR($12,12)
841		SAVEFPR($13,13)
842		SAVEFPR($14,14)
843		SAVEFPR($15,15)
844		SAVEFPR($16,16)
845		SAVEFPR($17,17)
846		SAVEFPR($18,18)
847		SAVEFPR($19,19)
848		SAVEFPR($20,20)
849		SAVEFPR($21,21)
850		SAVEFPR($22,22)
851		SAVEFPR($23,23)
852		SAVEFPR($24,24)
853		SAVEFPR($25,25)
854		SAVEFPR($26,26)
855		SAVEFPR($27,27)
856		SAVEFPR($28,28)
857		SAVEFPR($29,29)
858		SAVEFPR($30,30)
859		SAVEFPR($31,31)
860
861		SAVECP1($0,32)		/* FIR */
862		SAVECP1($31,33)		/* Status */
863		SAVECP1($25,34)		/* condition codes */
864		SAVECP1($26,35)		/* Exceptions */
865		SAVECP1($28,36)		/* enables */
866
867		SETRECTYPE(VAPI_FMT_FPRS,a0)
868		SETRECLEN_CONST(FPMAXREGS)
869		add	RECPTR,FPREGLOGMAX
870		sd	RECPTR,vapi_logptr
871
87299:		RESTORETEMPS(vapi_regsave)
873
874		j	ra			# go home
875
876END(vapi_logfprs)
877
878/*  *********************************************************************
879    *  VAPI_PUTS(string)
880    *
881    *  Display a string on the console
882    *
883    *  Input parameters:
884    *  	   a0 - pointer to null-terminated string
885    *
886    *  Return value:
887    *  	   nothing
888    *
889    *  Registers used:
890    *  	   k0 - scratch register for CFE
891    ********************************************************************* */
892
893LEAF(vapi_puts)
894
895		.set	noat
896		la	k0,vapi_regsave
897		sd	$0,REGIDX(0)(k0)
898		sd	$1,REGIDX(1)(k0)
899		sd	$2,REGIDX(2)(k0)
900		sd	$3,REGIDX(3)(k0)
901		sd	$4,REGIDX(4)(k0)
902		sd	$5,REGIDX(5)(k0)
903		sd	$6,REGIDX(6)(k0)
904		sd	$7,REGIDX(7)(k0)
905		sd	$8,REGIDX(8)(k0)
906		sd	$9,REGIDX(9)(k0)
907		sd	$10,REGIDX(10)(k0)
908		sd	$11,REGIDX(11)(k0)
909		sd	$12,REGIDX(12)(k0)
910		sd	$13,REGIDX(13)(k0)
911		sd	$14,REGIDX(14)(k0)
912		sd	$15,REGIDX(15)(k0)
913		sd	$16,REGIDX(16)(k0)
914		sd	$17,REGIDX(17)(k0)
915		sd	$18,REGIDX(18)(k0)
916		sd	$19,REGIDX(19)(k0)
917		sd	$20,REGIDX(20)(k0)
918		sd	$21,REGIDX(21)(k0)
919		sd	$22,REGIDX(22)(k0)
920		sd	$23,REGIDX(23)(k0)
921		sd	$24,REGIDX(24)(k0)
922		sd	$25,REGIDX(25)(k0)
923		sd	$26,REGIDX(26)(k0)	/* k0 */
924		sd	$27,REGIDX(27)(k0)
925		sd	$28,REGIDX(28)(k0)
926		sd	$29,REGIDX(29)(k0)
927		sd	$30,REGIDX(30)(k0)
928		sd	$31,REGIDX(31)(k0)
929		.set    at
930
931		la	gp,_gp
932		LR	sp,mem_heapstart
933		/*use bottom 1/4 of stack so not to trash top of stack */
934		ADD	sp,((CFG_HEAP_SIZE*1024)+(STACK_SIZE/4) - 8)
935
936		jal	vapi_doputs		/* dump registers in 'C' */
937
938		.set	noat
939		la	k0,vapi_regsave
940		ld	$1,REGIDX(1)(k0)
941		ld	$2,REGIDX(2)(k0)
942		ld	$3,REGIDX(3)(k0)
943		ld	$4,REGIDX(4)(k0)
944		ld	$5,REGIDX(5)(k0)
945		ld	$6,REGIDX(6)(k0)
946		ld	$7,REGIDX(7)(k0)
947		ld	$8,REGIDX(8)(k0)
948		ld	$9,REGIDX(9)(k0)
949		ld	$10,REGIDX(10)(k0)
950		ld	$11,REGIDX(11)(k0)
951		ld	$12,REGIDX(12)(k0)
952		ld	$13,REGIDX(13)(k0)
953		ld	$14,REGIDX(14)(k0)
954		ld	$15,REGIDX(15)(k0)
955		ld	$16,REGIDX(16)(k0)
956		ld	$17,REGIDX(17)(k0)
957		ld	$18,REGIDX(18)(k0)
958		ld	$19,REGIDX(19)(k0)
959		ld	$20,REGIDX(20)(k0)
960		ld	$21,REGIDX(21)(k0)
961		ld	$22,REGIDX(22)(k0)
962		ld	$23,REGIDX(23)(k0)
963		ld	$24,REGIDX(24)(k0)
964		ld	$25,REGIDX(25)(k0)
965		/*ld	$26,REGIDX(26)(k0)	don't restore k0 */
966		ld	$27,REGIDX(27)(k0)
967		ld	$28,REGIDX(28)(k0)
968		ld	$29,REGIDX(29)(k0)
969		ld	$30,REGIDX(30)(k0)
970		ld	$31,REGIDX(31)(k0)
971		.set    at
972
973		j	ra
974
975END(vapi_puts)
976
977/*  *********************************************************************
978    *  VAPI_SETLEDS(leds)
979    *
980    *  Set the onboard LEDS on the swarm board.
981    *
982    *  Input parameters:
983    *  	   a0 - LED value, "ABCD" is 0x41424344
984    *
985    *  Return value:
986    *  	   nothing
987    *
988    *  Registers used:
989    *  	   k0 - scratch register for CFE
990    ********************************************************************* */
991
992
993LEAF(vapi_setleds)
994
995		SAVETEMPS(vapi_regsave)
996
997		jal	board_setleds
998
999		RESTORETEMPS(vapi_regsave)
1000
1001		j	ra
1002
1003END(vapi_setleds)
1004
1005/*  *********************************************************************
1006    *  VAPI_KSEG1_SWITCH
1007    *
1008    *  Hack the return address so we will come back in KSEG1 (uncached)
1009    *
1010    *  Input parameters:
1011    *  	   nothing
1012    *
1013    *  Return value:
1014    *  	   nothing
1015    ********************************************************************* */
1016
1017LEAF(vapi_kseg1_switch)
1018
1019		and	ra,(K0SIZE-1)
1020		or	ra,K1BASE
1021		jr	ra
1022
1023END(vapi_kseg1_switch)
1024
1025
1026/*  *********************************************************************
1027    *  VAPI_RUN()
1028    *
1029    *  Jump to the diagnostic program, which must be loaded at the
1030    *  special address (typically 8002_0000).  First we flush the
1031    *  cache, then set magic #'s in the mailbox.   Finally, the core
1032    *  is reset.  On restart, we do minimal initialization and jump
1033    *  directly to the diagnostic.
1034    *
1035    *  Input parameters:
1036    *  	   a0 - nonzero to restart uncached.
1037    *
1038    *  Return value:
1039    *  	   nothing
1040    ********************************************************************* */
1041
1042LEAF(vapi_run)
1043
1044	/*
1045	 * Run uncached
1046	 */
1047
1048		bal	vapi_kseg1_switch	# now running in KSEG1
1049
1050	/*
1051	 * Flush the caches
1052	 */
1053
1054		move	s0,a0			# L2 flush trashes A0
1055		CALLKSEG1(sb1250_l1cache_flush_d)
1056		CALLKSEG1(sb1250_l1cache_inval_i)
1057		CALLKSEG1(sb1250_l2cache_flush)
1058		move	a0,s0
1059
1060#ifdef _P5064_
1061
1062       /* In the case of the P5064, just jump directly to the entry point */
1063
1064		li	t0,VAPI_DIAG_ENTRY
1065		j	t0
1066
1067#else
1068
1069	/*
1070	 * Set the magic code in the mailbox.
1071	 */
1072
1073		li	t0,-1
1074		la	t1,PHYS_TO_K1(A_IMR_REGISTER(0,R_IMR_MAILBOX_CLR_CPU))
1075		sd	t0,0(t1)
1076
1077		dli	t0,VAPI_MAGIC_NUMBER
1078		beq	a0,0,1f
1079		dli	t0,VAPI_MAGIC_NUMBER_UNC
1080		beq	a0,1,1f
1081		dli	t0,VAPI_MAGIC_NUMBER_MC
10821:		la	t1,PHYS_TO_K1(A_IMR_REGISTER(0,R_IMR_MAILBOX_SET_CPU))
1083		sd	t0,0(t1)
1084
1085	/*
1086	 * Whack the reset line.
1087	 */
1088#if defined(_PTSWARM_)
1089		li	k0,PHYS_TO_K1(0x1B0A0000+32+8*3)
1090#else
1091		li	k0,PHYS_TO_K1(0x100A0000+32+8*3)
1092#endif
1093		li	k1,'!'
1094
1095		li	t1,PHYS_TO_K1(A_SCD_SYSTEM_CFG)
1096		ld	t2,0(t1)
1097		dli	t0,M_SYS_CPU_RESET_0 | M_SYS_CPU_RESET_1
1098		or	t2,t2,t0
1099		bal	vapi_kseg0_switch
1100		.align 5
1101#if defined(_CSWARM_) || defined(_SWARM_) || defined(_PTSWARM_)
1102		sb	k1,0(k0)
1103#else
1104		nop
1105#endif
1106		sync			/* flush the write buffer */
1107		sd	t2,0(t1)
11081:		b	1b
1109
1110	/*
1111	 * And he never returned, no he never returned... and his fate
1112	 * is still unknown, he will ride forever 'neath the cycles of
1113	 * the SB1, he's the core that never returned!
1114	 */
1115#endif
1116
1117
1118
1119END(vapi_run)
1120
1121
1122LEAF(vapi_flushtest)
1123
1124		move	s1,ra
1125
1126	/*
1127	 * Run uncached
1128	 */
1129
1130		bal	vapi_kseg1_switch	# now running in KSEG1
1131
1132	/*
1133	 * Flush the caches
1134	 */
1135
1136		move	s0,a0			# L2 flush trashes A0
1137		CALLKSEG1(sb1250_l1cache_flush_d)
1138		CALLKSEG1(sb1250_l1cache_inval_i)
1139		CALLKSEG1(sb1250_l2cache_flush)
1140		move	a0,s0
1141
1142	/*
1143	 * Back to cached
1144	 */
1145
1146		bal	vapi_kseg0_switch	# now running in KSEG1
1147
1148		move	ra,s1
1149		j	ra
1150
1151END(vapi_flushtest)
1152
1153
1154#endif /* CFG_VAPI */
1155
1156/*  *********************************************************************
1157    *  End
1158    ********************************************************************* */
1159