1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 1994, 1995, 1996, 1999 Ralf Baechle 7 * Copyright (C) 1994, 1995, 1996 Paul M. Antoine. 8 * Copyright (C) 1999 Silicon Graphics, Inc. 9 */ 10#ifndef _ASM_STACKFRAME_H 11#define _ASM_STACKFRAME_H 12 13#include <linux/config.h> 14 15#include <asm/asm.h> 16#include <asm/offset.h> 17#include <asm/processor.h> 18#include <asm/addrspace.h> 19 20#ifndef __ASSEMBLY__ 21 22#define __str2(x) #x 23#define __str(x) __str2(x) 24 25#define save_static(frame) \ 26 __asm__ __volatile__( \ 27 "sd\t$16,"__str(PT_R16)"(%0)\n\t" \ 28 "sd\t$17,"__str(PT_R17)"(%0)\n\t" \ 29 "sd\t$18,"__str(PT_R18)"(%0)\n\t" \ 30 "sd\t$19,"__str(PT_R19)"(%0)\n\t" \ 31 "sd\t$20,"__str(PT_R20)"(%0)\n\t" \ 32 "sd\t$21,"__str(PT_R21)"(%0)\n\t" \ 33 "sd\t$22,"__str(PT_R22)"(%0)\n\t" \ 34 "sd\t$23,"__str(PT_R23)"(%0)\n\t" \ 35 "sd\t$30,"__str(PT_R30)"(%0)\n\t" \ 36 : /* No outputs */ \ 37 : "r" (frame)) 38 39#endif /* !__ASSEMBLY__ */ 40 41#ifdef __ASSEMBLY__ 42 43 .macro SAVE_AT 44 .set push 45 .set noat 46 sd $1, PT_R1(sp) 47 .set pop 48 .endm 49 50 .macro SAVE_TEMP 51 mfhi v1 52 sd $8, PT_R8(sp) 53 sd $9, PT_R9(sp) 54 sd v1, PT_HI(sp) 55 mflo v1 56 sd $10, PT_R10(sp) 57 sd $11, PT_R11(sp) 58 sd v1, PT_LO(sp) 59 sd $12, PT_R12(sp) 60 sd $13, PT_R13(sp) 61 sd $14, PT_R14(sp) 62 sd $15, PT_R15(sp) 63 sd $24, PT_R24(sp) 64 .endm 65 66 .macro SAVE_STATIC 67 sd $16, PT_R16(sp) 68 sd $17, PT_R17(sp) 69 sd $18, PT_R18(sp) 70 sd $19, PT_R19(sp) 71 sd $20, PT_R20(sp) 72 sd $21, PT_R21(sp) 73 sd $22, PT_R22(sp) 74 sd $23, PT_R23(sp) 75 sd $30, PT_R30(sp) 76 .endm 77 78#ifdef CONFIG_SMP 79 .macro get_saved_sp /* R10000 variation */ 80#ifdef CONFIG_CPU_SB1 81 dmfc0 k1, CP0_WATCHLO 82#else 83 mfc0 k0, CP0_WATCHLO 84 mfc0 k1, CP0_WATCHHI 85 dsll32 k0, k0, 0 /* Get rid of sign extension */ 86 dsrl32 k0, k0, 0 /* Get rid of sign extension */ 87 dsll32 k1, k1, 0 88 or k1, k1, k0 89 li k0, K0BASE 90 or k1, k1, k0 91#endif 92 .endm 93 94 .macro set_saved_sp stackp temp 95#ifdef CONFIG_CPU_SB1 96 dmtc0 \stackp, CP0_WATCHLO 97#else 98 mtc0 \stackp, CP0_WATCHLO 99 dsrl32 \temp, \stackp, 0 100 mtc0 \temp, CP0_WATCHHI 101#endif 102 .endm 103 104 .macro declare_saved_sp 105 # empty, stackpointer stored in a register 106 .endm 107#else 108 .macro get_saved_sp /* Uniprocessor variation */ 109 lui k1, %hi(kernelsp) 110 ld k1, %lo(kernelsp)(k1) 111 .endm 112 113 .macro set_saved_sp stackp temp 114 sd \stackp, kernelsp 115 .endm 116 117 .macro declare_saved_sp 118 .comm kernelsp, 8, 8 # current stackpointer 119 .endm 120#endif 121 122 .macro SAVE_SOME 123 .set push 124 .set reorder 125 mfc0 k0, CP0_STATUS 126 sll k0, 3 /* extract cu0 bit */ 127 .set noreorder 128 bltz k0, 8f 129 move k1, sp 130 .set reorder 131 /* Called from user mode, new stack. */ 132 get_saved_sp 1338: move k0, sp 134 dsubu sp, k1, PT_SIZE 135 sd k0, PT_R29(sp) 136 sd $3, PT_R3(sp) 137 sd $0, PT_R0(sp) 138 mfc0 v1, CP0_STATUS 139 sd $2, PT_R2(sp) 140 sd v1, PT_STATUS(sp) 141 sd $4, PT_R4(sp) 142 mfc0 v1, CP0_CAUSE 143 sd $5, PT_R5(sp) 144 sd v1, PT_CAUSE(sp) 145 sd $6, PT_R6(sp) 146 dmfc0 v1, CP0_EPC 147 sd $7, PT_R7(sp) 148 sd v1, PT_EPC(sp) 149 sd $25, PT_R25(sp) 150 sd $28, PT_R28(sp) 151 sd $31, PT_R31(sp) 152 ori $28, sp, 0x3fff 153 xori $28, 0x3fff 154 .set pop 155 .endm 156 157 .macro SAVE_ALL 158 SAVE_SOME 159 SAVE_AT 160 SAVE_TEMP 161 SAVE_STATIC 162 .endm 163 164 .macro RESTORE_AT 165 .set push 166 .set noat 167 ld $1, PT_R1(sp) 168 .set pop 169 .endm 170 171 .macro RESTORE_SP 172 ld sp, PT_R29(sp) 173 .endm 174 175 .macro RESTORE_TEMP 176 ld $24, PT_LO(sp) 177 ld $8, PT_R8(sp) 178 ld $9, PT_R9(sp) 179 mtlo $24 180 ld $24, PT_HI(sp) 181 ld $10, PT_R10(sp) 182 ld $11, PT_R11(sp) 183 mthi $24 184 ld $12, PT_R12(sp) 185 ld $13, PT_R13(sp) 186 ld $14, PT_R14(sp) 187 ld $15, PT_R15(sp) 188 ld $24, PT_R24(sp) 189 .endm 190 191 .macro RESTORE_STATIC 192 ld $16, PT_R16(sp) 193 ld $17, PT_R17(sp) 194 ld $18, PT_R18(sp) 195 ld $19, PT_R19(sp) 196 ld $20, PT_R20(sp) 197 ld $21, PT_R21(sp) 198 ld $22, PT_R22(sp) 199 ld $23, PT_R23(sp) 200 ld $30, PT_R30(sp) 201 .endm 202 203 .macro RESTORE_SOME 204 .set push 205 .set reorder 206 mfc0 t0, CP0_STATUS 207 .set pop 208 ori t0, 0x1f 209 xori t0, 0x1f 210 mtc0 t0, CP0_STATUS 211 li v1, 0xff00 212 and t0, v1 213 ld v0, PT_STATUS(sp) 214 nor v1, $0, v1 215 and v0, v1 216 or v0, t0 217 mtc0 v0, CP0_STATUS 218 ld v1, PT_EPC(sp) 219 dmtc0 v1, CP0_EPC 220 ld $31, PT_R31(sp) 221 ld $28, PT_R28(sp) 222 ld $25, PT_R25(sp) 223 ld $7, PT_R7(sp) 224 ld $6, PT_R6(sp) 225 ld $5, PT_R5(sp) 226 ld $4, PT_R4(sp) 227 ld $3, PT_R3(sp) 228 ld $2, PT_R2(sp) 229 .endm 230 231 .macro RESTORE_ALL 232 RESTORE_SOME 233 RESTORE_AT 234 RESTORE_TEMP 235 RESTORE_STATIC 236 RESTORE_SP 237 .endm 238 239/* 240 * Move to kernel mode and disable interrupts. 241 * Set cp0 enable bit as sign that we're running on the kernel stack 242 */ 243 .macro CLI 244 mfc0 t0, CP0_STATUS 245 li t1, ST0_CU0|0x1f 246 or t0, t1 247 xori t0, 0x1f 248 mtc0 t0, CP0_STATUS 249 .endm 250 251/* 252 * Move to kernel mode and enable interrupts. 253 * Set cp0 enable bit as sign that we're running on the kernel stack 254 */ 255 .macro STI 256 mfc0 t0, CP0_STATUS 257 li t1, ST0_CU0 | 0x1f 258 or t0, t1 259 xori t0, 0x1e 260 mtc0 t0, CP0_STATUS 261 .endm 262 263/* 264 * Just move to kernel mode and leave interrupts as they are. 265 * Set cp0 enable bit as sign that we're running on the kernel stack 266 */ 267 .macro KMODE 268 mfc0 t0, CP0_STATUS 269 li t1, ST0_CU0 | 0x1e 270 or t0, t1 271 xori t0, 0x1e 272 mtc0 t0, CP0_STATUS 273 .endm 274 275#endif /* __ASSEMBLY__ */ 276 277#endif /* _ASM_STACKFRAME_H */ 278