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 ********************************************************************* */ 47 48 49#include "sbmips.h" 50#include "bsp_config.h" 51#include "mipsmacros.h" 52 53#if CFG_VAPI 54 55#if CFG_EMBEDDED_PIC 56#error "CFG_VAPI is not compatible with relocatable code" 57#endif 58 59#include "cfe_devfuncs.h" 60 61#include "sb1250_defs.h" 62#include "sb1250_regs.h" 63#include "sb1250_scd.h" 64 65#include "vapi.h" 66 67/* ********************************************************************* 68 * Constants 69 ********************************************************************* */ 70 71#define CALLKSEG1(x) \ 72 la t0,x ; \ 73 or t0,K1BASE ; \ 74 jal t0 75 76#ifndef CFG_STACK_SIZE 77#define STACK_SIZE 8192 78#else 79#define STACK_SIZE ((CFG_STACK_SIZE+1023) & ~1023) 80#endif 81 82 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 88 89#define REGIDX(x) ((x)*8) 90 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) 101 102#define SAVE_SIZE REGIDX(10) 103 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 119 120 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 135 136#define RECPTR t3 137 138#define CHECKPTR(label) \ 139 ld RECPTR,vapi_logptr ; \ 140 ld t0,vapi_logend ; \ 141 beq RECPTR,zero,label ; \ 142 bge RECPTR,t0,label 143 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) 159 160 161 162#define SETRECLEN_CONST(len) \ 163 ld t2,VAPI_REC_SIZE(RECPTR) ; \ 164 or t2,len ; \ 165 sd t2,VAPI_REC_SIZE(RECPTR) 166 167#define SETRECLEN_REG(r) \ 168 ld t2,VAPI_REC_SIZE(RECPTR) ; \ 169 or t2,r ; \ 170 sd t2,VAPI_REC_SIZE(RECPTR) 171 172 173/* ********************************************************************* 174 * Data 175 ********************************************************************* */ 176 177 .sdata 178 179 .globl vapi_logstart 180 .globl vapi_logend 181 .globl vapi_logptr 182 .globl vapi_status 183 .globl vapi_logover 184 185vapi_logstart: .dword 0 186vapi_logend: .dword 0 187vapi_logptr: .dword 0 188vapi_status: .dword -1 189vapi_logover: .dword 0 190 191 .extern mem_heapstart 192 193 .bss 194 195 .comm vapi_regsave,REGIDX(64) 196 197 .text 198 199 .globl vapi_socregs 200vapi_socregs: 201 202#ifdef _P5064_ 203 .word 0, 0 204#else 205#include "sb1250_socregs.inc" 206#endif 207 208 .text 209 210 .extern cfe_warmstart 211 212 .set reorder 213 214 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 ********************************************************************* */ 226 227LEAF(vapi_kseg0_switch) 228 229 and ra,(K0SIZE-1) 230 or ra,K0BASE 231 jr ra 232 233END(vapi_kseg0_switch) 234 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 ********************************************************************* */ 246 247 248LEAF(vapi_exit) 249 250 move k1,a0 251 252 253/* 254 * Reinitialize the CPU and the caches 255 */ 256 257 bal vapi_kseg1_switch 258 CALLKSEG1(sb1_cpu_init) 259/* 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) */ 266 267#ifdef __long64 268/* 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 276 277 bal vapi_kseg0_switch 278 279 li a0,0x42424242 # 'BBBB' 280 jal board_setleds 281 282 move a0,k1 283 284 la gp,_gp 285 sd a0,vapi_status 286 LR sp,mem_heapstart 287 ADD sp,((CFG_HEAP_SIZE*1024)+STACK_SIZE - 8) 288 289/* 290 * Create a log record for the EXIT status. 291 */ 292 ld t0,vapi_logptr 293 beq t0,zero,nolog 294 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 300nolog: 301 li a0,0x45454545 # 'EEEE' 302 jal board_setleds 303 304#if CFG_MULTI_CPUS 305 306 /* 307 * Restart the other CPU if it was left in RESET. 308 */ 309 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 315 316 li a0,1 # Whack the CPU 317 jal altcpu_cmd_stop # and put it back in idle 3181: 319#endif 320 321 ld a0,vapi_status 322 j cfe_warmstart 323 324END(vapi_exit) 325 326 327 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 ********************************************************************* */ 342 343LEAF(vapi_dumpgprs) 344 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 380 381# Save some CP0 registers here. 382#define LSAVECP0(cp0,idx) \ 383 dmfc0 t0,cp0 ; \ 384 sd t0,REGIDX(idx)(k0) 385 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) 411 412 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' */ 419 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 454 455 j ra 456 457END(vapi_dumpgprs) 458 459 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 ********************************************************************* */ 476 477LEAF(vapi_setlog) 478 479 SAVETEMPS(vapi_regsave) 480 481 sd a0,vapi_logstart 482 sd a0,vapi_logptr 483 sd a1,vapi_logend 484 sd zero,vapi_logover 485 486 RESTORETEMPS(vapi_regsave) 487 488 j ra 489 490END(vapi_setlog) 491 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 ********************************************************************* */ 507 508LEAF(vapi_logtrace) 509 510 j ra 511 512END(vapi_logtrace) 513 514 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 ********************************************************************* */ 531 532LEAF(vapi_logsingle) 533 534 535 SAVETEMPS(vapi_regsave) 536 537 CHECKPTR(99f) 538 539 SETRECTYPE(VAPI_FMT_DATA,a0) 540 SETRECLEN_CONST(1) 541 542 sd a1,VAPI_REC_DATA(RECPTR) 543 544 add RECPTR,32 # one record 545 sd RECPTR,vapi_logptr 546 54799: RESTORETEMPS(vapi_regsave) 548 549 j ra 550 551END(vapi_logsingle) 552 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 ********************************************************************* */ 570 571LEAF(vapi_logdata) 572 573 SAVETEMPS(vapi_regsave) 574 575 CHECKPTR(99f) 576 577 SETRECTYPE(VAPI_FMT_BUFFER,a0) 578 579 add t1,RECPTR,VAPI_REC_DATA # a1 = ptr to data ara 580 581 sd a1,0(t1) 582 add t1,8 583 584 move k0,a2 # counter for words 585 5861: 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 593 5942: 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 600 60199: RESTORETEMPS(vapi_regsave) 602 603 j ra 604 605END(vapi_logdata) 606 607 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 ********************************************************************* */ 624 625LEAF(vapi_savesoc) 626 627 SAVETEMPS(vapi_regsave) 628 629 CHECKPTR(99f) 630 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 640 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) 646 647 move a2,zero # Counts how many we write 648 649 la t2,vapi_socregs 650 6511: 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 655 656 lw t0,4(t2) # get address of register 657 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 661 662 or t0,K1BASE # Make K1seg 663 ld t0,0(t0) # Read SOC register 664 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 668 6693: add t2,8 # next reg from table 670 671 b 1b 672 6732: 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 677 678 add t1,24 # Account for extra fields in record 679 sd t1,vapi_logptr # Update the pointer 680 68199: RESTORETEMPS(vapi_regsave) 682 683 j ra 684 685END(vapi_savesoc) 686 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 ********************************************************************* */ 703 704#define REGLOG(x) (VAPI_REC_DATA+REGIDX(x)) 705#define MAXREGS 57 706#define REGLOGMAX REGLOG(MAXREGS) 707 708LEAF(vapi_loggprs) 709 710 SAVETEMPS(vapi_regsave) 711 CHECKPTR(99f) 712 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 748 749 750# Save some CP0 registers here. 751#define SAVECP0(cp0,idx) \ 752 dmfc0 t0,cp0 ; \ 753 sd t0,REGLOG(idx)(k0) 754 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) 780 781 SETRECTYPE(VAPI_FMT_GPRS,a0) 782 SETRECLEN_CONST(MAXREGS) 783 add RECPTR,REGLOGMAX 784 sd RECPTR,vapi_logptr 785 78699: RESTORETEMPS(vapi_regsave) 787 788 j ra # go home 789 790END(vapi_loggprs) 791 792 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 ********************************************************************* */ 809 810 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) 817 818#define FPREGLOG(x) (VAPI_REC_DATA+REGIDX(x)) 819#define FPMAXREGS 37 820#define FPREGLOGMAX FPREGLOG(FPMAXREGS) 821 822LEAF(vapi_logfprs) 823 824 SAVETEMPS(vapi_regsave) 825 CHECKPTR(99f) 826 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) 860 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 */ 866 867 SETRECTYPE(VAPI_FMT_FPRS,a0) 868 SETRECLEN_CONST(FPMAXREGS) 869 add RECPTR,FPREGLOGMAX 870 sd RECPTR,vapi_logptr 871 87299: RESTORETEMPS(vapi_regsave) 873 874 j ra # go home 875 876END(vapi_logfprs) 877 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 ********************************************************************* */ 892 893LEAF(vapi_puts) 894 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 930 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 972 973 j ra 974 975END(vapi_puts) 976 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 ********************************************************************* */ 991 992 993LEAF(vapi_setleds) 994 995 SAVETEMPS(vapi_regsave) 996 997 jal board_setleds 998 999 RESTORETEMPS(vapi_regsave) 1000 1001 j ra 1002 1003END(vapi_setleds) 1004 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 ********************************************************************* */ 1016 1017LEAF(vapi_kseg1_switch) 1018 1019 and ra,(K0SIZE-1) 1020 or ra,K1BASE 1021 jr ra 1022 1023END(vapi_kseg1_switch) 1024 1025 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 ********************************************************************* */ 1041 1042LEAF(vapi_run) 1043 1044 /* 1045 * Run uncached 1046 */ 1047 1048 bal vapi_kseg1_switch # now running in KSEG1 1049 1050 /* 1051 * Flush the caches 1052 */ 1053 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 1059 1060#ifdef _P5064_ 1061 1062 /* In the case of the P5064, just jump directly to the entry point */ 1063 1064 li t0,VAPI_DIAG_ENTRY 1065 j t0 1066 1067#else 1068 1069 /* 1070 * Set the magic code in the mailbox. 1071 */ 1072 1073 li t0,-1 1074 la t1,PHYS_TO_K1(A_IMR_REGISTER(0,R_IMR_MAILBOX_CLR_CPU)) 1075 sd t0,0(t1) 1076 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 10821: la t1,PHYS_TO_K1(A_IMR_REGISTER(0,R_IMR_MAILBOX_SET_CPU)) 1083 sd t0,0(t1) 1084 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,'!' 1094 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) 11081: b 1b 1109 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 1116 1117 1118 1119END(vapi_run) 1120 1121 1122LEAF(vapi_flushtest) 1123 1124 move s1,ra 1125 1126 /* 1127 * Run uncached 1128 */ 1129 1130 bal vapi_kseg1_switch # now running in KSEG1 1131 1132 /* 1133 * Flush the caches 1134 */ 1135 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 1141 1142 /* 1143 * Back to cached 1144 */ 1145 1146 bal vapi_kseg0_switch # now running in KSEG1 1147 1148 move ra,s1 1149 j ra 1150 1151END(vapi_flushtest) 1152 1153 1154#endif /* CFG_VAPI */ 1155 1156/* ********************************************************************* 1157 * End 1158 ********************************************************************* */ 1159