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