b291ea30b5e62ffbf30f120b083754c8d658a2b5
[openwrt.git] / target / linux / brcm-2.4 / files / arch / mips / bcm947xx / include / mipsinc.h
1 /*
2  * HND Run Time Environment for standalone MIPS programs.
3  *
4  * Copyright 2007, Broadcom Corporation
5  * All Rights Reserved.
6  * 
7  * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8  * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9  * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10  * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
11  *
12  * $Id$
13  */
14
15 #ifndef _MISPINC_H
16 #define _MISPINC_H
17
18
19 /* MIPS defines */
20
21 #ifdef  _LANGUAGE_ASSEMBLY
22
23 /*
24  * Symbolic register names for 32 bit ABI
25  */
26 #define zero    $0      /* wired zero */
27 #define AT      $1      /* assembler temp - uppercase because of ".set at" */
28 #define v0      $2      /* return value */
29 #define v1      $3
30 #define a0      $4      /* argument registers */
31 #define a1      $5
32 #define a2      $6
33 #define a3      $7
34 #define t0      $8      /* caller saved */
35 #define t1      $9
36 #define t2      $10
37 #define t3      $11
38 #define t4      $12
39 #define t5      $13
40 #define t6      $14
41 #define t7      $15
42 #define s0      $16     /* callee saved */
43 #define s1      $17
44 #define s2      $18
45 #define s3      $19
46 #define s4      $20
47 #define s5      $21
48 #define s6      $22
49 #define s7      $23
50 #define t8      $24     /* caller saved */
51 #define t9      $25
52 #define jp      $25     /* PIC jump register */
53 #define k0      $26     /* kernel scratch */
54 #define k1      $27
55 #define gp      $28     /* global pointer */
56 #define sp      $29     /* stack pointer */
57 #define fp      $30     /* frame pointer */
58 #define s8      $30     /* same like fp! */
59 #define ra      $31     /* return address */
60
61
62 /* CP0 Registers */
63
64 #define C0_INX          $0
65 #define C0_RAND         $1
66 #define C0_TLBLO0       $2
67 #define C0_TLBLO        C0_TLBLO0
68 #define C0_TLBLO1       $3
69 #define C0_CTEXT        $4
70 #define C0_PGMASK       $5
71 #define C0_WIRED        $6
72 #define C0_INFO         $7
73 #define C0_BADVADDR     $8
74 #define C0_COUNT        $9
75 #define C0_TLBHI        $10
76 #define C0_COMPARE      $11
77 #define C0_SR           $12
78 #define C0_STATUS       C0_SR
79 #define C0_CAUSE        $13
80 #define C0_EPC          $14
81 #define C0_PRID         $15
82 #define C0_CONFIG       $16
83 #define C0_LLADDR       $17
84 #define C0_WATCHLO      $18
85 #define C0_WATCHHI      $19
86 #define C0_XCTEXT       $20
87 #define C0_DIAGNOSTIC   $22
88 #define C0_BROADCOM     C0_DIAGNOSTIC
89 #define C0_PERFORMANCE  $25
90 #define C0_ECC          $26
91 #define C0_CACHEERR     $27
92 #define C0_TAGLO        $28
93 #define C0_TAGHI        $29
94 #define C0_ERREPC       $30
95 #define C0_DESAVE       $31
96
97 /*
98  * LEAF - declare leaf routine
99  */
100 #define LEAF(symbol)                            \
101                 .globl  symbol;                 \
102                 .align  2;                      \
103                 .type   symbol, @function;      \
104                 .ent    symbol, 0;              \
105 symbol:         .frame  sp, 0, ra
106
107 /*
108  * END - mark end of function
109  */
110 #define END(function)                           \
111                 .end    function;               \
112                 .size   function, . - function
113
114 #define _ULCAST_
115
116 #define MFC0_SEL(dst, src, sel) \
117                 .word\t(0x40000000 | ((dst) << 16) | ((src) << 11) | (sel))
118
119
120 #define MTC0_SEL(dst, src, sel) \
121                 .word\t(0x40800000 | ((dst) << 16) | ((src) << 11) | (sel))
122
123 #else
124
125 /*
126  * The following macros are especially useful for __asm__
127  * inline assembler.
128  */
129 #ifndef __STR
130 #define __STR(x) #x
131 #endif
132 #ifndef STR
133 #define STR(x) __STR(x)
134 #endif
135
136 #define _ULCAST_ (unsigned long)
137
138
139 /* CP0 Registers */
140
141 #define C0_INX          0               /* CP0: TLB Index */
142 #define C0_RAND         1               /* CP0: TLB Random */
143 #define C0_TLBLO0       2               /* CP0: TLB EntryLo0 */
144 #define C0_TLBLO        C0_TLBLO0       /* CP0: TLB EntryLo0 */
145 #define C0_TLBLO1       3               /* CP0: TLB EntryLo1 */
146 #define C0_CTEXT        4               /* CP0: Context */
147 #define C0_PGMASK       5               /* CP0: TLB PageMask */
148 #define C0_WIRED        6               /* CP0: TLB Wired */
149 #define C0_INFO         7               /* CP0: Info */
150 #define C0_BADVADDR     8               /* CP0: Bad Virtual Address */
151 #define C0_COUNT        9               /* CP0: Count */
152 #define C0_TLBHI        10              /* CP0: TLB EntryHi */
153 #define C0_COMPARE      11              /* CP0: Compare */
154 #define C0_SR           12              /* CP0: Processor Status */
155 #define C0_STATUS       C0_SR           /* CP0: Processor Status */
156 #define C0_CAUSE        13              /* CP0: Exception Cause */
157 #define C0_EPC          14              /* CP0: Exception PC */
158 #define C0_PRID         15              /* CP0: Processor Revision Indentifier */
159 #define C0_CONFIG       16              /* CP0: Config */
160 #define C0_LLADDR       17              /* CP0: LLAddr */
161 #define C0_WATCHLO      18              /* CP0: WatchpointLo */
162 #define C0_WATCHHI      19              /* CP0: WatchpointHi */
163 #define C0_XCTEXT       20              /* CP0: XContext */
164 #define C0_DIAGNOSTIC   22              /* CP0: Diagnostic */
165 #define C0_BROADCOM     C0_DIAGNOSTIC   /* CP0: Broadcom Register */
166 #define C0_PERFORMANCE  25              /* CP0: Performance Counter/Control Registers */
167 #define C0_ECC          26              /* CP0: ECC */
168 #define C0_CACHEERR     27              /* CP0: CacheErr */
169 #define C0_TAGLO        28              /* CP0: TagLo */
170 #define C0_TAGHI        29              /* CP0: TagHi */
171 #define C0_ERREPC       30              /* CP0: ErrorEPC */
172 #define C0_DESAVE       31              /* CP0: DebugSave */
173
174 #endif  /* _LANGUAGE_ASSEMBLY */
175
176 /*
177  * Memory segments (32bit kernel mode addresses)
178  */
179 #undef KUSEG
180 #undef KSEG0
181 #undef KSEG1
182 #undef KSEG2
183 #undef KSEG3
184 #define KUSEG           0x00000000
185 #define KSEG0           0x80000000
186 #define KSEG1           0xa0000000
187 #define KSEG2           0xc0000000
188 #define KSEG3           0xe0000000
189 #define PHYSADDR_MASK   0x1fffffff
190
191 /*
192  * Map an address to a certain kernel segment
193  */
194 #undef PHYSADDR
195 #undef KSEG0ADDR
196 #undef KSEG1ADDR
197 #undef KSEG2ADDR
198 #undef KSEG3ADDR
199
200 #define PHYSADDR(a)     (_ULCAST_(a) & PHYSADDR_MASK)
201 #define KSEG0ADDR(a)    ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG0)
202 #define KSEG1ADDR(a)    ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG1)
203 #define KSEG2ADDR(a)    ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG2)
204 #define KSEG3ADDR(a)    ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG3)
205
206
207 #ifndef Index_Invalidate_I
208 /*
209  * Cache Operations
210  */
211 #define Index_Invalidate_I      0x00
212 #define Index_Writeback_Inv_D   0x01
213 #define Index_Invalidate_SI     0x02
214 #define Index_Writeback_Inv_SD  0x03
215 #define Index_Load_Tag_I        0x04
216 #define Index_Load_Tag_D        0x05
217 #define Index_Load_Tag_SI       0x06
218 #define Index_Load_Tag_SD       0x07
219 #define Index_Store_Tag_I       0x08
220 #define Index_Store_Tag_D       0x09
221 #define Index_Store_Tag_SI      0x0A
222 #define Index_Store_Tag_SD      0x0B
223 #define Create_Dirty_Excl_D     0x0d
224 #define Create_Dirty_Excl_SD    0x0f
225 #define Hit_Invalidate_I        0x10
226 #define Hit_Invalidate_D        0x11
227 #define Hit_Invalidate_SI       0x12
228 #define Hit_Invalidate_SD       0x13
229 #define Fill_I                  0x14
230 #define Hit_Writeback_Inv_D     0x15
231                                         /* 0x16 is unused */
232 #define Hit_Writeback_Inv_SD    0x17
233 #define R5K_Page_Invalidate_S   0x17
234 #define Hit_Writeback_I         0x18
235 #define Hit_Writeback_D         0x19
236                                         /* 0x1a is unused */
237 #define Hit_Writeback_SD        0x1b
238                                         /* 0x1c is unused */
239                                         /* 0x1e is unused */
240 #define Hit_Set_Virtual_SI      0x1e
241 #define Hit_Set_Virtual_SD      0x1f
242 #endif  /* !Index_Invalidate_I */
243
244
245 /*
246  * R4x00 interrupt enable / cause bits
247  */
248 #define IE_SW0                  (_ULCAST_(1) <<  8)
249 #define IE_SW1                  (_ULCAST_(1) <<  9)
250 #define IE_IRQ0                 (_ULCAST_(1) << 10)
251 #define IE_IRQ1                 (_ULCAST_(1) << 11)
252 #define IE_IRQ2                 (_ULCAST_(1) << 12)
253 #define IE_IRQ3                 (_ULCAST_(1) << 13)
254 #define IE_IRQ4                 (_ULCAST_(1) << 14)
255 #define IE_IRQ5                 (_ULCAST_(1) << 15)
256
257 #ifndef ST0_UM
258 /*
259  * Bitfields in the mips32 cp0 status register
260  */
261 #define ST0_IE                  0x00000001
262 #define ST0_EXL                 0x00000002
263 #define ST0_ERL                 0x00000004
264 #define ST0_UM                  0x00000010
265 #define ST0_SWINT0              0x00000100
266 #define ST0_SWINT1              0x00000200
267 #define ST0_HWINT0              0x00000400
268 #define ST0_HWINT1              0x00000800
269 #define ST0_HWINT2              0x00001000
270 #define ST0_HWINT3              0x00002000
271 #define ST0_HWINT4              0x00004000
272 #define ST0_HWINT5              0x00008000
273 #define ST0_IM                  0x0000ff00
274 #define ST0_NMI                 0x00080000
275 #define ST0_SR                  0x00100000
276 #define ST0_TS                  0x00200000
277 #define ST0_BEV                 0x00400000
278 #define ST0_RE                  0x02000000
279 #define ST0_RP                  0x08000000
280 #define ST0_CU                  0xf0000000
281 #define ST0_CU0                 0x10000000
282 #define ST0_CU1                 0x20000000
283 #define ST0_CU2                 0x40000000
284 #define ST0_CU3                 0x80000000
285 #endif  /* !ST0_UM */
286
287
288 /*
289  * Bitfields in the mips32 cp0 cause register
290  */
291 #define C_EXC                   0x0000007c
292 #define C_EXC_SHIFT             2
293 #define C_INT                   0x0000ff00
294 #define C_INT_SHIFT             8
295 #define C_SW0                   (_ULCAST_(1) <<  8)
296 #define C_SW1                   (_ULCAST_(1) <<  9)
297 #define C_IRQ0                  (_ULCAST_(1) << 10)
298 #define C_IRQ1                  (_ULCAST_(1) << 11)
299 #define C_IRQ2                  (_ULCAST_(1) << 12)
300 #define C_IRQ3                  (_ULCAST_(1) << 13)
301 #define C_IRQ4                  (_ULCAST_(1) << 14)
302 #define C_IRQ5                  (_ULCAST_(1) << 15)
303 #define C_WP                    0x00400000
304 #define C_IV                    0x00800000
305 #define C_CE                    0x30000000
306 #define C_CE_SHIFT              28
307 #define C_BD                    0x80000000
308
309 /* Values in C_EXC */
310 #define EXC_INT                 0
311 #define EXC_TLBM                1
312 #define EXC_TLBL                2
313 #define EXC_TLBS                3
314 #define EXC_AEL                 4
315 #define EXC_AES                 5
316 #define EXC_IBE                 6
317 #define EXC_DBE                 7
318 #define EXC_SYS                 8
319 #define EXC_BPT                 9
320 #define EXC_RI                  10
321 #define EXC_CU                  11
322 #define EXC_OV                  12
323 #define EXC_TR                  13
324 #define EXC_WATCH               23
325 #define EXC_MCHK                24
326
327
328 /*
329  * Bits in the cp0 config register.
330  */
331 #define CONF_CM_CACHABLE_NO_WA          0
332 #define CONF_CM_CACHABLE_WA             1
333 #define CONF_CM_UNCACHED                2
334 #define CONF_CM_CACHABLE_NONCOHERENT    3
335 #define CONF_CM_CACHABLE_CE             4
336 #define CONF_CM_CACHABLE_COW            5
337 #define CONF_CM_CACHABLE_CUW            6
338 #define CONF_CM_CACHABLE_ACCELERATED    7
339 #define CONF_CM_CMASK                   7
340 #define CONF_CU                         (_ULCAST_(1) <<  3)
341 #define CONF_DB                         (_ULCAST_(1) <<  4)
342 #define CONF_IB                         (_ULCAST_(1) <<  5)
343 #define CONF_SE                         (_ULCAST_(1) << 12)
344 #ifndef CONF_BE                             /* duplicate in mipsregs.h */
345 #define CONF_BE                         (_ULCAST_(1) << 15)
346 #endif
347 #define CONF_SC                         (_ULCAST_(1) << 17)
348 #define CONF_AC                         (_ULCAST_(1) << 23)
349 #define CONF_HALT                       (_ULCAST_(1) << 25)
350 #ifndef CONF_M                              /* duplicate in mipsregs.h */
351 #define CONF_M                          (_ULCAST_(1) << 31)
352 #endif
353
354
355 /*
356  * Bits in the cp0 config register select 1.
357  */
358 #define CONF1_FP                0x00000001      /* FPU present */
359 #define CONF1_EP                0x00000002      /* EJTAG present */
360 #define CONF1_CA                0x00000004      /* mips16 implemented */
361 #define CONF1_WR                0x00000008      /* Watch registers present */
362 #define CONF1_PC                0x00000010      /* Performance counters present */
363 #define CONF1_DA_SHIFT          7               /* D$ associativity */
364 #define CONF1_DA_MASK           0x00000380
365 #define CONF1_DA_BASE           1
366 #define CONF1_DL_SHIFT          10              /* D$ line size */
367 #define CONF1_DL_MASK           0x00001c00
368 #define CONF1_DL_BASE           2
369 #define CONF1_DS_SHIFT          13              /* D$ sets/way */
370 #define CONF1_DS_MASK           0x0000e000
371 #define CONF1_DS_BASE           64
372 #define CONF1_IA_SHIFT          16              /* I$ associativity */
373 #define CONF1_IA_MASK           0x00070000
374 #define CONF1_IA_BASE           1
375 #define CONF1_IL_SHIFT          19              /* I$ line size */
376 #define CONF1_IL_MASK           0x00380000
377 #define CONF1_IL_BASE           2
378 #define CONF1_IS_SHIFT          22              /* Instruction cache sets/way */
379 #define CONF1_IS_MASK           0x01c00000
380 #define CONF1_IS_BASE           64
381 #define CONF1_MS_MASK           0x7e000000      /* Number of tlb entries */
382 #define CONF1_MS_SHIFT          25
383
384 /* PRID register */
385 #define PRID_COPT_MASK          0xff000000
386 #define PRID_COMP_MASK          0x00ff0000
387 #define PRID_IMP_MASK           0x0000ff00
388 #define PRID_REV_MASK           0x000000ff
389
390 #define PRID_COMP_LEGACY        0x000000
391 #define PRID_COMP_MIPS          0x010000
392 #define PRID_COMP_BROADCOM      0x020000
393 #define PRID_COMP_ALCHEMY       0x030000
394 #define PRID_COMP_SIBYTE        0x040000
395 #define PRID_IMP_BCM4710        0x4000
396 #define PRID_IMP_BCM3302        0x9000
397 #define PRID_IMP_BCM3303        0x9100
398
399 #define PRID_IMP_UNKNOWN        0xff00
400
401 #define BCM330X(id) \
402                 (((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == \
403                  (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) || \
404                 ((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == \
405                  (PRID_COMP_BROADCOM | PRID_IMP_BCM3303)))
406
407 /* Bits in C0_BROADCOM */
408 #define BRCM_PFC_AVAIL          0x20000000      /* PFC is available */
409 #define BRCM_DC_ENABLE          0x40000000      /* Enable Data $ */
410 #define BRCM_IC_ENABLE          0x80000000      /* Enable Instruction $ */
411 #define BRCM_PFC_ENABLE         0x00400000      /* Obsolete? Enable PFC (at least on 4310) */
412 #define BRCM_CLF_ENABLE         0x00100000      /* Enable cache line first feature */
413
414 /* PreFetch Cache aka Read Ahead Cache */
415
416 #define PFC_CR0                 0xff400000      /* control reg 0 */
417 #define PFC_CR1                 0xff400004      /* control reg 1 */
418
419 /* PFC operations */
420 #define PFC_I                   0x00000001      /* Enable PFC use for instructions */
421 #define PFC_D                   0x00000002      /* Enable PFC use for data */
422 #define PFC_PFI                 0x00000004      /* Enable seq. prefetch for instructions */
423 #define PFC_PFD                 0x00000008      /* Enable seq. prefetch for data */
424 #define PFC_CINV                0x00000010      /* Enable selective (i/d) cacheop flushing */
425 #define PFC_NCH                 0x00000020      /* Disable flushing based on cacheops */
426 #define PFC_DPF                 0x00000040      /* Enable directional prefetching */
427 #define PFC_FLUSH               0x00000100      /* Flush the PFC */
428 #define PFC_BRR                 0x40000000      /* Bus error indication */
429 #define PFC_PWR                 0x80000000      /* Disable power saving (clock gating) */
430
431 /* Handy defaults */
432 #define PFC_DISABLED            0
433 #define PFC_AUTO                        0xffffffff      /* auto select the default mode */
434 #define PFC_INST                (PFC_I | PFC_PFI | PFC_CINV)
435 #define PFC_INST_NOPF           (PFC_I | PFC_CINV)
436 #define PFC_DATA                (PFC_D | PFC_PFD | PFC_CINV)
437 #define PFC_DATA_NOPF           (PFC_D | PFC_CINV)
438 #define PFC_I_AND_D             (PFC_INST | PFC_DATA)
439 #define PFC_I_AND_D_NOPF        (PFC_INST_NOPF | PFC_DATA_NOPF)
440
441 #ifndef _LANGUAGE_ASSEMBLY
442
443 /*
444  * Macros to access the system control coprocessor
445  */
446
447 #define MFC0(source, sel)                                       \
448 ({                                                              \
449         int __res;                                              \
450         __asm__ __volatile__("                                  \
451         .set\tnoreorder;                                        \
452         .set\tnoat;                                             \
453         .word\t"STR(0x40010000 | ((source) << 11) | (sel))";    \
454         move\t%0, $1;                                           \
455         .set\tat;                                               \
456         .set\treorder"                                          \
457         :"=r" (__res)                                           \
458         :                                                       \
459         :"$1");                                                 \
460         __res;                                                  \
461 })
462
463 #define MTC0(source, sel, value)                                \
464 do {                                                            \
465         __asm__ __volatile__("                                  \
466         .set\tnoreorder;                                        \
467         .set\tnoat;                                             \
468         move\t$1, %z0;                                          \
469         .word\t"STR(0x40810000 | ((source) << 11) | (sel))";    \
470         .set\tat;                                               \
471         .set\treorder"                                          \
472         :                                                       \
473         :"jr" (value)                                           \
474         :"$1");                                                 \
475 } while (0)
476
477 #define get_c0_count()                                          \
478 ({                                                              \
479         int __res;                                              \
480         __asm__ __volatile__("                                  \
481         .set\tnoreorder;                                        \
482         .set\tnoat;                                             \
483         mfc0\t%0, $9;                                           \
484         .set\tat;                                               \
485         .set\treorder"                                          \
486         :"=r" (__res));                                         \
487         __res;                                                  \
488 })
489
490 static INLINE void icache_probe(uint32 config1, uint *size, uint *lsize)
491 {
492         uint lsz, sets, ways;
493
494         /* Instruction Cache Size = Associativity * Line Size * Sets Per Way */
495         if ((lsz = ((config1 & CONF1_IL_MASK) >> CONF1_IL_SHIFT)))
496                 lsz = CONF1_IL_BASE << lsz;
497         sets = CONF1_IS_BASE << ((config1 & CONF1_IS_MASK) >> CONF1_IS_SHIFT);
498         ways = CONF1_IA_BASE + ((config1 & CONF1_IA_MASK) >> CONF1_IA_SHIFT);
499         *size = lsz * sets * ways;
500         *lsize = lsz;
501 }
502
503 static INLINE void dcache_probe(uint32 config1, uint *size, uint *lsize)
504 {
505         uint lsz, sets, ways;
506
507         /* Data Cache Size = Associativity * Line Size * Sets Per Way */
508         if ((lsz = ((config1 & CONF1_DL_MASK) >> CONF1_DL_SHIFT)))
509                 lsz = CONF1_DL_BASE << lsz;
510         sets = CONF1_DS_BASE << ((config1 & CONF1_DS_MASK) >> CONF1_DS_SHIFT);
511         ways = CONF1_DA_BASE + ((config1 & CONF1_DA_MASK) >> CONF1_DA_SHIFT);
512         *size = lsz * sets * ways;
513         *lsize = lsz;
514 }
515
516 #define cache_op(base, op)                      \
517         __asm__ __volatile__("                  \
518                 .set noreorder;                 \
519                 .set mips3;                     \
520                 cache %1, (%0);                 \
521                 .set mips0;                     \
522                 .set reorder"                   \
523                 :                               \
524                 : "r" (base),                   \
525                   "i" (op));
526
527 #define cache_unroll4(base, delta, op)          \
528         __asm__ __volatile__("                  \
529                 .set noreorder;                 \
530                 .set mips3;                     \
531                 cache %1, 0(%0);                \
532                 cache %1, delta(%0);            \
533                 cache %1, (2 * delta)(%0);      \
534                 cache %1, (3 * delta)(%0);      \
535                 .set mips0;                     \
536                 .set reorder"                   \
537                 :                               \
538                 : "r" (base),                   \
539                   "i" (op));
540
541 #endif /* !_LANGUAGE_ASSEMBLY */
542
543 #endif  /* _MISPINC_H */