Home | History | Annotate | Line # | Download | only in common
      1  1.4  andvar /*	$NetBSD: start.S,v 1.4 2021/12/03 10:49:25 andvar 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.4  andvar  * Like the overriding of the exception vectors, right 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.2   pooka NESTED_NOPROFILE(ExceptionHandler,SIZEOF_CXTINFO,$31)
    103  1.1   pooka     la     k1, UserInterruptHandler
    104  1.1   pooka     lw     k1,0(k1)
    105  1.1   pooka     bne    k1,zero,Dispatch
    106  1.1   pooka     mfc0   k0, MIPS_COP_0_EXC_PC
    107  1.1   pooka     j      k0
    108  1.1   pooka     nop /* do not! pop status */
    109  1.1   pooka 
    110  1.1   pooka EXPORT(UserInterruptHandler)
    111  1.1   pooka     .word 0
    112  1.1   pooka 
    113  1.1   pooka EXPORT(Dispatch)
    114  1.1   pooka 	/* Save state on stack */
    115  1.1   pooka 	addiu   sp, sp, -SIZEOF_CXTINFO
    116  1.1   pooka 	/* save registers */
    117  1.1   pooka     .set noat
    118  1.1   pooka 	sw      AT, TS_AT(sp)
    119  1.1   pooka     .set at
    120  1.1   pooka 	sw      v0, TS_V0(sp)
    121  1.1   pooka 	sw      v1, TS_V1(sp)
    122  1.1   pooka 	sw      a0, TS_A0(sp)
    123  1.1   pooka 	sw      a1, TS_A1(sp)
    124  1.1   pooka 	sw      a2, TS_A2(sp)
    125  1.1   pooka 	sw      a3, TS_A3(sp)
    126  1.1   pooka 	sw      t0, TS_T0(sp)
    127  1.1   pooka 	sw      t1, TS_T1(sp)
    128  1.1   pooka 	sw      t2, TS_T2(sp)
    129  1.1   pooka 	sw      t3, TS_T3(sp)
    130  1.1   pooka 	sw      t4, TS_T4(sp)
    131  1.1   pooka 	sw      t5, TS_T5(sp)
    132  1.1   pooka 	sw      t6, TS_T6(sp)
    133  1.1   pooka 	sw      t7, TS_T7(sp)
    134  1.1   pooka 	sw      s0, TS_S0(sp)
    135  1.1   pooka 	sw      s1, TS_S1(sp)
    136  1.1   pooka 	sw      s2, TS_S2(sp)
    137  1.1   pooka 	sw      s3, TS_S3(sp)
    138  1.1   pooka 	sw      s4, TS_S4(sp)
    139  1.1   pooka 	sw      s5, TS_S5(sp)
    140  1.1   pooka 	sw      s6, TS_S6(sp)
    141  1.1   pooka 	sw      s7, TS_S7(sp)
    142  1.1   pooka 	sw      t8, TS_T8(sp)
    143  1.1   pooka 	sw      t9, TS_T9(sp)
    144  1.1   pooka 	sw      k0, TS_K0(sp)
    145  1.1   pooka 	sw      k1, TS_K1(sp)
    146  1.1   pooka 	sw      gp, TS_GP(sp)
    147  1.1   pooka 	/* sp: later */
    148  1.1   pooka 	sw      fp, TS_FP(sp)
    149  1.1   pooka 	sw      ra, TS_RA(sp)
    150  1.1   pooka 
    151  1.1   pooka     mfc0    a0, MIPS_COP_0_STATUS
    152  1.1   pooka     mflo    t0
    153  1.1   pooka     mfhi    t1
    154  1.1   pooka 	sw      a0, TS_SR(sp)
    155  1.1   pooka 	sw      t0, TS_LO(sp)
    156  1.1   pooka 	sw      t1, TS_HI(sp)
    157  1.1   pooka 	sw      k0, TS_PC(sp)
    158  1.1   pooka 
    159  1.1   pooka 	/* Save original stack */
    160  1.1   pooka     move    a0,sp
    161  1.1   pooka 	addiu   t0, sp, SIZEOF_CXTINFO
    162  1.1   pooka     jalr    k1
    163  1.1   pooka 	sw      t0, TS_SP(sp)
    164  1.1   pooka 
    165  1.1   pooka     /* Returned value is new PCXINFO */
    166  1.1   pooka     move    a0,v0
    167  1.1   pooka 
    168  1.1   pooka 	/* First load most registers */
    169  1.1   pooka     .set noat
    170  1.1   pooka 	lw       AT, TS_AT(a0)
    171  1.1   pooka 	lw       v0, TS_V0(a0)
    172  1.1   pooka 	lw       v1, TS_V1(a0)
    173  1.1   pooka 	/* a0 later */
    174  1.1   pooka 	lw       a1, TS_A1(a0)
    175  1.1   pooka 	lw       a2, TS_A2(a0)
    176  1.1   pooka 	lw       a3, TS_A3(a0)
    177  1.1   pooka 	lw       t0, TS_T0(a0)
    178  1.1   pooka 	lw       t1, TS_T1(a0)
    179  1.1   pooka 	lw       t2, TS_T2(a0)
    180  1.1   pooka 	lw       t3, TS_T3(a0)
    181  1.1   pooka 	lw       t4, TS_T4(a0)
    182  1.1   pooka 	lw       t5, TS_T5(a0)
    183  1.1   pooka 	lw       t6, TS_T6(a0)
    184  1.1   pooka 	lw       t7, TS_T7(a0)
    185  1.1   pooka 	lw       s0, TS_S0(a0)
    186  1.1   pooka 	lw       s1, TS_S1(a0)
    187  1.1   pooka 	lw       s2, TS_S2(a0)
    188  1.1   pooka 	lw       s3, TS_S3(a0)
    189  1.1   pooka 	lw       s4, TS_S4(a0)
    190  1.1   pooka 	lw       s5, TS_S5(a0)
    191  1.1   pooka 	lw       s6, TS_S6(a0)
    192  1.1   pooka 	lw       s7, TS_S7(a0)
    193  1.1   pooka 	lw       t8, TS_T8(a0)
    194  1.1   pooka 	lw       t9, TS_T9(a0)
    195  1.1   pooka     /* k0,k1 not restored */
    196  1.1   pooka 	lw       gp, TS_GP(a0)
    197  1.1   pooka 	/* sp later */
    198  1.1   pooka 	lw       fp, TS_FP(a0)
    199  1.1   pooka 	lw       ra, TS_RA(a0)
    200  1.1   pooka 
    201  1.1   pooka     lw       k1, TS_HI(a0)
    202  1.1   pooka     lw       k0, TS_LO(a0)
    203  1.1   pooka     mthi     k1
    204  1.1   pooka     mtlo     k0
    205  1.1   pooka     lw       k1, TS_SR(a0)
    206  1.1   pooka     mtc0     k1, MIPS_COP_0_STATUS
    207  1.1   pooka      /* NB: After this instruction we cannot take any interrupts or traps
    208  1.1   pooka       */
    209  1.1   pooka 	lw	sp, TS_SP(a0)
    210  1.1   pooka 
    211  1.1   pooka 	/* Put pc into k0 */
    212  1.1   pooka 	lw	k0, TS_PC(a0)
    213  1.1   pooka 	lw	a0, TS_A0(a0)
    214  1.1   pooka 	j	k0
    215  1.1   pooka     rfe
    216  1.1   pooka     .set at
    217  1.1   pooka 
    218  1.2   pooka END(ExceptionHandler)
    219  1.1   pooka 
    220  1.1   pooka      .org 0x00000200
    221  1.1   pooka EXPORT(real_start)
    222  1.1   pooka 	.ent _C_LABEL(real_start)
    223  1.1   pooka 
    224  1.1   pooka #ifdef SECONDARY_BOOTBLOCK
    225  1.1   pooka     /*
    226  1.1   pooka      * If this is the program that goes into FLASH we must copy ourselves down to RAM.
    227  1.1   pooka      * FLASH default on the MLx is at 0xf0000000, DRAM at 0.
    228  1.1   pooka      */
    229  1.1   pooka     addi    a0,ra,-8         /* Compensate for the first two instructions */
    230  1.1   pooka 
    231  1.1   pooka     /* Get the address(relative) of TextStart
    232  1.1   pooka      */
    233  1.1   pooka     bgezal  zero, _C_LABEL(MipsStart2) /* Always jumps */
    234  1.1   pooka     nop
    235  1.1   pooka 
    236  1.1   pooka     /* All of the static data, since we are at it.
    237  1.1   pooka      */
    238  1.1   pooka TextStart:                                /* + 0 */
    239  1.1   pooka     /* Text start at final link address */
    240  1.1   pooka     .int    start
    241  1.1   pooka 
    242  1.1   pooka DataEnd:                                  /* + 4 */
    243  1.1   pooka     /* Data end == bss start */
    244  1.1   pooka     .int    _edata
    245  1.1   pooka 
    246  1.1   pooka BssEnd:                                   /* + 8 */
    247  1.1   pooka     /* Bss end */
    248  1.1   pooka     .int    _end
    249  1.1   pooka 
    250  1.1   pooka RelocToRAM:                               /* *+12 */
    251  1.1   pooka     .int    InRAM
    252  1.1   pooka 
    253  1.1   pooka MipsStart2:
    254  1.1   pooka 
    255  1.1   pooka     /* Source = a0, Dst = t2 */
    256  1.1   pooka     lw      t2, 0(ra)     /* _C_LABEL(TextStart) */
    257  1.1   pooka 
    258  1.1   pooka     /* EndPtr = t3 */
    259  1.1   pooka      /* in bdelay slot */
    260  1.1   pooka 
    261  1.1   pooka     /* If a0 != t2 then we are running in Flash but should run in RAM
    262  1.1   pooka      * In that case copy .text. Otherwise skip to .bss.
    263  1.1   pooka      */
    264  1.1   pooka     beq     a0,t2,ZroLoop-4
    265  1.1   pooka     lw      t3, 4(ra)    /* _C_LABEL(DataEnd)   */
    266  1.1   pooka 
    267  1.1   pooka CpyLoop:
    268  1.1   pooka     /* loop copying 2 words at a time */
    269  1.1   pooka     lw      t4,0(a0)
    270  1.1   pooka     lw      t5,4(a0)
    271  1.1   pooka     addiu   a0,a0,8
    272  1.1   pooka     sw      t4,0(t2)
    273  1.1   pooka     addiu   t2,t2,8
    274  1.1   pooka     sltu    t1,t2,t3
    275  1.1   pooka     bne     t1,zero,CpyLoop
    276  1.1   pooka     sw      t5,-4(t2)
    277  1.1   pooka 
    278  1.1   pooka     /* zero the bss
    279  1.1   pooka      */
    280  1.1   pooka     lw      t4, 8(ra)   /* _C_LABEL(BssEnd)  */
    281  1.1   pooka ZroLoop:
    282  1.1   pooka     sltu    t1,t3,t4
    283  1.1   pooka     sw      zero,0(t3)
    284  1.1   pooka     bne     t1,zero,ZroLoop
    285  1.1   pooka     addiu   t3,t3,4
    286  1.1   pooka 
    287  1.1   pooka     /* Jump to RAM copy (below)
    288  1.1   pooka      */
    289  1.1   pooka     lw      t1, 12(ra)   /* _C_LABEL(RelocToRAM) */
    290  1.1   pooka     jr      t1
    291  1.1   pooka     nop
    292  1.1   pooka 
    293  1.1   pooka     /*
    294  1.1   pooka      * Execute from here after copying out of FLASH into RAM
    295  1.1   pooka      */
    296  1.1   pooka InRAM:
    297  1.1   pooka 
    298  1.1   pooka #endif /*  SECONDARY_BOOTBLOCK */
    299  1.1   pooka 
    300  1.1   pooka     /* Get a stack
    301  1.1   pooka      */
    302  1.1   pooka #ifdef __GP_SUPPORT__
    303  1.1   pooka     la      gp, _C_LABEL (_gp)
    304  1.1   pooka #endif
    305  1.1   pooka     la    sp,_end
    306  1.1   pooka 	addiu sp,sp,(8*1024)          /* BUGBUG arbitrary */
    307  1.1   pooka 
    308  1.1   pooka     /* Jump to main
    309  1.1   pooka      */
    310  1.1   pooka     jal   main
    311  1.1   pooka     add   a0,sp,zero
    312  1.1   pooka 
    313  1.1   pooka     /* Load failed, reset the processor and jump back to the origins.
    314  1.1   pooka      */
    315  1.1   pooka EXPORT(_rtt)    /* ahem */
    316  1.1   pooka     li     t0,0x1260ff80  /* NB: On new builds this is a SYS-RESET as well */
    317  1.1   pooka     mtc0   t0,MIPS_COP_0_STATUS
    318  1.1   pooka 
    319  1.1   pooka     lui    t0,(BRAM_DEFAULT_ADDRESS>>16) /* nb: knows about 16bit chop */
    320  1.1   pooka 	jr     t0
    321  1.1   pooka     nop
    322  1.1   pooka 
    323  1.1   pooka EXPORT(Stop)
    324  1.1   pooka 	b     Stop
    325  1.1   pooka     nop
    326  1.1   pooka 
    327  1.1   pooka END(real_start)
    328  1.1   pooka 
    329  1.1   pooka         .set noreorder
    330  1.1   pooka         .set noat
    331  1.1   pooka         .set nomacro
    332  1.1   pooka 
    333  1.1   pooka /* void Delay(UINT32 count)
    334  1.1   pooka  */
    335  1.1   pooka LEAF(Delay)
    336  1.1   pooka     bne    a0,zero,_C_LABEL(Delay)
    337  1.1   pooka     subu   a0,1
    338  1.1   pooka     j      ra
    339  1.1   pooka     nop
    340  1.1   pooka END(Delay)
    341  1.1   pooka 
    342  1.1   pooka /* UINT32 GetPsr(void)
    343  1.1   pooka  * Returns the PSR (coprocessor 0 status)
    344  1.1   pooka  */
    345  1.1   pooka LEAF(GetPsr)
    346  1.1   pooka     mfc0   v0, MIPS_COP_0_STATUS
    347  1.1   pooka     j      ra
    348  1.1   pooka     nop
    349  1.1   pooka END(GetPsr)
    350  1.1   pooka 
    351  1.1   pooka /* void SetPsr(UINT32 Psr)
    352  1.1   pooka  * Sets the PSR (coprocessor 0 status)
    353  1.1   pooka  */
    354  1.1   pooka LEAF(SetPsr)
    355  1.1   pooka     mtc0   a0,MIPS_COP_0_STATUS
    356  1.1   pooka     j      ra
    357  1.1   pooka     nop
    358  1.1   pooka END(SetPsr)
    359  1.1   pooka 
    360  1.1   pooka /* UINT32 GetCause(void)
    361  1.1   pooka  * Returns the Cause register (coprocessor 0)
    362  1.1   pooka  */
    363  1.1   pooka LEAF(GetCause)
    364  1.1   pooka     mfc0   v0,MIPS_COP_0_CAUSE
    365  1.1   pooka     j      ra
    366  1.1   pooka     nop
    367  1.1   pooka END(GetCause)
    368  1.1   pooka 
    369  1.1   pooka /* UINT32 GetEpc(void)
    370  1.1   pooka  * Returns the Epc register (coprocessor 0)
    371  1.1   pooka  */
    372  1.1   pooka LEAF(GetEpc)
    373  1.1   pooka     mfc0   v0,MIPS_COP_0_EXC_PC
    374  1.1   pooka     j      ra
    375  1.1   pooka     nop
    376  1.1   pooka END(GetEpc)
    377  1.1   pooka 
    378  1.1   pooka 
    379  1.1   pooka /* int PutWord(UINT32 Word);
    380  1.1   pooka  * Returns: 0 if ok, -1 otherwise
    381  1.1   pooka  */
    382  1.1   pooka NESTED(PutWord,12,$31)
    383  1.1   pooka     subu   sp,sp,12
    384  1.1   pooka     sw     s0,8(sp)
    385  1.1   pooka     sw     s1,4(sp)
    386  1.1   pooka     sw     ra,0(sp)
    387  1.1   pooka 
    388  1.1   pooka     or     s1,a0,zero
    389  1.1   pooka     /* Spit all nibbles
    390  1.1   pooka      */
    391  1.1   pooka     li     s0,8
    392  1.1   pooka PutWordLoop:
    393  1.1   pooka     srl    a0,s1,32-4
    394  1.1   pooka     li     t0,10
    395  1.1   pooka     sltu   t1,a0,t0
    396  1.1   pooka     bnez   t1,$Digit
    397  1.1   pooka     li     a1,'0'
    398  1.1   pooka     subu   a0,a0,t0
    399  1.1   pooka     li     a1,'a'
    400  1.1   pooka $Digit:
    401  1.1   pooka     sll    s1,s1,4
    402  1.1   pooka     jal    PutChar
    403  1.1   pooka     add    a0,a0,a1
    404  1.1   pooka 
    405  1.1   pooka     subu   s0,s0,1
    406  1.1   pooka     bne    v0,zero,PutWordDone /* printed ok? */
    407  1.1   pooka     li     v0,-1
    408  1.1   pooka 
    409  1.1   pooka     /* done yet? */
    410  1.1   pooka     bne    s0,zero,PutWordLoop
    411  1.1   pooka     nop
    412  1.1   pooka 
    413  1.1   pooka     /* done
    414  1.1   pooka      */
    415  1.1   pooka     li     v0,0
    416  1.1   pooka PutWordDone:
    417  1.1   pooka     lw     ra,0(sp)
    418  1.1   pooka     lw     s1,4(sp)
    419  1.1   pooka     lw     s0,8(sp)
    420  1.1   pooka     jr     ra
    421  1.1   pooka     addiu  sp,sp,12
    422  1.1   pooka 
    423  1.1   pooka END(PutWord)
    424  1.1   pooka 
    425  1.1   pooka /* int Puts(char *String);
    426  1.1   pooka  * Returns: 0 if ok, -1 otherwise
    427  1.1   pooka  */
    428  1.1   pooka NESTED(Puts,8,$31)
    429  1.1   pooka     subu   sp,sp,8
    430  1.1   pooka     sw     s0,4(sp)
    431  1.1   pooka     sw     ra,0(sp)
    432  1.1   pooka 
    433  1.1   pooka     or     s0,a0,zero
    434  1.1   pooka     /* Spit all chars until zero
    435  1.1   pooka      */
    436  1.1   pooka PutsLoop:
    437  1.1   pooka     lbu    a0,0(s0)
    438  1.1   pooka     addiu  s0,s0,1
    439  1.1   pooka     beq    a0,zero,PutsDoneOk
    440  1.1   pooka     nop
    441  1.1   pooka     jal    PutChar
    442  1.1   pooka     nop
    443  1.1   pooka     beq    v0,zero,PutsLoop
    444  1.1   pooka     nop
    445  1.1   pooka 
    446  1.1   pooka     /* Timed out
    447  1.1   pooka      */
    448  1.1   pooka     b      PutsDone
    449  1.1   pooka     li     v0,-1
    450  1.1   pooka 
    451  1.1   pooka     /* done
    452  1.1   pooka      */
    453  1.1   pooka PutsDoneOk:
    454  1.1   pooka     li     v0,0
    455  1.1   pooka PutsDone:
    456  1.1   pooka     lw     ra,0(sp)
    457  1.1   pooka     lw     s0,4(sp)
    458  1.1   pooka     jr     ra
    459  1.1   pooka     addiu  sp,sp,8
    460  1.1   pooka 
    461  1.1   pooka END(Puts)
    462  1.1   pooka 
    463  1.1   pooka 
    464  1.1   pooka /* int GetChar(void);
    465  1.1   pooka  * Returns: a non-negative value if ok, -1 otherwise
    466  1.1   pooka  */
    467  1.1   pooka LEAF(GetChar)
    468  1.1   pooka     lui    t0,(USART_DEFAULT_ADDRESS>>16) /* nb: knows about 16bit chop */
    469  1.1   pooka     lui    t1,1000          /* n*65k spins max */
    470  1.1   pooka RxNotReady:
    471  1.1   pooka     lw     t4,USARTST(t0)       /* ChannelStatus */
    472  1.1   pooka     andi   t4,t4,USI_RXRDY
    473  1.1   pooka     bgtz   t4,$GotByte
    474  1.1   pooka     subu   t1,t1,1
    475  1.1   pooka     /* still ok to spin? */
    476  1.1   pooka     bgtz   t1,RxNotReady
    477  1.1   pooka     nop
    478  1.1   pooka     /* Timed out
    479  1.1   pooka      */
    480  1.1   pooka     jr     ra
    481  1.1   pooka     li     v0,-1
    482  1.1   pooka 
    483  1.1   pooka     /* Gottabyte
    484  1.1   pooka      */
    485  1.1   pooka $GotByte:
    486  1.1   pooka     lw     v0,USARTRX(t0)        /* RxData */
    487  1.1   pooka     jr     ra
    488  1.1   pooka     andi   v0,0xff
    489  1.1   pooka END(GetChar)
    490  1.1   pooka 
    491  1.1   pooka /* int PutChar(UINT8 v);
    492  1.1   pooka  * Returns: 0 if ok, -1 otherwise
    493  1.1   pooka  */
    494  1.1   pooka LEAF(PutChar)
    495  1.1   pooka     lui    t0,(USART_DEFAULT_ADDRESS>>16) /* nb: knows about 16bit chop */
    496  1.1   pooka     lui    t1,1000          /* n*65k spins max */
    497  1.1   pooka     li     v0,0
    498  1.1   pooka TxNotReady:
    499  1.1   pooka     lw     t4,USARTST(t0)       /* ChannelStatus */
    500  1.1   pooka     andi   t4,t4,USI_TXRDY
    501  1.1   pooka     bgtz   t4,TxReady
    502  1.1   pooka     subu   t1,t1,1
    503  1.1   pooka     /* still ok to spin? */
    504  1.1   pooka     bgtz   t1,TxNotReady
    505  1.1   pooka     nop
    506  1.1   pooka     /* Timed out
    507  1.1   pooka      */
    508  1.1   pooka     jr     ra
    509  1.1   pooka     li     v0,-1
    510  1.1   pooka 
    511  1.1   pooka     /* Send it
    512  1.1   pooka      */
    513  1.1   pooka TxReady:
    514  1.1   pooka     jr     ra
    515  1.1   pooka     sw     a0,USARTTX(t0)
    516  1.1   pooka 
    517  1.1   pooka END(PutChar)
    518  1.1   pooka 
    519  1.1   pooka /* Second arg is a function to call with the first arg:
    520  1.1   pooka  * void switch_stack_and_call(void *arg, void (*function)(void *));
    521  1.1   pooka  */
    522  1.1   pooka LEAF(switch_stack_and_call)
    523  1.1   pooka     /* Get a stack and jump. It would be a very bad idea to return but..
    524  1.1   pooka      */
    525  1.3    matt     lui   sp,%hi(_end)
    526  1.3    matt     addiu sp,%lo(_end)
    527  1.1   pooka     jr    a1
    528  1.1   pooka 	addiu sp,sp,(2*1024)          /* BUGBUG arbitrary */
    529  1.1   pooka 
    530  1.1   pooka END(switch_stack_and_call)
    531  1.1   pooka 
    532