PageRenderTime 56ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/arch/mips/include/asm/hazards.h

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