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