1 /*        $NetBSD: ctlreg.h,v 1.71 2024/03/10 17:34:47 rillig Exp $ */
2 
3 /*
4  * Copyright (c) 1996-2002 Eduardo Horvath
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR  ``AS IS'' AND
13  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR  BE LIABLE
16  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22  * SUCH DAMAGE.
23  *
24  */
25 
26 #ifndef _SPARC_CTLREG_H_
27 #define _SPARC_CTLREG_H_
28 
29 /*
30  * Sun 4u control registers. (includes address space definitions
31  * and some registers in control space).
32  */
33 
34 /*
35  * The Alternate address spaces.
36  *
37  * 0x00-0x7f are privileged
38  * 0x80-0xff can be used by users
39  */
40 
41 #define   ASI_LITTLE          0x08                /* This bit should make an ASI little endian */
42 
43 #define   ASI_NUCLEUS                             0x04      /* [4u] kernel address space */
44 #define   ASI_NUCLEUS_LITTLE            0x0c      /* [4u] kernel address space, little endian */
45 
46 #define   ASI_AS_IF_USER_PRIMARY                  0x10      /* [4u] primary user address space */
47 #define   ASI_AS_IF_USER_SECONDARY      0x11      /* [4u] secondary user address space */
48 
49 #define   ASI_PHYS_CACHED                         0x14      /* [4u] MMU bypass to main memory */
50 #define   ASI_PHYS_NON_CACHED           0x15      /* [4u] MMU bypass to I/O location */
51 
52 #define   ASI_AS_IF_USER_PRIMARY_LITTLE 0x18      /* [4u] primary user address space, little endian  */
53 #define   ASI_AS_IF_USER_SECONDARY_LITTLE         0x19      /* [4u] secondary user address space, little endian  */
54 
55 #define   ASI_PHYS_CACHED_LITTLE                  0x1c      /* [4u] MMU bypass to main memory, little endian */
56 #define   ASI_PHYS_NON_CACHED_LITTLE    0x1d      /* [4u] MMU bypass to I/O location, little endian */
57 
58 #define ASI_MMU_CONTEXTID               0x21      /* [4v] MMU context control - both IMMU and DMMU */
59 
60 #define   ASI_NUCLEUS_QUAD_LDD                    0x24      /* [4u] use w/LDDA to load 128-bit item */
61 #define   ASI_QUEUE                     0x25      /* [4v] interrupt queue registers */
62 #define   ASI_NUCLEUS_QUAD_LDD_LITTLE   0x2c      /* [4u] use w/LDDA to load 128-bit item, little endian */
63 
64 #define   ASI_FLUSH_D_PAGE_PRIMARY      0x38      /* [4u] flush D-cache page using primary context */
65 #define   ASI_FLUSH_D_PAGE_SECONDARY    0x39      /* [4u] flush D-cache page using secondary context */
66 #define   ASI_FLUSH_D_CTX_PRIMARY                 0x3a      /* [4u] flush D-cache context using primary context */
67 #define   ASI_FLUSH_D_CTX_SECONDARY     0x3b      /* [4u] flush D-cache context using secondary context */
68 
69 #define   ASI_DCACHE_INVALIDATE                   0x42      /* [III] invalidate D-cache */
70 #define   ASI_DCACHE_UTAG                         0x43      /* [III] diagnostic access to D-cache micro tag */
71 #define   ASI_DCACHE_SNOOP_TAG                    0x44      /* [III] diagnostic access to D-cache snoop tag RAM */
72 
73 #define   ASI_LSU_CONTROL_REGISTER      0x45      /* [4u] load/store unit control register */
74 
75 #define   ASI_DCACHE_DATA                         0x46      /* [4u] diagnostic access to D-cache data RAM */
76 #define   ASI_DCACHE_TAG                          0x47      /* [4u] diagnostic access to D-cache tag RAM */
77 
78 #define   ASI_INTR_DISPATCH_STATUS      0x48      /* [4u] interrupt dispatch status register */
79 #define   ASI_INTR_RECEIVE              0x49      /* [4u] interrupt receive status register */
80 #define   ASI_MID_REG                             0x4a      /* [4u] hardware config and MID */
81 #define   ASI_ERROR_EN_REG              0x4b      /* [4u] asynchronous error enables */
82 #define   ASI_AFSR                      0x4c      /* [4u] asynchronous fault status register */
83 #define   ASI_AFAR                      0x4d      /* [4u] asynchronous fault address register */
84 
85 #define   ASI_ICACHE_DATA                         0x66      /* [4u] diagnostic access to I-cache data RAM */
86 #define   ASI_ICACHE_TAG                          0x67      /* [4u] diagnostic access to I-cache tag RAM */
87 #define   ASI_FLUSH_I_PAGE_PRIMARY      0x68      /* [4u] flush I-cache page using primary context */
88 #define   ASI_FLUSH_I_PAGE_SECONDARY    0x69      /* [4u] flush I-cache page using secondary context */
89 #define   ASI_FLUSH_I_CTX_PRIMARY                 0x6a      /* [4u] flush I-cache context using primary context */
90 #define   ASI_FLUSH_I_CTX_SECONDARY     0x6b      /* [4u] flush I-cache context using secondary context */
91 
92 #define   ASI_BLOCK_AS_IF_USER_PRIMARY  0x70      /* [4u] primary user address space, block loads/stores */
93 #define   ASI_BLOCK_AS_IF_USER_SECONDARY          0x71      /* [4u] secondary user address space, block loads/stores */
94 
95 #define   ASI_ECACHE_DIAG                         0x76      /* [4u] diag access to E-cache tag and data */
96 #define   ASI_DATAPATH_ERR_REG_WRITE    0x77      /* [4u] ASI is reused */
97 
98 #define   ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE     0x78      /* [4u] primary user address space, block loads/stores */
99 #define   ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE   0x79      /* [4u] secondary user address space, block loads/stores */
100 
101 #define   ASI_INTERRUPT_RECEIVE_DATA    0x7f      /* [4u] interrupt receive data registers {0,1,2} */
102 #define   ASI_DATAPATH_ERR_REG_READ     0x7f      /* [4u] read access to datapath error registers (ASI reused) */
103 
104 #define   ASI_PRIMARY                             0x80      /* [4u] primary address space */
105 #define   ASI_SECONDARY                           0x81      /* [4u] secondary address space */
106 #define   ASI_PRIMARY_NOFAULT           0x82      /* [4u] primary address space, no fault */
107 #define   ASI_SECONDARY_NOFAULT                   0x83      /* [4u] secondary address space, no fault */
108 
109 #define   ASI_PRIMARY_LITTLE            0x88      /* [4u] primary address space, little endian */
110 #define   ASI_SECONDARY_LITTLE                    0x89      /* [4u] secondary address space, little endian */
111 #define   ASI_PRIMARY_NOFAULT_LITTLE    0x8a      /* [4u] primary address space, no fault, little endian */
112 #define   ASI_SECONDARY_NOFAULT_LITTLE  0x8b      /* [4u] secondary address space, no fault, little endian */
113 
114 #define   ASI_PST8_PRIMARY              0xc0      /* [VIS] Eight 8-bit partial store, primary */
115 #define   ASI_PST8_SECONDARY            0xc1      /* [VIS] Eight 8-bit partial store, secondary */
116 #define   ASI_PST16_PRIMARY             0xc2      /* [VIS] Four 16-bit partial store, primary */
117 #define   ASI_PST16_SECONDARY           0xc3      /* [VIS] Fout 16-bit partial store, secondary */
118 #define   ASI_PST32_PRIMARY             0xc4      /* [VIS] Two 32-bit partial store, primary */
119 #define   ASI_PST32_SECONDARY           0xc5      /* [VIS] Two 32-bit partial store, secondary */
120 
121 #define   ASI_PST8_PRIMARY_LITTLE                 0xc8      /* [VIS] Eight 8-bit partial store, primary, little endian */
122 #define   ASI_PST8_SECONDARY_LITTLE     0xc9      /* [VIS] Eight 8-bit partial store, secondary, little endian */
123 #define   ASI_PST16_PRIMARY_LITTLE      0xca      /* [VIS] Four 16-bit partial store, primary, little endian */
124 #define   ASI_PST16_SECONDARY_LITTLE    0xcb      /* [VIS] Fout 16-bit partial store, secondary, little endian */
125 #define   ASI_PST32_PRIMARY_LITTLE      0xcc      /* [VIS] Two 32-bit partial store, primary, little endian */
126 #define   ASI_PST32_SECONDARY_LITTLE    0xcd      /* [VIS] Two 32-bit partial store, secondary, little endian */
127 
128 #define   ASI_FL8_PRIMARY                         0xd0      /* [VIS] One 8-bit load/store floating, primary */
129 #define   ASI_FL8_SECONDARY             0xd1      /* [VIS] One 8-bit load/store floating, secondary */
130 #define   ASI_FL16_PRIMARY              0xd2      /* [VIS] One 16-bit load/store floating, primary */
131 #define   ASI_FL16_SECONDARY            0xd3      /* [VIS] One 16-bit load/store floating, secondary */
132 
133 #define   ASI_FL8_PRIMARY_LITTLE                  0xd8      /* [VIS] One 8-bit load/store floating, primary, little endian */
134 #define   ASI_FL8_SECONDARY_LITTLE      0xd9      /* [VIS] One 8-bit load/store floating, secondary, little endian */
135 #define   ASI_FL16_PRIMARY_LITTLE                 0xda      /* [VIS] One 16-bit load/store floating, primary, little endian */
136 #define   ASI_FL16_SECONDARY_LITTLE     0xdb      /* [VIS] One 16-bit load/store floating, secondary, little endian */
137 
138 #define   ASI_BLOCK_COMMIT_PRIMARY      0xe0      /* [4u] block store with commit, primary */
139 #define   ASI_BLOCK_COMMIT_SECONDARY    0xe1      /* [4u] block store with commit, secondary */
140 #define   ASI_BLOCK_PRIMARY             0xf0      /* [4u] block load/store, primary */
141 #define   ASI_BLOCK_SECONDARY           0xf1      /* [4u] block load/store, secondary */
142 #define   ASI_BLOCK_PRIMARY_LITTLE      0xf8      /* [4u] block load/store, primary, little endian */
143 #define   ASI_BLOCK_SECONDARY_LITTLE    0xf9      /* [4u] block load/store, secondary, little endian */
144 
145 
146 /*
147  * These are the shorter names used by Solaris
148  */
149 
150 #define   ASI_N               ASI_NUCLEUS
151 #define   ASI_NL              ASI_NUCLEUS_LITTLE
152 #define   ASI_AIUP  ASI_AS_IF_USER_PRIMARY
153 #define   ASI_AIUS  ASI_AS_IF_USER_SECONDARY
154 #define   ASI_AIUPL ASI_AS_IF_USER_PRIMARY_LITTLE
155 #define   ASI_AIUSL ASI_AS_IF_USER_SECONDARY_LITTLE
156 #define   ASI_P               ASI_PRIMARY
157 #define   ASI_S               ASI_SECONDARY
158 #define   ASI_PNF             ASI_PRIMARY_NOFAULT
159 #define   ASI_SNF             ASI_SECONDARY_NOFAULT
160 #define   ASI_PL              ASI_PRIMARY_LITTLE
161 #define   ASI_SL              ASI_SECONDARY_LITTLE
162 #define   ASI_PNFL  ASI_PRIMARY_NOFAULT_LITTLE
163 #define   ASI_SNFL  ASI_SECONDARY_NOFAULT_LITTLE
164 #define   ASI_FL8_P ASI_FL8_PRIMARY
165 #define   ASI_FL8_S ASI_FL8_SECONDARY
166 #define   ASI_FL16_P          ASI_FL16_PRIMARY
167 #define   ASI_FL16_S          ASI_FL16_SECONDARY
168 #define   ASI_FL8_PL          ASI_FL8_PRIMARY_LITTLE
169 #define   ASI_FL8_SL          ASI_FL8_SECONDARY_LITTLE
170 #define   ASI_FL16_PL         ASI_FL16_PRIMARY_LITTLE
171 #define   ASI_FL16_SL         ASI_FL16_SECONDARY_LITTLE
172 #define   ASI_BLK_AIUP        ASI_BLOCK_AS_IF_USER_PRIMARY
173 #define   ASI_BLK_AIUPL       ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE
174 #define   ASI_BLK_AIUS        ASI_BLOCK_AS_IF_USER_SECONDARY
175 #define   ASI_BLK_AIUSL       ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE
176 #define   ASI_BLK_COMMIT_P              ASI_BLOCK_COMMIT_PRIMARY
177 #define   ASI_BLK_COMMIT_PRIMARY                  ASI_BLOCK_COMMIT_PRIMARY
178 #define   ASI_BLK_COMMIT_S              ASI_BLOCK_COMMIT_SECONDARY
179 #define   ASI_BLK_COMMIT_SECONDARY      ASI_BLOCK_COMMIT_SECONDARY
180 #define   ASI_BLK_P                     ASI_BLOCK_PRIMARY
181 #define   ASI_BLK_PL                              ASI_BLOCK_PRIMARY_LITTLE
182 #define   ASI_BLK_S                     ASI_BLOCK_SECONDARY
183 #define   ASI_BLK_SL                              ASI_BLOCK_SECONDARY_LITTLE
184 
185 /* Alternative spellings */
186 #define ASI_PRIMARY_NO_FAULT            ASI_PRIMARY_NOFAULT
187 #define ASI_PRIMARY_NO_FAULT_LITTLE     ASI_PRIMARY_NOFAULT_LITTLE
188 #define ASI_SECONDARY_NO_FAULT                    ASI_SECONDARY_NOFAULT
189 #define ASI_SECONDARY_NO_FAULT_LITTLE   ASI_SECONDARY_NOFAULT_LITTLE
190 
191 #define   PHYS_ASI(x)         (((x) | 0x09) == 0x1d)
192 #define   LITTLE_ASI(x)       ((x) & ASI_LITTLE)
193 
194 /*
195  * The following are 4u control registers
196  */
197 
198 /* Get the CPU's UPAID */
199 #define   UPA_CR_MID_SHIFT    (17)
200 #define   UPA_CR_MID_SIZE               (5)
201 #define   UPA_CR_MID_MASK \
202           (((1 << UPA_CR_MID_SIZE) - 1) << UPA_CR_MID_SHIFT)
203 
204 #define   UPA_CR_MID(x)       (((x)>>UPA_CR_MID_SHIFT)&((1 << UPA_CR_MID_SIZE) - 1))
205 
206 #ifdef _LOCORE
207 
208 #define   UPA_GET_MID(r1) \
209           ldxa      [%g0] ASI_MID_REG, r1 ; \
210           srlx      r1, UPA_CR_MID_SHIFT, r1 ; \
211           and       r1, (1 << UPA_CR_MID_SIZE) - 1, r1
212 
213 #else
214 #define   CPU_UPAID UPA_CR_MID(ldxa(0, ASI_MID_REG))
215 #endif
216 
217 /* Get the CPU's Fireplane agent ID */
218 #define FIREPLANE_CR_AID(x)   (((x) >> 17) & 0x3ff)
219 #define CPU_FIREPLANEID                 FIREPLANE_CR_AID(ldxa(0, ASI_MID_REG))
220 
221 /* Get the CPU's Jupiter Bus interrupt target ID */
222 #define JUPITER_CR_ITID(x)    ((x) & 0x3ff)
223 #define CPU_JUPITERID                   JUPITER_CR_ITID(ldxa(0, ASI_MID_REG))
224 
225 /*
226  * [4u] MMU and Cache Control Register (MCCR)
227  * use ASI = 0x45
228  */
229 #define   ASI_MCCR  ASI_LSU_CONTROL_REGISTER
230 #define   MCCR                0x00
231 
232 /* MCCR Bits and their meanings */
233 #define   MCCR_DMMU_EN        0x08
234 #define   MCCR_IMMU_EN        0x04
235 #define   MCCR_DCACHE_EN      0x02
236 #define   MCCR_ICACHE_EN      0x01
237 #define   MCCR_RAW_EN         0x400000000000
238 
239 
240 /*
241  * MMU control registers
242  */
243 
244 /* Choose an MMU */
245 #define   ASI_DMMU            0x58
246 #define   ASI_IMMU            0x50
247 
248 /* Other assorted MMU ASIs */
249 #define   ASI_IMMU_8KPTR                0x51
250 #define   ASI_IMMU_64KPTR               0x52
251 #define   ASI_IMMU_DATA_IN    0x54
252 #define   ASI_IMMU_TLB_DATA   0x55
253 #define   ASI_IMMU_TLB_TAG    0x56
254 #define   ASI_DMMU_8KPTR                0x59
255 #define   ASI_DMMU_64KPTR               0x5a
256 #define   ASI_DMMU_DATA_IN    0x5c
257 #define   ASI_DMMU_TLB_DATA   0x5d
258 #define   ASI_DMMU_TLB_TAG    0x5e
259 
260 /*
261  * The following are the control registers
262  * They work on both MMUs unless noted.
263  * III = cheetah only
264  *
265  * Register contents are defined later on individual registers.
266  */
267 #define   TSB_TAG_TARGET                0x0
268 #define   TLB_DATA_IN                   0x0
269 #define   CTX_PRIMARY                   0x08      /* primary context -- DMMU only */
270 #define   CTX_SECONDARY                 0x10      /* secondary context -- DMMU only */
271 #define   SFSR                          0x18
272 #define   SFAR                          0x20      /* fault address -- DMMU only */
273 #define   TSB                           0x28
274 #define   TLB_TAG_ACCESS                0x30
275 #define   VIRTUAL_WATCHPOINT  0x38
276 #define   PHYSICAL_WATCHPOINT 0x40
277 #define   TSB_PEXT            0x48      /* III primary ext */
278 #define   TSB_SEXT            0x50      /* III 2ndary ext -- DMMU only */
279 #define   TSB_NEXT            0x58      /* III nucleus ext */
280 
281 /* Tag Target bits */
282 #define   TAG_TARGET_VA_MASK  0x03ffffffffffffffffLL
283 #define   TAG_TARGET_VA(x)    (((x)<<22)&TAG_TARGET_VA_MASK)
284 #define   TAG_TARGET_CONTEXT(x)         ((x)>>48)
285 #define   TAG_TARGET(c,v)               ((((uint64_t)c)<<48)|(((uint64_t)v)&TAG_TARGET_VA_MASK))
286 
287 /* SFSR bits for both D_SFSR and I_SFSR */
288 #define   SFSR_ASI(x)                   ((x)>>16)
289 #define   SFSR_FT_VA_OOR_2    0x02000 /* IMMU: jumpl or return to unsupported VA */
290 #define   SFSR_FT_VA_OOR_1    0x01000 /* fault at unsupported VA */
291 #define   SFSR_FT_NFO                   0x00800   /* DMMU: Access to page marked NFO */
292 #define   SFSR_ILL_ASI                  0x00400   /* DMMU: Illegal (unsupported) ASI */
293 #define   SFSR_FT_IO_ATOMIC   0x00200   /* DMMU: Atomic access to noncacheable page */
294 #define   SFSR_FT_ILL_NF                0x00100   /* DMMU: NF load or flush to page marked E (has side effects) */
295 #define   SFSR_FT_PRIV                  0x00080   /* Privilege violation */
296 #define   SFSR_FT_E           0x00040   /* DMMU: value of E bit associated address */
297 #define   SFSR_CTXT(x)                  (((x)>>4)&0x3)
298 #define   SFSR_CTXT_IS_PRIM(x)          (SFSR_CTXT(x)==0x00)
299 #define   SFSR_CTXT_IS_SECOND(x)        (SFSR_CTXT(x)==0x01)
300 #define   SFSR_CTXT_IS_NUCLEUS(x)       (SFSR_CTXT(x)==0x02)
301 #define   SFSR_PRIV           0x00008   /* value of PSTATE.PRIV for faulting access */
302 #define   SFSR_W                        0x00004 /* DMMU: attempted write */
303 #define   SFSR_OW                       0x00002 /* Overwrite; prev vault was still valid */
304 #define   SFSR_FV                       0x00001   /* Fault is valid */
305 #define   SFSR_FT   (SFSR_FT_VA_OOR_2|SFSR_FT_VA_OOR_1|SFSR_FT_NFO| \
306                     SFSR_ILL_ASI|SFSR_FT_IO_ATOMIC|SFSR_FT_ILL_NF|SFSR_FT_PRIV)
307 
308 #define   SFSR_BITS "\177\20" \
309           "f\20\30ASI\0"                          "b\15VAT\0"         "b\14VAD\0" \
310           "b\13NFO\0"         "b\12ASI\0"         "b\11A\0" "b\10NF\0" \
311           "b\07PRIV\0"        "b\06E\0" "b\05NUCLEUS\0"     "b\04SECONDCTX\0" \
312           "b\03PRIV\0"        "b\02W\0" "b\01OW\0"          "b\00FV\0"
313 
314 /* ASFR bits */
315 #define   ASFR_ME                       0x100000000LL
316 #define   ASFR_PRIV           0x080000000LL
317 #define   ASFR_ISAP           0x040000000LL
318 #define   ASFR_ETP            0x020000000LL
319 #define   ASFR_IVUE           0x010000000LL
320 #define   ASFR_TO                       0x008000000LL
321 #define   ASFR_BERR           0x004000000LL
322 #define   ASFR_LDP            0x002000000LL
323 #define   ASFR_CP                       0x001000000LL
324 #define   ASFR_WP                       0x000800000LL
325 #define   ASFR_EDP            0x000400000LL
326 #define   ASFR_UE                       0x000200000LL
327 #define   ASFR_CE                       0x000100000LL
328 #define   ASFR_ETS            0x0000f0000LL
329 #define   ASFT_P_SYND                   0x00000ffffLL
330 
331 #define   AFSR_BITS "\177\20" \
332         "b\40ME\0"      "b\37PRIV\0"    "b\36ISAP\0"    "b\35ETP\0" \
333         "b\34IVUE\0"    "b\33TO\0"      "b\32BERR\0"    "b\31LDP\0" \
334         "b\30CP\0"      "b\27WP\0"      "b\26EDP\0"     "b\25UE\0" \
335         "b\24CE\0"      "f\20\4ETS\0"   "f\0\20P_SYND\0"
336 
337 /*
338  * Here's the spitfire TSB control register bits.
339  *
340  * Each TSB entry is 16-bytes wide.  The TSB must be size aligned
341  */
342 #define   TSB_SIZE_512                  0x0       /* 8kB, etc. */
343 #define   TSB_SIZE_1K                   0x01
344 #define   TSB_SIZE_2K                   0x02
345 #define   TSB_SIZE_4K                   0x03
346 #define   TSB_SIZE_8K                   0x04
347 #define   TSB_SIZE_16K                  0x05
348 #define   TSB_SIZE_32K                  0x06
349 #define   TSB_SIZE_64K                  0x07
350 #define   TSB_SPLIT           0x1000
351 #define   TSB_BASE            0xffffffffffffe000
352 
353 /*  TLB Tag Access bits */
354 #define   TLB_TAG_ACCESS_VA   0xffffffffffffe000
355 #define   TLB_TAG_ACCESS_CTX  0x0000000000001fff
356 
357 /*
358  * TLB demap registers.  TTEs are defined in v9pte.h
359  *
360  * Use the address space to select between IMMU and DMMU.
361  * The address of the register selects which context register
362  * to read the ASI from.
363  *
364  * The data stored in the register is interpreted as the VA to
365  * use.  The DEMAP_CTX_<> registers ignore the address and demap the
366  * entire ASI.
367  *
368  */
369 #define   ASI_IMMU_DEMAP                          0x57      /* [4u] IMMU TLB demap */
370 #define   ASI_DMMU_DEMAP                          0x5f      /* [4u] IMMU TLB demap */
371 
372 #define   DEMAP_PAGE_NUCLEUS            ((0x02)<<4)         /* Demap page from kernel AS */
373 #define   DEMAP_PAGE_PRIMARY            ((0x00)<<4)         /* Demap a page from primary CTXT */
374 #define   DEMAP_PAGE_SECONDARY                    ((0x01)<<4)         /* Demap page from secondary CTXT (DMMU only) */
375 #define   DEMAP_CTX_NUCLEUS             ((0x06)<<4)         /* Demap all of kernel CTXT */
376 #define   DEMAP_CTX_PRIMARY             ((0x04)<<4)         /* Demap all of primary CTXT */
377 #define   DEMAP_CTX_SECONDARY           ((0x05)<<4)         /* Demap all of secondary CTXT */
378 #define   DEMAP_ALL                     ((0x08)<<4)         /* Demap all non-locked TLB entries [USIII] */
379 
380 /*
381  * These define the sizes of the TLB in various CPUs.
382  * They're mostly not necessary except for diagnostic code.
383  */
384 #define TLB_SIZE_SPITFIRE               64
385 #define TLB_SIZE_CHEETAH_I16            16
386 #define TLB_SIZE_CHEETAH_I128           128
387 #define TLB_SIZE_CHEETAH_D16            16
388 #define TLB_SIZE_CHEETAH_D512_0                   512
389 #define TLB_SIZE_CHEETAH_D512_1                   512
390 #define TLB_CHEETAH_I16                           (0 << 16)
391 #define TLB_CHEETAH_I128                (2 << 16)
392 #define TLB_CHEETAH_D16                           (0 << 16)
393 #define TLB_CHEETAH_D512_0              (2 << 16)
394 #define TLB_CHEETAH_D512_1              (3 << 16)
395 
396 /*
397  * Interrupt registers.  This really gets hairy.
398  */
399 
400 /* IRSR -- Interrupt Receive Status Register */
401 #define   ASI_IRSR  0x49
402 #define   IRSR                0x00
403 #define   IRSR_BUSY 0x020
404 #define   IRSR_MID(x)         (x&0x1f)
405 
406 /* IRDR -- Interrupt Receive Data Registers */
407 #define   ASI_IRDR  0x7f
408 #define   IRDR_0H             0x40
409 #define   IRDR_0L             0x48      /* unimplemented */
410 #define   IRDR_1H             0x50
411 #define   IRDR_1L             0x58      /* unimplemented */
412 #define   IRDR_2H             0x60
413 #define   IRDR_2L             0x68      /* unimplemented */
414 #define   IRDR_3H             0x70      /* unimplemented */
415 #define   IRDR_3L             0x78      /* unimplemented */
416 
417 /* Interrupt Dispatch -- usually reserved for cross-calls */
418 #define   ASI_IDSR  0x48 /* Interrupt dispatch status reg */
419 #define   IDSR                0x00
420 #define   IDSR_NACK 0x02
421 #define   IDSR_BUSY 0x01
422 
423 #define   ASI_INTERRUPT_DISPATCH                  0x77      /* [4u] spitfire interrupt dispatch regs */
424 
425 /* Interrupt delivery initiation */
426 #define   IDCR(x)             ((((uint64_t)(x)) << 14) | 0x70)
427 
428 #define   IDDR_0H             0x40      /* Store data to send in these regs */
429 #define   IDDR_0L             0x48      /* unimplemented */
430 #define   IDDR_1H             0x50
431 #define   IDDR_1L             0x58      /* unimplemented */
432 #define   IDDR_2H             0x60
433 #define   IDDR_2L             0x68      /* unimplemented */
434 #define   IDDR_3H             0x70      /* unimplemented */
435 #define   IDDR_3L             0x78      /* unimplemented */
436 
437 /*
438  * Error registers
439  */
440 
441 /* Since we won't try to fix async errs, we don't care about the bits in the regs */
442 #define   ASI_AFAR  0x4d      /* Asynchronous fault address register */
443 #define   AFAR                0x00
444 #define   ASI_AFSR  0x4c      /* Asynchronous fault status register */
445 #define   AFSR                0x00
446 
447 #define   ASI_P_EER 0x4b      /* Error enable register */
448 #define   P_EER               0x00
449 #define   P_EER_ISAPEN        0x04      /* Enable fatal on ISAP */
450 #define   P_EER_NCEEN         0x02      /* Enable trap on uncorrectable errs */
451 #define   P_EER_CEEN          0x01      /* Enable trap on correctable errs */
452 
453 #define   ASI_DATAPATH_READ   0x7f /* Read the regs */
454 #define   ASI_DATAPATH_WRITE  0x77 /* Write to the regs */
455 #define   P_DPER_0  0x00      /* Datapath err reg 0 */
456 #define   P_DPER_1  0x18      /* Datapath err reg 1 */
457 #define   P_DCR_0             0x20      /* Datapath control reg 0 */
458 #define   P_DCR_1             0x38      /* Datapath control reg 0 */
459 
460 
461 /* From sparc64/asm.h which I think I'll deprecate since it makes bus.h a pain. */
462 
463 #ifndef _LOCORE
464 /*
465  * GCC __asm constructs for doing assembly stuff.
466  */
467 
468 /*
469  * ``Routines'' to load and store from/to alternate address space.
470  * The location can be a variable, the asi value (address space indicator)
471  * must be a constant.
472  *
473  * N.B.: You can put as many special functions here as you like, since
474  * they cost no kernel space or time if they are not used.
475  *
476  * These were static inline functions, but gcc screws up the constraints
477  * on the address space identifiers (the "n"umeric value part) because
478  * it inlines too late, so we have to use the funny valued-macro syntax.
479  */
480 
481 /*
482  * Apparently the definition of bypass ASIs is that they all use the
483  * D$ so we need to flush the D$ to make sure we don't get data pollution.
484  */
485 
486 #ifdef __arch64__
487 
488 /* 64-bit kernel, non-constant */
489 #define SPARC64_LD_NONCONST(ld)         \
490           __asm volatile(                                                                 \
491                     "wr %2,%%g0,%%asi;  "                                       \
492                     #ld " [%1]%%asi,%0  "                                       \
493                     : "=r" (_v)                                                           \
494                     : "r" ((__uintptr_t)(loc)), "r" (asi))
495 
496 #if defined(__GNUC__) && defined(__OPTIMIZE__)
497 #define SPARC64_LD_DEF(ld, type, vtype) \
498 static __inline type ld(paddr_t loc, int asi)                                   \
499 {                                                                                         \
500           vtype _v;                                                             \
501           if (__builtin_constant_p(asi))                                                  \
502                     __asm volatile(                                                       \
503                               #ld " [%1]%2,%0               "                             \
504                               : "=r" (_v)                                                 \
505                               : "r" ((__uintptr_t)(loc)), "n" (asi));           \
506           else                                                                            \
507                     SPARC64_LD_NONCONST(ld);                                    \
508           return _v;                                                                      \
509 }
510 #else
511 #define SPARC64_LD_DEF(ld, type, vtype) \
512 static __inline type ld(paddr_t loc, int asi)                                   \
513 {                                                                                         \
514           vtype _v;                                                             \
515           SPARC64_LD_NONCONST(ld);                                              \
516           return _v;                                                                      \
517 }
518 #endif
519 #define SPARC64_LD_DEF64(ld, type)      SPARC64_LD_DEF(ld, type, uint64_t)
520 
521 #else     /* __arch64__ */
522 
523 /* 32-bit kernel, MMU bypass, non-constant */
524 #define SPARC64_LD_PHYS_NONCONST(ld)    \
525           __asm volatile(                                                                 \
526                     "clruw %2;                    "                                       \
527                     "rdpr %%pstate,%1;  "                                       \
528                     "sllx %3,32,%0;               "                                       \
529                     "wrpr %1,8,%%pstate;          "                                       \
530                     "or %0,%2,%0;                 "                                       \
531                     "wr %4,%%g0,%%asi;  "                                       \
532                     #ld " [%0]%%asi,%0; "                                       \
533                     "wrpr %1,0,%%pstate "                                       \
534                     : "=&r" (_v),  "=&r" (_pstate)                                        \
535                     : "r" ((uint32_t)(loc)), "r" (_hi), "r" (asi))
536 /* 32-bit kernel, non-constant */
537 #define SPARC64_LD_NONCONST(ld)         \
538           __asm volatile(                                                                 \
539                     "wr %2,%%g0,%%asi;  "                                       \
540                     #ld " [%1]%%asi,%0  "                                       \
541                     : "=&r" (_v)                                                          \
542                     : "r" ((uint32_t)(loc)), "r" (asi))
543 /* 32-bit kernel, MMU bypass, non-constant, 64-bit value */
544 #define SPARC64_LD_PHYS_NONCONST64(ld)  \
545           __asm volatile(                                                                 \
546                     "clruw %2;                    "                                       \
547                     "rdpr %%pstate,%1;  "                                       \
548                     "sllx %3,32,%0;               "                                       \
549                     "wrpr %1,8,%%pstate;          "                                       \
550                     "or %0,%2,%0;                 "                                       \
551                     "wr %4,%%g0,%%asi;  "                                       \
552                     #ld " [%0]%%asi,%0; "                                       \
553                     "wrpr %1,0,%%pstate;          "                                       \
554                     "srlx %0,32,%1;               "                                       \
555                     "srl %0,0,%0                  "                                       \
556                     : "=&r" (_vlo), "=&r" (_vhi)                                \
557                     : "r" ((uint32_t)(loc)), "r" (_hi), "r" (asi))
558 /* 32-bit kernel, non-constant, 64-bit value  */
559 #define SPARC64_LD_NONCONST64(ld)       \
560           __asm volatile(                                                                 \
561                     "wr %3,%%g0,%%asi;  "                                       \
562                     #ld " [%2]%%asi,%0; "                                       \
563                     "srlx %0,32,%1;               "                                       \
564                     "srl %0,0,%0                  "                                       \
565                     : "=&r" (_vlo), "=&r" (_vhi)                                \
566                     : "r" ((uint32_t)(loc)), "r" (asi))
567 
568 #if defined(__GNUC__) && defined(__OPTIMIZE__)
569 #define SPARC64_LD_DEF(ld, type, vtype) \
570 static __inline type ld(paddr_t loc, int asi)                                   \
571 {                                                                                         \
572           vtype _v;                                                             \
573           uint32_t _hi, _pstate;                                                          \
574           if (PHYS_ASI(asi)) {                                                            \
575                     _hi = (uint64_t)(loc) >> 32;                                \
576                     if (__builtin_constant_p(asi))                                        \
577                               __asm volatile(                                             \
578                                         "clruw %2;                    "                   \
579                                         "rdpr %%pstate,%1;  "                   \
580                                         "sllx %3,32,%0;               "                   \
581                                         "wrpr %1,8,%%pstate;          "                   \
582                                         "or %0,%2,%0;                 "                   \
583                                         #ld " [%0]%4,%0;    "                   \
584                                         "wrpr %1,0,%%pstate;          "                   \
585                                         : "=&r" (_v),  "=&r" (_pstate)                    \
586                                         : "r" ((uint32_t)(loc)), "r" (_hi),     \
587                                           "n" (asi));                                     \
588                     else                                                                  \
589                               SPARC64_LD_PHYS_NONCONST(ld);                     \
590           } else {                                                              \
591                     if (__builtin_constant_p(asi))                                        \
592                               __asm volatile(                                             \
593                                         #ld " [%1]%2,%0               "                   \
594                                         : "=&r" (_v)                                      \
595                                         : "r" ((uint32_t)(loc)), "n" (asi));    \
596                     else                                                                  \
597                               SPARC64_LD_NONCONST(ld);                          \
598           }                                                                               \
599           return _v;                                                                      \
600 }
601 #define SPARC64_LD_DEF64(ld, type)      \
602 static __inline type ld(paddr_t loc, int asi)                                   \
603 {                                                                                         \
604           uint32_t _vlo, _vhi, _hi;                                             \
605           if (PHYS_ASI(asi)) {                                                            \
606                     _hi = (uint64_t)(loc) >> 32;                                \
607                     if (__builtin_constant_p(asi))                                        \
608                               __asm volatile(                                             \
609                                         "clruw %2;                    "                   \
610                                         "rdpr %%pstate,%1;  "                   \
611                                         "sllx %3,32,%0;               "                   \
612                                         "wrpr %1,8,%%pstate;          "                   \
613                                         "or %0,%2,%0;                 "                   \
614                                         #ld " [%0]%4,%0;    "                   \
615                                         "wrpr %1,0,%%pstate;          "                   \
616                                         "srlx %0,32,%1;               "                   \
617                                         "srl %0,0,%0                  "                   \
618                                         : "=&r" (_vlo),  "=&r" (_vhi)           \
619                                         : "r" ((uint32_t)(loc)), "r" (_hi),     \
620                                           "n" (asi));                                     \
621                     else                                                                  \
622                               SPARC64_LD_PHYS_NONCONST64(ld);                             \
623           } else {                                                              \
624                     if (__builtin_constant_p(asi))                                        \
625                               __asm volatile(                                             \
626                                         #ld " [%2]%3,%0;    "                   \
627                                         "srlx %0,32,%1;               "                   \
628                                         "srl %0,0,%0                  "                   \
629                                         : "=&r" (_vlo),  "=&r" (_vhi)           \
630                                         : "r" ((uint32_t)(loc)), "n" (asi));    \
631                     else                                                                  \
632                               SPARC64_LD_NONCONST64(ld);                        \
633           }                                                                               \
634           return ((uint64_t)_vhi << 32) | _vlo;                                 \
635 }
636 #else
637 #define SPARC64_LD_DEF(ld, type, vtype) \
638 static __inline type ld(paddr_t loc, int asi)                                   \
639 {                                                                                         \
640           vtype _v;                                                             \
641           uint32_t _hi, _pstate;                                                          \
642           if (PHYS_ASI(asi)) {                                                            \
643                     _hi = (uint64_t)(loc) >> 32;                                \
644                     SPARC64_LD_PHYS_NONCONST(ld);                               \
645           } else                                                                          \
646                     SPARC64_LD_NONCONST(ld);                                    \
647           return _v;                                                                      \
648 }
649 #define SPARC64_LD_DEF64(ld, type)      \
650 static __inline type ld(paddr_t loc, int asi)                                   \
651 {                                                                                         \
652           uint32_t _vlo, _vhi, _hi;                                             \
653           if (PHYS_ASI(asi)) {                                                            \
654                     _hi = (uint64_t)(loc) >> 32;                                \
655                     SPARC64_LD_PHYS_NONCONST64(ld);                                       \
656           } else                                                                          \
657                     SPARC64_LD_NONCONST64(ld);                                  \
658           return ((uint64_t)_vhi << 32) | _vlo;                                 \
659 }
660 #endif
661 
662 #endif    /* __arch64__ */
663 
664 /* load byte from alternate address space */
665 SPARC64_LD_DEF(lduba, uint8_t, uint32_t)
666 /* load half-word from alternate address space */
667 SPARC64_LD_DEF(lduha, uint16_t, uint32_t)
668 /* load unsigned int from alternate address space */
669 SPARC64_LD_DEF(lda, uint32_t, uint32_t)
670 /* load unsigned word from alternate address space */
671 SPARC64_LD_DEF(lduwa, uint32_t, uint32_t)
672 /* load signed int from alternate address space */
673 SPARC64_LD_DEF(ldswa, int, int)
674 /* load 64-bit unsigned int from alternate address space */
675 SPARC64_LD_DEF64(ldxa, uint64_t)
676 
677 
678 #ifdef __arch64__
679 
680 /* 64-bit kernel, non-constant */
681 #define SPARC64_ST_NONCONST(st)         \
682           __asm volatile(                                                                 \
683                     "wr %2,%%g0,%%asi;  "                                       \
684                     #st " %0,[%1]%%asi  "                                       \
685                     : : "r" (value), "r" ((__uintptr_t)(loc)),                  \
686                         "r" (asi))
687 
688 #if defined(__GNUC__) && defined(__OPTIMIZE__)
689 #define SPARC64_ST_DEF(st, type)        \
690 static __inline void st(paddr_t loc, int asi, type value)             \
691 {                                                                                         \
692           if (__builtin_constant_p(asi))                                                  \
693                     __asm volatile(                                                       \
694                               #st " %0,[%1]%2               "                             \
695                               : : "r" (value), "r" ((__uintptr_t)(loc)),        \
696                                   "n" (asi));                                             \
697           else                                                                            \
698                     SPARC64_ST_NONCONST(st);                                    \
699 }
700 #else
701 #define SPARC64_ST_DEF(st, type)        \
702 static __inline void st(paddr_t loc, int asi, type value)             \
703 {                                                                                         \
704           SPARC64_ST_NONCONST(st);                                              \
705 }
706 #endif
707 #define SPARC64_ST_DEF64(st, type)      SPARC64_ST_DEF(st, type)
708 
709 #else     /* __arch64__ */
710 
711 /* 32-bit kernel, MMU bypass, non-constant */
712 #define SPARC64_ST_PHYS_NONCONST(st)    \
713           __asm volatile(                                                                 \
714                     "clruw %3;                    "                                       \
715                     "rdpr %%pstate,%1;  "                                       \
716                     "sllx %4,32,%0;               "                                       \
717                     "wrpr %1,8,%%pstate;          "                                       \
718                     "or %0,%3,%0;                 "                                       \
719                     "wr %5,%%g0,%%asi;  "                                       \
720                     #st " %2,[%0]%%asi; "                                       \
721                     "wrpr %1,0,%%pstate "                                       \
722                     : "=&r" (_hi), "=&r" (_pstate)                                        \
723                     : "r" (value), "r" ((uint32_t)(loc)),                       \
724                       "r" (_hi), "r" (asi))
725 /* 32-bit kernel, non-constant */
726 #define SPARC64_ST_NONCONST(st)         \
727           __asm volatile(                                                                 \
728                     "wr %2,%%g0,%%asi;  "                                       \
729                     #st " %0,[%1]%%asi  "                                       \
730                     : : "r" (value), "r" ((uint32_t)(loc)), "r" (asi))
731 /* 32-bit kernel, MMU bypass, non-constant, 64-bit value */
732 #define SPARC64_ST_PHYS_NONCONST64(st)  \
733           __asm volatile(                                                                 \
734                     "clruw %3;                    "                                       \
735                     "clruw %5;                    "                                       \
736                     "sllx %4,32,%1;               "                                       \
737                     "sllx %6,32,%0;     "                                       \
738                     "rdpr %%pstate,%2;  "                                       \
739                     "or %1,%3,%1;                 "                                       \
740                     "wrpr %2,8,%%pstate;          "                                       \
741                     "or %0,%5,%0;                 "                                       \
742                     "wr %7,%%g0,%%asi;  "                                       \
743                     #st " %1,[%0]%%asi; "                                       \
744                     "wrpr %2,0,%%pstate "                                       \
745                     : "=&r" (_hi), "=&r" (_vhi), "=&r" (_vlo)                   \
746                     : "r" (_vlo), "r" (_vhi),                                   \
747                       "r" ((uint32_t)(loc)), "r" (_hi), "r" (asi))
748 /* 32-bit kernel, non-constant, 64-bit value */
749 #define SPARC64_ST_NONCONST64(st)       \
750           __asm volatile(                                                                 \
751                     "clruw %1;                    "                                       \
752                     "sllx %2,32,%0;               "                                       \
753                     "or %0,%1,%0;                 "                                       \
754                     "wr %4,%%g0,%%asi;  "                                       \
755                     #st " %0,[%3]%%asi  "                                       \
756                     : "=&r" (_vhi)                                                        \
757                     : "r" (_vlo), "r" (_vhi),                                   \
758                       "r" ((uint32_t)(loc)), "r" (asi))
759 
760 #if defined(__GNUC__) && defined(__OPTIMIZE__)
761 #define SPARC64_ST_DEF(st, type)        \
762 static __inline void st(paddr_t loc, int asi, type value)             \
763 {                                                                                         \
764           uint32_t _hi, _pstate;                                                          \
765           if (PHYS_ASI(asi)) {                                                            \
766                     _hi = (uint64_t)(loc) >> 32;                                \
767                     if (__builtin_constant_p(asi))                                        \
768                               __asm volatile(                                             \
769                                         "clruw %3;                    "                   \
770                                         "sllx %4,32,%0;               "                   \
771                                         "rdpr %%pstate,%1;  "                   \
772                                         "or %0,%3,%0;                 "                   \
773                                         "wrpr %1,8,%%pstate;          "                   \
774                                         #st " %2,[%0]%5;    "                   \
775                                         "wrpr %1,0,%%pstate "                   \
776                                         : "=&r" (_hi), "=&r" (_pstate)                    \
777                                         : "r" (value), "r" ((uint32_t)(loc)),   \
778                                           "r" (_hi), "n" (asi));                \
779                     else                                                                  \
780                               SPARC64_ST_PHYS_NONCONST(st);                     \
781           } else {                                                              \
782                     if (__builtin_constant_p(asi))                                        \
783                               __asm volatile(                                             \
784                                         #st " %0,[%1]%2               "                   \
785                                         : : "r" (value), "r" ((uint32_t)(loc)), \
786                                           "n" (asi));                                     \
787                     else                                                                  \
788                               SPARC64_ST_NONCONST(st);                          \
789           }                                                                               \
790 }
791 #define SPARC64_ST_DEF64(st, type)      \
792 static __inline void st(paddr_t loc, int asi, type value)             \
793 {                                                                                         \
794           uint32_t _vlo, _vhi, _hi;                                             \
795           _vlo = value;                                                                   \
796           _vhi = (uint64_t)(value) >> 32;                                                 \
797           if (PHYS_ASI(asi)) {                                                            \
798                     _hi = (uint64_t)(loc) >> 32;                                \
799                     if (__builtin_constant_p(asi))                                        \
800                               __asm volatile(                                             \
801                                         "clruw %3;                    "                   \
802                                         "clruw %5;                    "                   \
803                                         "sllx %4,32,%1;               "                   \
804                                         "sllx %6,32,%0;     "                   \
805                                         "rdpr %%pstate,%2;  "                   \
806                                         "or %1,%3,%1;                 "                   \
807                                         "or %0,%5,%0;                 "                   \
808                                         "wrpr %2,8,%%pstate;          "                   \
809                                         #st " %1,[%0]%7;    "                   \
810                                         "wrpr %2,0,%%pstate "                   \
811                                         : "=&r" (_hi), "=&r" (_vhi), "=&r" (_vlo) \
812                                         : "r" (_vlo), "r" (_vhi),               \
813                                           "r" ((uint32_t)(loc)), "r" (_hi),     \
814                                           "n" (asi));                                     \
815                     else                                                                  \
816                               SPARC64_ST_PHYS_NONCONST64(st);                             \
817           } else {                                                              \
818                     if (__builtin_constant_p(asi))                                        \
819                               __asm volatile(                                             \
820                                         "clruw %1;                    "                   \
821                                         "sllx %2,32,%0;               "                   \
822                                         "or %0,%1,%0;                 "                   \
823                                         #st " %0,[%3]%4               "                   \
824                                         : "=&r" (_vhi)                                    \
825                                         : "r" (_vlo), "r" (_vhi),               \
826                                           "r" ((uint32_t)(loc)), "n" (asi));    \
827                     else                                                                  \
828                               SPARC64_ST_NONCONST64(st);                        \
829           }                                                                               \
830 }
831 #else
832 #define SPARC64_ST_DEF(st, type)        \
833 static __inline void st(paddr_t loc, int asi, type value)             \
834 {                                                                                         \
835           uint32_t _hi, _pstate;                                                          \
836           if (PHYS_ASI(asi)) {                                                            \
837                     _hi = (uint64_t)(loc) >> 32;                                \
838                     SPARC64_ST_PHYS_NONCONST(st);                               \
839           } else                                                                          \
840                     SPARC64_ST_NONCONST(st);                                    \
841 }
842 #define SPARC64_ST_DEF64(st, type)      \
843 static __inline void st(paddr_t loc, int asi, type value)             \
844 {                                                                                         \
845           uint32_t _vlo, _vhi, _hi;                                             \
846           _vlo = value;                                                                   \
847           _vhi = (uint64_t)(value) >> 32;                                                 \
848           if (PHYS_ASI(asi)) {                                                            \
849                     _hi = (uint64_t)(loc) >> 32;                                \
850                     SPARC64_ST_PHYS_NONCONST64(st);                                       \
851           } else                                                                          \
852                     SPARC64_ST_NONCONST64(st);                                  \
853 }
854 #endif
855 
856 #endif    /* __arch64__ */
857 
858 /* store byte to alternate address space */
859 SPARC64_ST_DEF(stba, uint8_t)
860 /* store half-word to alternate address space */
861 SPARC64_ST_DEF(stha, uint16_t)
862 /* store unsigned int to alternate address space */
863 SPARC64_ST_DEF(sta, uint32_t)
864 /* store 64-bit unsigned int to alternate address space */
865 SPARC64_ST_DEF64(stxa, uint64_t)
866 
867 
868 
869 /* flush address from cache */
870 #define   sparc_flush_icache(loc) __asm \
871           volatile("flush %0" : : "r" ((__uintptr_t)(loc)))
872 
873 /*
874  * SPARC V9 memory barrier instructions.
875  */
876 /* Make all stores complete before next store */
877 #define   membar_StoreStore() __asm volatile("membar #StoreStore" : :)
878 /* Make all loads complete before next store */
879 #define   membar_LoadStore() __asm volatile("membar #LoadStore" : :)
880 /* Make all stores complete before next load */
881 #define   membar_StoreLoad() __asm volatile("membar #StoreLoad" : :)
882 /* Make all loads complete before next load */
883 #define   membar_LoadLoad() __asm volatile("membar #LoadLoad" : :)
884 /* Complete all outstanding memory operations and exceptions */
885 #define   membar_Sync() __asm volatile("membar #Sync" : :)
886 /* Complete all outstanding memory operations */
887 #define   membar_MemIssue() __asm volatile("membar #MemIssue" : :)
888 /* Complete all outstanding stores before any new loads */
889 #define   membar_Lookaside() __asm volatile("membar #Lookaside" : :)
890 
891 #define membar_Load() __asm volatile("membar #LoadLoad | #LoadStore" : :)
892 #define membar_Store() __asm volatile("membar #LoadStore | #StoreStore" : :)
893 
894 #endif
895 
896 #endif /* _SPARC_CTLREG_H_ */
897