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) 1994, 1995, 1996, 1997, 2000, 2001 by Ralf Baechle
7 * Copyright (C) 2000 Silicon Graphics, Inc.
8 * Modified for further R[236]000 support by Paul M. Antoine, 1996.
9 * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
10 * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
11 * Copyright (C) 2003, 2004  Maciej W. Rozycki
12 */
13#ifndef _ASM_MIPSREGS_H
14#define _ASM_MIPSREGS_H
15
16#include <linux/linkage.h>
17#include <asm/hazards.h>
18
19/*
20 * The following macros are especially useful for __asm__
21 * inline assembler.
22 */
23#ifndef __STR
24#define __STR(x) #x
25#endif
26#ifndef STR
27#define STR(x) __STR(x)
28#endif
29
30/*
31 *  Configure language
32 */
33#ifdef __ASSEMBLY__
34#define _ULCAST_
35#else
36#define _ULCAST_ (unsigned long)
37#endif
38
39/*
40 * Coprocessor 0 register names
41 */
42#define CP0_INDEX $0
43#define CP0_RANDOM $1
44#define CP0_ENTRYLO0 $2
45#define CP0_ENTRYLO1 $3
46#define CP0_CONF $3
47#define CP0_CONTEXT $4
48#define CP0_PAGEMASK $5
49#define CP0_WIRED $6
50#define CP0_INFO $7
51#define CP0_BADVADDR $8
52#define CP0_COUNT $9
53#define CP0_ENTRYHI $10
54#define CP0_COMPARE $11
55#define CP0_STATUS $12
56#define CP0_CAUSE $13
57#define CP0_EPC $14
58#define CP0_PRID $15
59#define CP0_CONFIG $16
60#define CP0_LLADDR $17
61#define CP0_WATCHLO $18
62#define CP0_WATCHHI $19
63#define CP0_XCONTEXT $20
64#define CP0_FRAMEMASK $21
65#define CP0_DIAGNOSTIC $22
66#define CP0_DEBUG $23
67#define CP0_DEPC $24
68#define CP0_PERFORMANCE $25
69#define CP0_ECC $26
70#define CP0_CACHEERR $27
71#define CP0_TAGLO $28
72#define CP0_TAGHI $29
73#define CP0_ERROREPC $30
74#define CP0_DESAVE $31
75
76/*
77 * R4640/R4650 cp0 register names.  These registers are listed
78 * here only for completeness; without MMU these CPUs are not useable
79 * by Linux.  A future ELKS port might take make Linux run on them
80 * though ...
81 */
82#define CP0_IBASE $0
83#define CP0_IBOUND $1
84#define CP0_DBASE $2
85#define CP0_DBOUND $3
86#define CP0_CALG $17
87#define CP0_IWATCH $18
88#define CP0_DWATCH $19
89
90/*
91 * Coprocessor 0 Set 1 register names
92 */
93#define CP0_S1_DERRADDR0  $26
94#define CP0_S1_DERRADDR1  $27
95#define CP0_S1_INTCONTROL $20
96
97/*
98 * Coprocessor 0 Set 2 register names
99 */
100#define CP0_S2_SRSCTL	  $12	/* MIPSR2 */
101
102/*
103 * Coprocessor 0 Set 3 register names
104 */
105#define CP0_S3_SRSMAP	  $12	/* MIPSR2 */
106
107/*
108 *  TX39 Series
109 */
110#define CP0_TX39_CACHE	$7
111
112/*
113 * Coprocessor 1 (FPU) register names
114 */
115#define CP1_REVISION   $0
116#define CP1_STATUS     $31
117
118/*
119 * FPU Status Register Values
120 */
121/*
122 * Status Register Values
123 */
124
125#define FPU_CSR_FLUSH   0x01000000      /* flush denormalised results to 0 */
126#define FPU_CSR_COND    0x00800000      /* $fcc0 */
127#define FPU_CSR_COND0   0x00800000      /* $fcc0 */
128#define FPU_CSR_COND1   0x02000000      /* $fcc1 */
129#define FPU_CSR_COND2   0x04000000      /* $fcc2 */
130#define FPU_CSR_COND3   0x08000000      /* $fcc3 */
131#define FPU_CSR_COND4   0x10000000      /* $fcc4 */
132#define FPU_CSR_COND5   0x20000000      /* $fcc5 */
133#define FPU_CSR_COND6   0x40000000      /* $fcc6 */
134#define FPU_CSR_COND7   0x80000000      /* $fcc7 */
135
136/*
137 * X the exception cause indicator
138 * E the exception enable
139 * S the sticky/flag bit
140*/
141#define FPU_CSR_ALL_X   0x0003f000
142#define FPU_CSR_UNI_X   0x00020000
143#define FPU_CSR_INV_X   0x00010000
144#define FPU_CSR_DIV_X   0x00008000
145#define FPU_CSR_OVF_X   0x00004000
146#define FPU_CSR_UDF_X   0x00002000
147#define FPU_CSR_INE_X   0x00001000
148
149#define FPU_CSR_ALL_E   0x00000f80
150#define FPU_CSR_INV_E   0x00000800
151#define FPU_CSR_DIV_E   0x00000400
152#define FPU_CSR_OVF_E   0x00000200
153#define FPU_CSR_UDF_E   0x00000100
154#define FPU_CSR_INE_E   0x00000080
155
156#define FPU_CSR_ALL_S   0x0000007c
157#define FPU_CSR_INV_S   0x00000040
158#define FPU_CSR_DIV_S   0x00000020
159#define FPU_CSR_OVF_S   0x00000010
160#define FPU_CSR_UDF_S   0x00000008
161#define FPU_CSR_INE_S   0x00000004
162
163/* rounding mode */
164#define FPU_CSR_RN      0x0     /* nearest */
165#define FPU_CSR_RZ      0x1     /* towards zero */
166#define FPU_CSR_RU      0x2     /* towards +Infinity */
167#define FPU_CSR_RD      0x3     /* towards -Infinity */
168
169
170/*
171 * Values for PageMask register
172 */
173#ifdef CONFIG_CPU_VR41XX
174
175/* Why doesn't stupidity hurt ... */
176
177#define PM_1K		0x00000000
178#define PM_4K		0x00001800
179#define PM_16K		0x00007800
180#define PM_64K		0x0001f800
181#define PM_256K		0x0007f800
182
183#else
184
185#define PM_4K		0x00000000
186#define PM_16K		0x00006000
187#define PM_64K		0x0001e000
188#define PM_256K		0x0007e000
189#define PM_1M		0x001fe000
190#define PM_4M		0x007fe000
191#define PM_16M		0x01ffe000
192#define PM_64M		0x07ffe000
193#define PM_256M		0x1fffe000
194
195#endif
196
197/*
198 * Default page size for a given kernel configuration
199 */
200#ifdef CONFIG_PAGE_SIZE_4KB
201#define PM_DEFAULT_MASK	PM_4K
202#elif defined(CONFIG_PAGE_SIZE_16KB)
203#define PM_DEFAULT_MASK	PM_16K
204#elif defined(CONFIG_PAGE_SIZE_64KB)
205#define PM_DEFAULT_MASK	PM_64K
206#else
207#error Bad page size configuration!
208#endif
209
210
211/*
212 * Values used for computation of new tlb entries
213 */
214#define PL_4K		12
215#define PL_16K		14
216#define PL_64K		16
217#define PL_256K		18
218#define PL_1M		20
219#define PL_4M		22
220#define PL_16M		24
221#define PL_64M		26
222#define PL_256M		28
223
224/*
225 * R4x00 interrupt enable / cause bits
226 */
227#define IE_SW0          (_ULCAST_(1) <<  8)
228#define IE_SW1          (_ULCAST_(1) <<  9)
229#define IE_IRQ0         (_ULCAST_(1) << 10)
230#define IE_IRQ1         (_ULCAST_(1) << 11)
231#define IE_IRQ2         (_ULCAST_(1) << 12)
232#define IE_IRQ3         (_ULCAST_(1) << 13)
233#define IE_IRQ4         (_ULCAST_(1) << 14)
234#define IE_IRQ5         (_ULCAST_(1) << 15)
235
236/*
237 * R4x00 interrupt cause bits
238 */
239#define C_SW0           (_ULCAST_(1) <<  8)
240#define C_SW1           (_ULCAST_(1) <<  9)
241#define C_IRQ0          (_ULCAST_(1) << 10)
242#define C_IRQ1          (_ULCAST_(1) << 11)
243#define C_IRQ2          (_ULCAST_(1) << 12)
244#define C_IRQ3          (_ULCAST_(1) << 13)
245#define C_IRQ4          (_ULCAST_(1) << 14)
246#define C_IRQ5          (_ULCAST_(1) << 15)
247
248/*
249 * Bitfields in the R4xx0 cp0 status register
250 */
251#define ST0_IE			0x00000001
252#define ST0_EXL			0x00000002
253#define ST0_ERL			0x00000004
254#define ST0_KSU			0x00000018
255#  define KSU_USER		0x00000010
256#  define KSU_SUPERVISOR	0x00000008
257#  define KSU_KERNEL		0x00000000
258#define ST0_UX			0x00000020
259#define ST0_SX			0x00000040
260#define ST0_KX 			0x00000080
261#define ST0_DE			0x00010000
262#define ST0_CE			0x00020000
263
264/*
265 * Setting c0_status.co enables Hit_Writeback and Hit_Writeback_Invalidate
266 * cacheops in userspace.  This bit exists only on RM7000 and RM9000
267 * processors.
268 */
269#define ST0_CO			0x08000000
270
271/*
272 * Bitfields in the R[23]000 cp0 status register.
273 */
274#define ST0_IEC                 0x00000001
275#define ST0_KUC			0x00000002
276#define ST0_IEP			0x00000004
277#define ST0_KUP			0x00000008
278#define ST0_IEO			0x00000010
279#define ST0_KUO			0x00000020
280/* bits 6 & 7 are reserved on R[23]000 */
281#define ST0_ISC			0x00010000
282#define ST0_SWC			0x00020000
283#define ST0_CM			0x00080000
284
285/*
286 * Bits specific to the R4640/R4650
287 */
288#define ST0_UM			(_ULCAST_(1) <<  4)
289#define ST0_IL			(_ULCAST_(1) << 23)
290#define ST0_DL			(_ULCAST_(1) << 24)
291
292/*
293 * Enable the MIPS MDMX and DSP ASEs
294 */
295#define ST0_MX			0x01000000
296
297/*
298 * Bitfields in the TX39 family CP0 Configuration Register 3
299 */
300#define TX39_CONF_ICS_SHIFT	19
301#define TX39_CONF_ICS_MASK	0x00380000
302#define TX39_CONF_ICS_1KB 	0x00000000
303#define TX39_CONF_ICS_2KB 	0x00080000
304#define TX39_CONF_ICS_4KB 	0x00100000
305#define TX39_CONF_ICS_8KB 	0x00180000
306#define TX39_CONF_ICS_16KB 	0x00200000
307
308#define TX39_CONF_DCS_SHIFT	16
309#define TX39_CONF_DCS_MASK	0x00070000
310#define TX39_CONF_DCS_1KB 	0x00000000
311#define TX39_CONF_DCS_2KB 	0x00010000
312#define TX39_CONF_DCS_4KB 	0x00020000
313#define TX39_CONF_DCS_8KB 	0x00030000
314#define TX39_CONF_DCS_16KB 	0x00040000
315
316#define TX39_CONF_CWFON 	0x00004000
317#define TX39_CONF_WBON  	0x00002000
318#define TX39_CONF_RF_SHIFT	10
319#define TX39_CONF_RF_MASK	0x00000c00
320#define TX39_CONF_DOZE		0x00000200
321#define TX39_CONF_HALT		0x00000100
322#define TX39_CONF_LOCK		0x00000080
323#define TX39_CONF_ICE		0x00000020
324#define TX39_CONF_DCE		0x00000010
325#define TX39_CONF_IRSIZE_SHIFT	2
326#define TX39_CONF_IRSIZE_MASK	0x0000000c
327#define TX39_CONF_DRSIZE_SHIFT	0
328#define TX39_CONF_DRSIZE_MASK	0x00000003
329
330/*
331 * Status register bits available in all MIPS CPUs.
332 */
333#define ST0_IM			0x0000ff00
334#define  STATUSB_IP0		8
335#define  STATUSF_IP0		(_ULCAST_(1) <<  8)
336#define  STATUSB_IP1		9
337#define  STATUSF_IP1		(_ULCAST_(1) <<  9)
338#define  STATUSB_IP2		10
339#define  STATUSF_IP2		(_ULCAST_(1) << 10)
340#define  STATUSB_IP3		11
341#define  STATUSF_IP3		(_ULCAST_(1) << 11)
342#define  STATUSB_IP4		12
343#define  STATUSF_IP4		(_ULCAST_(1) << 12)
344#define  STATUSB_IP5		13
345#define  STATUSF_IP5		(_ULCAST_(1) << 13)
346#define  STATUSB_IP6		14
347#define  STATUSF_IP6		(_ULCAST_(1) << 14)
348#define  STATUSB_IP7		15
349#define  STATUSF_IP7		(_ULCAST_(1) << 15)
350#define  STATUSB_IP8		0
351#define  STATUSF_IP8		(_ULCAST_(1) <<  0)
352#define  STATUSB_IP9		1
353#define  STATUSF_IP9		(_ULCAST_(1) <<  1)
354#define  STATUSB_IP10		2
355#define  STATUSF_IP10		(_ULCAST_(1) <<  2)
356#define  STATUSB_IP11		3
357#define  STATUSF_IP11		(_ULCAST_(1) <<  3)
358#define  STATUSB_IP12		4
359#define  STATUSF_IP12		(_ULCAST_(1) <<  4)
360#define  STATUSB_IP13		5
361#define  STATUSF_IP13		(_ULCAST_(1) <<  5)
362#define  STATUSB_IP14		6
363#define  STATUSF_IP14		(_ULCAST_(1) <<  6)
364#define  STATUSB_IP15		7
365#define  STATUSF_IP15		(_ULCAST_(1) <<  7)
366#define ST0_CH			0x00040000
367#define ST0_SR			0x00100000
368#define ST0_TS			0x00200000
369#define ST0_BEV			0x00400000
370#define ST0_RE			0x02000000
371#define ST0_FR			0x04000000
372#define ST0_CU			0xf0000000
373#define ST0_CU0			0x10000000
374#define ST0_CU1			0x20000000
375#define ST0_CU2			0x40000000
376#define ST0_CU3			0x80000000
377#define ST0_XX			0x80000000	/* MIPS IV naming */
378
379/*
380 * Bitfields and bit numbers in the coprocessor 0 cause register.
381 *
382 * Refer to your MIPS R4xx0 manual, chapter 5 for explanation.
383 */
384#define  CAUSEB_EXCCODE		2
385#define  CAUSEF_EXCCODE		(_ULCAST_(31)  <<  2)
386#define  CAUSEB_IP		8
387#define  CAUSEF_IP		(_ULCAST_(255) <<  8)
388#define  CAUSEB_IP0		8
389#define  CAUSEF_IP0		(_ULCAST_(1)   <<  8)
390#define  CAUSEB_IP1		9
391#define  CAUSEF_IP1		(_ULCAST_(1)   <<  9)
392#define  CAUSEB_IP2		10
393#define  CAUSEF_IP2		(_ULCAST_(1)   << 10)
394#define  CAUSEB_IP3		11
395#define  CAUSEF_IP3		(_ULCAST_(1)   << 11)
396#define  CAUSEB_IP4		12
397#define  CAUSEF_IP4		(_ULCAST_(1)   << 12)
398#define  CAUSEB_IP5		13
399#define  CAUSEF_IP5		(_ULCAST_(1)   << 13)
400#define  CAUSEB_IP6		14
401#define  CAUSEF_IP6		(_ULCAST_(1)   << 14)
402#define  CAUSEB_IP7		15
403#define  CAUSEF_IP7		(_ULCAST_(1)   << 15)
404#define  CAUSEB_IV		23
405#define  CAUSEF_IV		(_ULCAST_(1)   << 23)
406#define  CAUSEB_CE		28
407#define  CAUSEF_CE		(_ULCAST_(3)   << 28)
408#define  CAUSEB_BD		31
409#define  CAUSEF_BD		(_ULCAST_(1)   << 31)
410
411/*
412 * Bits in the coprocessor 0 config register.
413 */
414/* Generic bits.  */
415#define CONF_CM_CACHABLE_NO_WA		0
416#define CONF_CM_CACHABLE_WA		1
417#define CONF_CM_UNCACHED		2
418#define CONF_CM_CACHABLE_NONCOHERENT	3
419#define CONF_CM_CACHABLE_CE		4
420#define CONF_CM_CACHABLE_COW		5
421#define CONF_CM_CACHABLE_CUW		6
422#define CONF_CM_CACHABLE_ACCELERATED	7
423#define CONF_CM_CMASK			7
424#define CONF_BE			(_ULCAST_(1) << 15)
425
426/* Bits common to various processors.  */
427#define CONF_CU			(_ULCAST_(1) <<  3)
428#define CONF_DB			(_ULCAST_(1) <<  4)
429#define CONF_IB			(_ULCAST_(1) <<  5)
430#define CONF_DC			(_ULCAST_(7) <<  6)
431#define CONF_IC			(_ULCAST_(7) <<  9)
432#define CONF_EB			(_ULCAST_(1) << 13)
433#define CONF_EM			(_ULCAST_(1) << 14)
434#define CONF_SM			(_ULCAST_(1) << 16)
435#define CONF_SC			(_ULCAST_(1) << 17)
436#define CONF_EW			(_ULCAST_(3) << 18)
437#define CONF_EP			(_ULCAST_(15)<< 24)
438#define CONF_EC			(_ULCAST_(7) << 28)
439#define CONF_CM			(_ULCAST_(1) << 31)
440
441/* Bits specific to the R4xx0.  */
442#define R4K_CONF_SW		(_ULCAST_(1) << 20)
443#define R4K_CONF_SS		(_ULCAST_(1) << 21)
444#define R4K_CONF_SB		(_ULCAST_(3) << 22)
445
446/* Bits specific to the R5000.  */
447#define R5K_CONF_SE		(_ULCAST_(1) << 12)
448#define R5K_CONF_SS		(_ULCAST_(3) << 20)
449
450/* Bits specific to the RM7000.  */
451#define RM7K_CONF_SE		(_ULCAST_(1) <<  3)
452#define RM7K_CONF_TE		(_ULCAST_(1) << 12)
453#define RM7K_CONF_CLK		(_ULCAST_(1) << 16)
454#define RM7K_CONF_TC		(_ULCAST_(1) << 17)
455#define RM7K_CONF_SI		(_ULCAST_(3) << 20)
456#define RM7K_CONF_SC		(_ULCAST_(1) << 31)
457
458/* Bits specific to the R10000.  */
459#define R10K_CONF_DN		(_ULCAST_(3) <<  3)
460#define R10K_CONF_CT		(_ULCAST_(1) <<  5)
461#define R10K_CONF_PE		(_ULCAST_(1) <<  6)
462#define R10K_CONF_PM		(_ULCAST_(3) <<  7)
463#define R10K_CONF_EC		(_ULCAST_(15)<<  9)
464#define R10K_CONF_SB		(_ULCAST_(1) << 13)
465#define R10K_CONF_SK		(_ULCAST_(1) << 14)
466#define R10K_CONF_SS		(_ULCAST_(7) << 16)
467#define R10K_CONF_SC		(_ULCAST_(7) << 19)
468#define R10K_CONF_DC		(_ULCAST_(7) << 26)
469#define R10K_CONF_IC		(_ULCAST_(7) << 29)
470
471/* Bits specific to the VR41xx.  */
472#define VR41_CONF_CS		(_ULCAST_(1) << 12)
473#define VR41_CONF_P4K		(_ULCAST_(1) << 13)
474#define VR41_CONF_BP		(_ULCAST_(1) << 16)
475#define VR41_CONF_M16		(_ULCAST_(1) << 20)
476#define VR41_CONF_AD		(_ULCAST_(1) << 23)
477
478/* Bits specific to the R30xx.  */
479#define R30XX_CONF_FDM		(_ULCAST_(1) << 19)
480#define R30XX_CONF_REV		(_ULCAST_(1) << 22)
481#define R30XX_CONF_AC		(_ULCAST_(1) << 23)
482#define R30XX_CONF_RF		(_ULCAST_(1) << 24)
483#define R30XX_CONF_HALT		(_ULCAST_(1) << 25)
484#define R30XX_CONF_FPINT	(_ULCAST_(7) << 26)
485#define R30XX_CONF_DBR		(_ULCAST_(1) << 29)
486#define R30XX_CONF_SB		(_ULCAST_(1) << 30)
487#define R30XX_CONF_LOCK		(_ULCAST_(1) << 31)
488
489/* Bits specific to the TX49.  */
490#define TX49_CONF_DC		(_ULCAST_(1) << 16)
491#define TX49_CONF_IC		(_ULCAST_(1) << 17)  /* conflict with CONF_SC */
492#define TX49_CONF_HALT		(_ULCAST_(1) << 18)
493#define TX49_CONF_CWFON		(_ULCAST_(1) << 27)
494
495/* Bits specific to the MIPS32/64 PRA.  */
496#define MIPS_CONF_MT		(_ULCAST_(7) <<  7)
497#define MIPS_CONF_AR		(_ULCAST_(7) << 10)
498#define MIPS_CONF_AT		(_ULCAST_(3) << 13)
499#define MIPS_CONF_M		(_ULCAST_(1) << 31)
500
501/*
502 * Bits in the MIPS32/64 PRA coprocessor 0 config registers 1 and above.
503 */
504#define MIPS_CONF1_FP		(_ULCAST_(1) <<  0)
505#define MIPS_CONF1_EP		(_ULCAST_(1) <<  1)
506#define MIPS_CONF1_CA		(_ULCAST_(1) <<  2)
507#define MIPS_CONF1_WR		(_ULCAST_(1) <<  3)
508#define MIPS_CONF1_PC		(_ULCAST_(1) <<  4)
509#define MIPS_CONF1_MD		(_ULCAST_(1) <<  5)
510#define MIPS_CONF1_C2		(_ULCAST_(1) <<  6)
511#define MIPS_CONF1_DA		(_ULCAST_(7) <<  7)
512#define MIPS_CONF1_DL		(_ULCAST_(7) << 10)
513#define MIPS_CONF1_DS		(_ULCAST_(7) << 13)
514#define MIPS_CONF1_IA		(_ULCAST_(7) << 16)
515#define MIPS_CONF1_IL		(_ULCAST_(7) << 19)
516#define MIPS_CONF1_IS		(_ULCAST_(7) << 22)
517#define MIPS_CONF1_TLBS		(_ULCAST_(63)<< 25)
518
519#define MIPS_CONF2_SA		(_ULCAST_(15)<<  0)
520#define MIPS_CONF2_SL		(_ULCAST_(15)<<  4)
521#define MIPS_CONF2_SS		(_ULCAST_(15)<<  8)
522#define MIPS_CONF2_SU		(_ULCAST_(15)<< 12)
523#define MIPS_CONF2_TA		(_ULCAST_(15)<< 16)
524#define MIPS_CONF2_TL		(_ULCAST_(15)<< 20)
525#define MIPS_CONF2_TS		(_ULCAST_(15)<< 24)
526#define MIPS_CONF2_TU		(_ULCAST_(7) << 28)
527
528#define MIPS_CONF3_TL		(_ULCAST_(1) <<  0)
529#define MIPS_CONF3_SM		(_ULCAST_(1) <<  1)
530#define MIPS_CONF3_MT		(_ULCAST_(1) <<  2)
531#define MIPS_CONF3_SP		(_ULCAST_(1) <<  4)
532#define MIPS_CONF3_VINT		(_ULCAST_(1) <<  5)
533#define MIPS_CONF3_VEIC		(_ULCAST_(1) <<  6)
534#define MIPS_CONF3_LPA		(_ULCAST_(1) <<  7)
535#define MIPS_CONF3_DSP		(_ULCAST_(1) << 10)
536
537#define MIPS_CONF7_WII		(_ULCAST_(1) << 31)
538
539/*
540 * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register.
541 */
542#define MIPS_FPIR_S		(_ULCAST_(1) << 16)
543#define MIPS_FPIR_D		(_ULCAST_(1) << 17)
544#define MIPS_FPIR_PS		(_ULCAST_(1) << 18)
545#define MIPS_FPIR_3D		(_ULCAST_(1) << 19)
546#define MIPS_FPIR_W		(_ULCAST_(1) << 20)
547#define MIPS_FPIR_L		(_ULCAST_(1) << 21)
548#define MIPS_FPIR_F64		(_ULCAST_(1) << 22)
549
550#ifndef __ASSEMBLY__
551
552/*
553 * Functions to access the R10000 performance counters.  These are basically
554 * mfc0 and mtc0 instructions from and to coprocessor register with a 5-bit
555 * performance counter number encoded into bits 1 ... 5 of the instruction.
556 * Only performance counters 0 to 1 actually exist, so for a non-R10000 aware
557 * disassembler these will look like an access to sel 0 or 1.
558 */
559#define read_r10k_perf_cntr(counter)				\
560({								\
561	unsigned int __res;					\
562	__asm__ __volatile__(					\
563	"mfpc\t%0, %1"						\
564        : "=r" (__res)						\
565	: "i" (counter));					\
566								\
567        __res;							\
568})
569
570#define write_r10k_perf_cntr(counter,val)                       \
571do {								\
572	__asm__ __volatile__(					\
573	"mtpc\t%0, %1"						\
574	:							\
575	: "r" (val), "i" (counter));				\
576} while (0)
577
578#define read_r10k_perf_event(counter)				\
579({								\
580	unsigned int __res;					\
581	__asm__ __volatile__(					\
582	"mfps\t%0, %1"						\
583        : "=r" (__res)						\
584	: "i" (counter));					\
585								\
586        __res;							\
587})
588
589#define write_r10k_perf_cntl(counter,val)                       \
590do {								\
591	__asm__ __volatile__(					\
592	"mtps\t%0, %1"						\
593	:							\
594	: "r" (val), "i" (counter));				\
595} while (0)
596
597
598/*
599 * Macros to access the system control coprocessor
600 */
601
602#define __read_32bit_c0_register(source, sel)				\
603({ int __res;								\
604	if (sel == 0)							\
605		__asm__ __volatile__(					\
606			"mfc0\t%0, " #source "\n\t"			\
607			: "=r" (__res));				\
608	else								\
609		__asm__ __volatile__(					\
610			".set\tmips32\n\t"				\
611			"mfc0\t%0, " #source ", " #sel "\n\t"		\
612			".set\tmips0\n\t"				\
613			: "=r" (__res));				\
614	__res;								\
615})
616
617#define __read_64bit_c0_register(source, sel)				\
618({ unsigned long long __res;						\
619	if (sizeof(unsigned long) == 4)					\
620		__res = __read_64bit_c0_split(source, sel);		\
621	else if (sel == 0)						\
622		__asm__ __volatile__(					\
623			".set\tmips3\n\t"				\
624			"dmfc0\t%0, " #source "\n\t"			\
625			".set\tmips0"					\
626			: "=r" (__res));				\
627	else								\
628		__asm__ __volatile__(					\
629			".set\tmips64\n\t"				\
630			"dmfc0\t%0, " #source ", " #sel "\n\t"		\
631			".set\tmips0"					\
632			: "=r" (__res));				\
633	__res;								\
634})
635
636#define __write_32bit_c0_register(register, sel, value)			\
637do {									\
638	if (sel == 0)							\
639		__asm__ __volatile__(					\
640			"mtc0\t%z0, " #register "\n\t"			\
641			: : "Jr" ((unsigned int)(value)));		\
642	else								\
643		__asm__ __volatile__(					\
644			".set\tmips32\n\t"				\
645			"mtc0\t%z0, " #register ", " #sel "\n\t"	\
646			".set\tmips0"					\
647			: : "Jr" ((unsigned int)(value)));		\
648} while (0)
649
650#define __write_64bit_c0_register(register, sel, value)			\
651do {									\
652	if (sizeof(unsigned long) == 4)					\
653		__write_64bit_c0_split(register, sel, value);		\
654	else if (sel == 0)						\
655		__asm__ __volatile__(					\
656			".set\tmips3\n\t"				\
657			"dmtc0\t%z0, " #register "\n\t"			\
658			".set\tmips0"					\
659			: : "Jr" (value));				\
660	else								\
661		__asm__ __volatile__(					\
662			".set\tmips64\n\t"				\
663			"dmtc0\t%z0, " #register ", " #sel "\n\t"	\
664			".set\tmips0"					\
665			: : "Jr" (value));				\
666} while (0)
667
668#define __read_ulong_c0_register(reg, sel)				\
669	((sizeof(unsigned long) == 4) ?					\
670	(unsigned long) __read_32bit_c0_register(reg, sel) :		\
671	(unsigned long) __read_64bit_c0_register(reg, sel))
672
673#define __write_ulong_c0_register(reg, sel, val)			\
674do {									\
675	if (sizeof(unsigned long) == 4)					\
676		__write_32bit_c0_register(reg, sel, val);		\
677	else								\
678		__write_64bit_c0_register(reg, sel, val);		\
679} while (0)
680
681/*
682 * On RM7000/RM9000 these are uses to access cop0 set 1 registers
683 */
684#define __read_32bit_c0_ctrl_register(source)				\
685({ int __res;								\
686	__asm__ __volatile__(						\
687		"cfc0\t%0, " #source "\n\t"				\
688		: "=r" (__res));					\
689	__res;								\
690})
691
692#define __write_32bit_c0_ctrl_register(register, value)			\
693do {									\
694	__asm__ __volatile__(						\
695		"ctc0\t%z0, " #register "\n\t"				\
696		: : "Jr" ((unsigned int)(value)));			\
697} while (0)
698
699/*
700 * These versions are only needed for systems with more than 38 bits of
701 * physical address space running the 32-bit kernel.  That's none atm :-)
702 */
703#define __read_64bit_c0_split(source, sel)				\
704({									\
705	unsigned long long val;						\
706	unsigned long flags;						\
707									\
708	local_irq_save(flags);						\
709	if (sel == 0)							\
710		__asm__ __volatile__(					\
711			".set\tmips64\n\t"				\
712			"dmfc0\t%M0, " #source "\n\t"			\
713			"dsll\t%L0, %M0, 32\n\t"			\
714			"dsrl\t%M0, %M0, 32\n\t"			\
715			"dsrl\t%L0, %L0, 32\n\t"			\
716			".set\tmips0"					\
717			: "=r" (val));					\
718	else								\
719		__asm__ __volatile__(					\
720			".set\tmips64\n\t"				\
721			"dmfc0\t%M0, " #source ", " #sel "\n\t"		\
722			"dsll\t%L0, %M0, 32\n\t"			\
723			"dsrl\t%M0, %M0, 32\n\t"			\
724			"dsrl\t%L0, %L0, 32\n\t"			\
725			".set\tmips0"					\
726			: "=r" (val));					\
727	local_irq_restore(flags);					\
728									\
729	val;								\
730})
731
732#define __write_64bit_c0_split(source, sel, val)			\
733do {									\
734	unsigned long flags;						\
735									\
736	local_irq_save(flags);						\
737	if (sel == 0)							\
738		__asm__ __volatile__(					\
739			".set\tmips64\n\t"				\
740			"dsll\t%L0, %L0, 32\n\t"			\
741			"dsrl\t%L0, %L0, 32\n\t"			\
742			"dsll\t%M0, %M0, 32\n\t"			\
743			"or\t%L0, %L0, %M0\n\t"				\
744			"dmtc0\t%L0, " #source "\n\t"			\
745			".set\tmips0"					\
746			: : "r" (val));					\
747	else								\
748		__asm__ __volatile__(					\
749			".set\tmips64\n\t"				\
750			"dsll\t%L0, %L0, 32\n\t"			\
751			"dsrl\t%L0, %L0, 32\n\t"			\
752			"dsll\t%M0, %M0, 32\n\t"			\
753			"or\t%L0, %L0, %M0\n\t"				\
754			"dmtc0\t%L0, " #source ", " #sel "\n\t"		\
755			".set\tmips0"					\
756			: : "r" (val));					\
757	local_irq_restore(flags);					\
758} while (0)
759
760#define read_c0_index()		__read_32bit_c0_register($0, 0)
761#define write_c0_index(val)	__write_32bit_c0_register($0, 0, val)
762
763#define read_c0_entrylo0()	__read_ulong_c0_register($2, 0)
764#define write_c0_entrylo0(val)	__write_ulong_c0_register($2, 0, val)
765
766#define read_c0_entrylo1()	__read_ulong_c0_register($3, 0)
767#define write_c0_entrylo1(val)	__write_ulong_c0_register($3, 0, val)
768
769#define read_c0_conf()		__read_32bit_c0_register($3, 0)
770#define write_c0_conf(val)	__write_32bit_c0_register($3, 0, val)
771
772#define read_c0_context()	__read_ulong_c0_register($4, 0)
773#define write_c0_context(val)	__write_ulong_c0_register($4, 0, val)
774
775#define read_c0_pagemask()	__read_32bit_c0_register($5, 0)
776#define write_c0_pagemask(val)	__write_32bit_c0_register($5, 0, val)
777
778#define read_c0_wired()		__read_32bit_c0_register($6, 0)
779#define write_c0_wired(val)	__write_32bit_c0_register($6, 0, val)
780
781#define read_c0_info()		__read_32bit_c0_register($7, 0)
782
783#define read_c0_cache()		__read_32bit_c0_register($7, 0)	/* TX39xx */
784#define write_c0_cache(val)	__write_32bit_c0_register($7, 0, val)
785
786#define read_c0_badvaddr()	__read_ulong_c0_register($8, 0)
787#define write_c0_badvaddr(val)	__write_ulong_c0_register($8, 0, val)
788
789#define read_c0_count()		__read_32bit_c0_register($9, 0)
790#define write_c0_count(val)	__write_32bit_c0_register($9, 0, val)
791
792#define read_c0_count2()	__read_32bit_c0_register($9, 6) /* pnx8550 */
793#define write_c0_count2(val)	__write_32bit_c0_register($9, 6, val)
794
795#define read_c0_count3()	__read_32bit_c0_register($9, 7) /* pnx8550 */
796#define write_c0_count3(val)	__write_32bit_c0_register($9, 7, val)
797
798#define read_c0_entryhi()	__read_ulong_c0_register($10, 0)
799#define write_c0_entryhi(val)	__write_ulong_c0_register($10, 0, val)
800
801#define read_c0_compare()	__read_32bit_c0_register($11, 0)
802#define write_c0_compare(val)	__write_32bit_c0_register($11, 0, val)
803
804#define read_c0_compare2()	__read_32bit_c0_register($11, 6) /* pnx8550 */
805#define write_c0_compare2(val)	__write_32bit_c0_register($11, 6, val)
806
807#define read_c0_compare3()	__read_32bit_c0_register($11, 7) /* pnx8550 */
808#define write_c0_compare3(val)	__write_32bit_c0_register($11, 7, val)
809
810#define read_c0_status()	__read_32bit_c0_register($12, 0)
811#ifdef CONFIG_MIPS_MT_SMTC
812#define write_c0_status(val)						\
813do {									\
814	__write_32bit_c0_register($12, 0, val);				\
815	__ehb();							\
816} while (0)
817#else
818/*
819 * Legacy non-SMTC code, which may be hazardous
820 * but which might not support EHB
821 */
822#define write_c0_status(val)	__write_32bit_c0_register($12, 0, val)
823#endif /* CONFIG_MIPS_MT_SMTC */
824
825#define read_c0_cause()		__read_32bit_c0_register($13, 0)
826#define write_c0_cause(val)	__write_32bit_c0_register($13, 0, val)
827
828#define read_c0_epc()		__read_ulong_c0_register($14, 0)
829#define write_c0_epc(val)	__write_ulong_c0_register($14, 0, val)
830
831#define read_c0_prid()		__read_32bit_c0_register($15, 0)
832
833#define read_c0_config()	__read_32bit_c0_register($16, 0)
834#define read_c0_config1()	__read_32bit_c0_register($16, 1)
835#define read_c0_config2()	__read_32bit_c0_register($16, 2)
836#define read_c0_config3()	__read_32bit_c0_register($16, 3)
837#define read_c0_config4()	__read_32bit_c0_register($16, 4)
838#define read_c0_config5()	__read_32bit_c0_register($16, 5)
839#define read_c0_config6()	__read_32bit_c0_register($16, 6)
840#define read_c0_config7()	__read_32bit_c0_register($16, 7)
841#define write_c0_config(val)	__write_32bit_c0_register($16, 0, val)
842#define write_c0_config1(val)	__write_32bit_c0_register($16, 1, val)
843#define write_c0_config2(val)	__write_32bit_c0_register($16, 2, val)
844#define write_c0_config3(val)	__write_32bit_c0_register($16, 3, val)
845#define write_c0_config4(val)	__write_32bit_c0_register($16, 4, val)
846#define write_c0_config5(val)	__write_32bit_c0_register($16, 5, val)
847#define write_c0_config6(val)	__write_32bit_c0_register($16, 6, val)
848#define write_c0_config7(val)	__write_32bit_c0_register($16, 7, val)
849
850/*
851 * The WatchLo register.  There may be upto 8 of them.
852 */
853#define read_c0_watchlo0()	__read_ulong_c0_register($18, 0)
854#define read_c0_watchlo1()	__read_ulong_c0_register($18, 1)
855#define read_c0_watchlo2()	__read_ulong_c0_register($18, 2)
856#define read_c0_watchlo3()	__read_ulong_c0_register($18, 3)
857#define read_c0_watchlo4()	__read_ulong_c0_register($18, 4)
858#define read_c0_watchlo5()	__read_ulong_c0_register($18, 5)
859#define read_c0_watchlo6()	__read_ulong_c0_register($18, 6)
860#define read_c0_watchlo7()	__read_ulong_c0_register($18, 7)
861#define write_c0_watchlo0(val)	__write_ulong_c0_register($18, 0, val)
862#define write_c0_watchlo1(val)	__write_ulong_c0_register($18, 1, val)
863#define write_c0_watchlo2(val)	__write_ulong_c0_register($18, 2, val)
864#define write_c0_watchlo3(val)	__write_ulong_c0_register($18, 3, val)
865#define write_c0_watchlo4(val)	__write_ulong_c0_register($18, 4, val)
866#define write_c0_watchlo5(val)	__write_ulong_c0_register($18, 5, val)
867#define write_c0_watchlo6(val)	__write_ulong_c0_register($18, 6, val)
868#define write_c0_watchlo7(val)	__write_ulong_c0_register($18, 7, val)
869
870/*
871 * The WatchHi register.  There may be upto 8 of them.
872 */
873#define read_c0_watchhi0()	__read_32bit_c0_register($19, 0)
874#define read_c0_watchhi1()	__read_32bit_c0_register($19, 1)
875#define read_c0_watchhi2()	__read_32bit_c0_register($19, 2)
876#define read_c0_watchhi3()	__read_32bit_c0_register($19, 3)
877#define read_c0_watchhi4()	__read_32bit_c0_register($19, 4)
878#define read_c0_watchhi5()	__read_32bit_c0_register($19, 5)
879#define read_c0_watchhi6()	__read_32bit_c0_register($19, 6)
880#define read_c0_watchhi7()	__read_32bit_c0_register($19, 7)
881
882#define write_c0_watchhi0(val)	__write_32bit_c0_register($19, 0, val)
883#define write_c0_watchhi1(val)	__write_32bit_c0_register($19, 1, val)
884#define write_c0_watchhi2(val)	__write_32bit_c0_register($19, 2, val)
885#define write_c0_watchhi3(val)	__write_32bit_c0_register($19, 3, val)
886#define write_c0_watchhi4(val)	__write_32bit_c0_register($19, 4, val)
887#define write_c0_watchhi5(val)	__write_32bit_c0_register($19, 5, val)
888#define write_c0_watchhi6(val)	__write_32bit_c0_register($19, 6, val)
889#define write_c0_watchhi7(val)	__write_32bit_c0_register($19, 7, val)
890
891#define read_c0_xcontext()	__read_ulong_c0_register($20, 0)
892#define write_c0_xcontext(val)	__write_ulong_c0_register($20, 0, val)
893
894#define read_c0_intcontrol()	__read_32bit_c0_ctrl_register($20)
895#define write_c0_intcontrol(val) __write_32bit_c0_ctrl_register($20, val)
896
897#define read_c0_framemask()	__read_32bit_c0_register($21, 0)
898#define write_c0_framemask(val)	__write_32bit_c0_register($21, 0, val)
899
900/* RM9000 PerfControl performance counter control register */
901#define read_c0_perfcontrol()	__read_32bit_c0_register($22, 0)
902#define write_c0_perfcontrol(val) __write_32bit_c0_register($22, 0, val)
903
904#define read_c0_perf(sel)       __read_32bit_c0_register($25, sel)
905#define write_c0_perf(sel, val) __write_32bit_c0_register($25, sel, val)
906
907#define read_c0_diag()		__read_32bit_c0_register($22, 0)
908#define write_c0_diag(val)	__write_32bit_c0_register($22, 0, val)
909
910#define read_c0_diag1()		__read_32bit_c0_register($22, 1)
911#define write_c0_diag1(val)	__write_32bit_c0_register($22, 1, val)
912
913#define read_c0_diag2()		__read_32bit_c0_register($22, 2)
914#define write_c0_diag2(val)	__write_32bit_c0_register($22, 2, val)
915
916#define read_c0_diag3()		__read_32bit_c0_register($22, 3)
917#define write_c0_diag3(val)	__write_32bit_c0_register($22, 3, val)
918
919#define read_c0_diag4()		__read_32bit_c0_register($22, 4)
920#define write_c0_diag4(val)	__write_32bit_c0_register($22, 4, val)
921
922#define read_c0_diag5()		__read_32bit_c0_register($22, 5)
923#define write_c0_diag5(val)	__write_32bit_c0_register($22, 5, val)
924
925#define read_c0_debug()		__read_32bit_c0_register($23, 0)
926#define write_c0_debug(val)	__write_32bit_c0_register($23, 0, val)
927
928#define read_c0_depc()		__read_ulong_c0_register($24, 0)
929#define write_c0_depc(val)	__write_ulong_c0_register($24, 0, val)
930
931/*
932 * MIPS32 / MIPS64 performance counters
933 */
934#define read_c0_perfctrl0()	__read_32bit_c0_register($25, 0)
935#define write_c0_perfctrl0(val)	__write_32bit_c0_register($25, 0, val)
936#define read_c0_perfcntr0()	__read_32bit_c0_register($25, 1)
937#define write_c0_perfcntr0(val)	__write_32bit_c0_register($25, 1, val)
938#define read_c0_perfctrl1()	__read_32bit_c0_register($25, 2)
939#define write_c0_perfctrl1(val)	__write_32bit_c0_register($25, 2, val)
940#define read_c0_perfcntr1()	__read_32bit_c0_register($25, 3)
941#define write_c0_perfcntr1(val)	__write_32bit_c0_register($25, 3, val)
942#define read_c0_perfctrl2()	__read_32bit_c0_register($25, 4)
943#define write_c0_perfctrl2(val)	__write_32bit_c0_register($25, 4, val)
944#define read_c0_perfcntr2()	__read_32bit_c0_register($25, 5)
945#define write_c0_perfcntr2(val)	__write_32bit_c0_register($25, 5, val)
946#define read_c0_perfctrl3()	__read_32bit_c0_register($25, 6)
947#define write_c0_perfctrl3(val)	__write_32bit_c0_register($25, 6, val)
948#define read_c0_perfcntr3()	__read_32bit_c0_register($25, 7)
949#define write_c0_perfcntr3(val)	__write_32bit_c0_register($25, 7, val)
950
951/* RM9000 PerfCount performance counter register */
952#define read_c0_perfcount()	__read_64bit_c0_register($25, 0)
953#define write_c0_perfcount(val)	__write_64bit_c0_register($25, 0, val)
954
955#define read_c0_ecc()		__read_32bit_c0_register($26, 0)
956#define write_c0_ecc(val)	__write_32bit_c0_register($26, 0, val)
957
958#define read_c0_derraddr0()	__read_ulong_c0_register($26, 1)
959#define write_c0_derraddr0(val)	__write_ulong_c0_register($26, 1, val)
960
961#define read_c0_cacheerr()	__read_32bit_c0_register($27, 0)
962
963#define read_c0_derraddr1()	__read_ulong_c0_register($27, 1)
964#define write_c0_derraddr1(val)	__write_ulong_c0_register($27, 1, val)
965
966#define read_c0_taglo()		__read_32bit_c0_register($28, 0)
967#define write_c0_taglo(val)	__write_32bit_c0_register($28, 0, val)
968
969#define read_c0_dtaglo()	__read_32bit_c0_register($28, 2)
970#define write_c0_dtaglo(val)	__write_32bit_c0_register($28, 2, val)
971
972#define read_c0_taghi()		__read_32bit_c0_register($29, 0)
973#define write_c0_taghi(val)	__write_32bit_c0_register($29, 0, val)
974
975#define read_c0_errorepc()	__read_ulong_c0_register($30, 0)
976#define write_c0_errorepc(val)	__write_ulong_c0_register($30, 0, val)
977
978/* MIPSR2 */
979#define read_c0_hwrena()	__read_32bit_c0_register($7,0)
980#define write_c0_hwrena(val)	__write_32bit_c0_register($7, 0, val)
981
982#define read_c0_intctl()	__read_32bit_c0_register($12, 1)
983#define write_c0_intctl(val)	__write_32bit_c0_register($12, 1, val)
984
985#define read_c0_srsctl()	__read_32bit_c0_register($12, 2)
986#define write_c0_srsctl(val)	__write_32bit_c0_register($12, 2, val)
987
988#define read_c0_srsmap()	__read_32bit_c0_register($12, 3)
989#define write_c0_srsmap(val)	__write_32bit_c0_register($12, 3, val)
990
991#define read_c0_ebase()		__read_32bit_c0_register($15,1)
992#define write_c0_ebase(val)	__write_32bit_c0_register($15, 1, val)
993
994/*
995 * Macros to access the floating point coprocessor control registers
996 */
997#define read_32bit_cp1_register(source)                         \
998({ int __res;                                                   \
999	__asm__ __volatile__(                                   \
1000	".set\tpush\n\t"					\
1001	".set\treorder\n\t"					\
1002        "cfc1\t%0,"STR(source)"\n\t"                            \
1003	".set\tpop"						\
1004        : "=r" (__res));                                        \
1005        __res;})
1006
1007#define rddsp(mask)							\
1008({									\
1009	unsigned int __res;						\
1010									\
1011	__asm__ __volatile__(						\
1012	"	.set	push				\n"		\
1013	"	.set	noat				\n"		\
1014	"	# rddsp $1, %x1				\n"		\
1015	"	.word	0x7c000cb8 | (%x1 << 16)	\n"		\
1016	"	move	%0, $1				\n"		\
1017	"	.set	pop				\n"		\
1018	: "=r" (__res)							\
1019	: "i" (mask));							\
1020	__res;								\
1021})
1022
1023#define wrdsp(val, mask)						\
1024do {									\
1025	__asm__ __volatile__(						\
1026	"	.set	push					\n"	\
1027	"	.set	noat					\n"	\
1028	"	move	$1, %0					\n"	\
1029	"	# wrdsp $1, %x1					\n"	\
1030	"	.word	0x7c2004f8 | (%x1 << 11)		\n"	\
1031	"	.set	pop					\n"	\
1032        :								\
1033	: "r" (val), "i" (mask));					\
1034} while (0)
1035
1036
1037#define mfhi0()								\
1038({									\
1039	unsigned long __treg;						\
1040									\
1041	__asm__ __volatile__(						\
1042	"	.set	push			\n"			\
1043	"	.set	noat			\n"			\
1044	"	# mfhi	%0, $ac0		\n"			\
1045	"	.word	0x00000810		\n"			\
1046	"	move	%0, $1			\n"			\
1047	"	.set	pop			\n"			\
1048	: "=r" (__treg));						\
1049	__treg;								\
1050})
1051
1052#define mfhi1()								\
1053({									\
1054	unsigned long __treg;						\
1055									\
1056	__asm__ __volatile__(						\
1057	"	.set	push			\n"			\
1058	"	.set	noat			\n"			\
1059	"	# mfhi	%0, $ac1		\n"			\
1060	"	.word	0x00200810		\n"			\
1061	"	move	%0, $1			\n"			\
1062	"	.set	pop			\n"			\
1063	: "=r" (__treg));						\
1064	__treg;								\
1065})
1066
1067#define mfhi2()								\
1068({									\
1069	unsigned long __treg;						\
1070									\
1071	__asm__ __volatile__(						\
1072	"	.set	push			\n"			\
1073	"	.set	noat			\n"			\
1074	"	# mfhi	%0, $ac2		\n"			\
1075	"	.word	0x00400810		\n"			\
1076	"	move	%0, $1			\n"			\
1077	"	.set	pop			\n"			\
1078	: "=r" (__treg));						\
1079	__treg;								\
1080})
1081
1082#define mfhi3()								\
1083({									\
1084	unsigned long __treg;						\
1085									\
1086	__asm__ __volatile__(						\
1087	"	.set	push			\n"			\
1088	"	.set	noat			\n"			\
1089	"	# mfhi	%0, $ac3		\n"			\
1090	"	.word	0x00600810		\n"			\
1091	"	move	%0, $1			\n"			\
1092	"	.set	pop			\n"			\
1093	: "=r" (__treg));						\
1094	__treg;								\
1095})
1096
1097#define mflo0()								\
1098({									\
1099	unsigned long __treg;						\
1100									\
1101	__asm__ __volatile__(						\
1102	"	.set	push			\n"			\
1103	"	.set	noat			\n"			\
1104	"	# mflo	%0, $ac0		\n"			\
1105	"	.word	0x00000812		\n"			\
1106	"	move	%0, $1			\n"			\
1107	"	.set	pop			\n"			\
1108	: "=r" (__treg));						\
1109	__treg;								\
1110})
1111
1112#define mflo1()								\
1113({									\
1114	unsigned long __treg;						\
1115									\
1116	__asm__ __volatile__(						\
1117	"	.set	push			\n"			\
1118	"	.set	noat			\n"			\
1119	"	# mflo	%0, $ac1		\n"			\
1120	"	.word	0x00200812		\n"			\
1121	"	move	%0, $1			\n"			\
1122	"	.set	pop			\n"			\
1123	: "=r" (__treg));						\
1124	__treg;								\
1125})
1126
1127#define mflo2()								\
1128({									\
1129	unsigned long __treg;						\
1130									\
1131	__asm__ __volatile__(						\
1132	"	.set	push			\n"			\
1133	"	.set	noat			\n"			\
1134	"	# mflo	%0, $ac2		\n"			\
1135	"	.word	0x00400812		\n"			\
1136	"	move	%0, $1			\n"			\
1137	"	.set	pop			\n"			\
1138	: "=r" (__treg));						\
1139	__treg;								\
1140})
1141
1142#define mflo3()								\
1143({									\
1144	unsigned long __treg;						\
1145									\
1146	__asm__ __volatile__(						\
1147	"	.set	push			\n"			\
1148	"	.set	noat			\n"			\
1149	"	# mflo	%0, $ac3		\n"			\
1150	"	.word	0x00600812		\n"			\
1151	"	move	%0, $1			\n"			\
1152	"	.set	pop			\n"			\
1153	: "=r" (__treg));						\
1154	__treg;								\
1155})
1156
1157#define mthi0(x)							\
1158do {									\
1159	__asm__ __volatile__(						\
1160	"	.set	push					\n"	\
1161	"	.set	noat					\n"	\
1162	"	move	$1, %0					\n"	\
1163	"	# mthi	$1, $ac0				\n"	\
1164	"	.word	0x00200011				\n"	\
1165	"	.set	pop					\n"	\
1166	:								\
1167	: "r" (x));							\
1168} while (0)
1169
1170#define mthi1(x)							\
1171do {									\
1172	__asm__ __volatile__(						\
1173	"	.set	push					\n"	\
1174	"	.set	noat					\n"	\
1175	"	move	$1, %0					\n"	\
1176	"	# mthi	$1, $ac1				\n"	\
1177	"	.word	0x00200811				\n"	\
1178	"	.set	pop					\n"	\
1179	:								\
1180	: "r" (x));							\
1181} while (0)
1182
1183#define mthi2(x)							\
1184do {									\
1185	__asm__ __volatile__(						\
1186	"	.set	push					\n"	\
1187	"	.set	noat					\n"	\
1188	"	move	$1, %0					\n"	\
1189	"	# mthi	$1, $ac2				\n"	\
1190	"	.word	0x00201011				\n"	\
1191	"	.set	pop					\n"	\
1192	:								\
1193	: "r" (x));							\
1194} while (0)
1195
1196#define mthi3(x)							\
1197do {									\
1198	__asm__ __volatile__(						\
1199	"	.set	push					\n"	\
1200	"	.set	noat					\n"	\
1201	"	move	$1, %0					\n"	\
1202	"	# mthi	$1, $ac3				\n"	\
1203	"	.word	0x00201811				\n"	\
1204	"	.set	pop					\n"	\
1205	:								\
1206	: "r" (x));							\
1207} while (0)
1208
1209#define mtlo0(x)							\
1210do {									\
1211	__asm__ __volatile__(						\
1212	"	.set	push					\n"	\
1213	"	.set	noat					\n"	\
1214	"	move	$1, %0					\n"	\
1215	"	# mtlo	$1, $ac0				\n"	\
1216	"	.word	0x00200013				\n"	\
1217	"	.set	pop					\n"	\
1218	:								\
1219	: "r" (x));							\
1220} while (0)
1221
1222#define mtlo1(x)							\
1223do {									\
1224	__asm__ __volatile__(						\
1225	"	.set	push					\n"	\
1226	"	.set	noat					\n"	\
1227	"	move	$1, %0					\n"	\
1228	"	# mtlo	$1, $ac1				\n"	\
1229	"	.word	0x00200813				\n"	\
1230	"	.set	pop					\n"	\
1231	:								\
1232	: "r" (x));							\
1233} while (0)
1234
1235#define mtlo2(x)							\
1236do {									\
1237	__asm__ __volatile__(						\
1238	"	.set	push					\n"	\
1239	"	.set	noat					\n"	\
1240	"	move	$1, %0					\n"	\
1241	"	# mtlo	$1, $ac2				\n"	\
1242	"	.word	0x00201013				\n"	\
1243	"	.set	pop					\n"	\
1244	:								\
1245	: "r" (x));							\
1246} while (0)
1247
1248#define mtlo3(x)							\
1249do {									\
1250	__asm__ __volatile__(						\
1251	"	.set	push					\n"	\
1252	"	.set	noat					\n"	\
1253	"	move	$1, %0					\n"	\
1254	"	# mtlo	$1, $ac3				\n"	\
1255	"	.word	0x00201813				\n"	\
1256	"	.set	pop					\n"	\
1257	:								\
1258	: "r" (x));							\
1259} while (0)
1260
1261/*
1262 * TLB operations.
1263 *
1264 * It is responsibility of the caller to take care of any TLB hazards.
1265 */
1266static inline void tlb_probe(void)
1267{
1268	__asm__ __volatile__(
1269		".set noreorder\n\t"
1270		"tlbp\n\t"
1271		".set reorder");
1272}
1273
1274static inline void tlb_read(void)
1275{
1276	__asm__ __volatile__(
1277		".set noreorder\n\t"
1278		"tlbr\n\t"
1279		".set reorder");
1280}
1281
1282static inline void tlb_write_indexed(void)
1283{
1284	__asm__ __volatile__(
1285		".set noreorder\n\t"
1286		"tlbwi\n\t"
1287		".set reorder");
1288}
1289
1290static inline void tlb_write_random(void)
1291{
1292	__asm__ __volatile__(
1293		".set noreorder\n\t"
1294		"tlbwr\n\t"
1295		".set reorder");
1296}
1297
1298/*
1299 * Manipulate bits in a c0 register.
1300 */
1301#ifndef CONFIG_MIPS_MT_SMTC
1302/*
1303 * SMTC Linux requires shutting-down microthread scheduling
1304 * during CP0 register read-modify-write sequences.
1305 */
1306#define __BUILD_SET_C0(name)					\
1307static inline unsigned int					\
1308set_c0_##name(unsigned int set)					\
1309{								\
1310	unsigned int res;					\
1311								\
1312	res = read_c0_##name();					\
1313	res |= set;						\
1314	write_c0_##name(res);					\
1315								\
1316	return res;						\
1317}								\
1318								\
1319static inline unsigned int					\
1320clear_c0_##name(unsigned int clear)				\
1321{								\
1322	unsigned int res;					\
1323								\
1324	res = read_c0_##name();					\
1325	res &= ~clear;						\
1326	write_c0_##name(res);					\
1327								\
1328	return res;						\
1329}								\
1330								\
1331static inline unsigned int					\
1332change_c0_##name(unsigned int change, unsigned int new)		\
1333{								\
1334	unsigned int res;					\
1335								\
1336	res = read_c0_##name();					\
1337	res &= ~change;						\
1338	res |= (new & change);					\
1339	write_c0_##name(res);					\
1340								\
1341	return res;						\
1342}
1343
1344#else /* SMTC versions that manage MT scheduling */
1345
1346#include <linux/irqflags.h>
1347
1348/*
1349 * This is a duplicate of dmt() in mipsmtregs.h to avoid problems with
1350 * header file recursion.
1351 */
1352static inline unsigned int __dmt(void)
1353{
1354	int res;
1355
1356	__asm__ __volatile__(
1357	"	.set	push						\n"
1358	"	.set	mips32r2					\n"
1359	"	.set	noat						\n"
1360	"	.word	0x41610BC1			# dmt $1	\n"
1361	"	ehb							\n"
1362	"	move	%0, $1						\n"
1363	"	.set	pop						\n"
1364	: "=r" (res));
1365
1366	instruction_hazard();
1367
1368	return res;
1369}
1370
1371#define __VPECONTROL_TE_SHIFT	15
1372#define __VPECONTROL_TE		(1UL << __VPECONTROL_TE_SHIFT)
1373
1374#define __EMT_ENABLE		__VPECONTROL_TE
1375
1376static inline void __emt(unsigned int previous)
1377{
1378	if ((previous & __EMT_ENABLE))
1379		__asm__ __volatile__(
1380		"	.set	mips32r2				\n"
1381		"	.word	0x41600be1		# emt		\n"
1382		"	ehb						\n"
1383		"	.set	mips0					\n");
1384}
1385
1386static inline void __ehb(void)
1387{
1388	__asm__ __volatile__(
1389	"	.set	mips32r2					\n"
1390	"	ehb							\n"		"	.set	mips0						\n");
1391}
1392
1393/*
1394 * Note that local_irq_save/restore affect TC-specific IXMT state,
1395 * not Status.IE as in non-SMTC kernel.
1396 */
1397
1398#define __BUILD_SET_C0(name)					\
1399static inline unsigned int					\
1400set_c0_##name(unsigned int set)					\
1401{								\
1402	unsigned int res;					\
1403	unsigned int omt;					\
1404	unsigned int flags;					\
1405								\
1406	local_irq_save(flags);					\
1407	omt = __dmt();						\
1408	res = read_c0_##name();					\
1409	res |= set;						\
1410	write_c0_##name(res);					\
1411	__emt(omt);						\
1412	local_irq_restore(flags);				\
1413								\
1414	return res;						\
1415}								\
1416								\
1417static inline unsigned int					\
1418clear_c0_##name(unsigned int clear)				\
1419{								\
1420	unsigned int res;					\
1421	unsigned int omt;					\
1422	unsigned int flags;					\
1423								\
1424	local_irq_save(flags);					\
1425	omt = __dmt();						\
1426	res = read_c0_##name();					\
1427	res &= ~clear;						\
1428	write_c0_##name(res);					\
1429	__emt(omt);						\
1430	local_irq_restore(flags);				\
1431								\
1432	return res;						\
1433}								\
1434								\
1435static inline unsigned int					\
1436change_c0_##name(unsigned int change, unsigned int new)		\
1437{								\
1438	unsigned int res;					\
1439	unsigned int omt;					\
1440	unsigned int flags;					\
1441								\
1442	local_irq_save(flags);					\
1443								\
1444	omt = __dmt();						\
1445	res = read_c0_##name();					\
1446	res &= ~change;						\
1447	res |= (new & change);					\
1448	write_c0_##name(res);					\
1449	__emt(omt);						\
1450	local_irq_restore(flags);				\
1451								\
1452	return res;						\
1453}
1454#endif
1455
1456__BUILD_SET_C0(status)
1457__BUILD_SET_C0(cause)
1458__BUILD_SET_C0(config)
1459__BUILD_SET_C0(config7)
1460__BUILD_SET_C0(intcontrol)
1461__BUILD_SET_C0(intctl)
1462__BUILD_SET_C0(srsmap)
1463
1464/*
1465 * Functions to access the performance counter and control registers
1466 */
1467extern asmlinkage unsigned int read_perf_cntr(unsigned int counter);
1468extern asmlinkage void write_perf_cntr(unsigned int counter, unsigned int val);
1469extern asmlinkage unsigned int read_perf_cntl(unsigned int counter);
1470extern asmlinkage void write_perf_cntl(unsigned int counter, unsigned int val);
1471
1472#endif /* !__ASSEMBLY__ */
1473
1474#endif /* _ASM_MIPSREGS_H */
1475