Home | History | Annotate | Line # | Download | only in common
start.S revision 1.1
      1  1.1  pooka /*	$NetBSD: start.S,v 1.1 2011/01/26 01:18:54 pooka Exp $	*/
      2  1.1  pooka 
      3  1.1  pooka /*-
      4  1.1  pooka  * Copyright (c) 2010 The NetBSD Foundation, Inc.
      5  1.1  pooka  * All rights reserved.
      6  1.1  pooka  *
      7  1.1  pooka  * This code was written by Alessandro Forin and Neil Pittman
      8  1.1  pooka  * at Microsoft Research and contributed to The NetBSD Foundation
      9  1.1  pooka  * by Microsoft Corporation.
     10  1.1  pooka  *
     11  1.1  pooka  * Redistribution and use in source and binary forms, with or without
     12  1.1  pooka  * modification, are permitted provided that the following conditions
     13  1.1  pooka  * are met:
     14  1.1  pooka  * 1. Redistributions of source code must retain the above copyright
     15  1.1  pooka  *    notice, this list of conditions and the following disclaimer.
     16  1.1  pooka  * 2. Redistributions in binary form must reproduce the above copyright
     17  1.1  pooka  *    notice, this list of conditions and the following disclaimer in the
     18  1.1  pooka  *    documentation and/or other materials provided with the distribution.
     19  1.1  pooka  *
     20  1.1  pooka  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     21  1.1  pooka  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  1.1  pooka  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  1.1  pooka  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     24  1.1  pooka  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25  1.1  pooka  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26  1.1  pooka  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27  1.1  pooka  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28  1.1  pooka  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29  1.1  pooka  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30  1.1  pooka  * POSSIBILITY OF SUCH DAMAGE.
     31  1.1  pooka  */
     32  1.1  pooka 
     33  1.1  pooka 	/* Trivial support for printing stuff on the serial line from C pgms.
     34  1.1  pooka      */
     35  1.1  pooka #include <mips/asm.h>
     36  1.1  pooka #include <mips/cpuregs.h>
     37  1.1  pooka #define __ASSEMBLER__ 1
     38  1.1  pooka #include <machine/emipsreg.h>
     39  1.1  pooka 
     40  1.1  pooka /* Offsets in the CXTINFO structure
     41  1.1  pooka  */
     42  1.1  pooka #define TS_AT (1 * 4)
     43  1.1  pooka #define TS_V0 (2 * 4)
     44  1.1  pooka #define TS_V1 (3 * 4)
     45  1.1  pooka #define TS_A0 (4 * 4)
     46  1.1  pooka #define TS_A1 (5 * 4)
     47  1.1  pooka #define TS_A2 (6 * 4)
     48  1.1  pooka #define TS_A3 (7 * 4)
     49  1.1  pooka #define TS_T0 (8 * 4)
     50  1.1  pooka #define TS_T1 (9 * 4)
     51  1.1  pooka #define TS_T2 (10 * 4)
     52  1.1  pooka #define TS_T3 (11 * 4)
     53  1.1  pooka #define TS_T4 (12 * 4)
     54  1.1  pooka #define TS_T5 (13 * 4)
     55  1.1  pooka #define TS_T6 (14 * 4)
     56  1.1  pooka #define TS_T7 (15 * 4)
     57  1.1  pooka #define TS_S0 (16 * 4)
     58  1.1  pooka #define TS_S1 (17 * 4)
     59  1.1  pooka #define TS_S2 (18 * 4)
     60  1.1  pooka #define TS_S3 (19 * 4)
     61  1.1  pooka #define TS_S4 (20 * 4)
     62  1.1  pooka #define TS_S5 (21 * 4)
     63  1.1  pooka #define TS_S6 (22 * 4)
     64  1.1  pooka #define TS_S7 (23 * 4)
     65  1.1  pooka #define TS_T8 (24 * 4)
     66  1.1  pooka #define TS_T9 (25 * 4)
     67  1.1  pooka #define TS_K0 (26 * 4)
     68  1.1  pooka #define TS_K1 (27 * 4)
     69  1.1  pooka #define TS_GP (28 * 4)
     70  1.1  pooka #define TS_SP (29 * 4)
     71  1.1  pooka #define TS_FP (30 * 4)
     72  1.1  pooka #define fp s8
     73  1.1  pooka #define TS_RA (31 * 4)
     74  1.1  pooka 
     75  1.1  pooka #define TS_PC (32 * 4)
     76  1.1  pooka #define TS_SR (33 * 4)
     77  1.1  pooka #define TS_HI (34 * 4)
     78  1.1  pooka #define TS_LO (35 * 4)
     79  1.1  pooka #define TS_EC (36 * 4)
     80  1.1  pooka #define SIZEOF_CXTINFO (37*4)
     81  1.1  pooka 
     82  1.1  pooka /* PROM_MODE means the user plans to keep this code around while running an OS.
     83  1.1  pooka  * So we act kind of like PROM code (BIOS?), but we live in RAM.
     84  1.1  pooka  * So we need to safeguard ourselves against corruptions, some unavoidable.
     85  1.1  pooka  * Like the overriding of the exception vectors, rigth where our "start" code is.
     86  1.1  pooka  */
     87  1.1  pooka 
     88  1.1  pooka         IMPORT(main,4)
     89  1.1  pooka         IMPORT(_end,4)
     90  1.1  pooka 
     91  1.1  pooka         .set noreorder
     92  1.1  pooka 
     93  1.1  pooka EXPORT(start)
     94  1.1  pooka     bgezal zero,_C_LABEL(real_start)
     95  1.1  pooka     nop
     96  1.1  pooka 
     97  1.1  pooka 
     98  1.1  pooka /* Does not handle the exception, really.
     99  1.1  pooka  * But to test interrupts should be enough
    100  1.1  pooka  */
    101  1.1  pooka      .org 0x00000080
    102  1.1  pooka VECTOR(ExceptionHandler,0)
    103  1.1  pooka 	.frame sp,SIZEOF_CXTINFO,$31
    104  1.1  pooka     la     k1, UserInterruptHandler
    105  1.1  pooka     lw     k1,0(k1)
    106  1.1  pooka     bne    k1,zero,Dispatch
    107  1.1  pooka     mfc0   k0, MIPS_COP_0_EXC_PC
    108  1.1  pooka     j      k0
    109  1.1  pooka     nop /* do not! pop status */
    110  1.1  pooka 
    111  1.1  pooka EXPORT(UserInterruptHandler)
    112  1.1  pooka     .word 0
    113  1.1  pooka 
    114  1.1  pooka EXPORT(Dispatch)
    115  1.1  pooka 	/* Save state on stack */
    116  1.1  pooka 	addiu   sp, sp, -SIZEOF_CXTINFO
    117  1.1  pooka 	/* save registers */
    118  1.1  pooka     .set noat
    119  1.1  pooka 	sw      AT, TS_AT(sp)
    120  1.1  pooka     .set at
    121  1.1  pooka 	sw      v0, TS_V0(sp)
    122  1.1  pooka 	sw      v1, TS_V1(sp)
    123  1.1  pooka 	sw      a0, TS_A0(sp)
    124  1.1  pooka 	sw      a1, TS_A1(sp)
    125  1.1  pooka 	sw      a2, TS_A2(sp)
    126  1.1  pooka 	sw      a3, TS_A3(sp)
    127  1.1  pooka 	sw      t0, TS_T0(sp)
    128  1.1  pooka 	sw      t1, TS_T1(sp)
    129  1.1  pooka 	sw      t2, TS_T2(sp)
    130  1.1  pooka 	sw      t3, TS_T3(sp)
    131  1.1  pooka 	sw      t4, TS_T4(sp)
    132  1.1  pooka 	sw      t5, TS_T5(sp)
    133  1.1  pooka 	sw      t6, TS_T6(sp)
    134  1.1  pooka 	sw      t7, TS_T7(sp)
    135  1.1  pooka 	sw      s0, TS_S0(sp)
    136  1.1  pooka 	sw      s1, TS_S1(sp)
    137  1.1  pooka 	sw      s2, TS_S2(sp)
    138  1.1  pooka 	sw      s3, TS_S3(sp)
    139  1.1  pooka 	sw      s4, TS_S4(sp)
    140  1.1  pooka 	sw      s5, TS_S5(sp)
    141  1.1  pooka 	sw      s6, TS_S6(sp)
    142  1.1  pooka 	sw      s7, TS_S7(sp)
    143  1.1  pooka 	sw      t8, TS_T8(sp)
    144  1.1  pooka 	sw      t9, TS_T9(sp)
    145  1.1  pooka 	sw      k0, TS_K0(sp)
    146  1.1  pooka 	sw      k1, TS_K1(sp)
    147  1.1  pooka 	sw      gp, TS_GP(sp)
    148  1.1  pooka 	/* sp: later */
    149  1.1  pooka 	sw      fp, TS_FP(sp)
    150  1.1  pooka 	sw      ra, TS_RA(sp)
    151  1.1  pooka 
    152  1.1  pooka     mfc0    a0, MIPS_COP_0_STATUS
    153  1.1  pooka     mflo    t0
    154  1.1  pooka     mfhi    t1
    155  1.1  pooka 	sw      a0, TS_SR(sp)
    156  1.1  pooka 	sw      t0, TS_LO(sp)
    157  1.1  pooka 	sw      t1, TS_HI(sp)
    158  1.1  pooka 	sw      k0, TS_PC(sp)
    159  1.1  pooka 
    160  1.1  pooka 	/* Save original stack */
    161  1.1  pooka     move    a0,sp
    162  1.1  pooka 	addiu   t0, sp, SIZEOF_CXTINFO
    163  1.1  pooka     jalr    k1
    164  1.1  pooka 	sw      t0, TS_SP(sp)
    165  1.1  pooka 
    166  1.1  pooka     /* Returned value is new PCXINFO */
    167  1.1  pooka     move    a0,v0
    168  1.1  pooka 
    169  1.1  pooka 	/* First load most registers */
    170  1.1  pooka     .set noat
    171  1.1  pooka 	lw       AT, TS_AT(a0)
    172  1.1  pooka 	lw       v0, TS_V0(a0)
    173  1.1  pooka 	lw       v1, TS_V1(a0)
    174  1.1  pooka 	/* a0 later */
    175  1.1  pooka 	lw       a1, TS_A1(a0)
    176  1.1  pooka 	lw       a2, TS_A2(a0)
    177  1.1  pooka 	lw       a3, TS_A3(a0)
    178  1.1  pooka 	lw       t0, TS_T0(a0)
    179  1.1  pooka 	lw       t1, TS_T1(a0)
    180  1.1  pooka 	lw       t2, TS_T2(a0)
    181  1.1  pooka 	lw       t3, TS_T3(a0)
    182  1.1  pooka 	lw       t4, TS_T4(a0)
    183  1.1  pooka 	lw       t5, TS_T5(a0)
    184  1.1  pooka 	lw       t6, TS_T6(a0)
    185  1.1  pooka 	lw       t7, TS_T7(a0)
    186  1.1  pooka 	lw       s0, TS_S0(a0)
    187  1.1  pooka 	lw       s1, TS_S1(a0)
    188  1.1  pooka 	lw       s2, TS_S2(a0)
    189  1.1  pooka 	lw       s3, TS_S3(a0)
    190  1.1  pooka 	lw       s4, TS_S4(a0)
    191  1.1  pooka 	lw       s5, TS_S5(a0)
    192  1.1  pooka 	lw       s6, TS_S6(a0)
    193  1.1  pooka 	lw       s7, TS_S7(a0)
    194  1.1  pooka 	lw       t8, TS_T8(a0)
    195  1.1  pooka 	lw       t9, TS_T9(a0)
    196  1.1  pooka     /* k0,k1 not restored */
    197  1.1  pooka 	lw       gp, TS_GP(a0)
    198  1.1  pooka 	/* sp later */
    199  1.1  pooka 	lw       fp, TS_FP(a0)
    200  1.1  pooka 	lw       ra, TS_RA(a0)
    201  1.1  pooka 
    202  1.1  pooka     lw       k1, TS_HI(a0)
    203  1.1  pooka     lw       k0, TS_LO(a0)
    204  1.1  pooka     mthi     k1
    205  1.1  pooka     mtlo     k0
    206  1.1  pooka     lw       k1, TS_SR(a0)
    207  1.1  pooka     mtc0     k1, MIPS_COP_0_STATUS
    208  1.1  pooka      /* NB: After this instruction we cannot take any interrupts or traps
    209  1.1  pooka       */
    210  1.1  pooka 	lw	sp, TS_SP(a0)
    211  1.1  pooka 
    212  1.1  pooka 	/* Put pc into k0 */
    213  1.1  pooka 	lw	k0, TS_PC(a0)
    214  1.1  pooka 	lw	a0, TS_A0(a0)
    215  1.1  pooka 	j	k0
    216  1.1  pooka     rfe
    217  1.1  pooka     .set at
    218  1.1  pooka 
    219  1.1  pooka VECTOR_END(ExceptionHandler)
    220  1.1  pooka 
    221  1.1  pooka      .org 0x00000200
    222  1.1  pooka EXPORT(real_start)
    223  1.1  pooka 	.ent _C_LABEL(real_start)
    224  1.1  pooka 
    225  1.1  pooka #ifdef SECONDARY_BOOTBLOCK
    226  1.1  pooka     /*
    227  1.1  pooka      * If this is the program that goes into FLASH we must copy ourselves down to RAM.
    228  1.1  pooka      * FLASH default on the MLx is at 0xf0000000, DRAM at 0.
    229  1.1  pooka      */
    230  1.1  pooka     addi    a0,ra,-8         /* Compensate for the first two instructions */
    231  1.1  pooka 
    232  1.1  pooka     /* Get the address(relative) of TextStart
    233  1.1  pooka      */
    234  1.1  pooka     bgezal  zero, _C_LABEL(MipsStart2) /* Always jumps */
    235  1.1  pooka     nop
    236  1.1  pooka 
    237  1.1  pooka     /* All of the static data, since we are at it.
    238  1.1  pooka      */
    239  1.1  pooka TextStart:                                /* + 0 */
    240  1.1  pooka     /* Text start at final link address */
    241  1.1  pooka     .int    start
    242  1.1  pooka 
    243  1.1  pooka DataEnd:                                  /* + 4 */
    244  1.1  pooka     /* Data end == bss start */
    245  1.1  pooka     .int    _edata
    246  1.1  pooka 
    247  1.1  pooka BssEnd:                                   /* + 8 */
    248  1.1  pooka     /* Bss end */
    249  1.1  pooka     .int    _end
    250  1.1  pooka 
    251  1.1  pooka RelocToRAM:                               /* *+12 */
    252  1.1  pooka     .int    InRAM
    253  1.1  pooka 
    254  1.1  pooka MipsStart2:
    255  1.1  pooka 
    256  1.1  pooka     /* Source = a0, Dst = t2 */
    257  1.1  pooka     lw      t2, 0(ra)     /* _C_LABEL(TextStart) */
    258  1.1  pooka 
    259  1.1  pooka     /* EndPtr = t3 */
    260  1.1  pooka      /* in bdelay slot */
    261  1.1  pooka 
    262  1.1  pooka     /* If a0 != t2 then we are running in Flash but should run in RAM
    263  1.1  pooka      * In that case copy .text. Otherwise skip to .bss.
    264  1.1  pooka      */
    265  1.1  pooka     beq     a0,t2,ZroLoop-4
    266  1.1  pooka     lw      t3, 4(ra)    /* _C_LABEL(DataEnd)   */
    267  1.1  pooka 
    268  1.1  pooka CpyLoop:
    269  1.1  pooka     /* loop copying 2 words at a time */
    270  1.1  pooka     lw      t4,0(a0)
    271  1.1  pooka     lw      t5,4(a0)
    272  1.1  pooka     addiu   a0,a0,8
    273  1.1  pooka     sw      t4,0(t2)
    274  1.1  pooka     addiu   t2,t2,8
    275  1.1  pooka     sltu    t1,t2,t3
    276  1.1  pooka     bne     t1,zero,CpyLoop
    277  1.1  pooka     sw      t5,-4(t2)
    278  1.1  pooka 
    279  1.1  pooka     /* zero the bss
    280  1.1  pooka      */
    281  1.1  pooka     lw      t4, 8(ra)   /* _C_LABEL(BssEnd)  */
    282  1.1  pooka ZroLoop:
    283  1.1  pooka     sltu    t1,t3,t4
    284  1.1  pooka     sw      zero,0(t3)
    285  1.1  pooka     bne     t1,zero,ZroLoop
    286  1.1  pooka     addiu   t3,t3,4
    287  1.1  pooka 
    288  1.1  pooka     /* Jump to RAM copy (below)
    289  1.1  pooka      */
    290  1.1  pooka     lw      t1, 12(ra)   /* _C_LABEL(RelocToRAM) */
    291  1.1  pooka     jr      t1
    292  1.1  pooka     nop
    293  1.1  pooka 
    294  1.1  pooka     /*
    295  1.1  pooka      * Execute from here after copying out of FLASH into RAM
    296  1.1  pooka      */
    297  1.1  pooka InRAM:
    298  1.1  pooka 
    299  1.1  pooka #endif /*  SECONDARY_BOOTBLOCK */
    300  1.1  pooka 
    301  1.1  pooka     /* Get a stack
    302  1.1  pooka      */
    303  1.1  pooka #ifdef __GP_SUPPORT__
    304  1.1  pooka     la      gp, _C_LABEL (_gp)
    305  1.1  pooka #endif
    306  1.1  pooka     la    sp,_end
    307  1.1  pooka 	addiu sp,sp,(8*1024)          /* BUGBUG arbitrary */
    308  1.1  pooka 
    309  1.1  pooka     /* Jump to main
    310  1.1  pooka      */
    311  1.1  pooka     jal   main
    312  1.1  pooka     add   a0,sp,zero
    313  1.1  pooka 
    314  1.1  pooka     /* Load failed, reset the processor and jump back to the origins.
    315  1.1  pooka      */
    316  1.1  pooka EXPORT(_rtt)    /* ahem */
    317  1.1  pooka     li     t0,0x1260ff80  /* NB: On new builds this is a SYS-RESET as well */
    318  1.1  pooka     mtc0   t0,MIPS_COP_0_STATUS
    319  1.1  pooka 
    320  1.1  pooka     lui    t0,(BRAM_DEFAULT_ADDRESS>>16) /* nb: knows about 16bit chop */
    321  1.1  pooka 	jr     t0
    322  1.1  pooka     nop
    323  1.1  pooka 
    324  1.1  pooka EXPORT(Stop)
    325  1.1  pooka 	b     Stop
    326  1.1  pooka     nop
    327  1.1  pooka 
    328  1.1  pooka END(real_start)
    329  1.1  pooka 
    330  1.1  pooka         .set noreorder
    331  1.1  pooka         .set noat
    332  1.1  pooka         .set nomacro
    333  1.1  pooka 
    334  1.1  pooka /* void Delay(UINT32 count)
    335  1.1  pooka  */
    336  1.1  pooka LEAF(Delay)
    337  1.1  pooka     bne    a0,zero,_C_LABEL(Delay)
    338  1.1  pooka     subu   a0,1
    339  1.1  pooka     j      ra
    340  1.1  pooka     nop
    341  1.1  pooka END(Delay)
    342  1.1  pooka 
    343  1.1  pooka /* UINT32 GetPsr(void)
    344  1.1  pooka  * Returns the PSR (coprocessor 0 status)
    345  1.1  pooka  */
    346  1.1  pooka LEAF(GetPsr)
    347  1.1  pooka     mfc0   v0, MIPS_COP_0_STATUS
    348  1.1  pooka     j      ra
    349  1.1  pooka     nop
    350  1.1  pooka END(GetPsr)
    351  1.1  pooka 
    352  1.1  pooka /* void SetPsr(UINT32 Psr)
    353  1.1  pooka  * Sets the PSR (coprocessor 0 status)
    354  1.1  pooka  */
    355  1.1  pooka LEAF(SetPsr)
    356  1.1  pooka     mtc0   a0,MIPS_COP_0_STATUS
    357  1.1  pooka     j      ra
    358  1.1  pooka     nop
    359  1.1  pooka END(SetPsr)
    360  1.1  pooka 
    361  1.1  pooka /* UINT32 GetCause(void)
    362  1.1  pooka  * Returns the Cause register (coprocessor 0)
    363  1.1  pooka  */
    364  1.1  pooka LEAF(GetCause)
    365  1.1  pooka     mfc0   v0,MIPS_COP_0_CAUSE
    366  1.1  pooka     j      ra
    367  1.1  pooka     nop
    368  1.1  pooka END(GetCause)
    369  1.1  pooka 
    370  1.1  pooka /* UINT32 GetEpc(void)
    371  1.1  pooka  * Returns the Epc register (coprocessor 0)
    372  1.1  pooka  */
    373  1.1  pooka LEAF(GetEpc)
    374  1.1  pooka     mfc0   v0,MIPS_COP_0_EXC_PC
    375  1.1  pooka     j      ra
    376  1.1  pooka     nop
    377  1.1  pooka END(GetEpc)
    378  1.1  pooka 
    379  1.1  pooka 
    380  1.1  pooka /* int PutWord(UINT32 Word);
    381  1.1  pooka  * Returns: 0 if ok, -1 otherwise
    382  1.1  pooka  */
    383  1.1  pooka NESTED(PutWord,12,$31)
    384  1.1  pooka     subu   sp,sp,12
    385  1.1  pooka     sw     s0,8(sp)
    386  1.1  pooka     sw     s1,4(sp)
    387  1.1  pooka     sw     ra,0(sp)
    388  1.1  pooka 
    389  1.1  pooka     or     s1,a0,zero
    390  1.1  pooka     /* Spit all nibbles
    391  1.1  pooka      */
    392  1.1  pooka     li     s0,8
    393  1.1  pooka PutWordLoop:
    394  1.1  pooka     srl    a0,s1,32-4
    395  1.1  pooka     li     t0,10
    396  1.1  pooka     sltu   t1,a0,t0
    397  1.1  pooka     bnez   t1,$Digit
    398  1.1  pooka     li     a1,'0'
    399  1.1  pooka     subu   a0,a0,t0
    400  1.1  pooka     li     a1,'a'
    401  1.1  pooka $Digit:
    402  1.1  pooka     sll    s1,s1,4
    403  1.1  pooka     jal    PutChar
    404  1.1  pooka     add    a0,a0,a1
    405  1.1  pooka 
    406  1.1  pooka     subu   s0,s0,1
    407  1.1  pooka     bne    v0,zero,PutWordDone /* printed ok? */
    408  1.1  pooka     li     v0,-1
    409  1.1  pooka 
    410  1.1  pooka     /* done yet? */
    411  1.1  pooka     bne    s0,zero,PutWordLoop
    412  1.1  pooka     nop
    413  1.1  pooka 
    414  1.1  pooka     /* done
    415  1.1  pooka      */
    416  1.1  pooka     li     v0,0
    417  1.1  pooka PutWordDone:
    418  1.1  pooka     lw     ra,0(sp)
    419  1.1  pooka     lw     s1,4(sp)
    420  1.1  pooka     lw     s0,8(sp)
    421  1.1  pooka     jr     ra
    422  1.1  pooka     addiu  sp,sp,12
    423  1.1  pooka 
    424  1.1  pooka END(PutWord)
    425  1.1  pooka 
    426  1.1  pooka /* int Puts(char *String);
    427  1.1  pooka  * Returns: 0 if ok, -1 otherwise
    428  1.1  pooka  */
    429  1.1  pooka NESTED(Puts,8,$31)
    430  1.1  pooka     subu   sp,sp,8
    431  1.1  pooka     sw     s0,4(sp)
    432  1.1  pooka     sw     ra,0(sp)
    433  1.1  pooka 
    434  1.1  pooka     or     s0,a0,zero
    435  1.1  pooka     /* Spit all chars until zero
    436  1.1  pooka      */
    437  1.1  pooka PutsLoop:
    438  1.1  pooka     lbu    a0,0(s0)
    439  1.1  pooka     addiu  s0,s0,1
    440  1.1  pooka     beq    a0,zero,PutsDoneOk
    441  1.1  pooka     nop
    442  1.1  pooka     jal    PutChar
    443  1.1  pooka     nop
    444  1.1  pooka     beq    v0,zero,PutsLoop
    445  1.1  pooka     nop
    446  1.1  pooka 
    447  1.1  pooka     /* Timed out
    448  1.1  pooka      */
    449  1.1  pooka     b      PutsDone
    450  1.1  pooka     li     v0,-1
    451  1.1  pooka 
    452  1.1  pooka     /* done
    453  1.1  pooka      */
    454  1.1  pooka PutsDoneOk:
    455  1.1  pooka     li     v0,0
    456  1.1  pooka PutsDone:
    457  1.1  pooka     lw     ra,0(sp)
    458  1.1  pooka     lw     s0,4(sp)
    459  1.1  pooka     jr     ra
    460  1.1  pooka     addiu  sp,sp,8
    461  1.1  pooka 
    462  1.1  pooka END(Puts)
    463  1.1  pooka 
    464  1.1  pooka 
    465  1.1  pooka /* int GetChar(void);
    466  1.1  pooka  * Returns: a non-negative value if ok, -1 otherwise
    467  1.1  pooka  */
    468  1.1  pooka LEAF(GetChar)
    469  1.1  pooka     lui    t0,(USART_DEFAULT_ADDRESS>>16) /* nb: knows about 16bit chop */
    470  1.1  pooka     lui    t1,1000          /* n*65k spins max */
    471  1.1  pooka RxNotReady:
    472  1.1  pooka     lw     t4,USARTST(t0)       /* ChannelStatus */
    473  1.1  pooka     andi   t4,t4,USI_RXRDY
    474  1.1  pooka     bgtz   t4,$GotByte
    475  1.1  pooka     subu   t1,t1,1
    476  1.1  pooka     /* still ok to spin? */
    477  1.1  pooka     bgtz   t1,RxNotReady
    478  1.1  pooka     nop
    479  1.1  pooka     /* Timed out
    480  1.1  pooka      */
    481  1.1  pooka     jr     ra
    482  1.1  pooka     li     v0,-1
    483  1.1  pooka 
    484  1.1  pooka     /* Gottabyte
    485  1.1  pooka      */
    486  1.1  pooka $GotByte:
    487  1.1  pooka     lw     v0,USARTRX(t0)        /* RxData */
    488  1.1  pooka     jr     ra
    489  1.1  pooka     andi   v0,0xff
    490  1.1  pooka END(GetChar)
    491  1.1  pooka 
    492  1.1  pooka /* int PutChar(UINT8 v);
    493  1.1  pooka  * Returns: 0 if ok, -1 otherwise
    494  1.1  pooka  */
    495  1.1  pooka LEAF(PutChar)
    496  1.1  pooka     lui    t0,(USART_DEFAULT_ADDRESS>>16) /* nb: knows about 16bit chop */
    497  1.1  pooka     lui    t1,1000          /* n*65k spins max */
    498  1.1  pooka     li     v0,0
    499  1.1  pooka TxNotReady:
    500  1.1  pooka     lw     t4,USARTST(t0)       /* ChannelStatus */
    501  1.1  pooka     andi   t4,t4,USI_TXRDY
    502  1.1  pooka     bgtz   t4,TxReady
    503  1.1  pooka     subu   t1,t1,1
    504  1.1  pooka     /* still ok to spin? */
    505  1.1  pooka     bgtz   t1,TxNotReady
    506  1.1  pooka     nop
    507  1.1  pooka     /* Timed out
    508  1.1  pooka      */
    509  1.1  pooka     jr     ra
    510  1.1  pooka     li     v0,-1
    511  1.1  pooka 
    512  1.1  pooka     /* Send it
    513  1.1  pooka      */
    514  1.1  pooka TxReady:
    515  1.1  pooka     jr     ra
    516  1.1  pooka     sw     a0,USARTTX(t0)
    517  1.1  pooka 
    518  1.1  pooka END(PutChar)
    519  1.1  pooka 
    520  1.1  pooka /* Second arg is a function to call with the first arg:
    521  1.1  pooka  * void switch_stack_and_call(void *arg, void (*function)(void *));
    522  1.1  pooka  */
    523  1.1  pooka LEAF(switch_stack_and_call)
    524  1.1  pooka     /* Get a stack and jump. It would be a very bad idea to return but..
    525  1.1  pooka      */
    526  1.1  pooka #ifdef __GP_SUPPORT__
    527  1.1  pooka     la      gp, _C_LABEL (_gp)
    528  1.1  pooka #endif
    529  1.1  pooka     la    sp,_end
    530  1.1  pooka     jr    a1
    531  1.1  pooka 	addiu sp,sp,(2*1024)          /* BUGBUG arbitrary */
    532  1.1  pooka 
    533  1.1  pooka END(switch_stack_and_call)
    534  1.1  pooka 
    535