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