summaryrefslogtreecommitdiff
path: root/firmware/export/mipsregs.h
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/export/mipsregs.h')
-rwxr-xr-xfirmware/export/mipsregs.h985
1 files changed, 985 insertions, 0 deletions
diff --git a/firmware/export/mipsregs.h b/firmware/export/mipsregs.h
new file mode 100755
index 0000000000..e2935e3024
--- /dev/null
+++ b/firmware/export/mipsregs.h
@@ -0,0 +1,985 @@
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 Maciej W. Rozycki
12 */
13#ifndef _ASM_MIPSREGS_H
14#define _ASM_MIPSREGS_H
15
16//#include <linux/config.h>
17//#include <linux/linkage.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 * TX39 Series
99 */
100#define CP0_TX39_CACHE $7
101
102/*
103 * Coprocessor 1 (FPU) register names
104 */
105#define CP1_REVISION $0
106#define CP1_STATUS $31
107
108/*
109 * FPU Status Register Values
110 */
111/*
112 * Status Register Values
113 */
114
115#define FPU_CSR_FLUSH 0x01000000 /* flush denormalised results to 0 */
116#define FPU_CSR_COND 0x00800000 /* $fcc0 */
117#define FPU_CSR_COND0 0x00800000 /* $fcc0 */
118#define FPU_CSR_COND1 0x02000000 /* $fcc1 */
119#define FPU_CSR_COND2 0x04000000 /* $fcc2 */
120#define FPU_CSR_COND3 0x08000000 /* $fcc3 */
121#define FPU_CSR_COND4 0x10000000 /* $fcc4 */
122#define FPU_CSR_COND5 0x20000000 /* $fcc5 */
123#define FPU_CSR_COND6 0x40000000 /* $fcc6 */
124#define FPU_CSR_COND7 0x80000000 /* $fcc7 */
125
126/*
127 * X the exception cause indicator
128 * E the exception enable
129 * S the sticky/flag bit
130*/
131#define FPU_CSR_ALL_X 0x0003f000
132#define FPU_CSR_UNI_X 0x00020000
133#define FPU_CSR_INV_X 0x00010000
134#define FPU_CSR_DIV_X 0x00008000
135#define FPU_CSR_OVF_X 0x00004000
136#define FPU_CSR_UDF_X 0x00002000
137#define FPU_CSR_INE_X 0x00001000
138
139#define FPU_CSR_ALL_E 0x00000f80
140#define FPU_CSR_INV_E 0x00000800
141#define FPU_CSR_DIV_E 0x00000400
142#define FPU_CSR_OVF_E 0x00000200
143#define FPU_CSR_UDF_E 0x00000100
144#define FPU_CSR_INE_E 0x00000080
145
146#define FPU_CSR_ALL_S 0x0000007c
147#define FPU_CSR_INV_S 0x00000040
148#define FPU_CSR_DIV_S 0x00000020
149#define FPU_CSR_OVF_S 0x00000010
150#define FPU_CSR_UDF_S 0x00000008
151#define FPU_CSR_INE_S 0x00000004
152
153/* rounding mode */
154#define FPU_CSR_RN 0x0 /* nearest */
155#define FPU_CSR_RZ 0x1 /* towards zero */
156#define FPU_CSR_RU 0x2 /* towards +Infinity */
157#define FPU_CSR_RD 0x3 /* towards -Infinity */
158
159
160/*
161 * Values for PageMask register
162 */
163#ifdef CONFIG_CPU_VR41XX
164
165/* Why doesn't stupidity hurt ... */
166
167#define PM_1K 0x00000000
168#define PM_4K 0x00001800
169#define PM_16K 0x00007800
170#define PM_64K 0x0001f800
171#define PM_256K 0x0007f800
172
173#else
174
175#define PM_4K 0x00000000
176#define PM_16K 0x00006000
177#define PM_64K 0x0001e000
178#define PM_256K 0x0007e000
179#define PM_1M 0x001fe000
180#define PM_4M 0x007fe000
181#define PM_16M 0x01ffe000
182#define PM_64M 0x07ffe000
183#define PM_256M 0x1fffe000
184
185#endif
186
187/*
188 * Values used for computation of new tlb entries
189 */
190#define PL_4K 12
191#define PL_16K 14
192#define PL_64K 16
193#define PL_256K 18
194#define PL_1M 20
195#define PL_4M 22
196#define PL_16M 24
197#define PL_64M 26
198#define PL_256M 28
199
200/*
201 * R4x00 interrupt enable / cause bits
202 */
203#define IE_SW0 (_ULCAST_(1) << 8)
204#define IE_SW1 (_ULCAST_(1) << 9)
205#define IE_IRQ0 (_ULCAST_(1) << 10)
206#define IE_IRQ1 (_ULCAST_(1) << 11)
207#define IE_IRQ2 (_ULCAST_(1) << 12)
208#define IE_IRQ3 (_ULCAST_(1) << 13)
209#define IE_IRQ4 (_ULCAST_(1) << 14)
210#define IE_IRQ5 (_ULCAST_(1) << 15)
211
212/*
213 * R4x00 interrupt cause bits
214 */
215#define C_SW0 (_ULCAST_(1) << 8)
216#define C_SW1 (_ULCAST_(1) << 9)
217#define C_IRQ0 (_ULCAST_(1) << 10)
218#define C_IRQ1 (_ULCAST_(1) << 11)
219#define C_IRQ2 (_ULCAST_(1) << 12)
220#define C_IRQ3 (_ULCAST_(1) << 13)
221#define C_IRQ4 (_ULCAST_(1) << 14)
222#define C_IRQ5 (_ULCAST_(1) << 15)
223
224/*
225 * Bitfields in the R4xx0 cp0 status register
226 */
227#define ST0_IE 0x00000001
228#define ST0_EXL 0x00000002
229#define ST0_ERL 0x00000004
230#define ST0_KSU 0x00000018
231# define KSU_USER 0x00000010
232# define KSU_SUPERVISOR 0x00000008
233# define KSU_KERNEL 0x00000000
234#define ST0_UX 0x00000020
235#define ST0_SX 0x00000040
236#define ST0_KX 0x00000080
237#define ST0_DE 0x00010000
238#define ST0_CE 0x00020000
239
240/*
241 * Bitfields in the R[23]000 cp0 status register.
242 */
243#define ST0_IEC 0x00000001
244#define ST0_KUC 0x00000002
245#define ST0_IEP 0x00000004
246#define ST0_KUP 0x00000008
247#define ST0_IEO 0x00000010
248#define ST0_KUO 0x00000020
249/* bits 6 & 7 are reserved on R[23]000 */
250#define ST0_ISC 0x00010000
251#define ST0_SWC 0x00020000
252#define ST0_CM 0x00080000
253
254/*
255 * Bits specific to the R4640/R4650
256 */
257#define ST0_UM (_ULCAST_(1) << 4)
258#define ST0_IL (_ULCAST_(1) << 23)
259#define ST0_DL (_ULCAST_(1) << 24)
260
261/*
262 * Bitfields in the TX39 family CP0 Configuration Register 3
263 */
264#define TX39_CONF_ICS_SHIFT 19
265#define TX39_CONF_ICS_MASK 0x00380000
266#define TX39_CONF_ICS_1KB 0x00000000
267#define TX39_CONF_ICS_2KB 0x00080000
268#define TX39_CONF_ICS_4KB 0x00100000
269#define TX39_CONF_ICS_8KB 0x00180000
270#define TX39_CONF_ICS_16KB 0x00200000
271
272#define TX39_CONF_DCS_SHIFT 16
273#define TX39_CONF_DCS_MASK 0x00070000
274#define TX39_CONF_DCS_1KB 0x00000000
275#define TX39_CONF_DCS_2KB 0x00010000
276#define TX39_CONF_DCS_4KB 0x00020000
277#define TX39_CONF_DCS_8KB 0x00030000
278#define TX39_CONF_DCS_16KB 0x00040000
279
280#define TX39_CONF_CWFON 0x00004000
281#define TX39_CONF_WBON 0x00002000
282#define TX39_CONF_RF_SHIFT 10
283#define TX39_CONF_RF_MASK 0x00000c00
284#define TX39_CONF_DOZE 0x00000200
285#define TX39_CONF_HALT 0x00000100
286#define TX39_CONF_LOCK 0x00000080
287#define TX39_CONF_ICE 0x00000020
288#define TX39_CONF_DCE 0x00000010
289#define TX39_CONF_IRSIZE_SHIFT 2
290#define TX39_CONF_IRSIZE_MASK 0x0000000c
291#define TX39_CONF_DRSIZE_SHIFT 0
292#define TX39_CONF_DRSIZE_MASK 0x00000003
293
294/*
295 * Status register bits available in all MIPS CPUs.
296 */
297#define ST0_IM 0x0000ff00
298#define STATUSB_IP0 8
299#define STATUSF_IP0 (_ULCAST_(1) << 8)
300#define STATUSB_IP1 9
301#define STATUSF_IP1 (_ULCAST_(1) << 9)
302#define STATUSB_IP2 10
303#define STATUSF_IP2 (_ULCAST_(1) << 10)
304#define STATUSB_IP3 11
305#define STATUSF_IP3 (_ULCAST_(1) << 11)
306#define STATUSB_IP4 12
307#define STATUSF_IP4 (_ULCAST_(1) << 12)
308#define STATUSB_IP5 13
309#define STATUSF_IP5 (_ULCAST_(1) << 13)
310#define STATUSB_IP6 14
311#define STATUSF_IP6 (_ULCAST_(1) << 14)
312#define STATUSB_IP7 15
313#define STATUSF_IP7 (_ULCAST_(1) << 15)
314#define STATUSB_IP8 0
315#define STATUSF_IP8 (_ULCAST_(1) << 0)
316#define STATUSB_IP9 1
317#define STATUSF_IP9 (_ULCAST_(1) << 1)
318#define STATUSB_IP10 2
319#define STATUSF_IP10 (_ULCAST_(1) << 2)
320#define STATUSB_IP11 3
321#define STATUSF_IP11 (_ULCAST_(1) << 3)
322#define STATUSB_IP12 4
323#define STATUSF_IP12 (_ULCAST_(1) << 4)
324#define STATUSB_IP13 5
325#define STATUSF_IP13 (_ULCAST_(1) << 5)
326#define STATUSB_IP14 6
327#define STATUSF_IP14 (_ULCAST_(1) << 6)
328#define STATUSB_IP15 7
329#define STATUSF_IP15 (_ULCAST_(1) << 7)
330#define ST0_CH 0x00040000
331#define ST0_SR 0x00100000
332#define ST0_TS 0x00200000
333#define ST0_BEV 0x00400000
334#define ST0_RE 0x02000000
335#define ST0_FR 0x04000000
336#define ST0_CU 0xf0000000
337#define ST0_CU0 0x10000000
338#define ST0_CU1 0x20000000
339#define ST0_CU2 0x40000000
340#define ST0_CU3 0x80000000
341#define ST0_XX 0x80000000 /* MIPS IV naming */
342
343/*
344 * Bitfields and bit numbers in the coprocessor 0 cause register.
345 *
346 * Refer to your MIPS R4xx0 manual, chapter 5 for explanation.
347 */
348#define CAUSEB_EXCCODE 2
349#define CAUSEF_EXCCODE (_ULCAST_(31) << 2)
350#define CAUSEB_IP 8
351#define CAUSEF_IP (_ULCAST_(255) << 8)
352#define CAUSEB_IP0 8
353#define CAUSEF_IP0 (_ULCAST_(1) << 8)
354#define CAUSEB_IP1 9
355#define CAUSEF_IP1 (_ULCAST_(1) << 9)
356#define CAUSEB_IP2 10
357#define CAUSEF_IP2 (_ULCAST_(1) << 10)
358#define CAUSEB_IP3 11
359#define CAUSEF_IP3 (_ULCAST_(1) << 11)
360#define CAUSEB_IP4 12
361#define CAUSEF_IP4 (_ULCAST_(1) << 12)
362#define CAUSEB_IP5 13
363#define CAUSEF_IP5 (_ULCAST_(1) << 13)
364#define CAUSEB_IP6 14
365#define CAUSEF_IP6 (_ULCAST_(1) << 14)
366#define CAUSEB_IP7 15
367#define CAUSEF_IP7 (_ULCAST_(1) << 15)
368#define CAUSEB_IV 23
369#define CAUSEF_IV (_ULCAST_(1) << 23)
370#define CAUSEB_CE 28
371#define CAUSEF_CE (_ULCAST_(3) << 28)
372#define CAUSEB_BD 31
373#define CAUSEF_BD (_ULCAST_(1) << 31)
374
375/*
376 * Bits in the coprocessor 0 config register.
377 */
378/* Generic bits. */
379#define CONF_CM_CACHABLE_NO_WA 0
380#define CONF_CM_CACHABLE_WA 1
381#define CONF_CM_UNCACHED 2
382#define CONF_CM_CACHABLE_NONCOHERENT 3
383#define CONF_CM_CACHABLE_CE 4
384#define CONF_CM_CACHABLE_COW 5
385#define CONF_CM_CACHABLE_CUW 6
386#define CONF_CM_CACHABLE_ACCELERATED 7
387#define CONF_CM_CMASK 7
388#define CONF_BE (_ULCAST_(1) << 15)
389
390/* Bits common to various processors. */
391#define CONF_CU (_ULCAST_(1) << 3)
392#define CONF_DB (_ULCAST_(1) << 4)
393#define CONF_IB (_ULCAST_(1) << 5)
394#define CONF_DC (_ULCAST_(7) << 6)
395#define CONF_IC (_ULCAST_(7) << 9)
396#define CONF_EB (_ULCAST_(1) << 13)
397#define CONF_EM (_ULCAST_(1) << 14)
398#define CONF_SM (_ULCAST_(1) << 16)
399#define CONF_SC (_ULCAST_(1) << 17)
400#define CONF_EW (_ULCAST_(3) << 18)
401#define CONF_EP (_ULCAST_(15)<< 24)
402#define CONF_EC (_ULCAST_(7) << 28)
403#define CONF_CM (_ULCAST_(1) << 31)
404
405/* Bits specific to the R4xx0. */
406#define R4K_CONF_SW (_ULCAST_(1) << 20)
407#define R4K_CONF_SS (_ULCAST_(1) << 21)
408#define R4K_CONF_SB (_ULCAST_(3) << 22)
409
410/* Bits specific to the R5000. */
411#define R5K_CONF_SE (_ULCAST_(1) << 12)
412#define R5K_CONF_SS (_ULCAST_(3) << 20)
413
414/* Bits specific to the R10000. */
415#define R10K_CONF_DN (_ULCAST_(3) << 3)
416#define R10K_CONF_CT (_ULCAST_(1) << 5)
417#define R10K_CONF_PE (_ULCAST_(1) << 6)
418#define R10K_CONF_PM (_ULCAST_(3) << 7)
419#define R10K_CONF_EC (_ULCAST_(15)<< 9)
420#define R10K_CONF_SB (_ULCAST_(1) << 13)
421#define R10K_CONF_SK (_ULCAST_(1) << 14)
422#define R10K_CONF_SS (_ULCAST_(7) << 16)
423#define R10K_CONF_SC (_ULCAST_(7) << 19)
424#define R10K_CONF_DC (_ULCAST_(7) << 26)
425#define R10K_CONF_IC (_ULCAST_(7) << 29)
426
427/* Bits specific to the VR41xx. */
428#define VR41_CONF_CS (_ULCAST_(1) << 12)
429#define VR41_CONF_M16 (_ULCAST_(1) << 20)
430#define VR41_CONF_AD (_ULCAST_(1) << 23)
431
432/* Bits specific to the R30xx. */
433#define R30XX_CONF_FDM (_ULCAST_(1) << 19)
434#define R30XX_CONF_REV (_ULCAST_(1) << 22)
435#define R30XX_CONF_AC (_ULCAST_(1) << 23)
436#define R30XX_CONF_RF (_ULCAST_(1) << 24)
437#define R30XX_CONF_HALT (_ULCAST_(1) << 25)
438#define R30XX_CONF_FPINT (_ULCAST_(7) << 26)
439#define R30XX_CONF_DBR (_ULCAST_(1) << 29)
440#define R30XX_CONF_SB (_ULCAST_(1) << 30)
441#define R30XX_CONF_LOCK (_ULCAST_(1) << 31)
442
443/* Bits specific to the TX49. */
444#define TX49_CONF_DC (_ULCAST_(1) << 16)
445#define TX49_CONF_IC (_ULCAST_(1) << 17) /* conflict with CONF_SC */
446#define TX49_CONF_HALT (_ULCAST_(1) << 18)
447#define TX49_CONF_CWFON (_ULCAST_(1) << 27)
448
449/* Bits specific to the MIPS32/64 PRA. */
450#define MIPS_CONF_MT (_ULCAST_(7) << 7)
451#define MIPS_CONF_AR (_ULCAST_(7) << 10)
452#define MIPS_CONF_AT (_ULCAST_(3) << 13)
453#define MIPS_CONF_M (_ULCAST_(1) << 31)
454
455/*
456 * R10000 performance counter definitions.
457 *
458 * FIXME: The R10000 performance counter opens a nice way to implement CPU
459 * time accounting with a precission of one cycle. I don't have
460 * R10000 silicon but just a manual, so ...
461 */
462
463/*
464 * Events counted by counter #0
465 */
466#define CE0_CYCLES 0
467#define CE0_INSN_ISSUED 1
468#define CE0_LPSC_ISSUED 2
469#define CE0_S_ISSUED 3
470#define CE0_SC_ISSUED 4
471#define CE0_SC_FAILED 5
472#define CE0_BRANCH_DECODED 6
473#define CE0_QW_WB_SECONDARY 7
474#define CE0_CORRECTED_ECC_ERRORS 8
475#define CE0_ICACHE_MISSES 9
476#define CE0_SCACHE_I_MISSES 10
477#define CE0_SCACHE_I_WAY_MISSPREDICTED 11
478#define CE0_EXT_INTERVENTIONS_REQ 12
479#define CE0_EXT_INVALIDATE_REQ 13
480#define CE0_VIRTUAL_COHERENCY_COND 14
481#define CE0_INSN_GRADUATED 15
482
483/*
484 * Events counted by counter #1
485 */
486#define CE1_CYCLES 0
487#define CE1_INSN_GRADUATED 1
488#define CE1_LPSC_GRADUATED 2
489#define CE1_S_GRADUATED 3
490#define CE1_SC_GRADUATED 4
491#define CE1_FP_INSN_GRADUATED 5
492#define CE1_QW_WB_PRIMARY 6
493#define CE1_TLB_REFILL 7
494#define CE1_BRANCH_MISSPREDICTED 8
495#define CE1_DCACHE_MISS 9
496#define CE1_SCACHE_D_MISSES 10
497#define CE1_SCACHE_D_WAY_MISSPREDICTED 11
498#define CE1_EXT_INTERVENTION_HITS 12
499#define CE1_EXT_INVALIDATE_REQ 13
500#define CE1_SP_HINT_TO_CEXCL_SC_BLOCKS 14
501#define CE1_SP_HINT_TO_SHARED_SC_BLOCKS 15
502
503/*
504 * These flags define in which priviledge mode the counters count events
505 */
506#define CEB_USER 8 /* Count events in user mode, EXL = ERL = 0 */
507#define CEB_SUPERVISOR 4 /* Count events in supvervisor mode EXL = ERL = 0 */
508#define CEB_KERNEL 2 /* Count events in kernel mode EXL = ERL = 0 */
509#define CEB_EXL 1 /* Count events with EXL = 1, ERL = 0 */
510
511#ifndef __ASSEMBLY__
512
513#define CAUSE_EXCCODE(x) ((CAUSEF_EXCCODE & (x->cp0_cause)) >> CAUSEB_EXCCODE)
514#define CAUSE_EPC(x) (x->cp0_epc + (((x->cp0_cause & CAUSEF_BD) >> CAUSEB_BD) << 2))
515
516/*
517 * Functions to access the r10k performance counter and control registers
518 */
519#define read_r10k_perf_cntr(counter) \
520({ unsigned int __res; \
521 __asm__ __volatile__( \
522 "mfpc\t%0, "STR(counter) \
523 : "=r" (__res)); \
524 __res;})
525
526#define write_r10k_perf_cntr(counter,val) \
527 __asm__ __volatile__( \
528 "mtpc\t%0, "STR(counter) \
529 : : "r" (val));
530
531#define read_r10k_perf_cntl(counter) \
532({ unsigned int __res; \
533 __asm__ __volatile__( \
534 "mfps\t%0, "STR(counter) \
535 : "=r" (__res)); \
536 __res;})
537
538#define write_r10k_perf_cntl(counter,val) \
539 __asm__ __volatile__( \
540 "mtps\t%0, "STR(counter) \
541 : : "r" (val));
542
543/*
544 * Macros to access the system control coprocessor
545 */
546
547#define __read_32bit_c0_register(source, sel) \
548({ int __res; \
549 if (sel == 0) \
550 __asm__ __volatile__( \
551 "mfc0\t%0, " #source "\n\t" \
552 : "=r" (__res)); \
553 else \
554 __asm__ __volatile__( \
555 ".set\tmips32\n\t" \
556 "mfc0\t%0, " #source ", " #sel "\n\t" \
557 ".set\tmips0\n\t" \
558 : "=r" (__res)); \
559 __res; \
560})
561
562#define __read_64bit_c0_register(source, sel) \
563({ unsigned long __res; \
564 if (sel == 0) \
565 __asm__ __volatile__( \
566 ".set\tmips3\n\t" \
567 "dmfc0\t%0, " #source "\n\t" \
568 ".set\tmips0" \
569 : "=r" (__res)); \
570 else \
571 __asm__ __volatile__( \
572 ".set\tmips64\n\t" \
573 "dmfc0\t%0, " #source ", " #sel "\n\t" \
574 ".set\tmips0" \
575 : "=r" (__res)); \
576 __res; \
577})
578
579#define __write_32bit_c0_register(register, sel, value) \
580do { \
581 if (sel == 0) \
582 __asm__ __volatile__( \
583 "mtc0\t%z0, " #register "\n\t" \
584 : : "Jr" (value)); \
585 else \
586 __asm__ __volatile__( \
587 ".set\tmips32\n\t" \
588 "mtc0\t%z0, " #register ", " #sel "\n\t" \
589 ".set\tmips0" \
590 : : "Jr" (value)); \
591} while (0)
592
593#define __write_64bit_c0_register(register, sel, value) \
594do { \
595 if (sel == 0) \
596 __asm__ __volatile__( \
597 ".set\tmips3\n\t" \
598 "dmtc0\t%z0, " #register "\n\t" \
599 ".set\tmips0" \
600 : : "Jr" (value)); \
601 else \
602 __asm__ __volatile__( \
603 ".set\tmips64\n\t" \
604 "dmtc0\t%z0, " #register ", " #sel "\n\t" \
605 ".set\tmips0" \
606 : : "Jr" (value)); \
607} while (0)
608
609#define __read_ulong_c0_register(reg, sel) \
610 ((sizeof(unsigned long) == 4) ? \
611 __read_32bit_c0_register(reg, sel) : \
612 __read_64bit_c0_register(reg, sel))
613
614#define __write_ulong_c0_register(reg, sel, val) \
615do { \
616 if (sizeof(unsigned long) == 4) \
617 __write_32bit_c0_register(reg, sel, val); \
618 else \
619 __write_64bit_c0_register(reg, sel, val); \
620} while (0)
621
622/*
623 * These versions are only needed for systems with more than 38 bits of
624 * physical address space running the 32-bit kernel. That's none atm :-)
625 */
626#define __read_64bit_c0_split(source, sel) \
627({ \
628 unsigned long long val; \
629 unsigned long flags; \
630 \
631 local_irq_save(flags); \
632 if (sel == 0) \
633 __asm__ __volatile__( \
634 ".set\tmips64\n\t" \
635 "dmfc0\t%M0, " #source "\n\t" \
636 "dsll\t%L0, %M0, 32\n\t" \
637 "dsrl\t%M0, %M0, 32\n\t" \
638 "dsrl\t%L0, %L0, 32\n\t" \
639 ".set\tmips0" \
640 : "=r" (val)); \
641 else \
642 __asm__ __volatile__( \
643 ".set\tmips64\n\t" \
644 "dmfc0\t%M0, " #source ", " #sel "\n\t" \
645 "dsll\t%L0, %M0, 32\n\t" \
646 "dsrl\t%M0, %M0, 32\n\t" \
647 "dsrl\t%L0, %L0, 32\n\t" \
648 ".set\tmips0" \
649 : "=r" (val)); \
650 local_irq_restore(flags); \
651 \
652 val; \
653})
654
655#define __write_64bit_c0_split(source, sel, val) \
656do { \
657 unsigned long flags; \
658 \
659 local_irq_save(flags); \
660 if (sel == 0) \
661 __asm__ __volatile__( \
662 ".set\tmips64\n\t" \
663 "dsll\t%L0, %L0, 32\n\t" \
664 "dsrl\t%L0, %L0, 32\n\t" \
665 "dsll\t%M0, %M0, 32\n\t" \
666 "or\t%L0, %L0, %M0\n\t" \
667 "dmtc0\t%L0, " #source "\n\t" \
668 ".set\tmips0" \
669 : : "r" (val)); \
670 else \
671 __asm__ __volatile__( \
672 ".set\tmips64\n\t" \
673 "dsll\t%L0, %L0, 32\n\t" \
674 "dsrl\t%L0, %L0, 32\n\t" \
675 "dsll\t%M0, %M0, 32\n\t" \
676 "or\t%L0, %L0, %M0\n\t" \
677 "dmtc0\t%L0, " #source ", " #sel "\n\t" \
678 ".set\tmips0" \
679 : : "r" (val)); \
680 local_irq_restore(flags); \
681} while (0)
682
683#define read_c0_index() __read_32bit_c0_register($0, 0)
684#define write_c0_index(val) __write_32bit_c0_register($0, 0, val)
685
686#define read_c0_entrylo0() __read_ulong_c0_register($2, 0)
687#define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val)
688
689#define read_c0_entrylo1() __read_ulong_c0_register($3, 0)
690#define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val)
691
692#define read_c0_conf() __read_32bit_c0_register($3, 0)
693#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val)
694
695#define read_c0_context() __read_ulong_c0_register($4, 0)
696#define write_c0_context(val) __write_ulong_c0_register($4, 0, val)
697
698#define read_c0_pagemask() __read_32bit_c0_register($5, 0)
699#define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val)
700
701#define read_c0_wired() __read_32bit_c0_register($6, 0)
702#define write_c0_wired(val) __write_32bit_c0_register($6, 0, val)
703
704#define read_c0_info() __read_32bit_c0_register($7, 0)
705
706#define read_c0_cache() __read_32bit_c0_register($7, 0) /* TX39xx */
707#define write_c0_cache(val) __write_32bit_c0_register($7, 0, val)
708
709#define read_c0_count() __read_32bit_c0_register($9, 0)
710#define write_c0_count(val) __write_32bit_c0_register($9, 0, val)
711
712#define read_c0_entryhi() __read_ulong_c0_register($10, 0)
713#define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val)
714
715#define read_c0_compare() __read_32bit_c0_register($11, 0)
716#define write_c0_compare(val) __write_32bit_c0_register($11, 0, val)
717
718#define read_c0_status() __read_32bit_c0_register($12, 0)
719#define write_c0_status(val) __write_32bit_c0_register($12, 0, val)
720
721#define read_c0_cause() __read_32bit_c0_register($13, 0)
722#define write_c0_cause(val) __write_32bit_c0_register($13, 0, val)
723
724#define read_c0_prid() __read_32bit_c0_register($15, 0)
725
726#define read_c0_config() __read_32bit_c0_register($16, 0)
727#define read_c0_config1() __read_32bit_c0_register($16, 1)
728#define read_c0_config2() __read_32bit_c0_register($16, 2)
729#define read_c0_config3() __read_32bit_c0_register($16, 3)
730#define write_c0_config(val) __write_32bit_c0_register($16, 0, val)
731#define write_c0_config1(val) __write_32bit_c0_register($16, 1, val)
732#define write_c0_config2(val) __write_32bit_c0_register($16, 2, val)
733#define write_c0_config3(val) __write_32bit_c0_register($16, 3, val)
734
735/*
736 * The WatchLo register. There may be upto 8 of them.
737 */
738#define read_c0_watchlo0() __read_ulong_c0_register($18, 0)
739#define read_c0_watchlo1() __read_ulong_c0_register($18, 1)
740#define read_c0_watchlo2() __read_ulong_c0_register($18, 2)
741#define read_c0_watchlo3() __read_ulong_c0_register($18, 3)
742#define read_c0_watchlo4() __read_ulong_c0_register($18, 4)
743#define read_c0_watchlo5() __read_ulong_c0_register($18, 5)
744#define read_c0_watchlo6() __read_ulong_c0_register($18, 6)
745#define read_c0_watchlo7() __read_ulong_c0_register($18, 7)
746#define write_c0_watchlo0(val) __write_ulong_c0_register($18, 0, val)
747#define write_c0_watchlo1(val) __write_ulong_c0_register($18, 1, val)
748#define write_c0_watchlo2(val) __write_ulong_c0_register($18, 2, val)
749#define write_c0_watchlo3(val) __write_ulong_c0_register($18, 3, val)
750#define write_c0_watchlo4(val) __write_ulong_c0_register($18, 4, val)
751#define write_c0_watchlo5(val) __write_ulong_c0_register($18, 5, val)
752#define write_c0_watchlo6(val) __write_ulong_c0_register($18, 6, val)
753#define write_c0_watchlo7(val) __write_ulong_c0_register($18, 7, val)
754
755/*
756 * The WatchHi register. There may be upto 8 of them.
757 */
758#define read_c0_watchhi0() __read_32bit_c0_register($19, 0)
759#define read_c0_watchhi1() __read_32bit_c0_register($19, 1)
760#define read_c0_watchhi2() __read_32bit_c0_register($19, 2)
761#define read_c0_watchhi3() __read_32bit_c0_register($19, 3)
762#define read_c0_watchhi4() __read_32bit_c0_register($19, 4)
763#define read_c0_watchhi5() __read_32bit_c0_register($19, 5)
764#define read_c0_watchhi6() __read_32bit_c0_register($19, 6)
765#define read_c0_watchhi7() __read_32bit_c0_register($19, 7)
766
767#define write_c0_watchhi0(val) __write_32bit_c0_register($19, 0, val)
768#define write_c0_watchhi1(val) __write_32bit_c0_register($19, 1, val)
769#define write_c0_watchhi2(val) __write_32bit_c0_register($19, 2, val)
770#define write_c0_watchhi3(val) __write_32bit_c0_register($19, 3, val)
771#define write_c0_watchhi4(val) __write_32bit_c0_register($19, 4, val)
772#define write_c0_watchhi5(val) __write_32bit_c0_register($19, 5, val)
773#define write_c0_watchhi6(val) __write_32bit_c0_register($19, 6, val)
774#define write_c0_watchhi7(val) __write_32bit_c0_register($19, 7, val)
775
776#define read_c0_xcontext() __read_ulong_c0_register($20, 0)
777#define write_c0_xcontext(val) __write_ulong_c0_register($20, 0, val)
778
779#define read_c0_intcontrol() __read_32bit_c0_register($20, 1)
780#define write_c0_intcontrol(val) __write_32bit_c0_register($20, 1, val)
781
782#define read_c0_framemask() __read_32bit_c0_register($21, 0)
783#define write_c0_framemask(val) __write_32bit_c0_register($21, 0, val)
784
785#define read_c0_debug() __read_32bit_c0_register($23, 0)
786#define write_c0_debug(val) __write_32bit_c0_register($23, 0, val)
787
788#define read_c0_depc() __read_ulong_c0_register($24, 0)
789#define write_c0_depc(val) __write_ulong_c0_register($24, 0, val)
790
791#define read_c0_ecc() __read_32bit_c0_register($26, 0)
792#define write_c0_ecc(val) __write_32bit_c0_register($26, 0, val)
793
794#define read_c0_derraddr0() __read_ulong_c0_register($26, 1)
795#define write_c0_derraddr0(val) __write_ulong_c0_register($26, 1, val)
796
797#define read_c0_cacheerr() __read_32bit_c0_register($27, 0)
798
799#define read_c0_derraddr1() __read_ulong_c0_register($27, 1)
800#define write_c0_derraddr1(val) __write_ulong_c0_register($27, 1, val)
801
802#define read_c0_taglo() __read_32bit_c0_register($28, 0)
803#define write_c0_taglo(val) __write_32bit_c0_register($28, 0, val)
804
805#define read_c0_taghi() __read_32bit_c0_register($29, 0)
806#define write_c0_taghi(val) __write_32bit_c0_register($29, 0, val)
807
808#define read_c0_errorepc() __read_ulong_c0_register($30, 0)
809#define write_c0_errorepc(val) __write_ulong_c0_register($30, 0, val)
810
811#define read_c0_epc() __read_ulong_c0_register($14, 0)
812#define write_c0_epc(val) __write_ulong_c0_register($14, 0, val)
813
814#if 1
815/*
816 * Macros to access the system control coprocessor
817 */
818#define read_32bit_cp0_register(source) \
819({ int __res; \
820 __asm__ __volatile__( \
821 ".set\tpush\n\t" \
822 ".set\treorder\n\t" \
823 "mfc0\t%0,"STR(source)"\n\t" \
824 ".set\tpop" \
825 : "=r" (__res)); \
826 __res;})
827
828#define read_32bit_cp0_set1_register(source) \
829({ int __res; \
830 __asm__ __volatile__( \
831 ".set\tpush\n\t" \
832 ".set\treorder\n\t" \
833 "cfc0\t%0,"STR(source)"\n\t" \
834 ".set\tpop" \
835 : "=r" (__res)); \
836 __res;})
837
838/*
839 * For now use this only with interrupts disabled!
840 */
841#define read_64bit_cp0_register(source) \
842({ int __res; \
843 __asm__ __volatile__( \
844 ".set\tmips3\n\t" \
845 "dmfc0\t%0,"STR(source)"\n\t" \
846 ".set\tmips0" \
847 : "=r" (__res)); \
848 __res;})
849
850#define write_32bit_cp0_register(register,value) \
851 __asm__ __volatile__( \
852 "mtc0\t%0,"STR(register)"\n\t" \
853 "nop" \
854 : : "r" (value));
855
856#define write_32bit_cp0_set1_register(register,value) \
857 __asm__ __volatile__( \
858 "ctc0\t%0,"STR(register)"\n\t" \
859 "nop" \
860 : : "r" (value));
861
862#define write_64bit_cp0_register(register,value) \
863 __asm__ __volatile__( \
864 ".set\tmips3\n\t" \
865 "dmtc0\t%0,"STR(register)"\n\t" \
866 ".set\tmips0" \
867 : : "r" (value))
868
869/*
870 * This should be changed when we get a compiler that support the MIPS32 ISA.
871 */
872#define read_mips32_cp0_config1() \
873({ int __res; \
874 __asm__ __volatile__( \
875 ".set\tnoreorder\n\t" \
876 ".set\tnoat\n\t" \
877 "#.set\tmips64\n\t" \
878 "#mfc0\t$1, $16, 1\n\t" \
879 "#.set\tmips0\n\t" \
880 ".word\t0x40018001\n\t" \
881 "move\t%0,$1\n\t" \
882 ".set\tat\n\t" \
883 ".set\treorder" \
884 :"=r" (__res)); \
885 __res;})
886
887#endif
888/*
889 * Macros to access the floating point coprocessor control registers
890 */
891#define read_32bit_cp1_register(source) \
892({ int __res; \
893 __asm__ __volatile__( \
894 ".set\tpush\n\t" \
895 ".set\treorder\n\t" \
896 "cfc1\t%0,"STR(source)"\n\t" \
897 ".set\tpop" \
898 : "=r" (__res)); \
899 __res;})
900
901/* TLB operations. */
902static inline void tlb_probe(void)
903{
904 __asm__ __volatile__(
905 ".set noreorder\n\t"
906 "tlbp\n\t"
907 ".set reorder");
908}
909
910static inline void tlb_read(void)
911{
912 __asm__ __volatile__(
913 ".set noreorder\n\t"
914 "tlbr\n\t"
915 ".set reorder");
916}
917
918static inline void tlb_write_indexed(void)
919{
920 __asm__ __volatile__(
921 ".set noreorder\n\t"
922 "tlbwi\n\t"
923 ".set reorder");
924}
925
926static inline void tlb_write_random(void)
927{
928 __asm__ __volatile__(
929 ".set noreorder\n\t"
930 "tlbwr\n\t"
931 ".set reorder");
932}
933
934/*
935 * Manipulate bits in a c0 register.
936 */
937#define __BUILD_SET_C0(name,register) \
938static inline unsigned int \
939set_c0_##name(unsigned int set) \
940{ \
941 unsigned int res; \
942 \
943 res = read_c0_##name(); \
944 res |= set; \
945 write_c0_##name(res); \
946 \
947 return res; \
948} \
949 \
950static inline unsigned int \
951clear_c0_##name(unsigned int clear) \
952{ \
953 unsigned int res; \
954 \
955 res = read_c0_##name(); \
956 res &= ~clear; \
957 write_c0_##name(res); \
958 \
959 return res; \
960} \
961 \
962static inline unsigned int \
963change_c0_##name(unsigned int change, unsigned int new) \
964{ \
965 unsigned int res; \
966 \
967 res = read_c0_##name(); \
968 res &= ~change; \
969 res |= (new & change); \
970 write_c0_##name(res); \
971 \
972 return res; \
973}
974
975__BUILD_SET_C0(status,CP0_STATUS)
976__BUILD_SET_C0(cause,CP0_CAUSE)
977__BUILD_SET_C0(config,CP0_CONFIG)
978
979#define set_cp0_status(x) set_c0_status(x)
980#define set_cp0_cause(x) set_c0_cause(x)
981#define set_cp0_config(x) set_c0_config(x)
982
983#endif /* !__ASSEMBLY__ */
984
985#endif /* _ASM_MIPSREGS_H */