at v2.6.16 6.9 kB view raw
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, 95, 96, 99, 2001 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#include <linux/threads.h> 15 16#include <asm/asm.h> 17#include <asm/mipsregs.h> 18#include <asm/asm-offsets.h> 19 20 .macro SAVE_AT 21 .set push 22 .set noat 23 LONG_S $1, PT_R1(sp) 24 .set pop 25 .endm 26 27 .macro SAVE_TEMP 28 mfhi v1 29#ifdef CONFIG_32BIT 30 LONG_S $8, PT_R8(sp) 31 LONG_S $9, PT_R9(sp) 32#endif 33 LONG_S v1, PT_HI(sp) 34 mflo v1 35 LONG_S $10, PT_R10(sp) 36 LONG_S $11, PT_R11(sp) 37 LONG_S v1, PT_LO(sp) 38 LONG_S $12, PT_R12(sp) 39 LONG_S $13, PT_R13(sp) 40 LONG_S $14, PT_R14(sp) 41 LONG_S $15, PT_R15(sp) 42 LONG_S $24, PT_R24(sp) 43 .endm 44 45 .macro SAVE_STATIC 46 LONG_S $16, PT_R16(sp) 47 LONG_S $17, PT_R17(sp) 48 LONG_S $18, PT_R18(sp) 49 LONG_S $19, PT_R19(sp) 50 LONG_S $20, PT_R20(sp) 51 LONG_S $21, PT_R21(sp) 52 LONG_S $22, PT_R22(sp) 53 LONG_S $23, PT_R23(sp) 54 LONG_S $30, PT_R30(sp) 55 .endm 56 57#ifdef CONFIG_SMP 58 .macro get_saved_sp /* SMP variation */ 59#ifdef CONFIG_32BIT 60 mfc0 k0, CP0_CONTEXT 61 lui k1, %hi(kernelsp) 62 srl k0, k0, 23 63 addu k1, k0 64 LONG_L k1, %lo(kernelsp)(k1) 65#endif 66#if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64) 67 MFC0 k1, CP0_CONTEXT 68 dsra k1, 23 69 lui k0, %hi(pgd_current) 70 addiu k0, %lo(pgd_current) 71 dsubu k1, k0 72 lui k0, %hi(kernelsp) 73 daddu k1, k0 74 LONG_L k1, %lo(kernelsp)(k1) 75#endif 76#if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64) 77 MFC0 k1, CP0_CONTEXT 78 lui k0, %highest(kernelsp) 79 dsrl k1, 23 80 daddiu k0, %higher(kernelsp) 81 dsll k0, k0, 16 82 daddiu k0, %hi(kernelsp) 83 dsll k0, k0, 16 84 daddu k1, k1, k0 85 LONG_L k1, %lo(kernelsp)(k1) 86#endif 87 .endm 88 89 .macro set_saved_sp stackp temp temp2 90#ifdef CONFIG_32BIT 91 mfc0 \temp, CP0_CONTEXT 92 srl \temp, 23 93#endif 94#if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64) 95 lw \temp, TI_CPU(gp) 96 dsll \temp, 3 97#endif 98#if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64) 99 MFC0 \temp, CP0_CONTEXT 100 dsrl \temp, 23 101#endif 102 LONG_S \stackp, kernelsp(\temp) 103 .endm 104#else 105 .macro get_saved_sp /* Uniprocessor variation */ 106#if defined(CONFIG_64BIT) && defined(CONFIG_BUILD_ELF64) 107 lui k1, %highest(kernelsp) 108 daddiu k1, %higher(kernelsp) 109 dsll k1, k1, 16 110 daddiu k1, %hi(kernelsp) 111 dsll k1, k1, 16 112#else 113 lui k1, %hi(kernelsp) 114#endif 115 LONG_L k1, %lo(kernelsp)(k1) 116 .endm 117 118 .macro set_saved_sp stackp temp temp2 119 LONG_S \stackp, kernelsp 120 .endm 121#endif 122 123 .macro SAVE_SOME 124 .set push 125 .set noat 126 .set reorder 127 mfc0 k0, CP0_STATUS 128 sll k0, 3 /* extract cu0 bit */ 129 .set noreorder 130 bltz k0, 8f 131 move k1, sp 132 .set reorder 133 /* Called from user mode, new stack. */ 134 get_saved_sp 1358: move k0, sp 136 PTR_SUBU sp, k1, PT_SIZE 137 LONG_S k0, PT_R29(sp) 138 LONG_S $3, PT_R3(sp) 139 LONG_S $0, PT_R0(sp) 140 mfc0 v1, CP0_STATUS 141 LONG_S $2, PT_R2(sp) 142 LONG_S v1, PT_STATUS(sp) 143 LONG_S $4, PT_R4(sp) 144 mfc0 v1, CP0_CAUSE 145 LONG_S $5, PT_R5(sp) 146 LONG_S v1, PT_CAUSE(sp) 147 LONG_S $6, PT_R6(sp) 148 MFC0 v1, CP0_EPC 149 LONG_S $7, PT_R7(sp) 150#ifdef CONFIG_64BIT 151 LONG_S $8, PT_R8(sp) 152 LONG_S $9, PT_R9(sp) 153#endif 154 LONG_S v1, PT_EPC(sp) 155 LONG_S $25, PT_R25(sp) 156 LONG_S $28, PT_R28(sp) 157 LONG_S $31, PT_R31(sp) 158 ori $28, sp, _THREAD_MASK 159 xori $28, _THREAD_MASK 160 .set pop 161 .endm 162 163 .macro SAVE_ALL 164 SAVE_SOME 165 SAVE_AT 166 SAVE_TEMP 167 SAVE_STATIC 168 .endm 169 170 .macro RESTORE_AT 171 .set push 172 .set noat 173 LONG_L $1, PT_R1(sp) 174 .set pop 175 .endm 176 177 .macro RESTORE_TEMP 178 LONG_L $24, PT_LO(sp) 179#ifdef CONFIG_32BIT 180 LONG_L $8, PT_R8(sp) 181 LONG_L $9, PT_R9(sp) 182#endif 183 mtlo $24 184 LONG_L $24, PT_HI(sp) 185 LONG_L $10, PT_R10(sp) 186 LONG_L $11, PT_R11(sp) 187 mthi $24 188 LONG_L $12, PT_R12(sp) 189 LONG_L $13, PT_R13(sp) 190 LONG_L $14, PT_R14(sp) 191 LONG_L $15, PT_R15(sp) 192 LONG_L $24, PT_R24(sp) 193 .endm 194 195 .macro RESTORE_STATIC 196 LONG_L $16, PT_R16(sp) 197 LONG_L $17, PT_R17(sp) 198 LONG_L $18, PT_R18(sp) 199 LONG_L $19, PT_R19(sp) 200 LONG_L $20, PT_R20(sp) 201 LONG_L $21, PT_R21(sp) 202 LONG_L $22, PT_R22(sp) 203 LONG_L $23, PT_R23(sp) 204 LONG_L $30, PT_R30(sp) 205 .endm 206 207#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) 208 209 .macro RESTORE_SOME 210 .set push 211 .set reorder 212 .set noat 213 mfc0 a0, CP0_STATUS 214 ori a0, 0x1f 215 xori a0, 0x1f 216 mtc0 a0, CP0_STATUS 217 li v1, 0xff00 218 and a0, v1 219 LONG_L v0, PT_STATUS(sp) 220 nor v1, $0, v1 221 and v0, v1 222 or v0, a0 223 mtc0 v0, CP0_STATUS 224 LONG_L $31, PT_R31(sp) 225 LONG_L $28, PT_R28(sp) 226 LONG_L $25, PT_R25(sp) 227#ifdef CONFIG_64BIT 228 LONG_L $8, PT_R8(sp) 229 LONG_L $9, PT_R9(sp) 230#endif 231 LONG_L $7, PT_R7(sp) 232 LONG_L $6, PT_R6(sp) 233 LONG_L $5, PT_R5(sp) 234 LONG_L $4, PT_R4(sp) 235 LONG_L $3, PT_R3(sp) 236 LONG_L $2, PT_R2(sp) 237 .set pop 238 .endm 239 240 .macro RESTORE_SP_AND_RET 241 .set push 242 .set noreorder 243 LONG_L k0, PT_EPC(sp) 244 LONG_L sp, PT_R29(sp) 245 jr k0 246 rfe 247 .set pop 248 .endm 249 250#else 251 252 .macro RESTORE_SOME 253 .set push 254 .set reorder 255 .set noat 256 mfc0 a0, CP0_STATUS 257 ori a0, 0x1f 258 xori a0, 0x1f 259 mtc0 a0, CP0_STATUS 260 li v1, 0xff00 261 and a0, v1 262 LONG_L v0, PT_STATUS(sp) 263 nor v1, $0, v1 264 and v0, v1 265 or v0, a0 266 mtc0 v0, CP0_STATUS 267 LONG_L v1, PT_EPC(sp) 268 MTC0 v1, CP0_EPC 269 LONG_L $31, PT_R31(sp) 270 LONG_L $28, PT_R28(sp) 271 LONG_L $25, PT_R25(sp) 272#ifdef CONFIG_64BIT 273 LONG_L $8, PT_R8(sp) 274 LONG_L $9, PT_R9(sp) 275#endif 276 LONG_L $7, PT_R7(sp) 277 LONG_L $6, PT_R6(sp) 278 LONG_L $5, PT_R5(sp) 279 LONG_L $4, PT_R4(sp) 280 LONG_L $3, PT_R3(sp) 281 LONG_L $2, PT_R2(sp) 282 .set pop 283 .endm 284 285 .macro RESTORE_SP_AND_RET 286 LONG_L sp, PT_R29(sp) 287 .set mips3 288 eret 289 .set mips0 290 .endm 291 292#endif 293 294 .macro RESTORE_SP 295 LONG_L sp, PT_R29(sp) 296 .endm 297 298 .macro RESTORE_ALL 299 RESTORE_TEMP 300 RESTORE_STATIC 301 RESTORE_AT 302 RESTORE_SOME 303 RESTORE_SP 304 .endm 305 306 .macro RESTORE_ALL_AND_RET 307 RESTORE_TEMP 308 RESTORE_STATIC 309 RESTORE_AT 310 RESTORE_SOME 311 RESTORE_SP_AND_RET 312 .endm 313 314/* 315 * Move to kernel mode and disable interrupts. 316 * Set cp0 enable bit as sign that we're running on the kernel stack 317 */ 318 .macro CLI 319 mfc0 t0, CP0_STATUS 320 li t1, ST0_CU0 | 0x1f 321 or t0, t1 322 xori t0, 0x1f 323 mtc0 t0, CP0_STATUS 324 irq_disable_hazard 325 .endm 326 327/* 328 * Move to kernel mode and enable interrupts. 329 * Set cp0 enable bit as sign that we're running on the kernel stack 330 */ 331 .macro STI 332 mfc0 t0, CP0_STATUS 333 li t1, ST0_CU0 | 0x1f 334 or t0, t1 335 xori t0, 0x1e 336 mtc0 t0, CP0_STATUS 337 irq_enable_hazard 338 .endm 339 340/* 341 * Just move to kernel mode and leave interrupts as they are. 342 * Set cp0 enable bit as sign that we're running on the kernel stack 343 */ 344 .macro KMODE 345 mfc0 t0, CP0_STATUS 346 li t1, ST0_CU0 | 0x1e 347 or t0, t1 348 xori t0, 0x1e 349 mtc0 t0, CP0_STATUS 350 irq_disable_hazard 351 .endm 352 353#endif /* _ASM_STACKFRAME_H */