~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/include/asm/hazards.h

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php