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