hazards.h 8.4 KB

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