stackframe.h 6.5 KB

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