1 /* $Id: ross.h,v 1.9 1996/04/08 08:34:21 davem Exp $
2 * ross.h: Ross module specific definitions and defines.
3 *
4 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
5 */
6
7 #ifndef _SPARC_ROSS_H
8 #define _SPARC_ROSS_H
9
10 #include <asm/asi.h>
11
12 /* Ross made Hypersparcs have a %psr 'impl' field of '0001'. The 'vers'
13 * field has '1111'.
14 */
15
16 /* The MMU control register fields on the HyperSparc.
17 *
18 * -----------------------------------------------------------------
19 * |implvers| RSV |CWR|SE|WBE| MID |BM| C|CS|MR|CM|RSV|CE|RSV|NF|ME|
20 * -----------------------------------------------------------------
21 * 31 24 23-22 21 20 19 18-15 14 13 12 11 10 9 8 7-2 1 0
22 *
23 * Phew, lots of fields there ;-)
24 *
25 * CWR: Cache Wrapping Enabled, if one cache wrapping is on.
26 * SE: Snoop Enable, turns on bus snooping for cache activity if one.
27 * WBE: Write Buffer Enable, one turns it on.
28 * MID: The ModuleID of the chip for MBus transactions.
29 * BM: Boot-Mode. One indicates the MMU is in boot mode.
30 * C: Indicates whether accesses are cachable while the MMU is
31 * disabled.
32 * CS: Cache Size -- 0 = 128k, 1 = 256k
33 * MR: Memory Reflection, one indicates that the memory bus connected
34 * to the MBus supports memory reflection.
35 * CM: Cache Mode -- 0 = write-through, 1 = copy-back
36 * CE: Cache Enable -- 0 = no caching, 1 = cache is on
37 * NF: No Fault -- 0 = faults trap the CPU from supervisor mode
38 * 1 = faults from supervisor mode do not generate traps
39 * ME: MMU Enable -- 0 = MMU is off, 1 = MMU is on
40 */
41
42 #define HYPERSPARC_CWENABLE 0x00200000
43 #define HYPERSPARC_SBENABLE 0x00100000
44 #define HYPERSPARC_WBENABLE 0x00080000
45 #define HYPERSPARC_MIDMASK 0x00078000
46 #define HYPERSPARC_BMODE 0x00004000
47 #define HYPERSPARC_ACENABLE 0x00002000
48 #define HYPERSPARC_CSIZE 0x00001000
49 #define HYPERSPARC_MRFLCT 0x00000800
50 #define HYPERSPARC_CMODE 0x00000400
51 #define HYPERSPARC_CENABLE 0x00000100
52 #define HYPERSPARC_NFAULT 0x00000002
53 #define HYPERSPARC_MENABLE 0x00000001
54
55
56 /* The ICCR instruction cache register on the HyperSparc.
57 *
58 * -----------------------------------------------
59 * | | FTD | ICE |
60 * -----------------------------------------------
61 * 31 1 0
62 *
63 * This register is accessed using the V8 'wrasr' and 'rdasr'
64 * opcodes, since not all assemblers understand them and those
65 * that do use different semantics I will just hard code the
66 * instruction with a '.word' statement.
67 *
68 * FTD: If set to one flush instructions executed during an
69 * instruction cache hit occurs, the corresponding line
70 * for said cache-hit is invalidated. If FTD is zero,
71 * an unimplemented 'flush' trap will occur when any
72 * flush is executed by the processor.
73 *
74 * ICE: If set to one, the instruction cache is enabled. If
75 * zero, the cache will not be used for instruction fetches.
76 *
77 * All other bits are read as zeros, and writes to them have no
78 * effect.
79 *
80 * Wheee, not many assemblers understand the %iccr register nor
81 * the generic asr r/w instructions.
82 *
83 * 1000 0011 0100 0111 1100 0000 0000 0000 ! rd %iccr, %g1
84 *
85 * 0x 8 3 4 7 c 0 0 0 ! 0x8347c000
86 *
87 * 1011 1111 1000 0000 0110 0000 0000 0000 ! wr %g1, 0x0, %iccr
88 *
89 * 0x b f 8 0 6 0 0 0 ! 0xbf806000
90 *
91 */
92
93 #define HYPERSPARC_ICCR_FTD 0x00000002
94 #define HYPERSPARC_ICCR_ICE 0x00000001
95
96 extern inline unsigned int get_ross_icr(void)
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
97 {
98 unsigned int icreg;
99
100 __asm__ __volatile__(".word 0x8347c000\n\t" /* rd %iccr, %g1 */
101 "mov %%g1, %0\n\t" :
102 "=r" (icreg) : :
103 "g1", "memory");
104
105 return icreg;
106 }
107
108 extern inline void put_ross_icr(unsigned int icreg)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
109 {
110 __asm__ __volatile__("or %%g0, %0, %%g1\n\t"
111 ".word 0xbf806000\n\t" /* wr %g1, 0x0, %iccr */
112 "nop\n\t"
113 "nop\n\t"
114 "nop\n\t" : :
115 "r" (icreg) :
116 "g1", "memory");
117
118 return;
119 }
120
121 /* HyperSparc specific cache flushing. */
122
123 /* This is for the on-chip instruction cache. */
124 extern inline void hyper_flush_whole_icache(void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
125 {
126 __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" : :
127 "i" (ASI_M_FLUSH_IWHOLE));
128 return;
129 }
130
131 extern int hyper_cache_size;
132 extern int hyper_line_size;
133
134 extern inline void hyper_clear_all_tags(void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
135 {
136 unsigned long addr;
137
138 for(addr = 0; addr < hyper_cache_size; addr += hyper_line_size)
139 __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
140 "r" (addr), "i" (ASI_M_DATAC_TAG));
141 }
142
143 extern inline void hyper_flush_unconditional_combined(void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
144 {
145 unsigned long addr;
146
147 for(addr = 0; addr < hyper_cache_size; addr += hyper_line_size)
148 __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
149 "r" (addr), "i" (ASI_M_FLUSH_CTX));
150 }
151
152 extern inline void hyper_flush_cache_user(void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
153 {
154 unsigned long addr;
155
156 for(addr = 0; addr < hyper_cache_size; addr += hyper_line_size)
157 __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
158 "r" (addr), "i" (ASI_M_FLUSH_USER));
159 }
160
161 extern inline void hyper_flush_cache_page(unsigned long page)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
162 {
163 unsigned long end;
164
165 page &= PAGE_MASK;
166 end = page + PAGE_SIZE;
167 while(page < end) {
168 __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : :
169 "r" (page), "i" (ASI_M_FLUSH_PAGE));
170 page += hyper_line_size;
171 }
172 }
173
174 #endif /* !(_SPARC_ROSS_H) */