diff options
author | root <root@lamia.panaceas.james.local> | 2015-12-19 13:13:57 +0000 |
---|---|---|
committer | root <root@lamia.panaceas.james.local> | 2015-12-19 14:18:03 +0000 |
commit | 1a2238d1bddc823df06f67312d96ccf9de2893cc (patch) | |
tree | c58a3944d674a667f133ea5a730f5037e57d3d2e /cfe/cfe/verif | |
download | bootloader-1a2238d1bddc823df06f67312d96ccf9de2893cc.tar.gz bootloader-1a2238d1bddc823df06f67312d96ccf9de2893cc.tar.bz2 bootloader-1a2238d1bddc823df06f67312d96ccf9de2893cc.zip |
CFE from danitool [without hostTools dir]: https://mega.nz/#!mwZyFK7a!CPT3BKC8dEw29kubtdYxhB91G9vIIismTkgzQ3iUy3k
Diffstat (limited to 'cfe/cfe/verif')
-rw-r--r-- | cfe/cfe/verif/Makefile | 7 | ||||
-rw-r--r-- | cfe/cfe/verif/readme.txt | 342 | ||||
-rw-r--r-- | cfe/cfe/verif/ui_vapi.c | 300 | ||||
-rw-r--r-- | cfe/cfe/verif/vapi.S | 1150 | ||||
-rw-r--r-- | cfe/cfe/verif/vapi.h | 242 | ||||
-rw-r--r-- | cfe/cfe/verif/vapisubr.c | 122 | ||||
-rw-r--r-- | cfe/cfe/verif/vapitest.S | 108 |
7 files changed, 2271 insertions, 0 deletions
diff --git a/cfe/cfe/verif/Makefile b/cfe/cfe/verif/Makefile new file mode 100644 index 0000000..939b494 --- /dev/null +++ b/cfe/cfe/verif/Makefile @@ -0,0 +1,7 @@ + +# +# Object files needed by VAPI +# + +CFLAGS += -DCFG_VAPI=1 +ALLOBJS += vapi.o vapisubr.o vapitest.o ui_vapi.o diff --git a/cfe/cfe/verif/readme.txt b/cfe/cfe/verif/readme.txt new file mode 100644 index 0000000..4a35dee --- /dev/null +++ b/cfe/cfe/verif/readme.txt @@ -0,0 +1,342 @@ +CFE Diagnostic Entry Points +--------------------------- + +--------------------------------------------------------------------------- + +The CFE diagnostic entry points are used when running verification +programs under the control of the firmware. They are fixed (constant) +addresses and have register-based calling sequences. These entry +points are designed to be as minimal as possible so that as much of the +verification code as possible can be reused. + +You can call the KSEG0 or KSEG1 version of the routine. It is +recommended that you call the cached version from cached code and +vice versa. + +The firmware will reserve the top megabyte of memory for itself. The +diagnostic must not touch this memory. + +The firmware will be compiled to *NOT* use relocatable data and +code segments. + +The firmware will need one general register that it is allowed to +trash without saving - I'll be using this to generate the pointer to +the save area. + +The diagnostics can generate records in a log buffer. This buffer +is allocated in the diagnostic's memory space but is filled in +by the firmware through the diagnostic entry points. At the end +of the diagnostic run, user commands in the firmware may be used +to look through accumulated log records. + +If you mess with the caches or with the console device, the +VAPI functions that print messages to the console may not work. + +Log records follow this format: + + +0 SIGNATURE, FORMAT, and ID-CODE + +8 Number of 64-bit words in 'Log Data' field. + Upper 32 bits are CP0 count register + +16 Return address of routine generating this record + +24 Log Data + +The "Log Record size" field is the number of bytes in the "log data" +field. No log data would use a value of zero. + +The bytes in the SIGNATURE word are broken down as follows: + + S1 S2 P1 F1 I1 I2 I3 I4 + CF E1 pp xx ii ii ii ii + +The "F1" byte is the format code; it describes the type +of log record being generated. + + 0x00 - General register and CP0 dump + 0x01 - SOC state dump + 0x02 - Generic log data (multiple of 8 bytes) + 0x03 - trace RAM + 0x04 - Diagnostic termination status (8 bytes) + 0x05 - Floating point registers + +The "P1" byte is the processor number, 0 or 1. + +The "I1" through "I4" bytes are supplied by the diagnostic +and can take on any value. You can use these bytes to identify +what part of the program generated this particular log record. + +For example, if the diagnostic logs a single value of +0x0123_4567_89ab_cdef the log entry might look like: + + 0xCCFF_EE02_0000_0001 + 0x0001_3F22_0000_0008 + 0xFFFF_FFFF_8000_0120 + 0x0123_4567_89AB_CDEF + + +RETURN TO FIRMWARE +------------------ + +Description: + + Returns control to the firmware and displays the test status. + The status result is in register A0. + + The firmware will store a "diagnostic termination status" + record in the log with the A0 register value. The ID code + will be zero for this record. + + CFE's log scanning commands can be used to display log + records accumulated by the test. + + +Routine address: 0xBFC00510 (KSEG1) + 0x9FC00510 (KSEG0) + +On entry: A0 ($4) Exit status (9=ok, nonzero=fail) +On return: Does not return +Registers used: All + + +DUMP GENERAL REGISTERS +---------------------- + +Description: + + This routine causes CFE to display a register dump on the console + port. It is assumed that the console hardware state has not been + altered by the diagnostic. + + The format of the register dump is: TBD [XXX should it look like the + one that the functional simulator uses?] + + The firmware needs one scratch register. + + +Routine address: 0xBFC00520 (KSEG1) + 0x9FC00520 (KSEG0) + +On Entry: RA ($31) Return Address +On Return: nothing +Registers used: K0 ($26) Scratch register for CFE + + +SET LOG BUFFER +-------------- + +Description: + + This routine sets the address of the log buffer. This + call must be made once at the beginning of the diagnostic + or else the "SAVE" functions will be considered as + NOPs. + + The buffer addresses must be 64-bit aligned. + +Routine address: 0xBFC00530 (KSEG1) + 0x9FC00530 (KSEG0) + +On Entry: RA ($31) Return Address + A0 ($4) Address of start of buffer + A1 ($5) Address of end of buffer +On Return: Nothing +Registers Used: K0 ($26) Scratch register for CFE + + + +LOG SINGLE VALUE +---------------- + +Description: + + This routine saves a single 64-bit value in the log. + + +Routine address: 0xBFC00540 (KSEG1) + 0x9FC00540 (KSEG0) + +On Entry: RA ($31) Return Address + A0 ($4) Low 32 bits are ID code for value + A1 ($5) Value to log +On Return: Nothing +Registers Used: K0 ($26) Scratch register for CFE + + + +LOG MEMORY DATA +--------------- + +Description: + + This routine saves a block of memory in the log. The source + buffer must be 64-bit aligned. + + +Routine address: 0xBFC00550 (KSEG1) + 0x9FC00550 (KSEG0) + +On Entry: RA ($31) Return Address + A0 ($4) Low 32 bits are ID code for values + A1 ($5) Address of buffer containing values + A2 ($6) Number of 64-bit words to store +On Return: Nothing +Registers Used: K0 ($26) Scratch register for CFE + + + + + +SAVE SOC STATE +-------------- + +Description: + + This routine saves the SOC state in a user-supplied buffer. + The buffer must be large enough to accomodate the SOC state. + The SOC state will be written as records with the following + format: + + uint64_t phys_address + uint64_t value + uint64_t phys_address + uint64_t value + ... + uint64_t phys_address + uint64_t value + + The table of SOC registers to dump will be maintained by + the firmware. + + The firmware needs one scratch register. + +Routine address: 0xBFC00570 (KSEG1) + 0x9FC00570 (KSEG0) + +On entry: A0 ($4) Low 32 bits are ID code for values + A1 ($5) Bitmask of agents to store in log +On return: nothing +Registers used: K0 ($26) Scratch register for CFE + + +SAVE CPU REGISTERS +------------------ + +Description: + + This routine saves the CPU general registers and certain CP0 + registers in a user-supplied buffer. + + This buffer must be large enough to accomodate the data + that will be saved. The registers will be written in + the following format: + + uint64_t general_registers[32] + uint64_t C0_INX + uint64_t C0_RAND + uint64_t C0_TLBLO0 + uint64_t C0_TLBLO1 + uint64_t C0_CTEXT + uint64_t C0_PGMASK + uint64_t C0_WIRED + uint64_t C0_BADVADDR + uint64_t C0_COUNT + uint64_t C0_TLBHI + uint64_t C0_COMPARE + uint64_t C0_SR + uint64_t C0_CAUSE + uint64_t C0_EPC + uint64_t C0_PRID + uint64_t C0_CONFIG + uint64_t C0_LLADDR + uint64_t C0_WATCHLO + uint64_t C0_WATCHHI + uint64_t C0_XCTEXT + uint64_t C0_ECC + uint64_t C0_CACHEERR + uint64_t C0_TAGLO + uint64_t C0_TAGHI + uint64_t C0_ERREPC + + The firmware needs one scratch register. + +Routine address: 0xBFC00580 (KSEG1) + 0x9FC00580 (KSEG0) + +On entry: RA ($31) Return address + A0 ($4) Low 32 bits are ID code for values +On return: nothing +Registers used: K0 ($26) Scratch register for CFE + + +SAVE FPU REGISTERS +------------------ + +Description: + + This routine saves the floating point and floating point + control registers. The registers will be written in + the following format: + + uint64_t fp_registers[32] + uint64_t fp_fir + uint64_t fp_status + uint64_t fp_condition_codes + uint64_t fp_exceptions + uint64_t fp_enables + + The firmware needs one scratch register. + +Routine address: 0xBFC005B0 (KSEG1) + 0x9FC005B0 (KSEG0) + +On entry: RA ($31) Return address + A0 ($4) Low 32 bits are ID code for values +On return: nothing +Registers used: K0 ($26) Scratch register for CFE + + +DUMP STRING +----------- + +Description: + + This routine displays a zero-terminated ASCII text string on the + console port. + + The firmware needs one scratch register. + + +Routine address: 0xBFC00590 (KSEG1) + 0x9FC00590 (KSEG0) + +On entry: RA ($31) Return address + A0 ($4) Pointer to null-terminated string +On return: nothing +Registers used: K0 ($26) Scratch register for CFE + + + +SHOW LED MESSAGE +---------------- + +Description: + + This routine writes four characters onto the SWARM board LEDs. + Writing to the LEDs is very fast compared to writing to the + console and can be useful for providing progress feedback + during a run. + + The characters are packed into the low 4 bytes of register A0. + The string ABCD would be hex 0x0000_0000_4142_4344 + + The firmware needs one scratch register + +Routine address: 0xBFC005A0 (KSEG1) + 0x9FC005A0 (KSEG0) + +On entry: RA ($31) Return Address + A0 ($4) Four characters +On return: nothing +Registers used: K0 ($26) Scratch register for CFE + +------------------------------------------------------------------------ + diff --git a/cfe/cfe/verif/ui_vapi.c b/cfe/cfe/verif/ui_vapi.c new file mode 100644 index 0000000..4575322 --- /dev/null +++ b/cfe/cfe/verif/ui_vapi.c @@ -0,0 +1,300 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * VAPI commands File: ui_vapi.c + * + * User interface for the verification API + * + * 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 "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" +#include "bsp_config.h" + +#include "cfe_iocb.h" +#include "cfe_device.h" +#include "cfe_console.h" +#include "env_subr.h" +#include "ui_command.h" +#include "cfe.h" + +#if CFG_VAPI + +#include "vapi.h" + +int ui_init_vapicmds(void); + +extern void vapitest(void); + +extern void vapi_run(int); + +extern uint64_t vapi_logstart; +extern uint64_t vapi_logend; +extern uint64_t vapi_logptr; +extern uint64_t vapi_status; + +int ui_cmd_vapirun(ui_cmdline_t *cmd,int argc,char *argv[]); +int ui_cmd_vapitest(ui_cmdline_t *cmd,int argc,char *argv[]); +int ui_cmd_vapishow(ui_cmdline_t *cmd,int argc,char *argv[]); +int ui_cmd_vapidump(ui_cmdline_t *cmd,int argc,char *argv[]); +int ui_cmd_vapistatus(ui_cmdline_t *cmd,int argc,char *argv[]); + +static char *rectypes[7] = { + "GPRS ", + "SOC ", + "DATA ", + "BUF ", + "TRC ", + "EXIT ", + "FPRS " +}; + +int ui_cmd_vapidump(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + uint64_t *ptr; + uint64_t *eptr; + int recnum = 0; + + if (vapi_logptr == 0) { + xprintf("Diagnostic did not record any log records\n"); + return -1; + } + + ptr = (uint64_t *) (intptr_t) vapi_logstart; + eptr = (uint64_t *) (intptr_t) vapi_logptr; + + xprintf("*** VAPI LOG START %s\n", +#ifdef __MIPSEB + "big-endian" +#else + "little-endian" +#endif + ); + + while (ptr < eptr) { + xprintf("%6d %016llX %016llX %016llX %016llX\n", + recnum, + ptr[0],ptr[1],ptr[2],ptr[3]); + ptr += 4; + recnum++; + } + + xprintf("*** VAPI LOG END\n"); + + return 0; + + +} + +int ui_cmd_vapishow(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + uint64_t *ptr; + uint64_t *eptr; + uint32_t a,b; + uint32_t ts,len,fmt; + unsigned int idx; + int recnum = 0; + + if (vapi_logptr == 0) { + xprintf("Diagnostic did not record any log records\n"); + return -1; + } + + ptr = (uint64_t *) (intptr_t) vapi_logstart; + eptr = (uint64_t *) (intptr_t) vapi_logptr; + + while (ptr < eptr) { + a = (ptr[VAPI_IDX_SIGNATURE]) >> 32; + b = (ptr[VAPI_IDX_SIGNATURE]) & 0xFFFFFFFF; + if ((a & VAPI_SEAL_MASK) != VAPI_CFESEAL) { + xprintf("Incorrect record seal at %08X\n",ptr); + break; + } + + fmt = (a & VAPI_FMT_MASK); + + xprintf("%5d ID=%08X CPU%d %s RA=%08X ", + recnum, + b, + (a & VAPI_PRID_MASK) >> VAPI_PRNUM_SHIFT, + rectypes[fmt], + ptr[VAPI_IDX_RA]); + + ts = (ptr[VAPI_IDX_SIZE]) >> 32; + len = ((ptr[VAPI_IDX_SIZE]) & 0xFFFFFFFF); + + xprintf("TS=%08X ",ts); + + switch (fmt) { + case VAPI_FMT_GPRS: + xprintf("Len=%d\n",len); + for (idx = 0; idx < len; idx += 2) { + xprintf(" %016llX %016llX\n", + ptr[VAPI_IDX_DATA+idx], + ptr[VAPI_IDX_DATA+idx+1]); + } + break; + case VAPI_FMT_SOC: + xprintf("Len=%d\n",len); + for (idx = 0; idx < len; idx += 2) { + xprintf(" Reg=%016llX Val=%016llX\n", + ptr[VAPI_IDX_DATA+idx], + ptr[VAPI_IDX_DATA+idx+1]); + } + break; + case VAPI_FMT_DATA: + xprintf("Data=%016llX\n",ptr[VAPI_IDX_DATA]); + break; + case VAPI_FMT_BUFFER: + xprintf("Addr=%08X\n",(intptr_t) ptr[VAPI_IDX_DATA]); + for (idx = 0; idx < len-1; idx += 2) { + xprintf(" %016llX %016llX\n", + ptr[VAPI_IDX_DATA+idx+1], + ptr[VAPI_IDX_DATA+idx+2]); + } + if (idx != (len-1)) { + xprintf(" %016llX\n", + ptr[VAPI_IDX_DATA+idx+1]); + } + break; + case VAPI_FMT_TRACE: + xprintf("\n"); + break; + case VAPI_FMT_EXIT: + xprintf("Stat=%016llX\n",ptr[VAPI_IDX_DATA]); + break; + default: + xprintf("\n"); + break; + } + + ptr += 3 + len; + recnum++; + } + + return 0; + +} + +int ui_cmd_vapitest(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + + vapitest(); + + xprintf("LogStart=%llX LogEnd=%llX LogPtr=%llX\n", + vapi_logstart,vapi_logend,vapi_logptr); + + return 0; +} + +int ui_cmd_vapistatus(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + + xprintf("VAPI Exit Status = <%016llX>\n", vapi_status); + return 0; +} + +int ui_cmd_vapirun(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int mode; /* 0 = cached, 1 = uncached, 2 = mc mode */ + + mode = 0; + if (cmd_sw_isset(cmd,"-uncached")) mode = 1; + if (cmd_sw_isset(cmd,"-mc")) mode = 2; + + vapi_run(mode); + return -1; +} + + +int ui_init_vapicmds(void) +{ + cmd_addcmd("vapi run", + ui_cmd_vapirun, + NULL, + "Run a program using the VAPI reset vector.", + "vapi run\n" + "Executes a previously loaded VAPI program by resetting the\n" + "CPUs and jumping directly to user code. The program\n" + "must be located at absolute address 0x8002_0000\n", + "-uncached;Start execution at 0xA002_0000 (KSEG1)|" + "-mc;Start execution at 0xBFD0_0000"); + + cmd_addcmd("vapi test", + ui_cmd_vapitest, + NULL, + "Test VAPI interface.", + "vapi test\n\n" + "Do some basic calls to the VAPI interface, then return to CFE\n\n", + ""); + + cmd_addcmd("vapi dump", + ui_cmd_vapidump, + NULL, + "Show VAPI log in an easily processed format.", + "vapi dump\n\n" + "Display the VAPI log in a format that is more easily postprocessed\n" + "by external programs.\n\n", + ""); + + cmd_addcmd("vapi show", + ui_cmd_vapishow, + NULL, + "Show VAPI log.\n", + "vapi show\n\n" + "Display the VAPI log in a human readable form (sort of)\n\n", + ""); + + cmd_addcmd("vapi status", + ui_cmd_vapistatus, + NULL, + "Print last VAPI exit status.\n", + "vapi status\n\n" + "Display the exit status of the last VAPI program that was run\n", + ""); + + return 0; +} + +#endif 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 + ********************************************************************* */ + + diff --git a/cfe/cfe/verif/vapi.h b/cfe/cfe/verif/vapi.h new file mode 100644 index 0000000..1deb8a5 --- /dev/null +++ b/cfe/cfe/verif/vapi.h @@ -0,0 +1,242 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * Verification Test APIs File: vapi.h + * + * 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. + ********************************************************************* */ + + +#define VAPI_EPTSEAL 0x56415049 +#define VAPI_CFESEAL 0xCFE10000 +#define VAPI_SEAL_MASK 0xFFFF0000 +#define VAPI_FMT_MASK 0x000000FF +#define VAPI_PRID_MASK 0x0000FF00 + +#define VAPI_DIAG_ENTRY 0x80020000 +#define VAPI_DIAG_ENTRY_UNC 0xA0020000 +#define VAPI_DIAG_ENTRY_MC 0xBFD00000 +#define VAPI_MAGIC_NUMBER 0x1CFE2CFE3CFE4CFE +#define VAPI_MAGIC_NUMBER_UNC 0x0CFE1CFE2CFE3CFE +#define VAPI_MAGIC_NUMBER_MC 0xACFEBCFECCFEDCFE + +#define VAPI_FMT_GPRS 0 +#define VAPI_FMT_SOC 1 +#define VAPI_FMT_DATA 2 +#define VAPI_FMT_BUFFER 3 +#define VAPI_FMT_TRACE 4 +#define VAPI_FMT_EXIT 5 +#define VAPI_FMT_FPRS 6 + +#define VAPI_PRNUM_SHIFT 8 + +#define VAPI_REC_SIGNATURE 0 +#define VAPI_REC_SIZE 8 +#define VAPI_REC_RA 16 +#define VAPI_REC_DATA 24 + +#define VAPI_IDX_SIGNATURE 0 +#define VAPI_IDX_SIZE 1 +#define VAPI_IDX_RA 2 +#define VAPI_IDX_DATA 3 + + +#define VAPI_FUNC_EXIT 0x9fc00510 +#define VAPI_FUNC_DUMPGPRS 0x9fc00520 +#define VAPI_FUNC_SETLOG 0x9fc00530 +#define VAPI_FUNC_LOGVALUE 0x9fc00540 +#define VAPI_FUNC_LOGDATA 0x9fc00550 +#define VAPI_FUNC_LOGTRACE 0x9fc00560 +#define VAPI_FUNC_LOGSOC 0x9fc00570 +#define VAPI_FUNC_LOGGPRS 0x9fc00580 +#define VAPI_FUNC_DUMPSTRING 0x9fc00590 +#define VAPI_FUNC_SETLEDS 0x9fc005a0 +#define VAPI_FUNC_LOGFPRS 0x9fc005b0 + + +#define VAPI_LOG_SETBUF(start,end) \ + .set push ; \ + .set reorder ; \ + la a0, start ; \ + la a1, end ; \ + li k0, VAPI_FUNC_SETLOG ; \ + jalr k0 ; \ + .set pop + +#define VAPI_EXIT_CONST(val) \ + .set push ; \ + .set reorder ; \ + li a0, val ; \ + li k0, VAPI_FUNC_EXIT ; \ + jr k0 ; \ + .set pop + +#define VAPI_EXIT_REG(val) \ + .set push ; \ + .set reorder ; \ + move a0, val ; \ + li k0, VAPI_FUNC_EXIT ; \ + jr k0 ; \ + .set pop + +#define VAPI_LOG_CONST(id,value) \ + .set push ; \ + .set reorder ; \ + li a0, id ; \ + li a1, value ; \ + li k0, VAPI_FUNC_LOGVALUE ; \ + jalr k0 ; \ + .set pop + +#define VAPI_LOG_REG(id,value) \ + .set push ; \ + .set reorder ; \ + li a0, id ; \ + move a1, value ; \ + li k0, VAPI_FUNC_LOGVALUE ; \ + jalr k0 ; \ + .set pop + +#define VAPI_LOG_BUFFER(id,addr,nwords) \ + .set push ; \ + .set reorder ; \ + li a0,id ; \ + la a1,addr ; \ + li a2,nwords ; \ + li k0, VAPI_FUNC_LOGDATA ; \ + jalr k0 ; \ + .set pop + +#define VAPI_PUTS(text) \ + .set push ; \ + .set reorder ; \ + b 1f ; \ +2: .asciz text ; \ + .align 4 ; \ +1: la a0, 2b ; \ + li k0, VAPI_FUNC_DUMPSTRING ; \ + jalr k0 ; \ + .set pop + +#define VAPI_PRINTGPRS() \ + .set push ; \ + .set reorder ; \ + li k0, VAPI_FUNC_DUMPGPRS ; \ + jalr k0 ; \ + .set pop + +#define VAPI_LOG_GPRS(id) \ + .set push ; \ + .set reorder ; \ + li a0, id ; \ + li k0, VAPI_FUNC_LOGGPRS ; \ + jalr k0 ; \ + .set pop + +#define VAPI_LOG_FPRS(id) \ + .set push ; \ + .set reorder ; \ + li a0, id ; \ + li k0, VAPI_FUNC_LOGFPRS ; \ + jalr k0 ; \ + .set pop + +#define VAPI_LOG_TRACE(id) \ + .set push ; \ + .set reorder ; \ + li a0, id ; \ + li k0, VAPI_FUNC_LOGTRACE ; \ + jalr k0 ; \ + .set pop + +#define VAPI_LOG_SOCSTATE(id,bits) \ + .set push ; \ + .set reorder ; \ + li a0, id ; \ + li a1, bits ; \ + li k0, VAPI_FUNC_LOGSOC ; \ + jalr k0 ; \ + .set pop + +#define VAPI_SETLEDS(a,b,c,d) \ + .set push ; \ + .set reorder ; \ + li a0, ((a) << 24) | ((b) << 16) | ((c) << 8) | (d) ; \ + li k0, VAPI_FUNC_SETLEDS ; \ + jalr k0 ; \ + .set pop + +#ifndef SOC_AGENT_MC0 +#define SOC_AGENT_MC0 0x00000001 +#define SOC_AGENT_MC1 0x00000002 +#define SOC_AGENT_MC 0x00000003 +#define SOC_AGENT_L2 0x00000004 +#define SOC_AGENT_MACDMA0 0x00000008 +#define SOC_AGENT_MACDMA1 0x00000010 +#define SOC_AGENT_MACDMA2 0x00000020 +#define SOC_AGENT_MACDMA 0x00000038 +#define SOC_AGENT_MACRMON0 0x00000040 +#define SOC_AGENT_MACRMON1 0x00000080 +#define SOC_AGENT_MACRMON2 0x00000100 +#define SOC_AGENT_MACRMON 0x000001C0 +#define SOC_AGENT_MAC0 0x00000200 +#define SOC_AGENT_MAC1 0x00000400 +#define SOC_AGENT_MAC2 0x00000800 +#define SOC_AGENT_MAC 0x00000E00 +#define SOC_AGENT_DUART 0x00001000 +#define SOC_AGENT_GENCS 0x00002000 +#define SOC_AGENT_GEN 0x00004000 +#define SOC_AGENT_GPIO 0x00008000 +#define SOC_AGENT_SMBUS0 0x00010000 +#define SOC_AGENT_SMBUS1 0x00020000 +#define SOC_AGENT_SMBUS 0x00030000 +#define SOC_AGENT_TIMER 0x00040000 +#define SOC_AGENT_SCD 0x00080000 +#define SOC_AGENT_BUSERR 0x00100000 +#define SOC_AGENT_DM 0x00200000 +#define SOC_AGENT_IMR0 0x00400000 +#define SOC_AGENT_IMR1 0x00800000 +#define SOC_AGENT_IMR 0x00C00000 +#endif + + + diff --git a/cfe/cfe/verif/vapisubr.c b/cfe/cfe/verif/vapisubr.c new file mode 100644 index 0000000..1ec130a --- /dev/null +++ b/cfe/cfe/verif/vapisubr.c @@ -0,0 +1,122 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * Verification Test APIs File: vapisubr.c + * + * This module contains special low-level routines for use + * by verification programs. The routines here are the "C" + * routines for higher-level functions. + * + * 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 "lib_types.h" +#include "lib_printf.h" +#include "lib_string.h" +#include "cfe_console.h" + +#if CFG_VAPI + +void vapi_doputs(char *str); +void vapi_dodumpregs(uint64_t *gprs); + +const static char * const gpregnames[] = { + "$0/zero","$1/AT","$2/v0","$3/v1","$4/a0","$5/a1","$6/a2","$7/a3", + "$8/t0","$9/t1","$10/t2","$11/t3","$12/t4","$13/t5","$14/t6","$15/t7", + "$16/s0","$17/s1","$18/s2","$19/s3","$20/s4","$21/s5","$22/s6","$23/s7", + "$24/t8","$25/t9","$26/k0","$27/k1","$28/gp","$29/sp","$30/fp","$31/ra", + "INX", + "RAND", + "TLBLO0", + "TLBLO1", + "CTEXT", + "PGMASK", + "WIRED", + "BADVADDR", + "COUNT", + "TLBHI", + "COMPARE", + "SR", + "CAUSE", + "EPC", + "PRID", + "CONFIG", + "LLADDR", + "WATCHLO", + "WATCHHI", + "XCTEXT", + "ECC", + "CACHEERR", + "TAGLO", + "TAGHI", + "ERREPC"}; + + + + +void vapi_doputs(char *str) +{ + xprintf("# %s\n",str); +} + +void vapi_dodumpregs(uint64_t *gprs) +{ + int cnt = sizeof(gpregnames)/sizeof(char *); + int idx; + + xprintf("# GPRS:\n"); + for (idx = 0; idx < cnt; idx++) { + if ((idx & 1) == 0) xprintf("# "); + xprintf(" %8s=%016llX ",gpregnames[idx],gprs[idx]); + if ((idx & 1) == 1) xprintf("\n"); + } + xprintf("\n"); + +} + +#endif /* CFG_VAPI */ + +/* ********************************************************************* + * End + ********************************************************************* */ + + diff --git a/cfe/cfe/verif/vapitest.S b/cfe/cfe/verif/vapitest.S new file mode 100644 index 0000000..4199f4e --- /dev/null +++ b/cfe/cfe/verif/vapitest.S @@ -0,0 +1,108 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * Verification Test APIs File: vapitest.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" + +#if CFG_VAPI + +#if (CFG_EMBEDDED_PIC) +#error "CFG_VAPI is not compatible with relocatable code" +#endif + + +#include "vapi.h" + +/* ********************************************************************* + * Constants + ********************************************************************* */ + .text + +testbuf: .dword 0x123456789ABCDEF0 + .dword 0xAABBCCDD + .dword 0xAABBCCDD + .dword 0xAABBCCDD + .dword 0xAABBCCDD + .dword 0xAABBCCDD + .dword 0xAABBCCDD + .dword 0xAABBCCDD + .dword 0xAABBCCDD + .dword 0xFEDCBA9876543210 + +LEAF(vapitest) + + sub sp,8 + sd ra,0(sp) + + VAPI_LOG_SETBUF(0x80200000,0x80300000) + + + VAPI_LOG_CONST(0x100,0xABCDEF) + VAPI_LOG_REG(0x101,sp) + VAPI_LOG_BUFFER(0x102,testbuf,10) + VAPI_PUTS("Hello world.\n") + VAPI_LOG_SOCSTATE(0x103,SOC_AGENT_DUART) + VAPI_PRINTGPRS(); + VAPI_LOG_CONST(0x1EE,0xEEEEEEEE) + VAPI_LOG_GPRS(0x199) + VAPI_SETLEDS('V','A','P','I') + + ld ra,0(sp) + add sp,8 + j ra + +END(vapitest) + + +#endif /* CFG_VAPI */ + +/* ********************************************************************* + * End + ********************************************************************* */ + + |