0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef _ASM_STACKFRAME_H
0012 #define _ASM_STACKFRAME_H
0013
0014 #include <linux/threads.h>
0015
0016 #include <asm/asm.h>
0017 #include <asm/asmmacro.h>
0018 #include <asm/mipsregs.h>
0019 #include <asm/asm-offsets.h>
0020 #include <asm/thread_info.h>
0021
0022
0023 .macro cfi_rel_offset reg offset=0 docfi=0
0024 .if \docfi
0025 .cfi_rel_offset \reg, \offset
0026 .endif
0027 .endm
0028
0029 .macro cfi_st reg offset=0 docfi=0
0030 LONG_S \reg, \offset(sp)
0031 cfi_rel_offset \reg, \offset, \docfi
0032 .endm
0033
0034 .macro cfi_restore reg offset=0 docfi=0
0035 .if \docfi
0036 .cfi_restore \reg
0037 .endif
0038 .endm
0039
0040 .macro cfi_ld reg offset=0 docfi=0
0041 LONG_L \reg, \offset(sp)
0042 cfi_restore \reg \offset \docfi
0043 .endm
0044
0045 #if defined(CONFIG_CPU_R3000)
0046 #define STATMASK 0x3f
0047 #else
0048 #define STATMASK 0x1f
0049 #endif
0050
0051 .macro SAVE_AT docfi=0
0052 .set push
0053 .set noat
0054 cfi_st $1, PT_R1, \docfi
0055 .set pop
0056 .endm
0057
0058 .macro SAVE_TEMP docfi=0
0059 #ifdef CONFIG_CPU_HAS_SMARTMIPS
0060 mflhxu v1
0061 LONG_S v1, PT_LO(sp)
0062 mflhxu v1
0063 LONG_S v1, PT_HI(sp)
0064 mflhxu v1
0065 LONG_S v1, PT_ACX(sp)
0066 #elif !defined(CONFIG_CPU_MIPSR6)
0067 mfhi v1
0068 #endif
0069 #ifdef CONFIG_32BIT
0070 cfi_st $8, PT_R8, \docfi
0071 cfi_st $9, PT_R9, \docfi
0072 #endif
0073 cfi_st $10, PT_R10, \docfi
0074 cfi_st $11, PT_R11, \docfi
0075 cfi_st $12, PT_R12, \docfi
0076 #if !defined(CONFIG_CPU_HAS_SMARTMIPS) && !defined(CONFIG_CPU_MIPSR6)
0077 LONG_S v1, PT_HI(sp)
0078 mflo v1
0079 #endif
0080 cfi_st $13, PT_R13, \docfi
0081 cfi_st $14, PT_R14, \docfi
0082 cfi_st $15, PT_R15, \docfi
0083 cfi_st $24, PT_R24, \docfi
0084 #if !defined(CONFIG_CPU_HAS_SMARTMIPS) && !defined(CONFIG_CPU_MIPSR6)
0085 LONG_S v1, PT_LO(sp)
0086 #endif
0087 #ifdef CONFIG_CPU_CAVIUM_OCTEON
0088
0089
0090
0091
0092
0093 jal octeon_mult_save
0094 #endif
0095 .endm
0096
0097 .macro SAVE_STATIC docfi=0
0098 cfi_st $16, PT_R16, \docfi
0099 cfi_st $17, PT_R17, \docfi
0100 cfi_st $18, PT_R18, \docfi
0101 cfi_st $19, PT_R19, \docfi
0102 cfi_st $20, PT_R20, \docfi
0103 cfi_st $21, PT_R21, \docfi
0104 cfi_st $22, PT_R22, \docfi
0105 cfi_st $23, PT_R23, \docfi
0106 cfi_st $30, PT_R30, \docfi
0107 .endm
0108
0109
0110
0111
0112
0113
0114
0115 #ifdef CONFIG_SMP
0116
0117
0118 .macro get_saved_sp docfi=0 tosp=0
0119 ASM_CPUID_MFC0 k0, ASM_SMP_CPUID_REG
0120 #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
0121 lui k1, %hi(kernelsp)
0122 #else
0123 lui k1, %highest(kernelsp)
0124 daddiu k1, %higher(kernelsp)
0125 dsll k1, 16
0126 daddiu k1, %hi(kernelsp)
0127 dsll k1, 16
0128 #endif
0129 LONG_SRL k0, SMP_CPUID_PTRSHIFT
0130 LONG_ADDU k1, k0
0131 .if \tosp
0132 move k0, sp
0133 .if \docfi
0134 .cfi_register sp, k0
0135 .endif
0136 LONG_L sp, %lo(kernelsp)(k1)
0137 .else
0138 LONG_L k1, %lo(kernelsp)(k1)
0139 .endif
0140 .endm
0141
0142 .macro set_saved_sp stackp temp temp2
0143 ASM_CPUID_MFC0 \temp, ASM_SMP_CPUID_REG
0144 LONG_SRL \temp, SMP_CPUID_PTRSHIFT
0145 LONG_S \stackp, kernelsp(\temp)
0146 .endm
0147 #else
0148
0149 .macro get_saved_sp docfi=0 tosp=0
0150 #ifdef CONFIG_CPU_JUMP_WORKAROUNDS
0151
0152
0153
0154
0155
0156 move k0, ra
0157 jal 1f
0158 nop
0159 1: jal 1f
0160 nop
0161 1: jal 1f
0162 nop
0163 1: jal 1f
0164 nop
0165 1: move ra, k0
0166 li k0, 3
0167 mtc0 k0, $22
0168 #endif
0169 #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
0170 lui k1, %hi(kernelsp)
0171 #else
0172 lui k1, %highest(kernelsp)
0173 daddiu k1, %higher(kernelsp)
0174 dsll k1, k1, 16
0175 daddiu k1, %hi(kernelsp)
0176 dsll k1, k1, 16
0177 #endif
0178 .if \tosp
0179 move k0, sp
0180 .if \docfi
0181 .cfi_register sp, k0
0182 .endif
0183 LONG_L sp, %lo(kernelsp)(k1)
0184 .else
0185 LONG_L k1, %lo(kernelsp)(k1)
0186 .endif
0187 .endm
0188
0189 .macro set_saved_sp stackp temp temp2
0190 LONG_S \stackp, kernelsp
0191 .endm
0192 #endif
0193
0194 .macro SAVE_SOME docfi=0
0195 .set push
0196 .set noat
0197 .set reorder
0198 mfc0 k0, CP0_STATUS
0199 sll k0, 3
0200 .set noreorder
0201 bltz k0, 8f
0202 move k0, sp
0203 .if \docfi
0204 .cfi_register sp, k0
0205 .endif
0206 #ifdef CONFIG_EVA
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228 MFC0 k0, CP0_ENTRYHI
0229 MTC0 k0, CP0_ENTRYHI
0230 #endif
0231 .set reorder
0232
0233 get_saved_sp docfi=\docfi tosp=1
0234 8:
0235 #ifdef CONFIG_CPU_DADDI_WORKAROUNDS
0236 .set at=k1
0237 #endif
0238 PTR_SUBU sp, PT_SIZE
0239 #ifdef CONFIG_CPU_DADDI_WORKAROUNDS
0240 .set noat
0241 #endif
0242 .if \docfi
0243 .cfi_def_cfa sp,0
0244 .endif
0245 cfi_st k0, PT_R29, \docfi
0246 cfi_rel_offset sp, PT_R29, \docfi
0247 cfi_st v1, PT_R3, \docfi
0248
0249
0250
0251
0252
0253 LONG_S $0, PT_R0(sp)
0254 mfc0 v1, CP0_STATUS
0255 cfi_st v0, PT_R2, \docfi
0256 LONG_S v1, PT_STATUS(sp)
0257 cfi_st $4, PT_R4, \docfi
0258 mfc0 v1, CP0_CAUSE
0259 cfi_st $5, PT_R5, \docfi
0260 LONG_S v1, PT_CAUSE(sp)
0261 cfi_st $6, PT_R6, \docfi
0262 cfi_st ra, PT_R31, \docfi
0263 MFC0 ra, CP0_EPC
0264 cfi_st $7, PT_R7, \docfi
0265 #ifdef CONFIG_64BIT
0266 cfi_st $8, PT_R8, \docfi
0267 cfi_st $9, PT_R9, \docfi
0268 #endif
0269 LONG_S ra, PT_EPC(sp)
0270 .if \docfi
0271 .cfi_rel_offset ra, PT_EPC
0272 .endif
0273 cfi_st $25, PT_R25, \docfi
0274 cfi_st $28, PT_R28, \docfi
0275
0276
0277 mfc0 k0, CP0_STATUS
0278 sll k0, 3
0279 bltz k0, 9f
0280
0281 ori $28, sp, _THREAD_MASK
0282 xori $28, _THREAD_MASK
0283 #ifdef CONFIG_CPU_CAVIUM_OCTEON
0284 .set mips64
0285 pref 0, 0($28)
0286 #endif
0287 9:
0288 .set pop
0289 .endm
0290
0291 .macro SAVE_ALL docfi=0
0292 SAVE_SOME \docfi
0293 SAVE_AT \docfi
0294 SAVE_TEMP \docfi
0295 SAVE_STATIC \docfi
0296 .endm
0297
0298 .macro RESTORE_AT docfi=0
0299 .set push
0300 .set noat
0301 cfi_ld $1, PT_R1, \docfi
0302 .set pop
0303 .endm
0304
0305 .macro RESTORE_TEMP docfi=0
0306 #ifdef CONFIG_CPU_CAVIUM_OCTEON
0307
0308 jal octeon_mult_restore
0309 #endif
0310 #ifdef CONFIG_CPU_HAS_SMARTMIPS
0311 LONG_L $24, PT_ACX(sp)
0312 mtlhx $24
0313 LONG_L $24, PT_HI(sp)
0314 mtlhx $24
0315 LONG_L $24, PT_LO(sp)
0316 mtlhx $24
0317 #elif !defined(CONFIG_CPU_MIPSR6)
0318 LONG_L $24, PT_LO(sp)
0319 mtlo $24
0320 LONG_L $24, PT_HI(sp)
0321 mthi $24
0322 #endif
0323 #ifdef CONFIG_32BIT
0324 cfi_ld $8, PT_R8, \docfi
0325 cfi_ld $9, PT_R9, \docfi
0326 #endif
0327 cfi_ld $10, PT_R10, \docfi
0328 cfi_ld $11, PT_R11, \docfi
0329 cfi_ld $12, PT_R12, \docfi
0330 cfi_ld $13, PT_R13, \docfi
0331 cfi_ld $14, PT_R14, \docfi
0332 cfi_ld $15, PT_R15, \docfi
0333 cfi_ld $24, PT_R24, \docfi
0334 .endm
0335
0336 .macro RESTORE_STATIC docfi=0
0337 cfi_ld $16, PT_R16, \docfi
0338 cfi_ld $17, PT_R17, \docfi
0339 cfi_ld $18, PT_R18, \docfi
0340 cfi_ld $19, PT_R19, \docfi
0341 cfi_ld $20, PT_R20, \docfi
0342 cfi_ld $21, PT_R21, \docfi
0343 cfi_ld $22, PT_R22, \docfi
0344 cfi_ld $23, PT_R23, \docfi
0345 cfi_ld $30, PT_R30, \docfi
0346 .endm
0347
0348 .macro RESTORE_SP docfi=0
0349 cfi_ld sp, PT_R29, \docfi
0350 .endm
0351
0352 #if defined(CONFIG_CPU_R3000)
0353
0354 .macro RESTORE_SOME docfi=0
0355 .set push
0356 .set reorder
0357 .set noat
0358 mfc0 a0, CP0_STATUS
0359 li v1, ST0_CU1 | ST0_IM
0360 ori a0, STATMASK
0361 xori a0, STATMASK
0362 mtc0 a0, CP0_STATUS
0363 and a0, v1
0364 LONG_L v0, PT_STATUS(sp)
0365 nor v1, $0, v1
0366 and v0, v1
0367 or v0, a0
0368 mtc0 v0, CP0_STATUS
0369 cfi_ld $31, PT_R31, \docfi
0370 cfi_ld $28, PT_R28, \docfi
0371 cfi_ld $25, PT_R25, \docfi
0372 cfi_ld $7, PT_R7, \docfi
0373 cfi_ld $6, PT_R6, \docfi
0374 cfi_ld $5, PT_R5, \docfi
0375 cfi_ld $4, PT_R4, \docfi
0376 cfi_ld $3, PT_R3, \docfi
0377 cfi_ld $2, PT_R2, \docfi
0378 .set pop
0379 .endm
0380
0381 .macro RESTORE_SP_AND_RET docfi=0
0382 .set push
0383 .set noreorder
0384 LONG_L k0, PT_EPC(sp)
0385 RESTORE_SP \docfi
0386 jr k0
0387 rfe
0388 .set pop
0389 .endm
0390
0391 #else
0392 .macro RESTORE_SOME docfi=0
0393 .set push
0394 .set reorder
0395 .set noat
0396 mfc0 a0, CP0_STATUS
0397 ori a0, STATMASK
0398 xori a0, STATMASK
0399 mtc0 a0, CP0_STATUS
0400 li v1, ST0_CU1 | ST0_FR | ST0_IM
0401 and a0, v1
0402 LONG_L v0, PT_STATUS(sp)
0403 nor v1, $0, v1
0404 and v0, v1
0405 or v0, a0
0406 mtc0 v0, CP0_STATUS
0407 LONG_L v1, PT_EPC(sp)
0408 MTC0 v1, CP0_EPC
0409 cfi_ld $31, PT_R31, \docfi
0410 cfi_ld $28, PT_R28, \docfi
0411 cfi_ld $25, PT_R25, \docfi
0412 #ifdef CONFIG_64BIT
0413 cfi_ld $8, PT_R8, \docfi
0414 cfi_ld $9, PT_R9, \docfi
0415 #endif
0416 cfi_ld $7, PT_R7, \docfi
0417 cfi_ld $6, PT_R6, \docfi
0418 cfi_ld $5, PT_R5, \docfi
0419 cfi_ld $4, PT_R4, \docfi
0420 cfi_ld $3, PT_R3, \docfi
0421 cfi_ld $2, PT_R2, \docfi
0422 .set pop
0423 .endm
0424
0425 .macro RESTORE_SP_AND_RET docfi=0
0426 RESTORE_SP \docfi
0427 #if defined(CONFIG_CPU_MIPSR5) || defined(CONFIG_CPU_MIPSR6)
0428 eretnc
0429 #else
0430 .set push
0431 .set arch=r4000
0432 eret
0433 .set pop
0434 #endif
0435 .endm
0436
0437 #endif
0438
0439 .macro RESTORE_ALL docfi=0
0440 RESTORE_TEMP \docfi
0441 RESTORE_STATIC \docfi
0442 RESTORE_AT \docfi
0443 RESTORE_SOME \docfi
0444 RESTORE_SP \docfi
0445 .endm
0446
0447
0448
0449
0450
0451 .macro CLI
0452 mfc0 t0, CP0_STATUS
0453 li t1, ST0_KERNEL_CUMASK | STATMASK
0454 or t0, t1
0455 xori t0, STATMASK
0456 mtc0 t0, CP0_STATUS
0457 irq_disable_hazard
0458 .endm
0459
0460
0461
0462
0463
0464 .macro STI
0465 mfc0 t0, CP0_STATUS
0466 li t1, ST0_KERNEL_CUMASK | STATMASK
0467 or t0, t1
0468 xori t0, STATMASK & ~1
0469 mtc0 t0, CP0_STATUS
0470 irq_enable_hazard
0471 .endm
0472
0473
0474
0475
0476
0477
0478 .macro KMODE
0479 mfc0 t0, CP0_STATUS
0480 li t1, ST0_KERNEL_CUMASK | (STATMASK & ~1)
0481 #if defined(CONFIG_CPU_R3000)
0482 andi t2, t0, ST0_IEP
0483 srl t2, 2
0484 or t0, t2
0485 #endif
0486 or t0, t1
0487 xori t0, STATMASK & ~1
0488 mtc0 t0, CP0_STATUS
0489 irq_disable_hazard
0490 .endm
0491
0492 #endif