1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * CPU init module File: init_ram.S 5 * 6 * This module contains the vectors and lowest-level CPU startup 7 * functions for CFE. 8 * 9 * This is very similar to "init_mips.S" but is used when 10 * you want to locate CFE in DRAM, loading it like an 11 * application program. 12 * 13 * Author: Mitch Lichtenberg (mpl@broadcom.com) 14 * 15 ********************************************************************* 16 * 17 * Copyright 2000,2001,2002,2003 18 * Broadcom Corporation. All rights reserved. 19 * 20 * This software is furnished under license and may be used and 21 * copied only in accordance with the following terms and 22 * conditions. Subject to these conditions, you may download, 23 * copy, install, use, modify and distribute modified or unmodified 24 * copies of this software in source and/or binary form. No title 25 * or ownership is transferred hereby. 26 * 27 * 1) Any source code used, modified or distributed must reproduce 28 * and retain this copyright notice and list of conditions 29 * as they appear in the source file. 30 * 31 * 2) No right is granted to use any trade name, trademark, or 32 * logo of Broadcom Corporation. The "Broadcom Corporation" 33 * name may not be used to endorse or promote products derived 34 * from this software without the prior written permission of 35 * Broadcom Corporation. 36 * 37 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 38 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 39 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 40 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 41 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 42 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 43 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 44 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 45 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 46 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 47 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 48 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 49 * THE POSSIBILITY OF SUCH DAMAGE. 50 ********************************************************************* */ 51 52 53#include "sbmips.h" 54#include "exception.h" 55 56#include "bsp_config.h" 57#include "cpu_config.h" 58 59#include "cfe_devfuncs.h" 60 61/* ********************************************************************* 62 * Check some stuff 63 ********************************************************************* */ 64 65#if CFG_RELOC 66#error "RAM version is not compatible with relocation." 67#endif 68#if !(CFG_RUNFROMKSEG0) && !(defined(JTAG_RAM_BOOT)) 69#error "RAM version should be run cached" 70#endif 71 72#if CFG_MULTI_CPUS 73#error "Multiple CPUs not compatible with RAM version" 74#endif 75 76 77/* ********************************************************************* 78 * Macros 79 ********************************************************************* */ 80 81#include "mipsmacros.h" 82 83 84/* ********************************************************************* 85 * SETLEDS(a,b,c,d) 86 * 87 * Sets the on-board LED display (if present). 88 * 89 * Input parameters: 90 * a,b,c,d - four ASCII characters (literal constants) 91 * 92 * Return value: 93 * a0,k1,ra trashed 94 ********************************************************************* */ 95 96 97#define SETLEDS(a,b,c,d) \ 98 li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \ 99 jal board_setleds ; 100 101 102/* ********************************************************************* 103 * Other constants 104 ********************************************************************* */ 105 106/* 107 * This is the size of the stack, rounded to KByte boundaries. 108 */ 109 110#ifndef CFG_STACK_SIZE 111#error "CFG_STACK_SIZE not defined" 112#else 113#define STACK_SIZE ((CFG_STACK_SIZE+1023) & ~1023) 114#endif 115 116/* 117 * Duplicates from cfe_iocb.h -- warning! 118 */ 119 120#define CFE_CACHE_FLUSH_D 1 121#define CFE_CACHE_INVAL_I 2 122#define CFE_CACHE_INVAL_D 4 123#define CFE_CACHE_INVAL_L2 8 124#define CFE_CACHE_FLUSH_L2 16 125#define CFE_CACHE_INVAL_RANGE 32 126#define CFE_CACHE_FLUSH_RANGE 64 127 128 129/* 130 * To make life easier reading this code, define "KSEGBASE" 131 * to either K0BASE or K1BASE depending on whether we're running 132 * uncached. 133 */ 134#ifdef JTAG_RAM_BOOT 135#define KSEGBASE K1BASE /* JTAG RAM version always uncached */ 136#else 137#define KSEGBASE K0BASE /* RAM version always cached */ 138#endif /* JTAG_RAM_BOOT */ 139 140/* ********************************************************************* 141 * Names of registers used in this module 142 ********************************************************************* */ 143 144 .sdata 145 146#include "initdata.h" /* declare variables we use here */ 147 148#if CFG_MULTI_CPUS 149 .globl cfe_spinlock 150cfe_spinlock: .word 0 151#endif 152 153 .extern _fdata 154 .extern _edata 155 .extern _etext 156 157/* ********************************************************************* 158 * uninitialized data 159 ********************************************************************* */ 160 161 .bss 162 163 .comm __junk,4 164 165 .text 166 167 .set noreorder 168 169 170/* ********************************************************************* 171 * CFE Entry Point (used by OS boot loaders and such) 172 ********************************************************************* */ 173 174 .set noreorder 175 176 .globl vec_reset 177 178vec_reset: b cpu_reset 179 nop 180 181 182vec_apientry: b cpu_apientry 183 nop 184 .word CFE_EPTSEAL 185 .word CFE_EPTSEAL 186 187 .set reorder 188 189 190/* ********************************************************************* 191 * Segment Table. 192 * 193 * Addresses of data segments and of certain routines we're going 194 * to call from KSEG1. These are here mostly for the embedded 195 * PIC case, since we can't count on the 'la' instruction to 196 * do the expected thing (the assembler expands it into a macro 197 * for doing GP-relative stuff, and the code is NOT GP-relative. 198 * So, we (relocatably) get the offset of this table and then 199 * index within it. 200 * 201 * Pointer values in this segment will be relative to KSEG0 for 202 * cached versions of CFE, so we need to OR in K1BASE in the 203 * case of calling to a uncached address. 204 * 205 * The LOADREL macro handles most of the nastiness here. 206 ********************************************************************* */ 207 208 209#include "segtable.h" 210 211 .globl segment_table 212segment_table: 213 _LONG_ _etext # [ 0] End of text (R_SEG_ETEXT) 214 _LONG_ _fdata # [ 1] Beginning of data (R_SEG_FDATA) 215 _LONG_ _edata # [ 2] End of data (R_SEG_EDATA) 216 _LONG_ _end # [ 3] End of BSS (R_SEG_END) 217 _LONG_ _ftext # [ 4] Beginning of text (R_SEG_FTEXT) 218 _LONG_ _fbss # [ 5] Beginning of BSS (R_SEG_FBSS) 219 _LONG_ _gp # [ 6] Global Pointer (R_SEG_GP) 220 _LONG_ 0 # [ 7] Beginning of reloc entries 221 _LONG_ 0 # [ 8] End of reloc entries 222 _LONG_ cpu_apientry # [ 9] R_SEG_APIENTRY 223 224 225/* ********************************************************************* 226 * Init Table. 227 * 228 * This is like segment_table except it contains pointers to 229 * routines used during initialization. It serves both as a 230 * table for doing PIC stuff and also to separate out 231 * machine-specific init routines. 232 * 233 * The CALLINIT_xxx macros are used to call routines in this table. 234 ********************************************************************* */ 235 236 237 .globl init_table 238init_table: 239 _LONG_ board_earlyinit # [ 0] R_INIT_EARLYINIT 240 _LONG_ board_setleds # [ 1] R_INIT_SETLEDS 241 _LONG_ board_draminfo # [ 2] R_INIT_DRAMINFO 242 _LONG_ CPUCFG_CPUINIT # [ 3] R_INIT_CPUINIT 243 _LONG_ CPUCFG_ALTCPU_START1 # [ 4] R_INIT_ALTCPU_START1 244 _LONG_ CPUCFG_ALTCPU_START2 # [ 5] R_INIT_ALTCPU_START2 245 _LONG_ CPUCFG_ALTCPU_RESET # [ 6] R_INIT_ALTCPU_RESET 246 _LONG_ CPUCFG_CPURESTART # [ 7] R_INIT_CPURESTART 247 _LONG_ CPUCFG_DRAMINIT # [ 8] R_INIT_DRAMINIT 248 _LONG_ CPUCFG_CACHEOPS # [ 9] R_INIT_CACHEOPS 249 _LONG_ CPUCFG_TLBHANDLER # [ 10] R_INIT_TLBHANDLER 250 _LONG_ cfe_main # [ 11] R_INIT_CMDSTART 251 _LONG_ cfe_command_restart # [ 12] R_INIT_CMDRESTART 252 _LONG_ cfe_doxreq # [ 13] R_INIT_DOXREQ 253 254/* ********************************************************************* 255 * CPU Startup Code 256 ********************************************************************* */ 257 258 259cpu_reset: 260 261#------------------------------------------------------------------------------ 262 263 /* 264 * Do low-level board initialization. This is our first 265 * chance to customize the startup sequence. 266 */ 267 268 CALLINIT_KSEG0(init_table,R_INIT_EARLYINIT) 269 270 SETLEDS('H','E','L','O') 271 272#------------------------------------------------------------------------------ 273 274 /* 275 * DRAM is now running, and we're alive in cacheable memory 276 * on cpu0 in K0SEG. Set up GP. 277 */ 278 279 LOADREL(a0,segment_table) 280 LR gp,R_SEG_GP(a0) 281 282#------------------------------------------------------------------------------ 283 /* 284 * Zero BSS 285 */ 286 287 SETLEDS('Z','B','S','S') 288 289 LOADREL(a0,segment_table) 290__ZeroBss: 291 292 LR v0,R_SEG_FBSS(a0) 293 LR v1,R_SEG_END(a0) 294 2951: SR zero,0(v0) # Zero one cacheline at a time 296 SR zero,(REGSIZE*1)(v0) 297 SR zero,(REGSIZE*2)(v0) 298 SR zero,(REGSIZE*3)(v0) 299 add v0,REGSIZE*4 300 blt v0,v1,1b 301 302 303#------------------------------------------------------------------------------ 304 305 li k0,256 # memory size in megabytes 306 307 308#ifdef __long64 309 mfc0 t0,C0_SR 310 or t0,t0,M_SR_KX 311 mtc0 t0,C0_SR 312#endif 313 314#------------------------------------------------------------------------------ 315 316 /* 317 * Remember total amount of memory. This is *still* in k0 318 * after all this time. Hopefully. 319 */ 320 321__MemVars: 322 SR k0,mem_totalsize 323 SR zero,mem_datareloc 324 325 move v0,zero 326 327 LOADREL(a0,segment_table) # trashed by l2 cache flush 328 LR v0,R_SEG_FTEXT(a0) # bottom = beginning of text 329 LR v1,R_SEG_END(a0) 330 331 SR v0,mem_bottomofmem 332 SR v1,mem_heapstart 333 334 add v1,(CFG_HEAP_SIZE*1024) # Otherwise 335 add v1,STACK_SIZE 336 SR v1,mem_topofmem 337 338 SR zero,mem_textreloc 339 340 341 LR t1,R_SEG_FTEXT(a0) 342 LR t0,R_SEG_ETEXT(a0) 343 sub t0,t0,t1 344 SR t0,mem_textsize 345 SR t1,mem_textbase 346 347 348#------------------------------------------------------------------------------ 349 350#if CFG_MULTI_CPUS 351 /* 352 * Let secondary CPU(s) run their idle loops. Set the 353 * mailbox register to our relocation factor so we can read 354 * it out of the mailbox register and relocate GP properly. 355 */ 356 357 move a0,zero 358 CALLINIT_KSEG0(init_table,R_INIT_ALTCPU_START2) 359#endif 360 361 /* 362 * Stash away some config register stuff 363 */ 364 365 mfc0 v0,C0_PRID 366 SR v0,cpu_prid 367 368 369#------------------------------------------------------------------------------ 370 371 /* 372 * Set up the "C" stack and jump to the main routine. 373 */ 374 375 SETLEDS('M','A','I','N') 376 377 LR sp,mem_heapstart 378 ADD sp,((CFG_HEAP_SIZE*1024)+STACK_SIZE - 8) 379 li a0,0 # call as "cfe_main(0,0)" 380 li a1,0 381 382 CALLINIT_KSEG0(init_table,R_INIT_CMDSTART) # should not return 383 384 385 /* 386 * Terminate the simulator. 387 */ 388 389crash_sim: li $2,1 390 li $4,0 391 syscall 0xCA 392 b cpu_reset 393 394 395 396/* ********************************************************************* 397 * CFE_WARMSTART 398 * 399 * Restart the command interpreter 400 * 401 * Input parameters: 402 * A0 - command status 403 * nothing (GP has already been set up for us) 404 * 405 * Return value: 406 * nothing 407 ********************************************************************* */ 408 409LEAF(cfe_warmstart) 410 411 SR a0,0(sp) # store on old stack 412 LOADREL(v0,init_table) 413 LR v0,R_INIT_CPURESTART(v0) 414 jal v0 # had better not trash GP or K1 415 LR a0,0(sp) 416 417 LR sp,mem_heapstart 418 ADD sp,((CFG_HEAP_SIZE*1024)+STACK_SIZE - 8) 419 420 /* 421 * If someone called the API to do a warm start, clear the 422 * spin lock, since the call will never return. 423 */ 424 425#if CFG_MULTI_CPUS 426 SPIN_UNLOCK(cfe_spinlock,t0) 427#endif 428 429 CALLINIT_KSEG0(init_table,R_INIT_CMDRESTART) # should not return 430 431END(cfe_warmstart) 432 433/* ********************************************************************* 434 * CFE_FLUSHCACHE 435 * 436 * Perform certain cache operations 437 * 438 * Input parameters: 439 * a0 - flags (CFE_CACHE_xxx flags, or zero for a default) 440 * a1,a2 - start/end of range for "range invalidate" operations 441 * (not used otherwise) 442 * 443 * Return value: 444 * nothing 445 ********************************************************************* */ 446 447LEAF(_cfe_flushcache) 448#ifndef JTAG_RAM_BOOT 449 sub sp,32 450 SR ra,0(sp) 451 SR a0,8(sp) 452 SR s0,16(sp) 453 SR v1,32(sp) 454 455 456 CALLINIT_KSEG0(init_table,R_INIT_CACHEOPS) 457 458 LR v1,32(sp) 459 LR s0,16(sp) 460 LR a0,8(sp) 461 LR ra,0(sp) 462 add sp,32 463 j ra 464#endif 465END(_cfe_flushcache) 466 467 468/* ********************************************************************* 469 * CFE_LAUNCH 470 * 471 * Start the user program. The program is passed a handle 472 * that must be passed back when calling the firmware. 473 * 474 * Parameters passed to the called program are as follows: 475 * 476 * a0 - CFE handle 477 * a1 - entry vector 478 * a2 - reserved, will be 0 479 * a3 - entrypoint signature. 480 * 481 * Input parameters: 482 * a0 - entry vector 483 * 484 * Return value: 485 * does not return 486 ********************************************************************* */ 487 488LEAF(cfe_launch) 489 490 sub sp,8 491 SR a0,0(sp) 492 493 /* 494 * Mask all interrupts. 495 */ 496 mfc0 v0,C0_SR # Get current interrupt flag 497 li v1,M_SR_IE # master interrupt control 498 not v1 # disable interrupts 499 and v0,v1 # SR now has IE=0 500 mtc0 v0,C0_SR # put back into CP0 501 502#ifndef JTAG_RAM_BOOT 503 /* 504 * Flush the D-Cache, since the program we loaded is "data". 505 * Invalidate the I-Cache, so that addresses in the program 506 * region will miss and need to be filled from the data we 507 * just flushed above. 508 */ 509 li a0,CFE_CACHE_FLUSH_D|CFE_CACHE_INVAL_I 510 CALLINIT_KSEG0(init_table,R_INIT_CACHEOPS) 511#endif 512 /* 513 * Set things up for launching the program. Pass the 514 * handle in A0 - apps need to remember that and pass it 515 * back. 516 */ 517 518 j RunProgram 519 520END(cfe_launch) 521 522 /* 523 * This is a nice place to set a breakpoint. 524 */ 525LEAF(RunProgram) 526 527 LOADREL(a2,segment_table) 528 LR a2,R_SEG_APIENTRY(a2) # A2 = code entry 529 move t0,a0 # 530 move a1,zero # A1 = 0 531 move a0,gp # A0 = handle 532 li a3,CFE_EPTSEAL # A3 = entrypoint signature 533 LR t0,0(sp) # entry point 534 j t0 # go for it. 535END(RunProgram) 536 537 538 539 540/* ********************************************************************* 541 * CFE_LEDS 542 * 543 * Set the on-board LEDs. 544 * 545 * Input parameters: 546 * a0 - LEDs 547 * 548 * Return value: 549 * nothing 550 ********************************************************************* */ 551 552LEAF(cfe_leds) 553 554 j board_setleds # jump to BSP routine 555 556END(cfe_leds) 557 558/* ********************************************************************* 559 * TLB Fill Exeption Handler 560 ********************************************************************* */ 561 562cpu_tlbfill: 563 move k0,ra # Save, we're about to trash 564 LOADREL(k1,init_table) # Load offset of init table 565 LR k1,R_INIT_TLBHANDLER(k1) # Get entry from table 566 move ra,k0 # restore trashed ra 567 j k1 # Dispatch to handler 568 569/* ********************************************************************* 570 * XTLB Fill Exception Handler 571 ********************************************************************* */ 572 573cpu_xtlbfill: 574 j _exc_entry 575 576/* ********************************************************************* 577 * Cache Error Exception Handler 578 ********************************************************************* */ 579 580cpu_cacheerr: 581 j _exc_entry 582 583 584/* ********************************************************************* 585 * General Exception Handler 586 ********************************************************************* */ 587 588cpu_exception: 589 j _exc_entry 590 591 592/* ********************************************************************* 593 * General Interrupt Handler 594 ********************************************************************* */ 595 596cpu_interrupt: 597 j _exc_entry 598 599 600/* ********************************************************************* 601 * EJTAG Debug Exception Handler 602 ********************************************************************* */ 603 604cpu_ejtag: 605 j cpu_reset 606 607/* ********************************************************************* 608 * cpu_apientry(handle,iocb) 609 * 610 * API entry point for external apps. 611 * 612 * Input parameters: 613 * a0 - firmware handle (used to determine the location of 614 * our relocated data) 615 * a1 - pointer to IOCB to execute 616 * 617 * Return value: 618 * v0 - return code, 0 if ok 619 ********************************************************************* */ 620 621#define _regidx(x) ((x)*8) 622 623#define CAE_SRSAVE _regidx(0) 624#define CAE_GPSAVE _regidx(1) 625#define CAE_RASAVE _regidx(2) 626#define CAE_S0SAVE _regidx(3) 627#define CAE_S1SAVE _regidx(4) 628#define CAE_S2SAVE _regidx(5) 629#define CAE_S3SAVE _regidx(6) 630#define CAE_S4SAVE _regidx(7) 631#define CAE_S5SAVE _regidx(8) 632#define CAE_S6SAVE _regidx(9) 633#define CAE_S7SAVE _regidx(10) 634 635#define CAE_STKSIZE _regidx(11) 636 637LEAF(cpu_apientry) 638 639 sub sp,CAE_STKSIZE # Make room for our stuff 640 641 mfc0 v0,C0_SR # Get current interrupt flag 642 SR v0,CAE_SRSAVE(sp) # save on stack 643 li t0,M_SR_IE # master interrupt control 644 not t0 # disable interrupts 645 and v0,t0 # SR now has IE=0 646 mtc0 v0,C0_SR # put back into CP0 647 648 SR gp,CAE_GPSAVE(sp) # save GP 649 SR ra,CAE_RASAVE(sp) # and old RA 650 651 SR s0,CAE_S0SAVE(sp) 652 SR s1,CAE_S1SAVE(sp) 653 SR s2,CAE_S2SAVE(sp) 654 SR s3,CAE_S3SAVE(sp) 655 SR s4,CAE_S4SAVE(sp) 656 SR s5,CAE_S5SAVE(sp) 657 SR s6,CAE_S6SAVE(sp) 658 SR s7,CAE_S7SAVE(sp) 659 660 move gp,a0 # set up new GP 661 move a0,a1 # A0 points at IOCB 662 663 664#if CFG_MULTI_CPUS 665 SPIN_LOCK(cfe_spinlock,t0,t1) 666#endif 667 668 CALLINIT_KSEG0(init_table,R_INIT_DOXREQ) # should not return 669 670#if CFG_MULTI_CPUS 671 SPIN_UNLOCK(cfe_spinlock,t0) 672#endif 673 674 # 675 # Restore the saved registers. 676 # 677 678 LR s7,CAE_S7SAVE(sp) 679 LR s6,CAE_S6SAVE(sp) 680 LR s5,CAE_S5SAVE(sp) 681 LR s4,CAE_S4SAVE(sp) 682 LR s3,CAE_S3SAVE(sp) 683 LR s2,CAE_S2SAVE(sp) 684 LR s1,CAE_S1SAVE(sp) 685 LR s0,CAE_S0SAVE(sp) 686 687 LR ra,CAE_RASAVE(sp) # unwind the stack 688 LR gp,CAE_GPSAVE(sp) 689 690 LR t0,CAE_SRSAVE(sp) # old interrupt mask 691 692 add sp,CAE_STKSIZE # restore old stack pointer 693 694 mtc0 t0,C0_SR # restore interrupts 695 j ra 696 nop 697 698END(cpu_apientry) 699 700 701/* ********************************************************************* 702 * CPU_KSEG0_SWITCH 703 * 704 * Hack the return address so we will come back in KSEG0 705 * 706 * Input parameters: 707 * nothing 708 * 709 * Return value: 710 * nothing 711 ********************************************************************* */ 712 713LEAF(cpu_kseg0_switch) 714 715 and ra,(K0SIZE-1) 716 or ra,K0BASE 717 jr ra 718 719END(cpu_kseg0_switch) 720 721 722 723 724/* ********************************************************************* 725 * _GETSTATUS() 726 * 727 * Read the STATUS register into v0 728 * 729 * Input parameters: 730 * nothing 731 * 732 * Return value: 733 * v0 - Status register 734 ********************************************************************* */ 735 736LEAF(_getstatus) 737 738 mfc0 v0,C0_SR 739 j ra 740END(_getstatus) 741 742 743/* ********************************************************************* 744 * _SETSTATUS() 745 * 746 * Set the STATUS register to the value in a0 747 * 748 * Input parameters: 749 * nothing 750 * 751 * Return value: 752 * v0 - Status register 753 ********************************************************************* */ 754 755LEAF(_setstatus) 756 757 mtc0 a0,C0_SR 758 j ra 759END(_setstatus) 760 761/* ********************************************************************* 762 * _GETCAUSE() 763 * 764 * Read the CAUSE register into v0 765 * 766 * Input parameters: 767 * nothing 768 * 769 * Return value: 770 * v0 - Cause register 771 ********************************************************************* */ 772 773LEAF(_getcause) 774 775 mfc0 v0,C0_CAUSE 776 j ra 777END(_getcause) 778 779 780/* ********************************************************************* 781 * _GETTICKS() 782 * 783 * Read the COUNT register into v0 784 * 785 * Input parameters: 786 * nothing 787 * 788 * Return value: 789 * v0 - count register 790 ********************************************************************* */ 791 792LEAF(_getticks) 793 794 mfc0 v0,C0_COUNT 795 j ra 796END(_getticks) 797 798 799/* ********************************************************************* 800 * _SETALARM(ticks) 801 * 802 * Set the C0_Compare register from a0 803 * 804 * Input parameters: 805 * a0 - compare register 806 * 807 * Return value: 808 * none 809 ********************************************************************* */ 810 811LEAF(_setalarm) 812 813 mtc0 a0,C0_COMPARE 814 j ra 815END(_setalarm) 816 817 818/* ********************************************************************* 819 * _SETCONTEXT() 820 * 821 * Set the CONTEXT register. 822 * 823 * Input parameters: 824 * a0 - context 825 * 826 * Return value: 827 * nothing 828 ********************************************************************* */ 829 830LEAF(_setcontext) 831 832 mtc0 a0,C0_CTEXT 833 j ra 834END(_setcontext) 835 836/* ********************************************************************* 837 * _GETSEGTBL() 838 * 839 * Return the address of the segment table. We use this 840 * to display the startup messages. 841 * 842 * You can't just address the table from C because it lives 843 * in the text segment. 844 * 845 * Input parameters: 846 * nothing 847 * 848 * Return value: 849 * address of table 850 ********************************************************************* */ 851 852 853LEAF(_getsegtbl) 854 move t0,ra 855 LOADREL(v0,segment_table) 856 move ra,t0 857 j ra 858END(_getsegtbl) 859 860 861/* ********************************************************************* 862 * _wbflush() 863 * 864 * Flush the write buffer. This is probably not necessary 865 * on SiByte CPUs, but we have it for completeness. 866 * 867 * Input parameters: 868 * nothing 869 * 870 * Return value: 871 * nothing 872 ********************************************************************* */ 873 874LEAF(_wbflush) 875 876 sync /* drain the buffers */ 877 la t0,__junk /* do an uncached read to force it out */ 878 or t0,K1BASE 879 lw zero,0(t0) 880 j ra 881 882END(_wbflush) 883 884 885/* ********************************************************************* 886 * End 887 ********************************************************************* */ 888 889 890