stackframe.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  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/threads.h>
  13. #include <asm/asm.h>
  14. #include <asm/asmmacro.h>
  15. #include <asm/mipsregs.h>
  16. #include <asm/asm-offsets.h>
  17. #ifdef CONFIG_MIPS_MT_SMTC
  18. #include <asm/mipsmtregs.h>
  19. #endif /* CONFIG_MIPS_MT_SMTC */
  20. .macro SAVE_AT
  21. .set push
  22. .set noat
  23. LONG_S $1, PT_R1(sp)
  24. .set pop
  25. .endm
  26. .macro SAVE_TEMP
  27. mfhi v1
  28. #ifdef CONFIG_32BIT
  29. LONG_S $8, PT_R8(sp)
  30. LONG_S $9, PT_R9(sp)
  31. #endif
  32. LONG_S v1, PT_HI(sp)
  33. mflo v1
  34. LONG_S $10, PT_R10(sp)
  35. LONG_S $11, PT_R11(sp)
  36. LONG_S v1, PT_LO(sp)
  37. LONG_S $12, PT_R12(sp)
  38. LONG_S $13, PT_R13(sp)
  39. LONG_S $14, PT_R14(sp)
  40. LONG_S $15, PT_R15(sp)
  41. LONG_S $24, PT_R24(sp)
  42. .endm
  43. .macro SAVE_STATIC
  44. LONG_S $16, PT_R16(sp)
  45. LONG_S $17, PT_R17(sp)
  46. LONG_S $18, PT_R18(sp)
  47. LONG_S $19, PT_R19(sp)
  48. LONG_S $20, PT_R20(sp)
  49. LONG_S $21, PT_R21(sp)
  50. LONG_S $22, PT_R22(sp)
  51. LONG_S $23, PT_R23(sp)
  52. LONG_S $30, PT_R30(sp)
  53. .endm
  54. #ifdef CONFIG_SMP
  55. .macro get_saved_sp /* SMP variation */
  56. #ifdef CONFIG_32BIT
  57. #ifdef CONFIG_MIPS_MT_SMTC
  58. .set mips32
  59. mfc0 k0, CP0_TCBIND;
  60. .set mips0
  61. lui k1, %hi(kernelsp)
  62. srl k0, k0, 19
  63. /* No need to shift down and up to clear bits 0-1 */
  64. #else
  65. mfc0 k0, CP0_CONTEXT
  66. lui k1, %hi(kernelsp)
  67. srl k0, k0, 23
  68. #endif
  69. addu k1, k0
  70. LONG_L k1, %lo(kernelsp)(k1)
  71. #endif
  72. #ifdef CONFIG_64BIT
  73. #ifdef CONFIG_MIPS_MT_SMTC
  74. .set mips64
  75. mfc0 k0, CP0_TCBIND;
  76. .set mips0
  77. lui k0, %highest(kernelsp)
  78. dsrl k1, 19
  79. /* No need to shift down and up to clear bits 0-2 */
  80. #else
  81. MFC0 k1, CP0_CONTEXT
  82. lui k0, %highest(kernelsp)
  83. dsrl k1, 23
  84. daddiu k0, %higher(kernelsp)
  85. dsll k0, k0, 16
  86. daddiu k0, %hi(kernelsp)
  87. dsll k0, k0, 16
  88. #endif /* CONFIG_MIPS_MT_SMTC */
  89. daddu k1, k1, k0
  90. LONG_L k1, %lo(kernelsp)(k1)
  91. #endif /* CONFIG_64BIT */
  92. .endm
  93. .macro set_saved_sp stackp temp temp2
  94. #ifdef CONFIG_32BIT
  95. #ifdef CONFIG_MIPS_MT_SMTC
  96. mfc0 \temp, CP0_TCBIND
  97. srl \temp, 19
  98. #else
  99. mfc0 \temp, CP0_CONTEXT
  100. srl \temp, 23
  101. #endif
  102. #endif
  103. #ifdef CONFIG_64BIT
  104. #ifdef CONFIG_MIPS_MT_SMTC
  105. mfc0 \temp, CP0_TCBIND
  106. dsrl \temp, 19
  107. #else
  108. MFC0 \temp, CP0_CONTEXT
  109. dsrl \temp, 23
  110. #endif
  111. #endif
  112. LONG_S \stackp, kernelsp(\temp)
  113. .endm
  114. #else
  115. .macro get_saved_sp /* Uniprocessor variation */
  116. #ifdef CONFIG_64BIT
  117. lui k1, %highest(kernelsp)
  118. daddiu k1, %higher(kernelsp)
  119. dsll k1, k1, 16
  120. daddiu k1, %hi(kernelsp)
  121. dsll k1, k1, 16
  122. #else
  123. lui k1, %hi(kernelsp)
  124. #endif
  125. LONG_L k1, %lo(kernelsp)(k1)
  126. .endm
  127. .macro set_saved_sp stackp temp temp2
  128. LONG_S \stackp, kernelsp
  129. .endm
  130. #endif
  131. .macro SAVE_SOME
  132. .set push
  133. .set noat
  134. .set reorder
  135. mfc0 k0, CP0_STATUS
  136. sll k0, 3 /* extract cu0 bit */
  137. .set noreorder
  138. bltz k0, 8f
  139. move k1, sp
  140. .set reorder
  141. /* Called from user mode, new stack. */
  142. get_saved_sp
  143. 8: move k0, sp
  144. PTR_SUBU sp, k1, PT_SIZE
  145. LONG_S k0, PT_R29(sp)
  146. LONG_S $3, PT_R3(sp)
  147. /*
  148. * You might think that you don't need to save $0,
  149. * but the FPU emulator and gdb remote debug stub
  150. * need it to operate correctly
  151. */
  152. LONG_S $0, PT_R0(sp)
  153. mfc0 v1, CP0_STATUS
  154. LONG_S $2, PT_R2(sp)
  155. LONG_S v1, PT_STATUS(sp)
  156. #ifdef CONFIG_MIPS_MT_SMTC
  157. /*
  158. * Ideally, these instructions would be shuffled in
  159. * to cover the pipeline delay.
  160. */
  161. .set mips32
  162. mfc0 v1, CP0_TCSTATUS
  163. .set mips0
  164. LONG_S v1, PT_TCSTATUS(sp)
  165. #endif /* CONFIG_MIPS_MT_SMTC */
  166. LONG_S $4, PT_R4(sp)
  167. mfc0 v1, CP0_CAUSE
  168. LONG_S $5, PT_R5(sp)
  169. LONG_S v1, PT_CAUSE(sp)
  170. LONG_S $6, PT_R6(sp)
  171. MFC0 v1, CP0_EPC
  172. LONG_S $7, PT_R7(sp)
  173. #ifdef CONFIG_64BIT
  174. LONG_S $8, PT_R8(sp)
  175. LONG_S $9, PT_R9(sp)
  176. #endif
  177. LONG_S v1, PT_EPC(sp)
  178. LONG_S $25, PT_R25(sp)
  179. LONG_S $28, PT_R28(sp)
  180. LONG_S $31, PT_R31(sp)
  181. ori $28, sp, _THREAD_MASK
  182. xori $28, _THREAD_MASK
  183. .set pop
  184. .endm
  185. .macro SAVE_ALL
  186. SAVE_SOME
  187. SAVE_AT
  188. SAVE_TEMP
  189. SAVE_STATIC
  190. .endm
  191. .macro RESTORE_AT
  192. .set push
  193. .set noat
  194. LONG_L $1, PT_R1(sp)
  195. .set pop
  196. .endm
  197. .macro RESTORE_TEMP
  198. LONG_L $24, PT_LO(sp)
  199. #ifdef CONFIG_32BIT
  200. LONG_L $8, PT_R8(sp)
  201. LONG_L $9, PT_R9(sp)
  202. #endif
  203. mtlo $24
  204. LONG_L $24, PT_HI(sp)
  205. LONG_L $10, PT_R10(sp)
  206. LONG_L $11, PT_R11(sp)
  207. mthi $24
  208. LONG_L $12, PT_R12(sp)
  209. LONG_L $13, PT_R13(sp)
  210. LONG_L $14, PT_R14(sp)
  211. LONG_L $15, PT_R15(sp)
  212. LONG_L $24, PT_R24(sp)
  213. .endm
  214. .macro RESTORE_STATIC
  215. LONG_L $16, PT_R16(sp)
  216. LONG_L $17, PT_R17(sp)
  217. LONG_L $18, PT_R18(sp)
  218. LONG_L $19, PT_R19(sp)
  219. LONG_L $20, PT_R20(sp)
  220. LONG_L $21, PT_R21(sp)
  221. LONG_L $22, PT_R22(sp)
  222. LONG_L $23, PT_R23(sp)
  223. LONG_L $30, PT_R30(sp)
  224. .endm
  225. #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
  226. .macro RESTORE_SOME
  227. .set push
  228. .set reorder
  229. .set noat
  230. mfc0 a0, CP0_STATUS
  231. ori a0, 0x1f
  232. xori a0, 0x1f
  233. mtc0 a0, CP0_STATUS
  234. li v1, 0xff00
  235. and a0, v1
  236. LONG_L v0, PT_STATUS(sp)
  237. nor v1, $0, v1
  238. and v0, v1
  239. or v0, a0
  240. mtc0 v0, CP0_STATUS
  241. LONG_L $31, PT_R31(sp)
  242. LONG_L $28, PT_R28(sp)
  243. LONG_L $25, PT_R25(sp)
  244. #ifdef CONFIG_64BIT
  245. LONG_L $8, PT_R8(sp)
  246. LONG_L $9, PT_R9(sp)
  247. #endif
  248. LONG_L $7, PT_R7(sp)
  249. LONG_L $6, PT_R6(sp)
  250. LONG_L $5, PT_R5(sp)
  251. LONG_L $4, PT_R4(sp)
  252. LONG_L $3, PT_R3(sp)
  253. LONG_L $2, PT_R2(sp)
  254. .set pop
  255. .endm
  256. .macro RESTORE_SP_AND_RET
  257. .set push
  258. .set noreorder
  259. LONG_L k0, PT_EPC(sp)
  260. LONG_L sp, PT_R29(sp)
  261. jr k0
  262. rfe
  263. .set pop
  264. .endm
  265. #else
  266. /*
  267. * For SMTC kernel, global IE should be left set, and interrupts
  268. * controlled exclusively via IXMT.
  269. */
  270. #ifdef CONFIG_MIPS_MT_SMTC
  271. #define STATMASK 0x1e
  272. #else
  273. #define STATMASK 0x1f
  274. #endif
  275. .macro RESTORE_SOME
  276. .set push
  277. .set reorder
  278. .set noat
  279. #ifdef CONFIG_MIPS_MT_SMTC
  280. .set mips32r2
  281. /*
  282. * This may not really be necessary if ints are already
  283. * inhibited here.
  284. */
  285. mfc0 v0, CP0_TCSTATUS
  286. ori v0, TCSTATUS_IXMT
  287. mtc0 v0, CP0_TCSTATUS
  288. _ehb
  289. DMT 5 # dmt a1
  290. jal mips_ihb
  291. #endif /* CONFIG_MIPS_MT_SMTC */
  292. mfc0 a0, CP0_STATUS
  293. ori a0, STATMASK
  294. xori a0, STATMASK
  295. mtc0 a0, CP0_STATUS
  296. li v1, 0xff00
  297. and a0, v1
  298. LONG_L v0, PT_STATUS(sp)
  299. nor v1, $0, v1
  300. and v0, v1
  301. or v0, a0
  302. mtc0 v0, CP0_STATUS
  303. #ifdef CONFIG_MIPS_MT_SMTC
  304. /*
  305. * Only after EXL/ERL have been restored to status can we
  306. * restore TCStatus.IXMT.
  307. */
  308. LONG_L v1, PT_TCSTATUS(sp)
  309. _ehb
  310. mfc0 v0, CP0_TCSTATUS
  311. andi v1, TCSTATUS_IXMT
  312. /* We know that TCStatua.IXMT should be set from above */
  313. xori v0, v0, TCSTATUS_IXMT
  314. or v0, v0, v1
  315. mtc0 v0, CP0_TCSTATUS
  316. _ehb
  317. andi a1, a1, VPECONTROL_TE
  318. beqz a1, 1f
  319. emt
  320. 1:
  321. .set mips0
  322. #endif /* CONFIG_MIPS_MT_SMTC */
  323. LONG_L v1, PT_EPC(sp)
  324. MTC0 v1, CP0_EPC
  325. LONG_L $31, PT_R31(sp)
  326. LONG_L $28, PT_R28(sp)
  327. LONG_L $25, PT_R25(sp)
  328. #ifdef CONFIG_64BIT
  329. LONG_L $8, PT_R8(sp)
  330. LONG_L $9, PT_R9(sp)
  331. #endif
  332. LONG_L $7, PT_R7(sp)
  333. LONG_L $6, PT_R6(sp)
  334. LONG_L $5, PT_R5(sp)
  335. LONG_L $4, PT_R4(sp)
  336. LONG_L $3, PT_R3(sp)
  337. LONG_L $2, PT_R2(sp)
  338. .set pop
  339. .endm
  340. .macro RESTORE_SP_AND_RET
  341. LONG_L sp, PT_R29(sp)
  342. .set mips3
  343. eret
  344. .set mips0
  345. .endm
  346. #endif
  347. .macro RESTORE_SP
  348. LONG_L sp, PT_R29(sp)
  349. .endm
  350. .macro RESTORE_ALL
  351. RESTORE_TEMP
  352. RESTORE_STATIC
  353. RESTORE_AT
  354. RESTORE_SOME
  355. RESTORE_SP
  356. .endm
  357. .macro RESTORE_ALL_AND_RET
  358. RESTORE_TEMP
  359. RESTORE_STATIC
  360. RESTORE_AT
  361. RESTORE_SOME
  362. RESTORE_SP_AND_RET
  363. .endm
  364. /*
  365. * Move to kernel mode and disable interrupts.
  366. * Set cp0 enable bit as sign that we're running on the kernel stack
  367. */
  368. .macro CLI
  369. #if !defined(CONFIG_MIPS_MT_SMTC)
  370. mfc0 t0, CP0_STATUS
  371. li t1, ST0_CU0 | 0x1f
  372. or t0, t1
  373. xori t0, 0x1f
  374. mtc0 t0, CP0_STATUS
  375. #else /* CONFIG_MIPS_MT_SMTC */
  376. /*
  377. * For SMTC, we need to set privilege
  378. * and disable interrupts only for the
  379. * current TC, using the TCStatus register.
  380. */
  381. mfc0 t0,CP0_TCSTATUS
  382. /* Fortunately CU 0 is in the same place in both registers */
  383. /* Set TCU0, TMX, TKSU (for later inversion) and IXMT */
  384. li t1, ST0_CU0 | 0x08001c00
  385. or t0,t1
  386. /* Clear TKSU, leave IXMT */
  387. xori t0, 0x00001800
  388. mtc0 t0, CP0_TCSTATUS
  389. _ehb
  390. /* We need to leave the global IE bit set, but clear EXL...*/
  391. mfc0 t0, CP0_STATUS
  392. ori t0, ST0_EXL | ST0_ERL
  393. xori t0, ST0_EXL | ST0_ERL
  394. mtc0 t0, CP0_STATUS
  395. #endif /* CONFIG_MIPS_MT_SMTC */
  396. irq_disable_hazard
  397. .endm
  398. /*
  399. * Move to kernel mode and enable interrupts.
  400. * Set cp0 enable bit as sign that we're running on the kernel stack
  401. */
  402. .macro STI
  403. #if !defined(CONFIG_MIPS_MT_SMTC)
  404. mfc0 t0, CP0_STATUS
  405. li t1, ST0_CU0 | 0x1f
  406. or t0, t1
  407. xori t0, 0x1e
  408. mtc0 t0, CP0_STATUS
  409. #else /* CONFIG_MIPS_MT_SMTC */
  410. /*
  411. * For SMTC, we need to set privilege
  412. * and enable interrupts only for the
  413. * current TC, using the TCStatus register.
  414. */
  415. _ehb
  416. mfc0 t0,CP0_TCSTATUS
  417. /* Fortunately CU 0 is in the same place in both registers */
  418. /* Set TCU0, TKSU (for later inversion) and IXMT */
  419. li t1, ST0_CU0 | 0x08001c00
  420. or t0,t1
  421. /* Clear TKSU *and* IXMT */
  422. xori t0, 0x00001c00
  423. mtc0 t0, CP0_TCSTATUS
  424. _ehb
  425. /* We need to leave the global IE bit set, but clear EXL...*/
  426. mfc0 t0, CP0_STATUS
  427. ori t0, ST0_EXL
  428. xori t0, ST0_EXL
  429. mtc0 t0, CP0_STATUS
  430. /* irq_enable_hazard below should expand to EHB for 24K/34K cpus */
  431. #endif /* CONFIG_MIPS_MT_SMTC */
  432. irq_enable_hazard
  433. .endm
  434. /*
  435. * Just move to kernel mode and leave interrupts as they are.
  436. * Set cp0 enable bit as sign that we're running on the kernel stack
  437. */
  438. .macro KMODE
  439. #ifdef CONFIG_MIPS_MT_SMTC
  440. /*
  441. * This gets baroque in SMTC. We want to
  442. * protect the non-atomic clearing of EXL
  443. * with DMT/EMT, but we don't want to take
  444. * an interrupt while DMT is still in effect.
  445. */
  446. /* KMODE gets invoked from both reorder and noreorder code */
  447. .set push
  448. .set mips32r2
  449. .set noreorder
  450. mfc0 v0, CP0_TCSTATUS
  451. andi v1, v0, TCSTATUS_IXMT
  452. ori v0, TCSTATUS_IXMT
  453. mtc0 v0, CP0_TCSTATUS
  454. _ehb
  455. DMT 2 # dmt v0
  456. /*
  457. * We don't know a priori if ra is "live"
  458. */
  459. move t0, ra
  460. jal mips_ihb
  461. nop /* delay slot */
  462. move ra, t0
  463. #endif /* CONFIG_MIPS_MT_SMTC */
  464. mfc0 t0, CP0_STATUS
  465. li t1, ST0_CU0 | 0x1e
  466. or t0, t1
  467. xori t0, 0x1e
  468. mtc0 t0, CP0_STATUS
  469. #ifdef CONFIG_MIPS_MT_SMTC
  470. _ehb
  471. andi v0, v0, VPECONTROL_TE
  472. beqz v0, 2f
  473. nop /* delay slot */
  474. emt
  475. 2:
  476. mfc0 v0, CP0_TCSTATUS
  477. /* Clear IXMT, then OR in previous value */
  478. ori v0, TCSTATUS_IXMT
  479. xori v0, TCSTATUS_IXMT
  480. or v0, v1, v0
  481. mtc0 v0, CP0_TCSTATUS
  482. /*
  483. * irq_disable_hazard below should expand to EHB
  484. * on 24K/34K CPUS
  485. */
  486. .set pop
  487. #endif /* CONFIG_MIPS_MT_SMTC */
  488. irq_disable_hazard
  489. .endm
  490. #endif /* _ASM_STACKFRAME_H */