hazards.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  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) 2003, 04, 07 Ralf Baechle <ralf@linux-mips.org>
  7. * Copyright (C) MIPS Technologies, Inc.
  8. * written by Ralf Baechle <ralf@linux-mips.org>
  9. */
  10. #ifndef _ASM_HAZARDS_H
  11. #define _ASM_HAZARDS_H
  12. #include <linux/stringify.h>
  13. #include <asm/compiler.h>
  14. #define ___ssnop \
  15. sll $0, $0, 1
  16. #define ___ehb \
  17. sll $0, $0, 3
  18. /*
  19. * TLB hazards
  20. */
  21. #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) && !defined(CONFIG_CPU_CAVIUM_OCTEON)
  22. /*
  23. * MIPSR2 defines ehb for hazard avoidance
  24. */
  25. #define __mtc0_tlbw_hazard \
  26. ___ehb
  27. #define __tlbw_use_hazard \
  28. ___ehb
  29. #define __tlb_probe_hazard \
  30. ___ehb
  31. #define __irq_enable_hazard \
  32. ___ehb
  33. #define __irq_disable_hazard \
  34. ___ehb
  35. #define __back_to_back_c0_hazard \
  36. ___ehb
  37. /*
  38. * gcc has a tradition of misscompiling the previous construct using the
  39. * address of a label as argument to inline assembler. Gas otoh has the
  40. * annoying difference between la and dla which are only usable for 32-bit
  41. * rsp. 64-bit code, so can't be used without conditional compilation.
  42. * The alterantive is switching the assembler to 64-bit code which happens
  43. * to work right even for 32-bit code ...
  44. */
  45. #define instruction_hazard() \
  46. do { \
  47. unsigned long tmp; \
  48. \
  49. __asm__ __volatile__( \
  50. " .set "MIPS_ISA_LEVEL" \n" \
  51. " dla %0, 1f \n" \
  52. " jr.hb %0 \n" \
  53. " .set mips0 \n" \
  54. "1: \n" \
  55. : "=r" (tmp)); \
  56. } while (0)
  57. #elif (defined(CONFIG_CPU_MIPSR1) && !defined(CONFIG_MIPS_ALCHEMY)) || \
  58. defined(CONFIG_CPU_BMIPS)
  59. /*
  60. * These are slightly complicated by the fact that we guarantee R1 kernels to
  61. * run fine on R2 processors.
  62. */
  63. #define __mtc0_tlbw_hazard \
  64. ___ssnop; \
  65. ___ssnop; \
  66. ___ehb
  67. #define __tlbw_use_hazard \
  68. ___ssnop; \
  69. ___ssnop; \
  70. ___ssnop; \
  71. ___ehb
  72. #define __tlb_probe_hazard \
  73. ___ssnop; \
  74. ___ssnop; \
  75. ___ssnop; \
  76. ___ehb
  77. #define __irq_enable_hazard \
  78. ___ssnop; \
  79. ___ssnop; \
  80. ___ssnop; \
  81. ___ehb
  82. #define __irq_disable_hazard \
  83. ___ssnop; \
  84. ___ssnop; \
  85. ___ssnop; \
  86. ___ehb
  87. #define __back_to_back_c0_hazard \
  88. ___ssnop; \
  89. ___ssnop; \
  90. ___ssnop; \
  91. ___ehb
  92. /*
  93. * gcc has a tradition of misscompiling the previous construct using the
  94. * address of a label as argument to inline assembler. Gas otoh has the
  95. * annoying difference between la and dla which are only usable for 32-bit
  96. * rsp. 64-bit code, so can't be used without conditional compilation.
  97. * The alterantive is switching the assembler to 64-bit code which happens
  98. * to work right even for 32-bit code ...
  99. */
  100. #define __instruction_hazard() \
  101. do { \
  102. unsigned long tmp; \
  103. \
  104. __asm__ __volatile__( \
  105. " .set mips64r2 \n" \
  106. " dla %0, 1f \n" \
  107. " jr.hb %0 \n" \
  108. " .set mips0 \n" \
  109. "1: \n" \
  110. : "=r" (tmp)); \
  111. } while (0)
  112. #define instruction_hazard() \
  113. do { \
  114. if (cpu_has_mips_r2_r6) \
  115. __instruction_hazard(); \
  116. } while (0)
  117. #elif defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \
  118. defined(CONFIG_CPU_LOONGSON2) || defined(CONFIG_CPU_R10000) || \
  119. defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_XLR)
  120. /*
  121. * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.
  122. */
  123. #define __mtc0_tlbw_hazard
  124. #define __tlbw_use_hazard
  125. #define __tlb_probe_hazard
  126. #define __irq_enable_hazard
  127. #define __irq_disable_hazard
  128. #define __back_to_back_c0_hazard
  129. #define instruction_hazard() do { } while (0)
  130. #elif defined(CONFIG_CPU_SB1)
  131. /*
  132. * Mostly like R4000 for historic reasons
  133. */
  134. #define __mtc0_tlbw_hazard
  135. #define __tlbw_use_hazard
  136. #define __tlb_probe_hazard
  137. #define __irq_enable_hazard
  138. #define __irq_disable_hazard \
  139. ___ssnop; \
  140. ___ssnop; \
  141. ___ssnop
  142. #define __back_to_back_c0_hazard
  143. #define instruction_hazard() do { } while (0)
  144. #else
  145. /*
  146. * Finally the catchall case for all other processors including R4000, R4400,
  147. * R4600, R4700, R5000, RM7000, NEC VR41xx etc.
  148. *
  149. * The taken branch will result in a two cycle penalty for the two killed
  150. * instructions on R4000 / R4400. Other processors only have a single cycle
  151. * hazard so this is nice trick to have an optimal code for a range of
  152. * processors.
  153. */
  154. #define __mtc0_tlbw_hazard \
  155. nop; \
  156. nop
  157. #define __tlbw_use_hazard \
  158. nop; \
  159. nop; \
  160. nop
  161. #define __tlb_probe_hazard \
  162. nop; \
  163. nop; \
  164. nop
  165. #define __irq_enable_hazard \
  166. ___ssnop; \
  167. ___ssnop; \
  168. ___ssnop
  169. #define __irq_disable_hazard \
  170. nop; \
  171. nop; \
  172. nop
  173. #define __back_to_back_c0_hazard \
  174. ___ssnop; \
  175. ___ssnop; \
  176. ___ssnop
  177. #define instruction_hazard() do { } while (0)
  178. #endif
  179. /* FPU hazards */
  180. #if defined(CONFIG_CPU_SB1)
  181. #define __enable_fpu_hazard \
  182. .set push; \
  183. .set mips64; \
  184. .set noreorder; \
  185. ___ssnop; \
  186. bnezl $0, .+4; \
  187. ___ssnop; \
  188. .set pop
  189. #define __disable_fpu_hazard
  190. #elif defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
  191. #define __enable_fpu_hazard \
  192. ___ehb
  193. #define __disable_fpu_hazard \
  194. ___ehb
  195. #else
  196. #define __enable_fpu_hazard \
  197. nop; \
  198. nop; \
  199. nop; \
  200. nop
  201. #define __disable_fpu_hazard \
  202. ___ehb
  203. #endif
  204. #ifdef __ASSEMBLY__
  205. #define _ssnop ___ssnop
  206. #define _ehb ___ehb
  207. #define mtc0_tlbw_hazard __mtc0_tlbw_hazard
  208. #define tlbw_use_hazard __tlbw_use_hazard
  209. #define tlb_probe_hazard __tlb_probe_hazard
  210. #define irq_enable_hazard __irq_enable_hazard
  211. #define irq_disable_hazard __irq_disable_hazard
  212. #define back_to_back_c0_hazard __back_to_back_c0_hazard
  213. #define enable_fpu_hazard __enable_fpu_hazard
  214. #define disable_fpu_hazard __disable_fpu_hazard
  215. #else
  216. #define _ssnop() \
  217. do { \
  218. __asm__ __volatile__( \
  219. __stringify(___ssnop) \
  220. ); \
  221. } while (0)
  222. #define _ehb() \
  223. do { \
  224. __asm__ __volatile__( \
  225. __stringify(___ehb) \
  226. ); \
  227. } while (0)
  228. #define mtc0_tlbw_hazard() \
  229. do { \
  230. __asm__ __volatile__( \
  231. __stringify(__mtc0_tlbw_hazard) \
  232. ); \
  233. } while (0)
  234. #define tlbw_use_hazard() \
  235. do { \
  236. __asm__ __volatile__( \
  237. __stringify(__tlbw_use_hazard) \
  238. ); \
  239. } while (0)
  240. #define tlb_probe_hazard() \
  241. do { \
  242. __asm__ __volatile__( \
  243. __stringify(__tlb_probe_hazard) \
  244. ); \
  245. } while (0)
  246. #define irq_enable_hazard() \
  247. do { \
  248. __asm__ __volatile__( \
  249. __stringify(__irq_enable_hazard) \
  250. ); \
  251. } while (0)
  252. #define irq_disable_hazard() \
  253. do { \
  254. __asm__ __volatile__( \
  255. __stringify(__irq_disable_hazard) \
  256. ); \
  257. } while (0)
  258. #define back_to_back_c0_hazard() \
  259. do { \
  260. __asm__ __volatile__( \
  261. __stringify(__back_to_back_c0_hazard) \
  262. ); \
  263. } while (0)
  264. #define enable_fpu_hazard() \
  265. do { \
  266. __asm__ __volatile__( \
  267. __stringify(__enable_fpu_hazard) \
  268. ); \
  269. } while (0)
  270. #define disable_fpu_hazard() \
  271. do { \
  272. __asm__ __volatile__( \
  273. __stringify(__disable_fpu_hazard) \
  274. ); \
  275. } while (0)
  276. /*
  277. * MIPS R2 instruction hazard barrier. Needs to be called as a subroutine.
  278. */
  279. extern void mips_ihb(void);
  280. #endif /* __ASSEMBLY__ */
  281. #endif /* _ASM_HAZARDS_H */