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