root/user/lib/crt0/mips/crt0.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /*
   2  * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
   3  *      The President and Fellows of Harvard College.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  * 1. Redistributions of source code must retain the above copyright
   9  *    notice, this list of conditions and the following disclaimer.
  10  * 2. Redistributions in binary form must reproduce the above copyright
  11  *    notice, this list of conditions and the following disclaimer in the
  12  *    documentation and/or other materials provided with the distribution.
  13  * 3. Neither the name of the University nor the names of its contributors
  14  *    may be used to endorse or promote products derived from this software
  15  *    without specific prior written permission.
  16  *
  17  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
  18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
  21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27  * SUCH DAMAGE.
  28  */
  29 
  30 /*
  31  * crt0.o for MIPS r2000/r3000.
  32  *
  33  * crt stands for "C runtime".
  34  *
  35  * Basically, this is the startup code that gets invoked before main(),
  36  * and regains control when main returns.
  37  *
  38  * All we really do is save a copy of argv for use by the err* and warn*
  39  * functions, and call exit when main returns.
  40  */
  41 
  42 #include <kern/mips/regdefs.h>
  43 #include <kern/syscall.h>
  44 
  45         .set noreorder  /* so we can use delay slots explicitly */
  46 
  47         .text
  48         .globl __start
  49         .type __start,@function
  50         .ent __start
  51 __start:
  52         /* Load the "global pointer" register */
  53         la gp, _gp
  54 
  55         /*
  56          * We expect that the kernel passes argc in a0 and argv in a1.
  57          * We do not expect the kernel to set up a complete stack frame,
  58          * however.
  59          *
  60          * The MIPS ABI decrees that every caller will leave 16 bytes of
  61          * space in the bottom of its stack frame for writing back the
  62          * values of a0-a3, even when calling functions that take fewer
  63          * than four arguments. It also requires the stack to be aligned
  64          * to an 8-byte boundary. (This is because of 64-bit MIPS, which
  65          * we're not dealing with... but we'll conform to the standard.)
  66          */
  67         li t0, 0xfffffff8               /* mask for stack alignment */
  68         and sp, sp, t0                  /* align the stack */
  69         addiu sp, sp, -16               /* create our frame */
  70 
  71         sw a1, __argv   /* save second arg (argv) in __argv for use later */
  72 
  73         jal main        /* call main */
  74         nop             /* delay slot */
  75 
  76         /*
  77          * Now, we have the return value of main in v0.
  78          *
  79          * Move it to s0 (which is callee-save) so we still have
  80          * it in case exit() returns.
  81          *
  82          * Also move it to a0 so it's the argument to exit.
  83          */
  84         move s0, v0     /* save return value */
  85         jal exit        /* call exit() */
  86         move a0, s0     /* Set argument (in delay slot) */
  87 
  88         /*
  89          * If we got here, something is broken in exit().
  90          * Try using _exit().
  91          */
  92         jal _exit       /* Try _exit() */
  93         move a0, s0     /* Set argument (in delay slot) */
  94 
  95         /*
  96          * If *that* doesn't work, try doing an _exit syscall by hand.
  97          */
  98 1:
  99         move a0, s0
 100         li v0, SYS__exit
 101         syscall
 102 
 103         /*
 104          * ...and if we still can't exit, there's not much we can do
 105          * but keep trying.
 106          */
 107         j 1b            /* loop back */
 108         nop             /* delay slot */
 109         .end __start

/* [<][>][^][v][top][bottom][index][help] */