root/kern/arch/mips/thread/switchframe.c

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

DEFINITIONS

This source file includes following definitions.
  1. switchframe_init

   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 #include <types.h>
  31 #include <lib.h>
  32 #include <thread.h>
  33 #include <threadprivate.h>
  34 
  35 #include "switchframe.h"
  36 
  37 /* in threadstart.S */
  38 extern void mips_threadstart(/* arguments are in unusual registers */);
  39 
  40 
  41 /*
  42  * Function to initialize the switchframe of a new thread, which is
  43  * *not* the one that is currently running.
  44  *
  45  * The new thread should, when it is run the first time, end up calling
  46  * thread_startup(entrypoint, data1, data2).
  47  *
  48  * We arrange for this by creating a phony switchframe for
  49  * switchframe_switch() to switch to. The only trouble is that the
  50  * switchframe doesn't include the argument registers a0-a3. So we
  51  * store the arguments in the s* registers, and use a bit of asm
  52  * (mips_threadstart) to move them and then jump to thread_startup.
  53  */
  54 void 
  55 switchframe_init(struct thread *thread,
  56                  void (*entrypoint)(void *data1, unsigned long data2),
  57                  void *data1, unsigned long data2)
  58 {
  59         vaddr_t stacktop;
  60         struct switchframe *sf;
  61 
  62         /*
  63          * MIPS stacks grow down. t_stack is just a hunk of memory, so
  64          * get the other end of it. Then set up a switchframe on the
  65          * top of the stack.
  66          */
  67         stacktop = ((vaddr_t)thread->t_stack) + STACK_SIZE;
  68         sf = ((struct switchframe *) stacktop) - 1;
  69 
  70         /* Zero out the switchframe. */
  71         bzero(sf, sizeof(*sf));
  72 
  73         /*
  74          * Now set the important parts: pass through the three arguments,
  75          * and set the return address register to the place we want 
  76          * execution to begin.
  77          *
  78          * Thus, when switchframe_switch does its "j ra", it will
  79          * actually jump to mips_threadstart, which will move the
  80          * arguments into the right register and jump to
  81          * thread_startup().
  82          *
  83          * Note that this means that when we call switchframe_switch()
  84          * in thread_switch(), we may not come back out the same way
  85          * in the next thread. (Though we will come back out the same
  86          * way when we later come back to the same thread again.)
  87          *
  88          * This has implications for code at the bottom of
  89          * thread_switch, described in thread.c.
  90          */
  91         sf->sf_s0 = (uint32_t)entrypoint;
  92         sf->sf_s1 = (uint32_t)data1;
  93         sf->sf_s2 = (uint32_t)data2;
  94         sf->sf_ra = (uint32_t)mips_threadstart;
  95 
  96         /* Set ->t_context, and we're done. */
  97         thread->t_context = sf;
  98 }

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