fpu-low.S 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. /* MN10300 Low level FPU management operations
  2. *
  3. * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
  4. * Written by David Howells (dhowells@redhat.com)
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public Licence
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the Licence, or (at your option) any later version.
  10. */
  11. #include <linux/linkage.h>
  12. #include <asm/cpu-regs.h>
  13. #include <asm/smp.h>
  14. #include <asm/thread_info.h>
  15. #include <asm/asm-offsets.h>
  16. #include <asm/frame.inc>
  17. .macro FPU_INIT_STATE_ALL
  18. fmov 0,fs0
  19. fmov fs0,fs1
  20. fmov fs0,fs2
  21. fmov fs0,fs3
  22. fmov fs0,fs4
  23. fmov fs0,fs5
  24. fmov fs0,fs6
  25. fmov fs0,fs7
  26. fmov fs0,fs8
  27. fmov fs0,fs9
  28. fmov fs0,fs10
  29. fmov fs0,fs11
  30. fmov fs0,fs12
  31. fmov fs0,fs13
  32. fmov fs0,fs14
  33. fmov fs0,fs15
  34. fmov fs0,fs16
  35. fmov fs0,fs17
  36. fmov fs0,fs18
  37. fmov fs0,fs19
  38. fmov fs0,fs20
  39. fmov fs0,fs21
  40. fmov fs0,fs22
  41. fmov fs0,fs23
  42. fmov fs0,fs24
  43. fmov fs0,fs25
  44. fmov fs0,fs26
  45. fmov fs0,fs27
  46. fmov fs0,fs28
  47. fmov fs0,fs29
  48. fmov fs0,fs30
  49. fmov fs0,fs31
  50. fmov FPCR_INIT,fpcr
  51. .endm
  52. .macro FPU_SAVE_ALL areg,dreg
  53. fmov fs0,(\areg+)
  54. fmov fs1,(\areg+)
  55. fmov fs2,(\areg+)
  56. fmov fs3,(\areg+)
  57. fmov fs4,(\areg+)
  58. fmov fs5,(\areg+)
  59. fmov fs6,(\areg+)
  60. fmov fs7,(\areg+)
  61. fmov fs8,(\areg+)
  62. fmov fs9,(\areg+)
  63. fmov fs10,(\areg+)
  64. fmov fs11,(\areg+)
  65. fmov fs12,(\areg+)
  66. fmov fs13,(\areg+)
  67. fmov fs14,(\areg+)
  68. fmov fs15,(\areg+)
  69. fmov fs16,(\areg+)
  70. fmov fs17,(\areg+)
  71. fmov fs18,(\areg+)
  72. fmov fs19,(\areg+)
  73. fmov fs20,(\areg+)
  74. fmov fs21,(\areg+)
  75. fmov fs22,(\areg+)
  76. fmov fs23,(\areg+)
  77. fmov fs24,(\areg+)
  78. fmov fs25,(\areg+)
  79. fmov fs26,(\areg+)
  80. fmov fs27,(\areg+)
  81. fmov fs28,(\areg+)
  82. fmov fs29,(\areg+)
  83. fmov fs30,(\areg+)
  84. fmov fs31,(\areg+)
  85. fmov fpcr,\dreg
  86. mov \dreg,(\areg)
  87. .endm
  88. .macro FPU_RESTORE_ALL areg,dreg
  89. fmov (\areg+),fs0
  90. fmov (\areg+),fs1
  91. fmov (\areg+),fs2
  92. fmov (\areg+),fs3
  93. fmov (\areg+),fs4
  94. fmov (\areg+),fs5
  95. fmov (\areg+),fs6
  96. fmov (\areg+),fs7
  97. fmov (\areg+),fs8
  98. fmov (\areg+),fs9
  99. fmov (\areg+),fs10
  100. fmov (\areg+),fs11
  101. fmov (\areg+),fs12
  102. fmov (\areg+),fs13
  103. fmov (\areg+),fs14
  104. fmov (\areg+),fs15
  105. fmov (\areg+),fs16
  106. fmov (\areg+),fs17
  107. fmov (\areg+),fs18
  108. fmov (\areg+),fs19
  109. fmov (\areg+),fs20
  110. fmov (\areg+),fs21
  111. fmov (\areg+),fs22
  112. fmov (\areg+),fs23
  113. fmov (\areg+),fs24
  114. fmov (\areg+),fs25
  115. fmov (\areg+),fs26
  116. fmov (\areg+),fs27
  117. fmov (\areg+),fs28
  118. fmov (\areg+),fs29
  119. fmov (\areg+),fs30
  120. fmov (\areg+),fs31
  121. mov (\areg),\dreg
  122. fmov \dreg,fpcr
  123. .endm
  124. ###############################################################################
  125. #
  126. # void fpu_init_state(void)
  127. # - initialise the FPU
  128. #
  129. ###############################################################################
  130. .globl fpu_init_state
  131. .type fpu_init_state,@function
  132. fpu_init_state:
  133. mov epsw,d0
  134. or EPSW_FE,epsw
  135. #ifdef CONFIG_MN10300_PROC_MN103E010
  136. nop
  137. nop
  138. nop
  139. #endif
  140. FPU_INIT_STATE_ALL
  141. #ifdef CONFIG_MN10300_PROC_MN103E010
  142. nop
  143. nop
  144. nop
  145. #endif
  146. mov d0,epsw
  147. ret [],0
  148. .size fpu_init_state,.-fpu_init_state
  149. ###############################################################################
  150. #
  151. # void fpu_save(struct fpu_state_struct *)
  152. # - save the fpu state
  153. # - note that an FPU Operational exception might occur during this process
  154. #
  155. ###############################################################################
  156. .globl fpu_save
  157. .type fpu_save,@function
  158. fpu_save:
  159. mov epsw,d1
  160. or EPSW_FE,epsw /* enable the FPU so we can access it */
  161. #ifdef CONFIG_MN10300_PROC_MN103E010
  162. nop
  163. nop
  164. #endif
  165. mov d0,a0
  166. FPU_SAVE_ALL a0,d0
  167. #ifdef CONFIG_MN10300_PROC_MN103E010
  168. nop
  169. nop
  170. #endif
  171. mov d1,epsw
  172. ret [],0
  173. .size fpu_save,.-fpu_save
  174. ###############################################################################
  175. #
  176. # void fpu_disabled(void)
  177. # - handle an exception due to the FPU being disabled
  178. # when CONFIG_FPU is enabled
  179. #
  180. ###############################################################################
  181. .type fpu_disabled,@function
  182. .globl fpu_disabled
  183. fpu_disabled:
  184. or EPSW_nAR|EPSW_FE,epsw
  185. nop
  186. nop
  187. nop
  188. mov sp,a1
  189. mov (a1),d1 /* get epsw of user context */
  190. and ~(THREAD_SIZE-1),a1 /* a1: (thread_info *ti) */
  191. mov (TI_task,a1),a2 /* a2: (task_struct *tsk) */
  192. btst EPSW_nSL,d1
  193. beq fpu_used_in_kernel
  194. or EPSW_FE,d1
  195. mov d1,(sp)
  196. mov (TASK_THREAD+THREAD_FPU_FLAGS,a2),d1
  197. #ifndef CONFIG_LAZY_SAVE_FPU
  198. or __THREAD_HAS_FPU,d1
  199. mov d1,(TASK_THREAD+THREAD_FPU_FLAGS,a2)
  200. #else /* !CONFIG_LAZY_SAVE_FPU */
  201. mov (fpu_state_owner),a0
  202. cmp 0,a0
  203. beq fpu_regs_save_end
  204. mov (TASK_THREAD+THREAD_UREGS,a0),a1
  205. add TASK_THREAD+THREAD_FPU_STATE,a0
  206. FPU_SAVE_ALL a0,d0
  207. mov (REG_EPSW,a1),d0
  208. and ~EPSW_FE,d0
  209. mov d0,(REG_EPSW,a1)
  210. fpu_regs_save_end:
  211. mov a2,(fpu_state_owner)
  212. #endif /* !CONFIG_LAZY_SAVE_FPU */
  213. btst __THREAD_USING_FPU,d1
  214. beq fpu_regs_init
  215. add TASK_THREAD+THREAD_FPU_STATE,a2
  216. FPU_RESTORE_ALL a2,d0
  217. rti
  218. fpu_regs_init:
  219. FPU_INIT_STATE_ALL
  220. add TASK_THREAD+THREAD_FPU_FLAGS,a2
  221. bset __THREAD_USING_FPU,(0,a2)
  222. rti
  223. fpu_used_in_kernel:
  224. and ~(EPSW_nAR|EPSW_FE),epsw
  225. nop
  226. nop
  227. add -4,sp
  228. SAVE_ALL
  229. mov -1,d0
  230. mov d0,(REG_ORIG_D0,fp)
  231. and ~EPSW_NMID,epsw
  232. mov fp,d0
  233. call fpu_disabled_in_kernel[],0
  234. jmp ret_from_exception
  235. .size fpu_disabled,.-fpu_disabled