/* [<][>][^][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 * Assembly language context switch code.
32 */
33
34 #include <kern/mips/regdefs.h>
35
36 .text
37 .set noreorder
38
39 .globl switchframe_switch
40 .type switchframe_switch,@function
41 .ent switchframe_switch
42 switchframe_switch:
43 /*
44 * a0 contains the address of the switchframe pointer in the old thread.
45 * a1 contains the address of the switchframe pointer in the new thread.
46 *
47 * The switchframe pointer is really the stack pointer. The other
48 * registers get saved on the stack, namely:
49 *
50 * s0-s6, s8
51 * gp, ra
52 *
53 * The order must match <mips/switchframe.h>.
54 *
55 * Note that while we'd ordinarily need to save s7 too, because we
56 * use it to hold curthread saving it would interfere with the way
57 * curthread is managed by thread.c. So we'll just let thread.c
58 * manage it.
59 */
60
61 /* Allocate stack space for saving 10 registers. 10*4 = 40 */
62 addi sp, sp, -40
63
64 /* Save the registers */
65 sw ra, 36(sp)
66 sw gp, 32(sp)
67 sw s8, 28(sp)
68 sw s6, 24(sp)
69 sw s5, 20(sp)
70 sw s4, 16(sp)
71 sw s3, 12(sp)
72 sw s2, 8(sp)
73 sw s1, 4(sp)
74 sw s0, 0(sp)
75
76 /* Store the old stack pointer in the old thread */
77 sw sp, 0(a0)
78
79 /* Get the new stack pointer from the new thread */
80 lw sp, 0(a1)
81 nop /* delay slot for load */
82
83 /* Now, restore the registers */
84 lw s0, 0(sp)
85 lw s1, 4(sp)
86 lw s2, 8(sp)
87 lw s3, 12(sp)
88 lw s4, 16(sp)
89 lw s5, 20(sp)
90 lw s6, 24(sp)
91 lw s8, 28(sp)
92 lw gp, 32(sp)
93 lw ra, 36(sp)
94 nop /* delay slot for load */
95
96 /* and return. */
97 j ra
98 addi sp, sp, 40 /* in delay slot */
99 .end switchframe_switch