swtch64.S 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. /* $FreeBSD$ */
  2. /* $NetBSD: locore.S,v 1.24 2000/05/31 05:09:17 thorpej Exp $ */
  3. /*-
  4. * Copyright (C) 2001 Benno Rice
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
  17. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  18. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  19. * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  20. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  21. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  22. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  23. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  24. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  25. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. /*-
  28. * Copyright (C) 1995, 1996 Wolfgang Solfrank.
  29. * Copyright (C) 1995, 1996 TooLs GmbH.
  30. * All rights reserved.
  31. *
  32. * Redistribution and use in source and binary forms, with or without
  33. * modification, are permitted provided that the following conditions
  34. * are met:
  35. * 1. Redistributions of source code must retain the above copyright
  36. * notice, this list of conditions and the following disclaimer.
  37. * 2. Redistributions in binary form must reproduce the above copyright
  38. * notice, this list of conditions and the following disclaimer in the
  39. * documentation and/or other materials provided with the distribution.
  40. * 3. All advertising materials mentioning features or use of this software
  41. * must display the following acknowledgement:
  42. * This product includes software developed by TooLs GmbH.
  43. * 4. The name of TooLs GmbH may not be used to endorse or promote products
  44. * derived from this software without specific prior written permission.
  45. *
  46. * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
  47. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  48. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  49. * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  50. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  51. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  52. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  53. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  54. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  55. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  56. */
  57. #include "assym.inc"
  58. #include "opt_sched.h"
  59. #include <sys/syscall.h>
  60. #include <machine/trap.h>
  61. #include <machine/spr.h>
  62. #include <machine/param.h>
  63. #include <machine/asm.h>
  64. #ifdef _CALL_ELF
  65. .abiversion _CALL_ELF
  66. #endif
  67. TOC_ENTRY(blocked_lock)
  68. /*
  69. * void cpu_throw(struct thread *old, struct thread *new)
  70. */
  71. ENTRY(cpu_throw)
  72. mr %r13, %r4
  73. li %r14,0 /* Tell cpu_switchin not to release a thread */
  74. li %r18,0 /* No old pcb flags. The old thread is extinguished. */
  75. b cpu_switchin
  76. END(cpu_throw)
  77. /*
  78. * void cpu_switch(struct thread *old,
  79. * struct thread *new,
  80. * struct mutex *mtx);
  81. *
  82. * Switch to a new thread saving the current state in the old thread.
  83. *
  84. * Internally clobbers (not visible outside of this file):
  85. * r18 - old thread pcb_flags
  86. * r19 - new thread pcb_flags
  87. */
  88. ENTRY(cpu_switch)
  89. ld %r6,TD_PCB(%r3) /* Get the old thread's PCB ptr */
  90. std %r12,PCB_CONTEXT(%r6) /* Save the non-volatile GP regs.
  91. These can now be used for scratch */
  92. std %r14,PCB_CONTEXT+2*8(%r6)
  93. std %r15,PCB_CONTEXT+3*8(%r6)
  94. std %r16,PCB_CONTEXT+4*8(%r6)
  95. std %r17,PCB_CONTEXT+5*8(%r6)
  96. std %r18,PCB_CONTEXT+6*8(%r6)
  97. std %r19,PCB_CONTEXT+7*8(%r6)
  98. std %r20,PCB_CONTEXT+8*8(%r6)
  99. std %r21,PCB_CONTEXT+9*8(%r6)
  100. std %r22,PCB_CONTEXT+10*8(%r6)
  101. std %r23,PCB_CONTEXT+11*8(%r6)
  102. std %r24,PCB_CONTEXT+12*8(%r6)
  103. std %r25,PCB_CONTEXT+13*8(%r6)
  104. std %r26,PCB_CONTEXT+14*8(%r6)
  105. std %r27,PCB_CONTEXT+15*8(%r6)
  106. std %r28,PCB_CONTEXT+16*8(%r6)
  107. std %r29,PCB_CONTEXT+17*8(%r6)
  108. std %r30,PCB_CONTEXT+18*8(%r6)
  109. std %r31,PCB_CONTEXT+19*8(%r6)
  110. mfcr %r16 /* Save the condition register */
  111. std %r16,PCB_CR(%r6)
  112. mflr %r16 /* Save the link register */
  113. std %r16,PCB_LR(%r6)
  114. std %r1,PCB_SP(%r6) /* Save the stack pointer */
  115. std %r2,PCB_TOC(%r6) /* Save the TOC pointer */
  116. mr %r14,%r3 /* Copy the old thread ptr... */
  117. mr %r13,%r4 /* and the new thread ptr in curthread*/
  118. mr %r16,%r5 /* and the new lock */
  119. mr %r17,%r6 /* and the PCB */
  120. stdu %r1,-48(%r1)
  121. lwz %r18, PCB_FLAGS(%r17)
  122. andi. %r7, %r18, PCB_CFSCR
  123. beq 1f
  124. mfspr %r6, SPR_FSCR
  125. std %r6, PCB_FSCR(%r17)
  126. save_ebb:
  127. andi. %r0, %r6, FSCR_EBB
  128. beq save_lm
  129. mfspr %r7, SPR_EBBHR
  130. std %r7, PCB_EBB_EBBHR(%r17)
  131. mfspr %r7, SPR_EBBRR
  132. std %r7, PCB_EBB_EBBRR(%r17)
  133. mfspr %r7, SPR_BESCR
  134. std %r7, PCB_EBB_BESCR(%r17)
  135. save_lm:
  136. andi. %r0, %r6, FSCR_LM
  137. beq save_tar
  138. mfspr %r7, SPR_LMRR
  139. std %r7, PCB_LMON_LMRR(%r17)
  140. mfspr %r7, SPR_LMSER
  141. std %r7, PCB_LMON_LMSER(%r17)
  142. save_tar:
  143. andi. %r0, %r6, FSCR_TAR
  144. beq 1f
  145. mfspr %r7, SPR_TAR
  146. std %r7, PCB_TAR(%r17)
  147. 1:
  148. andi. %r7, %r18, PCB_CDSCR
  149. beq .L0
  150. mfspr %r6, SPR_DSCRP
  151. std %r6, PCB_DSCR(%r17)
  152. .L0:
  153. /* Save FPU context if needed */
  154. andi. %r7, %r18, PCB_FPU
  155. beq .L1
  156. bl save_fpu
  157. nop
  158. .L1:
  159. mr %r3,%r14 /* restore old thread ptr */
  160. /* Save Altivec context if needed */
  161. andi. %r7, %r18, PCB_VEC
  162. beq .L2
  163. bl save_vec
  164. nop
  165. .L2:
  166. mr %r3,%r14 /* restore old thread ptr */
  167. bl pmap_deactivate /* Deactivate the current pmap */
  168. nop
  169. sync /* Make sure all of that finished */
  170. cpu_switchin:
  171. #if defined(SMP) && defined(SCHED_ULE)
  172. /* Wait for the new thread to become unblocked */
  173. addis %r6,%r2,TOC_REF(blocked_lock)@ha
  174. ld %r6,TOC_REF(blocked_lock)@l(%r6)
  175. blocked_loop:
  176. ld %r7,TD_LOCK(%r13)
  177. cmpd %r6,%r7
  178. beq- blocked_loop
  179. isync
  180. #endif
  181. ld %r17,TD_PCB(%r13) /* Get new PCB */
  182. ld %r1,PCB_SP(%r17) /* Load the stack pointer */
  183. addi %r1,%r1,-48 /* Remember about cpu_switch stack frame */
  184. /* Release old thread now that we have a stack pointer set up */
  185. cmpdi %r14,0
  186. beq- 1f
  187. std %r16,TD_LOCK(%r14) /* ULE: update old thread's lock */
  188. 1: mfsprg %r7,0 /* Get the pcpu pointer */
  189. std %r13,PC_CURTHREAD(%r7) /* Store new current thread */
  190. ld %r17,TD_PCB(%r13) /* Store new current PCB */
  191. std %r17,PC_CURPCB(%r7)
  192. mr %r3,%r13 /* Get new thread ptr */
  193. bl pmap_activate /* Activate the new address space */
  194. nop
  195. lwz %r19, PCB_FLAGS(%r17)
  196. /* Restore FPU context if needed */
  197. andi. %r6, %r19, PCB_FPU
  198. beq .L3
  199. mr %r3,%r13 /* Pass curthread to enable_fpu */
  200. bl enable_fpu
  201. nop
  202. .L3:
  203. /* Restore Altivec context if needed */
  204. andi. %r6, %r19, PCB_VEC
  205. beq .L31
  206. mr %r3,%r13 /* Pass curthread to enable_vec */
  207. bl enable_vec
  208. nop
  209. .L31:
  210. /* Load custom DSCR on PowerISA 2.06+ CPUs. */
  211. /* Load changed FSCR on PowerISA 2.07+ CPUs. */
  212. or %r18,%r18,%r19
  213. /* Restore Custom DSCR if needed (zeroes if in old but not new) */
  214. andi. %r6, %r18, PCB_CDSCR
  215. beq .L32
  216. ld %r7, PCB_DSCR(%r17) /* Load the DSCR register*/
  217. mtspr SPR_DSCRP, %r7
  218. .L32:
  219. /* Restore FSCR if needed (zeroes if in old but not new) */
  220. andi. %r6, %r18, PCB_CFSCR
  221. beq .L4
  222. ld %r7, PCB_FSCR(%r17) /* Load the FSCR register*/
  223. mtspr SPR_FSCR, %r7
  224. restore_ebb:
  225. andi. %r0, %r7, FSCR_EBB
  226. beq restore_lm
  227. ld %r6, PCB_EBB_EBBHR(%r17)
  228. mtspr SPR_EBBHR, %r6
  229. ld %r6, PCB_EBB_EBBRR(%r17)
  230. mtspr SPR_EBBRR, %r6
  231. ld %r6, PCB_EBB_BESCR(%r17)
  232. mtspr SPR_BESCR, %r6
  233. restore_lm:
  234. andi. %r0, %r7, FSCR_LM
  235. beq restore_tar
  236. ld %r6, PCB_LMON_LMRR(%r17)
  237. mtspr SPR_LMRR, %r6
  238. ld %r6, PCB_LMON_LMSER(%r17)
  239. mtspr SPR_LMSER, %r6
  240. restore_tar:
  241. andi. %r0, %r7, FSCR_TAR
  242. beq .L4
  243. ld %r6, PCB_TAR(%r17)
  244. mtspr SPR_TAR, %r6
  245. /* thread to restore is in r3 */
  246. .L4:
  247. addi %r1,%r1,48
  248. mr %r3,%r17 /* Recover PCB ptr */
  249. ld %r12,PCB_CONTEXT(%r3) /* Load the non-volatile GP regs. */
  250. ld %r14,PCB_CONTEXT+2*8(%r3)
  251. ld %r15,PCB_CONTEXT+3*8(%r3)
  252. ld %r16,PCB_CONTEXT+4*8(%r3)
  253. ld %r17,PCB_CONTEXT+5*8(%r3)
  254. ld %r18,PCB_CONTEXT+6*8(%r3)
  255. ld %r19,PCB_CONTEXT+7*8(%r3)
  256. ld %r20,PCB_CONTEXT+8*8(%r3)
  257. ld %r21,PCB_CONTEXT+9*8(%r3)
  258. ld %r22,PCB_CONTEXT+10*8(%r3)
  259. ld %r23,PCB_CONTEXT+11*8(%r3)
  260. ld %r24,PCB_CONTEXT+12*8(%r3)
  261. ld %r25,PCB_CONTEXT+13*8(%r3)
  262. ld %r26,PCB_CONTEXT+14*8(%r3)
  263. ld %r27,PCB_CONTEXT+15*8(%r3)
  264. ld %r28,PCB_CONTEXT+16*8(%r3)
  265. ld %r29,PCB_CONTEXT+17*8(%r3)
  266. ld %r30,PCB_CONTEXT+18*8(%r3)
  267. ld %r31,PCB_CONTEXT+19*8(%r3)
  268. ld %r5,PCB_CR(%r3) /* Load the condition register */
  269. mtcr %r5
  270. ld %r5,PCB_LR(%r3) /* Load the link register */
  271. mtlr %r5
  272. ld %r1,PCB_SP(%r3) /* Load the stack pointer */
  273. ld %r2,PCB_TOC(%r3) /* Load the TOC pointer */
  274. /*
  275. * Perform a dummy stdcx. to clear any reservations we may have
  276. * inherited from the previous thread. It doesn't matter if the
  277. * stdcx succeeds or not. pcb_context[0] can be clobbered.
  278. */
  279. stdcx. %r1, 0, %r3
  280. blr
  281. END(cpu_switch)
  282. /*
  283. * savectx(pcb)
  284. * Update pcb, saving current processor state
  285. */
  286. ENTRY(savectx)
  287. std %r12,PCB_CONTEXT(%r3) /* Save the non-volatile GP regs. */
  288. std %r13,PCB_CONTEXT+1*8(%r3)
  289. std %r14,PCB_CONTEXT+2*8(%r3)
  290. std %r15,PCB_CONTEXT+3*8(%r3)
  291. std %r16,PCB_CONTEXT+4*8(%r3)
  292. std %r17,PCB_CONTEXT+5*8(%r3)
  293. std %r18,PCB_CONTEXT+6*8(%r3)
  294. std %r19,PCB_CONTEXT+7*8(%r3)
  295. std %r20,PCB_CONTEXT+8*8(%r3)
  296. std %r21,PCB_CONTEXT+9*8(%r3)
  297. std %r22,PCB_CONTEXT+10*8(%r3)
  298. std %r23,PCB_CONTEXT+11*8(%r3)
  299. std %r24,PCB_CONTEXT+12*8(%r3)
  300. std %r25,PCB_CONTEXT+13*8(%r3)
  301. std %r26,PCB_CONTEXT+14*8(%r3)
  302. std %r27,PCB_CONTEXT+15*8(%r3)
  303. std %r28,PCB_CONTEXT+16*8(%r3)
  304. std %r29,PCB_CONTEXT+17*8(%r3)
  305. std %r30,PCB_CONTEXT+18*8(%r3)
  306. std %r31,PCB_CONTEXT+19*8(%r3)
  307. mfcr %r4 /* Save the condition register */
  308. std %r4,PCB_CR(%r3)
  309. std %r1,PCB_SP(%r3) /* Save the stack pointer */
  310. std %r2,PCB_TOC(%r3) /* Save the TOC pointer */
  311. mflr %r4 /* Save the link register */
  312. std %r4,PCB_LR(%r3)
  313. blr
  314. END(savectx)
  315. /*
  316. * fork_trampoline()
  317. * Set up the return from cpu_fork()
  318. */
  319. ENTRY_NOPROF(fork_trampoline)
  320. ld %r3,CF_FUNC(%r1)
  321. ld %r4,CF_ARG0(%r1)
  322. ld %r5,CF_ARG1(%r1)
  323. stdu %r1,-48(%r1)
  324. bl fork_exit
  325. nop
  326. addi %r1,%r1,48+CF_SIZE-FSP /* Allow 8 bytes in front of
  327. trapframe to simulate FRAME_SETUP
  328. does when allocating space for
  329. a frame pointer/saved LR */
  330. bl trapexit
  331. nop
  332. END(fork_trampoline)