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