summaryrefslogtreecommitdiffstats
path: root/cfe/cfe/verif/vapi.S
diff options
context:
space:
mode:
Diffstat (limited to 'cfe/cfe/verif/vapi.S')
-rw-r--r--cfe/cfe/verif/vapi.S1150
1 files changed, 1150 insertions, 0 deletions
diff --git a/cfe/cfe/verif/vapi.S b/cfe/cfe/verif/vapi.S
new file mode 100644
index 0000000..a65fb6d
--- /dev/null
+++ b/cfe/cfe/verif/vapi.S
@@ -0,0 +1,1150 @@
+/* *********************************************************************
+ * Broadcom Common Firmware Environment (CFE)
+ *
+ * Verification Test APIs File: vapi.S
+ *
+ * This module contains special low-level routines for use
+ * by verification programs.
+ *
+ * Author: Mitch Lichtenberg (mpl@broadcom.com)
+ *
+ *********************************************************************
+ *
+ * Copyright 2000,2001,2002,2003
+ * Broadcom Corporation. All rights reserved.
+ *
+ * This software is furnished under license and may be used and
+ * copied only in accordance with the following terms and
+ * conditions. Subject to these conditions, you may download,
+ * copy, install, use, modify and distribute modified or unmodified
+ * copies of this software in source and/or binary form. No title
+ * or ownership is transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce
+ * and retain this copyright notice and list of conditions
+ * as they appear in the source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or
+ * logo of Broadcom Corporation. The "Broadcom Corporation"
+ * name may not be used to endorse or promote products derived
+ * from this software without the prior written permission of
+ * Broadcom Corporation.
+ *
+ * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
+ * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
+ * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************* */
+
+
+#include "sbmips.h"
+#include "bsp_config.h"
+#include "mipsmacros.h"
+
+#if CFG_VAPI
+
+#if (CFG_EMBEDDED_PIC)
+#error "CFG_VAPI is not compatible with relocatable code"
+#endif
+
+#include "cfe_devfuncs.h"
+
+#include "sb1250_defs.h"
+#include "sb1250_regs.h"
+#include "sb1250_scd.h"
+
+#include "vapi.h"
+
+/* *********************************************************************
+ * Constants
+ ********************************************************************* */
+
+#define CALLKSEG1(x) \
+ la t0,x ; \
+ or t0,K1BASE ; \
+ jal t0
+
+#ifndef CFG_STACK_SIZE
+#define STACK_SIZE 8192
+#else
+#define STACK_SIZE ((CFG_STACK_SIZE+1023) & ~1023)
+#endif
+
+#define REGIDX(x) ((x)*8)
+
+#define SAVE_RA REGIDX(0)
+#define SAVE_GP REGIDX(1)
+#define SAVE_AT REGIDX(2)
+#define SAVE_T0 REGIDX(3)
+#define SAVE_T1 REGIDX(4)
+#define SAVE_T2 REGIDX(5)
+#define SAVE_T3 REGIDX(6)
+#define SAVE_A0 REGIDX(7)
+#define SAVE_A1 REGIDX(8)
+#define SAVE_A2 REGIDX(9)
+
+#define SAVE_SIZE REGIDX(10)
+
+#define SAVETEMPS(x) \
+ .set noat ; \
+ la k0,x ; \
+ sd ra,SAVE_RA(k0) ; \
+ sd gp,SAVE_GP(k0) ; \
+ sd AT,SAVE_AT(k0) ; \
+ sd t0,SAVE_T0(k0) ; \
+ sd t1,SAVE_T1(k0) ; \
+ sd t2,SAVE_T2(k0) ; \
+ sd t3,SAVE_T3(k0) ; \
+ sd a0,SAVE_A0(k0) ; \
+ sd a1,SAVE_A1(k0) ; \
+ sd a2,SAVE_A2(k0) ; \
+ .set at ; \
+ la gp,_gp
+
+
+#define RESTORETEMPS(x) \
+ .set noat ; \
+ la k0,x ; \
+ ld ra,SAVE_RA(k0) ; \
+ ld gp,SAVE_GP(k0) ; \
+ ld AT,SAVE_AT(k0) ; \
+ ld t0,SAVE_T0(k0) ; \
+ ld t1,SAVE_T1(k0) ; \
+ ld t2,SAVE_T2(k0) ; \
+ ld t3,SAVE_T3(k0) ; \
+ ld a0,SAVE_A0(k0) ; \
+ ld a1,SAVE_A1(k0) ; \
+ ld a2,SAVE_A2(k0) ; \
+ .set at
+
+#define RECPTR t3
+
+#define CHECKPTR(label) \
+ ld RECPTR,vapi_logptr ; \
+ ld t0,vapi_logend ; \
+ beq RECPTR,zero,label ; \
+ bge RECPTR,t0,label
+
+#define SETRECTYPE(x,id) \
+ ld RECPTR,vapi_logptr ; \
+ li t2,(VAPI_CFESEAL | (x)) ; \
+ mfc0 t0,C0_PRID ; \
+ srl t0,t0,25 ; \
+ and t0,t0,7 ; \
+ sll t0,t0,VAPI_PRNUM_SHIFT ; \
+ or t2,t2,t0 ; \
+ dsll t2,t2,32 ; \
+ or t2,id ; \
+ sd t2,VAPI_REC_SIGNATURE(RECPTR) ; \
+ mfc0 t2,C0_COUNT ; \
+ dsll t2,t2,32 ; \
+ sd t2,VAPI_REC_SIZE(RECPTR) ; \
+ sd ra,VAPI_REC_RA(RECPTR)
+
+
+
+#define SETRECLEN_CONST(len) \
+ ld t2,VAPI_REC_SIZE(RECPTR) ; \
+ or t2,len ; \
+ sd t2,VAPI_REC_SIZE(RECPTR)
+
+#define SETRECLEN_REG(r) \
+ ld t2,VAPI_REC_SIZE(RECPTR) ; \
+ or t2,r ; \
+ sd t2,VAPI_REC_SIZE(RECPTR)
+
+
+/* *********************************************************************
+ * Data
+ ********************************************************************* */
+
+ .sdata
+
+ .globl vapi_logstart
+ .globl vapi_logend
+ .globl vapi_logptr
+ .globl vapi_status
+ .globl vapi_logover
+
+vapi_logstart: .dword 0
+vapi_logend: .dword 0
+vapi_logptr: .dword 0
+vapi_status: .dword -1
+vapi_logover: .dword 0
+
+ .extern mem_heapstart
+
+ .bss
+
+ .comm vapi_regsave,REGIDX(64)
+
+ .text
+
+ .globl vapi_socregs
+vapi_socregs:
+
+#ifdef _P5064_
+ .word 0, 0
+#else
+#include "sb1250_socregs.inc"
+#endif
+
+ .text
+
+ .extern cfe_warmstart
+
+ .set reorder
+
+
+/* *********************************************************************
+ * VAPI_KSEG0_SWITCH
+ *
+ * Hack the return address so we will come back in KSEG0
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(vapi_kseg0_switch)
+
+ and ra,(K0SIZE-1)
+ or ra,K0BASE
+ jr ra
+
+END(vapi_kseg0_switch)
+
+/* *********************************************************************
+ * VAPI_EXIT(status)
+ *
+ * Return from diagnostic to firmware
+ *
+ * Input parameters:
+ * a0 - exit status (0=ok, else error)
+ *
+ * Return value:
+ * does not return
+ ********************************************************************* */
+
+
+LEAF(vapi_exit)
+
+ move k1,a0
+
+
+/*
+ * Reinitialize the CPU and the caches
+ */
+
+ bal vapi_kseg1_switch
+ CALLKSEG1(sb1_cpu_init)
+/*
+ * Don't initialize the caches again. Some diags
+ * leave data in the caches and if we invalidate it
+ * now we won't be able to see what happened.
+ */
+/* CALLKSEG1(sb1250_l1cache_init) */
+/* CALLKSEG1(sb1250_l2cache_init) */
+
+#ifdef __long64
+/*
+ * Set back to 64-bit mode. Don't worry about the hazard
+ * here, it'll be eons before we need to use the KX space.
+ */
+ mfc0 t0,C0_SR
+ or t0,t0,M_SR_KX
+ mtc0 t0,C0_SR
+#endif
+
+ bal vapi_kseg0_switch
+
+ li a0,0x42424242 # 'BBBB'
+ jal board_setleds
+
+ move a0,k1
+
+ la gp,_gp
+ sd a0,vapi_status
+ LR sp,mem_heapstart
+ ADD sp,((CFG_HEAP_SIZE*1024)+STACK_SIZE - 8)
+
+/*
+ * Create a log record for the EXIT status.
+ */
+ ld t0,vapi_logptr
+ beq t0,zero,nolog
+
+ SETRECTYPE(VAPI_FMT_EXIT,0)
+ SETRECLEN_CONST(1)
+ sd a0,VAPI_REC_DATA(RECPTR)
+ add RECPTR,32
+ sd RECPTR,vapi_logptr
+nolog:
+ li a0,0x45454545 # 'EEEE'
+ jal board_setleds
+
+#if CFG_MULTI_CPUS
+
+ /*
+ * Restart the other CPU if it was left in RESET.
+ */
+
+ la t2,PHYS_TO_K1(A_SCD_SYSTEM_CFG)
+ ld t0,0(t2)
+ dli t1,M_SYS_CPU_RESET_1 # Reset mask
+ and t0,t1 # Test if CPU is in reset
+ beq t0,zero,1f # skip if not in reset
+
+ li a0,1 # Whack the CPU
+ jal altcpu_cmd_stop # and put it back in idle
+1:
+#endif
+
+ ld a0,vapi_status
+ j cfe_warmstart
+
+END(vapi_exit)
+
+
+
+/* *********************************************************************
+ * VAPI_DUMPGPRS()
+ *
+ * Dump the GPRs to the console
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * k0 - scratch register for CFE
+ ********************************************************************* */
+
+LEAF(vapi_dumpgprs)
+
+ .set noat
+ la k0,vapi_regsave
+ sd $0,REGIDX(0)(k0)
+ sd $1,REGIDX(1)(k0)
+ sd $2,REGIDX(2)(k0)
+ sd $3,REGIDX(3)(k0)
+ sd $4,REGIDX(4)(k0)
+ sd $5,REGIDX(5)(k0)
+ sd $6,REGIDX(6)(k0)
+ sd $7,REGIDX(7)(k0)
+ sd $8,REGIDX(8)(k0)
+ sd $9,REGIDX(9)(k0)
+ sd $10,REGIDX(10)(k0)
+ sd $11,REGIDX(11)(k0)
+ sd $12,REGIDX(12)(k0)
+ sd $13,REGIDX(13)(k0)
+ sd $14,REGIDX(14)(k0)
+ sd $15,REGIDX(15)(k0)
+ sd $16,REGIDX(16)(k0)
+ sd $17,REGIDX(17)(k0)
+ sd $18,REGIDX(18)(k0)
+ sd $19,REGIDX(19)(k0)
+ sd $20,REGIDX(20)(k0)
+ sd $21,REGIDX(21)(k0)
+ sd $22,REGIDX(22)(k0)
+ sd $23,REGIDX(23)(k0)
+ sd $24,REGIDX(24)(k0)
+ sd $25,REGIDX(25)(k0)
+ sd $26,REGIDX(26)(k0) /* k0 */
+ sd $27,REGIDX(27)(k0)
+ sd $28,REGIDX(28)(k0)
+ sd $29,REGIDX(29)(k0)
+ sd $30,REGIDX(30)(k0)
+ sd $31,REGIDX(31)(k0)
+ .set at
+
+# Save some CP0 registers here.
+#define LSAVECP0(cp0,idx) \
+ dmfc0 t0,cp0 ; \
+ sd t0,REGIDX(idx)(k0)
+
+ LSAVECP0(C0_INX,32)
+ LSAVECP0(C0_RAND,33)
+ LSAVECP0(C0_TLBLO0,34)
+ LSAVECP0(C0_TLBLO1,35)
+ LSAVECP0(C0_CTEXT,36)
+ LSAVECP0(C0_PGMASK,37)
+ LSAVECP0(C0_WIRED,38)
+ LSAVECP0(C0_BADVADDR,39)
+ LSAVECP0(C0_COUNT,40)
+ LSAVECP0(C0_TLBHI,41)
+ LSAVECP0(C0_COMPARE,42)
+ LSAVECP0(C0_SR,43)
+ LSAVECP0(C0_CAUSE,44)
+ LSAVECP0(C0_EPC,45)
+ LSAVECP0(C0_PRID,46)
+ LSAVECP0(C0_CONFIG,47)
+ LSAVECP0(C0_LLADDR,48)
+ LSAVECP0(C0_WATCHLO,49)
+ LSAVECP0(C0_WATCHHI,50)
+ LSAVECP0(C0_XCTEXT,51)
+ LSAVECP0(C0_ECC,52)
+ LSAVECP0(C0_CACHEERR,53)
+ LSAVECP0(C0_TAGLO,54)
+ LSAVECP0(C0_TAGHI,55)
+ LSAVECP0(C0_ERREPC,56)
+
+
+ move a0,k0 /* pass addr of regs */
+ la gp,_gp
+ LR sp,mem_heapstart
+ ADD sp,((CFG_HEAP_SIZE*1024)+STACK_SIZE - 8)
+ jal vapi_dodumpregs /* dump registers in 'C' */
+
+ .set noat
+ la k0,vapi_regsave
+ ld $1,REGIDX(1)(k0)
+ ld $2,REGIDX(2)(k0)
+ ld $3,REGIDX(3)(k0)
+ ld $4,REGIDX(4)(k0)
+ ld $5,REGIDX(5)(k0)
+ ld $6,REGIDX(6)(k0)
+ ld $7,REGIDX(7)(k0)
+ ld $8,REGIDX(8)(k0)
+ ld $9,REGIDX(9)(k0)
+ ld $10,REGIDX(10)(k0)
+ ld $11,REGIDX(11)(k0)
+ ld $12,REGIDX(12)(k0)
+ ld $13,REGIDX(13)(k0)
+ ld $14,REGIDX(14)(k0)
+ ld $15,REGIDX(15)(k0)
+ ld $16,REGIDX(16)(k0)
+ ld $17,REGIDX(17)(k0)
+ ld $18,REGIDX(18)(k0)
+ ld $19,REGIDX(19)(k0)
+ ld $20,REGIDX(20)(k0)
+ ld $21,REGIDX(21)(k0)
+ ld $22,REGIDX(22)(k0)
+ ld $23,REGIDX(23)(k0)
+ ld $24,REGIDX(24)(k0)
+ ld $25,REGIDX(25)(k0)
+ /*ld $26,REGIDX(26)(k0) don't restore k0 */
+ ld $27,REGIDX(27)(k0)
+ ld $28,REGIDX(28)(k0)
+ ld $29,REGIDX(29)(k0)
+ ld $30,REGIDX(30)(k0)
+ ld $31,REGIDX(31)(k0)
+ .set at
+
+ j ra
+
+END(vapi_dumpgprs)
+
+
+/* *********************************************************************
+ * VAPI_SETLOG(start,end)
+ *
+ * Set the address of the log buffer. This call is required
+ * before any data will be stored in the log.
+ *
+ * Input parameters:
+ * a0 - start of log buffer, 64-bit aligned
+ * a1 - end of log buffer, 64-bit aligned
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * k0 - scratch register for CFE
+ ********************************************************************* */
+
+LEAF(vapi_setlog)
+
+ SAVETEMPS(vapi_regsave)
+
+ sd a0,vapi_logstart
+ sd a0,vapi_logptr
+ sd a1,vapi_logend
+ sd zero,vapi_logover
+
+ RESTORETEMPS(vapi_regsave)
+
+ j ra
+
+END(vapi_setlog)
+
+/* *********************************************************************
+ * VAPI_LOGTRACE(id)
+ *
+ * Store a the contents of the trace buffer to the log
+ *
+ * Input parameters:
+ * a0 - low 32 bits are the ID code to store with the entry
+ * in the log.
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * k0 - scratch register for CFE
+ ********************************************************************* */
+
+LEAF(vapi_logtrace)
+
+ j ra
+
+END(vapi_logtrace)
+
+
+/* *********************************************************************
+ * VAPI_LOGSINGLE(id,value)
+ *
+ * Store a single value in the log.
+ *
+ * Input parameters:
+ * a0 - low 32 bits are the ID code to store with the entry
+ * in the log.
+ * a1 - value to store in the log
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * k0 - scratch register for CFE
+ ********************************************************************* */
+
+LEAF(vapi_logsingle)
+
+
+ SAVETEMPS(vapi_regsave)
+
+ CHECKPTR(99f)
+
+ SETRECTYPE(VAPI_FMT_DATA,a0)
+ SETRECLEN_CONST(1)
+
+ sd a1,VAPI_REC_DATA(RECPTR)
+
+ add RECPTR,32 # one record
+ sd RECPTR,vapi_logptr
+
+99: RESTORETEMPS(vapi_regsave)
+
+ j ra
+
+END(vapi_logsingle)
+
+/* *********************************************************************
+ * VAPI_LOGDATA(id,addr,cnt)
+ *
+ * Store multiple values in the log
+ *
+ * Input parameters:
+ * a0 - low 32 bits are the ID code to store with the entry
+ * in the log.
+ * a1 - Address of values to store in the log
+ * a2 - number of 64-bit values to store in the log
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * k0 - scratch register for CFE
+ ********************************************************************* */
+
+LEAF(vapi_logdata)
+
+ SAVETEMPS(vapi_regsave)
+
+ CHECKPTR(99f)
+
+ SETRECTYPE(VAPI_FMT_BUFFER,a0)
+
+ add t1,RECPTR,VAPI_REC_DATA # a1 = ptr to data ara
+
+ sd a1,0(t1)
+ add t1,8
+
+ move k0,a2 # counter for words
+
+1: beq k0,zero,2f
+ ld t0,0(a1)
+ sd t0,0(t1)
+ add a1,8
+ add t1,8
+ sub k0,1
+ b 1b
+
+2: add k0,a2,1 # total number of words
+ SETRECLEN_REG(k0)
+ sll k0,k0,3 # number of words we wrote
+ add k0,24 # size of header
+ add RECPTR,k0
+ sd RECPTR,vapi_logptr
+
+99: RESTORETEMPS(vapi_regsave)
+
+ j ra
+
+END(vapi_logdata)
+
+
+/* *********************************************************************
+ * VAPI_SAVESOC(id)
+ *
+ * Save the SOC registers in the log
+ *
+ * Input parameters:
+ * a0 - low 32 bits are the ID code to store with the entry
+ * in the log
+ * a1 - bitmask of SOC agents to save
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * k0 - scratch register for CFE
+ ********************************************************************* */
+
+LEAF(vapi_savesoc)
+
+ SAVETEMPS(vapi_regsave)
+
+ CHECKPTR(99f)
+
+ li t0,VAPI_CFESEAL | VAPI_FMT_SOC
+ dsll t0,t0,32
+ or t0,a0
+ mfc0 t1,C0_PRID
+ srl t1,t1,25
+ and t1,t1,7
+ sll t1,t1,VAPI_PRNUM_SHIFT
+ or t0,t0,t1
+ ld t1,vapi_logptr
+
+ sd t0,VAPI_REC_SIGNATURE(t1)
+ mfc0 t0,C0_COUNT
+ dsll t0,t0,32
+ sd t0,VAPI_REC_SIZE(t1)
+ sd ra,VAPI_REC_RA(t1)
+
+ move a2,zero # Counts how many we write
+
+ la t2,vapi_socregs
+
+1: lw t0,0(t2) # get flags
+ beq t0,zero,2f
+ and t0,t0,a1 # test flags
+ beq t0,zero,3f # skip if no flags set
+
+ lw t0,4(t2) # get address of register
+
+ sd t0,VAPI_REC_DATA(t1) # store address of register
+ add t1,8 # next destination addr
+ add a2,1 # count the words written
+
+ or t0,K1BASE # Make K1seg
+ ld t0,0(t0) # Read SOC register
+
+ sd t0,VAPI_REC_DATA(t1) # Store in log
+ add t1,8 # next destination addr
+ add a2,1 # count the words written
+
+3: add t2,8 # next reg from table
+
+ b 1b
+
+2: ld t0,vapi_logptr # get original pointer
+ ld a1,VAPI_REC_SIZE(t0) # Get C0_COUNT value
+ or a1,a2 # OR in the record size
+ sd a1,VAPI_REC_SIZE(t0) # put the record size back
+
+ add t1,24 # Account for extra fields in record
+ sd t1,vapi_logptr # Update the pointer
+
+99: RESTORETEMPS(vapi_regsave)
+
+ j ra
+
+END(vapi_savesoc)
+
+/* *********************************************************************
+ * VAPI_LOGGPRS(id)
+ *
+ * Save the general purpose registers and certain CP0 values
+ * in the log.
+ *
+ * Input parameters:
+ * a0 - low 32 bits are the ID code to store with the entry
+ * in the log
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * k0 - scratch register for CFE
+ ********************************************************************* */
+
+#define REGLOG(x) (VAPI_REC_DATA+REGIDX(x))
+#define MAXREGS 57
+#define REGLOGMAX REGLOG(MAXREGS)
+
+LEAF(vapi_loggprs)
+
+ SAVETEMPS(vapi_regsave)
+ CHECKPTR(99f)
+
+ .set noat
+ ld k0,vapi_logptr
+ sd $0,REGLOG(0)(k0)
+ sd $1,REGLOG(1)(k0)
+ sd $2,REGLOG(2)(k0)
+ sd $3,REGLOG(3)(k0)
+ sd $4,REGLOG(4)(k0)
+ sd $5,REGLOG(5)(k0)
+ sd $6,REGLOG(6)(k0)
+ sd $7,REGLOG(7)(k0)
+ sd $8,REGLOG(8)(k0)
+ sd $9,REGLOG(9)(k0)
+ sd $10,REGLOG(10)(k0)
+ sd $11,REGLOG(11)(k0)
+ sd $12,REGLOG(12)(k0)
+ sd $13,REGLOG(13)(k0)
+ sd $14,REGLOG(14)(k0)
+ sd $15,REGLOG(15)(k0)
+ sd $16,REGLOG(16)(k0)
+ sd $17,REGLOG(17)(k0)
+ sd $18,REGLOG(18)(k0)
+ sd $19,REGLOG(19)(k0)
+ sd $20,REGLOG(20)(k0)
+ sd $21,REGLOG(21)(k0)
+ sd $22,REGLOG(22)(k0)
+ sd $23,REGLOG(23)(k0)
+ sd $24,REGLOG(24)(k0)
+ sd $25,REGLOG(25)(k0)
+ sd $26,REGLOG(26)(k0)
+ sd $27,REGLOG(27)(k0)
+ sd $28,REGLOG(28)(k0)
+ sd $29,REGLOG(29)(k0)
+ sd $30,REGLOG(30)(k0)
+ sd $31,REGLOG(31)(k0)
+ .set at
+
+
+# Save some CP0 registers here.
+#define SAVECP0(cp0,idx) \
+ dmfc0 t0,cp0 ; \
+ sd t0,REGLOG(idx)(k0)
+
+ SAVECP0(C0_INX,32)
+ SAVECP0(C0_RAND,33)
+ SAVECP0(C0_TLBLO0,34)
+ SAVECP0(C0_TLBLO1,35)
+ SAVECP0(C0_CTEXT,36)
+ SAVECP0(C0_PGMASK,37)
+ SAVECP0(C0_WIRED,38)
+ SAVECP0(C0_BADVADDR,39)
+ SAVECP0(C0_COUNT,40)
+ SAVECP0(C0_TLBHI,41)
+ SAVECP0(C0_COMPARE,42)
+ SAVECP0(C0_SR,43)
+ SAVECP0(C0_CAUSE,44)
+ SAVECP0(C0_EPC,45)
+ SAVECP0(C0_PRID,46)
+ SAVECP0(C0_CONFIG,47)
+ SAVECP0(C0_LLADDR,48)
+ SAVECP0(C0_WATCHLO,49)
+ SAVECP0(C0_WATCHHI,50)
+ SAVECP0(C0_XCTEXT,51)
+ SAVECP0(C0_ECC,52)
+ SAVECP0(C0_CACHEERR,53)
+ SAVECP0(C0_TAGLO,54)
+ SAVECP0(C0_TAGHI,55)
+ SAVECP0(C0_ERREPC,56)
+
+ SETRECTYPE(VAPI_FMT_GPRS,a0)
+ SETRECLEN_CONST(MAXREGS)
+ add RECPTR,REGLOGMAX
+ sd RECPTR,vapi_logptr
+
+99: RESTORETEMPS(vapi_regsave)
+
+ j ra # go home
+
+END(vapi_loggprs)
+
+
+/* *********************************************************************
+ * VAPI_LOGFPRS(id)
+ *
+ * Save the floating point unit's registers
+ * in the log.
+ *
+ * Input parameters:
+ * a0 - low 32 bits are the ID code to store with the entry
+ * in the log
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * k0 - scratch register for CFE
+ ********************************************************************* */
+
+
+#define SAVEFPR(cp1,idx) \
+ dmfc1 t0,cp1 ; \
+ sd t0,FPREGLOG(idx)(k0)
+#define SAVECP1(cp1,idx) \
+ cfc1 t0,cp1 ; \
+ sd t0,FPREGLOG(idx)(k0)
+
+#define FPREGLOG(x) (VAPI_REC_DATA+REGIDX(x))
+#define FPMAXREGS 37
+#define FPREGLOGMAX FPREGLOG(FPMAXREGS)
+
+LEAF(vapi_logfprs)
+
+ SAVETEMPS(vapi_regsave)
+ CHECKPTR(99f)
+
+ ld k0,vapi_logptr
+ SAVEFPR($0,0)
+ SAVEFPR($1,1)
+ SAVEFPR($2,2)
+ SAVEFPR($3,3)
+ SAVEFPR($4,4)
+ SAVEFPR($5,5)
+ SAVEFPR($6,6)
+ SAVEFPR($7,7)
+ SAVEFPR($8,8)
+ SAVEFPR($9,9)
+ SAVEFPR($10,10)
+ SAVEFPR($11,11)
+ SAVEFPR($12,12)
+ SAVEFPR($13,13)
+ SAVEFPR($14,14)
+ SAVEFPR($15,15)
+ SAVEFPR($16,16)
+ SAVEFPR($17,17)
+ SAVEFPR($18,18)
+ SAVEFPR($19,19)
+ SAVEFPR($20,20)
+ SAVEFPR($21,21)
+ SAVEFPR($22,22)
+ SAVEFPR($23,23)
+ SAVEFPR($24,24)
+ SAVEFPR($25,25)
+ SAVEFPR($26,26)
+ SAVEFPR($27,27)
+ SAVEFPR($28,28)
+ SAVEFPR($29,29)
+ SAVEFPR($30,30)
+ SAVEFPR($31,31)
+
+ SAVECP1($0,32) /* FIR */
+ SAVECP1($31,33) /* Status */
+ SAVECP1($25,34) /* condition codes */
+ SAVECP1($26,35) /* Exceptions */
+ SAVECP1($28,36) /* enables */
+
+ SETRECTYPE(VAPI_FMT_FPRS,a0)
+ SETRECLEN_CONST(FPMAXREGS)
+ add RECPTR,FPREGLOGMAX
+ sd RECPTR,vapi_logptr
+
+99: RESTORETEMPS(vapi_regsave)
+
+ j ra # go home
+
+END(vapi_logfprs)
+
+/* *********************************************************************
+ * VAPI_PUTS(string)
+ *
+ * Display a string on the console
+ *
+ * Input parameters:
+ * a0 - pointer to null-terminated string
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * k0 - scratch register for CFE
+ ********************************************************************* */
+
+LEAF(vapi_puts)
+
+ .set noat
+ la k0,vapi_regsave
+ sd $0,REGIDX(0)(k0)
+ sd $1,REGIDX(1)(k0)
+ sd $2,REGIDX(2)(k0)
+ sd $3,REGIDX(3)(k0)
+ sd $4,REGIDX(4)(k0)
+ sd $5,REGIDX(5)(k0)
+ sd $6,REGIDX(6)(k0)
+ sd $7,REGIDX(7)(k0)
+ sd $8,REGIDX(8)(k0)
+ sd $9,REGIDX(9)(k0)
+ sd $10,REGIDX(10)(k0)
+ sd $11,REGIDX(11)(k0)
+ sd $12,REGIDX(12)(k0)
+ sd $13,REGIDX(13)(k0)
+ sd $14,REGIDX(14)(k0)
+ sd $15,REGIDX(15)(k0)
+ sd $16,REGIDX(16)(k0)
+ sd $17,REGIDX(17)(k0)
+ sd $18,REGIDX(18)(k0)
+ sd $19,REGIDX(19)(k0)
+ sd $20,REGIDX(20)(k0)
+ sd $21,REGIDX(21)(k0)
+ sd $22,REGIDX(22)(k0)
+ sd $23,REGIDX(23)(k0)
+ sd $24,REGIDX(24)(k0)
+ sd $25,REGIDX(25)(k0)
+ sd $26,REGIDX(26)(k0) /* k0 */
+ sd $27,REGIDX(27)(k0)
+ sd $28,REGIDX(28)(k0)
+ sd $29,REGIDX(29)(k0)
+ sd $30,REGIDX(30)(k0)
+ sd $31,REGIDX(31)(k0)
+ .set at
+
+ la gp,_gp
+ LR sp,mem_heapstart
+ ADD sp,((CFG_HEAP_SIZE*1024)+STACK_SIZE - 8)
+ jal vapi_doputs /* dump registers in 'C' */
+
+ .set noat
+ la k0,vapi_regsave
+ ld $1,REGIDX(1)(k0)
+ ld $2,REGIDX(2)(k0)
+ ld $3,REGIDX(3)(k0)
+ ld $4,REGIDX(4)(k0)
+ ld $5,REGIDX(5)(k0)
+ ld $6,REGIDX(6)(k0)
+ ld $7,REGIDX(7)(k0)
+ ld $8,REGIDX(8)(k0)
+ ld $9,REGIDX(9)(k0)
+ ld $10,REGIDX(10)(k0)
+ ld $11,REGIDX(11)(k0)
+ ld $12,REGIDX(12)(k0)
+ ld $13,REGIDX(13)(k0)
+ ld $14,REGIDX(14)(k0)
+ ld $15,REGIDX(15)(k0)
+ ld $16,REGIDX(16)(k0)
+ ld $17,REGIDX(17)(k0)
+ ld $18,REGIDX(18)(k0)
+ ld $19,REGIDX(19)(k0)
+ ld $20,REGIDX(20)(k0)
+ ld $21,REGIDX(21)(k0)
+ ld $22,REGIDX(22)(k0)
+ ld $23,REGIDX(23)(k0)
+ ld $24,REGIDX(24)(k0)
+ ld $25,REGIDX(25)(k0)
+ /*ld $26,REGIDX(26)(k0) don't restore k0 */
+ ld $27,REGIDX(27)(k0)
+ ld $28,REGIDX(28)(k0)
+ ld $29,REGIDX(29)(k0)
+ ld $30,REGIDX(30)(k0)
+ ld $31,REGIDX(31)(k0)
+ .set at
+
+ j ra
+
+END(vapi_puts)
+
+/* *********************************************************************
+ * VAPI_SETLEDS(leds)
+ *
+ * Set the onboard LEDS on the swarm board.
+ *
+ * Input parameters:
+ * a0 - LED value, "ABCD" is 0x41424344
+ *
+ * Return value:
+ * nothing
+ *
+ * Registers used:
+ * k0 - scratch register for CFE
+ ********************************************************************* */
+
+
+LEAF(vapi_setleds)
+
+ SAVETEMPS(vapi_regsave)
+
+ jal board_setleds
+
+ RESTORETEMPS(vapi_regsave)
+
+ j ra
+
+END(vapi_setleds)
+
+/* *********************************************************************
+ * VAPI_KSEG1_SWITCH
+ *
+ * Hack the return address so we will come back in KSEG1 (uncached)
+ *
+ * Input parameters:
+ * nothing
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(vapi_kseg1_switch)
+
+ and ra,(K0SIZE-1)
+ or ra,K1BASE
+ jr ra
+
+END(vapi_kseg1_switch)
+
+
+/* *********************************************************************
+ * VAPI_RUN()
+ *
+ * Jump to the diagnostic program, which must be loaded at the
+ * special address (typically 8002_0000). First we flush the
+ * cache, then set magic #'s in the mailbox. Finally, the core
+ * is reset. On restart, we do minimal initialization and jump
+ * directly to the diagnostic.
+ *
+ * Input parameters:
+ * a0 - nonzero to restart uncached.
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+
+LEAF(vapi_run)
+
+ /*
+ * Run uncached
+ */
+
+ bal vapi_kseg1_switch # now running in KSEG1
+
+ /*
+ * Flush the caches
+ */
+
+ move s0,a0 # L2 flush trashes A0
+ CALLKSEG1(sb1250_l1cache_flush_d)
+ CALLKSEG1(sb1250_l1cache_inval_i)
+ CALLKSEG1(sb1250_l2cache_flush)
+ move a0,s0
+
+#ifdef _P5064_
+
+ /* In the case of the P5064, just jump directly to the entry point */
+
+ li t0,VAPI_DIAG_ENTRY
+ j t0
+
+#else
+
+ /*
+ * Set the magic code in the mailbox.
+ */
+
+ li t0,-1
+ la t1,PHYS_TO_K1(A_IMR_REGISTER(0,R_IMR_MAILBOX_CLR_CPU))
+ sd t0,0(t1)
+
+ dli t0,VAPI_MAGIC_NUMBER
+ beq a0,0,1f
+ dli t0,VAPI_MAGIC_NUMBER_UNC
+ beq a0,1,1f
+ dli t0,VAPI_MAGIC_NUMBER_MC
+1: la t1,PHYS_TO_K1(A_IMR_REGISTER(0,R_IMR_MAILBOX_SET_CPU))
+ sd t0,0(t1)
+
+ /*
+ * Whack the reset line.
+ */
+#if defined(_PTSWARM_)
+ li k0,PHYS_TO_K1(0x1B0A0000+32+8*3)
+#else
+ li k0,PHYS_TO_K1(0x100A0000+32+8*3)
+#endif
+ li k1,'!'
+
+ li t1,PHYS_TO_K1(A_SCD_SYSTEM_CFG)
+ ld t2,0(t1)
+ dli t0,M_SYS_CPU_RESET_0 | M_SYS_CPU_RESET_1
+ or t2,t2,t0
+ bal vapi_kseg0_switch
+ .align 5
+#if defined(_CSWARM_) || defined(_SWARM_) || defined(_PTSWARM_)
+ sb k1,0(k0)
+#else
+ nop
+#endif
+ sync /* flush the write buffer */
+ sd t2,0(t1)
+1: b 1b
+
+ /*
+ * And he never returned, no he never returned... and his fate
+ * is still unknown, he will ride forever 'neath the cycles of
+ * the SB1, he's the core that never returned!
+ */
+#endif
+
+
+
+END(vapi_run)
+
+
+LEAF(vapi_flushtest)
+
+ move s1,ra
+
+ /*
+ * Run uncached
+ */
+
+ bal vapi_kseg1_switch # now running in KSEG1
+
+ /*
+ * Flush the caches
+ */
+
+ move s0,a0 # L2 flush trashes A0
+ CALLKSEG1(sb1250_l1cache_flush_d)
+ CALLKSEG1(sb1250_l1cache_inval_i)
+ CALLKSEG1(sb1250_l2cache_flush)
+ move a0,s0
+
+ /*
+ * Back to cached
+ */
+
+ bal vapi_kseg0_switch # now running in KSEG1
+
+ move ra,s1
+ j ra
+
+END(vapi_flushtest)
+
+
+#endif /* CFG_VAPI */
+
+/* *********************************************************************
+ * End
+ ********************************************************************* */
+
+