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