1 /* pgtsrmmu.h: SRMMU page table defines and code.
2 *
3 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
4 */
5
6 #include <asm/page.h> /* just in case */
7
8 #ifndef _SPARC_PGTSRMMU_H
9 #define _SPARC_PGTSRMMU_H
10
11 #define SRMMU_PAGE_TABLE_SIZE 0x100 /* 64 entries, 4 bytes a piece */
12 #define SRMMU_PMD_TABLE_SIZE 0x100 /* 64 entries, 4 bytes a piece */
13 #define SRMMU_PGD_TABLE_SIZE 0x400 /* 256 entries, 4 bytes a piece */
14
15 /* PMD_SHIFT determines the size of the area a second-level page table can map */
16 #define SRMMU_PMD_SHIFT 18
17 #define SRMMU_PMD_SIZE (1UL << SRMMU_PMD_SHIFT)
18 #define SRMMU_PMD_MASK (~(SRMMU_PMD_SIZE-1))
19 #define SRMMU_PMD_ALIGN(addr) (((addr)+SRMMU_PMD_SIZE-1)&SRMMU_PMD_MASK)
20
21 /* PGDIR_SHIFT determines what a third-level page table entry can map */
22 #define SRMMU_PGDIR_SHIFT 24
23 #define SRMMU_PGDIR_SIZE (1UL << SRMMU_PGDIR_SHIFT)
24 #define SRMMU_PGDIR_MASK (~(SRMMU_PGDIR_SIZE-1))
25 #define SRMMU_PGDIR_ALIGN(addr) (((addr)+SRMMU_PGDIR_SIZE-1)&SRMMU_PGDIR_MASK)
26
27 /*
28 * Three-level on SRMMU.
29 */
30
31 #define SRMMU_PTRS_PER_PTE 64
32 #define SRMMU_PTRS_PER_PMD 64
33 #define SRMMU_PTRS_PER_PGD 256
34
35 /* Just any arbitrary offset to the start of the vmalloc VM area: the
36 * current 8MB value just means that there will be a 8MB "hole" after the
37 * physical memory until the kernel virtual memory starts. That means that
38 * any out-of-bounds memory accesses will hopefully be caught.
39 * The vmalloc() routines leaves a hole of 4kB between each vmalloced
40 * area for the same reason. ;)
41 */
42 #define SRMMU_VMALLOC_OFFSET (8*1024*1024)
43 #define SRMMU_VMALLOC_START ((high_memory + SRMMU_VMALLOC_OFFSET) & ~(SRMMU_VMALLOC_OFFSET-1))
44
45 /*
46 * Sparc SRMMU page table fields.
47 */
48
49 #define _SRMMU_PAGE_VALID (SRMMU_ET_PTE)
50 #define _SRMMU_PMD_VALID (SRMMU_ET_PTD)
51 #define _SRMMU_PGD_VALID (SRMMU_ET_PTD)
52 #define _SRMMU_PAGE_WRITE_USR (SRMMU_ACC_US_RDWR)
53 #define _SRMMU_PAGE_WRITE_KERN (SRMMU_ACC_S_RDWR)
54 #define _SRMMU_PAGE_EXEC (SRMMU_ACC_US_RDEXEC)
55 #define _SRMMU_PAGE_RDONLY (SRMMU_ACC_US_RDONLY)
56 #define _SRMMU_PAGE_NOREAD (SRMMU_ACC_U_ACCDENIED)
57 #define _SRMMU_PAGE_NOCACHE (~SRMMU_PTE_C_MASK)
58 #define _SRMMU_PAGE_PRIV (SRMMU_ACC_S_RDWREXEC)
59 #define _SRMMU_PAGE_REF (SRMMU_PTE_R_MASK)
60 #define _SRMMU_PAGE_DIRTY (SRMMU_PTE_M_MASK)
61 #define _SRMMU_PAGE_COW (SRMMU_ACC_U_RDONLY)
62 #define _SRMMU_PAGE_UNCOW (SRMMU_ACC_US_RDWR)
63
64 /* We want the swapper not to swap out page tables, thus dirty and writable
65 * so that the kernel can change the entries as needed. Also valid for
66 * obvious reasons.
67 */
68 #define _SRMMU_PAGE_TABLE (_SRMMU_PAGE_VALID | _SRMMU_PAGE_WRITE_KERN | _SRMMU_PAGE_REF | _SRMMU_PAGE_DIRTY)
69 #define _SRMMU_PAGE_CHG_MASK (_SRMMU_PAGE_REF | _SRMMU_PAGE_DIRTY | SRMMU_ET_PTE)
70 #define _SRMMU_PMD_CHG_MASK (SRMMU_ET_PTD)
71 #define _SRMMU_PGD_CHG_MASK (SRMMU_ET_PTD)
72
73 #define SRMMU_PAGE_NONE __pgprot(_SRMMU_PAGE_VALID | _SRMMU_PAGE_REF)
74 #define SRMMU_PAGE_SHARED __pgprot(_SRMMU_PAGE_VALID | _SRMMU_PAGE_WRITE_USR | _SRMMU_PAGE_REF)
75 #define SRMMU_PAGE_COPY __pgprot(_SRMMU_PAGE_VALID | _SRMMU_PAGE_REF | _SRMMU_PAGE_COW)
76 #define SRMMU_PAGE_READONLY __pgprot(_SRMMU_PAGE_VALID | _SRMMU_PAGE_REF | SRMMU_ACC_US_RDONLY)
77 #define SRMMU_PAGE_KERNEL __pgprot(_SRMMU_PAGE_VALID | _SRMMU_PAGE_PRIV | SRMMU_PTE_C_MASK)
78 #define SRMMU_PAGE_INVALID __pgprot(SRMMU_ET_INVALID)
79
80 #define _SRMMU_PAGE_NORMAL(x) __pgprot(_SRMMU_PAGE_VALID | _SRMMU_PAGE_REF | (x))
81
82 /* SRMMU Register addresses */
83 #define SRMMU_CTRL_REG 0x00000000
84 #define SRMMU_CTXTBL_PTR 0x00000100
85 #define SRMMU_CTX_REG 0x00000200
86 #define SRMMU_FAULT_STATUS 0x00000300
87 #define SRMMU_FAULT_ADDR 0x00000400
88 #define SRMMU_AFAULT_STATUS 0x00000500
89 #define SRMMU_AFAULT_ADDR 0x00000600
90
91 /* The SRMMU control register fields:
92 * -------------------------------------------------------------------
93 * | IMPL | VERS | SysControl | PSO | Resv | No Fault | Enable |
94 * -------------------------------------------------------------------
95 * 31 28 27 24 23 8 7 6 2 1 0
96 *
97 * IMPL: Indicates the implementation of this SRMMU, read-only.
98 * VERS: The version of this implementation, again read-only.
99 * SysControl: This is an implementation specific field, the SRMMU
100 * specification does not define anything for this field.
101 * PSO: This determines whether the memory model as seen by the CPU
102 * is Partial Store Order (PSO=1) or Total Store Ordering (PSO=0).
103 * Resv: Don't touch these bits ;)
104 * No Fault: If zero, any fault acts as expected where the fault status
105 * and address registers are updated and a trap hits the CPU.
106 * When this bit is one, on any fault other than in ASI 9, the
107 * MMU updates the status and address fault registers but does
108 * not signal the CPU with a trap. This is useful to beat
109 * race conditions in low-level code when we have to throw
110 * a register window onto the stack in a spill/fill handler
111 * on multiprocessors.
112 * Enable: If one the MMU is doing translations, if zero the addresses
113 * given to the bus are pure physical.
114 */
115
116 #define SRMMU_CTREG_IMPL_MASK 0xf0000000
117 #define SRMMU_CTREG_IMPL_SHIFT 28
118 #define SRMMU_CTREG_VERS_MASK 0x0f000000
119 #define SRMMU_CTREG_VERS_SHIFT 24
120 #define SRMMU_CTREG_SYSCNTRL_MASK 0x00ffff00
121 #define SRMMU_CTREG_SYSCNTRL_SHIFT 8
122 #define SRMMU_CTREG_PSO_MASK 0x00000080
123 #define SRMMU_CTREG_PSO_SHIFT 7
124 #define SRMMU_CTREG_RESV_MASK 0x0000007c
125 #define SRMMU_CTREG_RESV_SHIFT 2
126 #define SRMMU_CTREG_NOFAULT_MASK 0x00000002
127 #define SRMMU_CTREG_NOFAULT_SHIFT 1
128 #define SRMMU_CTREG_ENABLE_MASK 0x00000001
129 #define SRMMU_CTREG_ENABLE_SHIFT 0
130
131 /* Get the MMU control register */
132 extern inline unsigned int srmmu_get_mmureg(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)
*/
133 {
134 register unsigned int retval;
135 __asm__ __volatile__("lda [%%g0] %1, %0\n\t" :
136 "=r" (retval) :
137 "i" (ASI_M_MMUREGS));
138 return retval;
139 }
140
141 /* Set the MMU control register */
142 extern inline void srmmu_set_mmureg(unsigned long regval)
/* ![[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)
*/
143 {
144 __asm__ __volatile__("sta %0, [%%g0] %1\n\t" : :
145 "r" (regval), "i" (ASI_M_MMUREGS) : "memory");
146
147 return;
148 }
149
150 /* The SRMMU Context Table Pointer Register:
151 * ---------------------------------
152 * | Context Table Pointer | Resv |
153 * ---------------------------------
154 * 31 2 1 0
155 *
156 * This is where the MMU goes to in physical RAM to fetch the
157 * elements in the context table. The non-Resv bits of this
158 * address appear in bits 6-35 of the physical bus during miss
159 * processing, then indexed by the value in the Context Register.
160 * This table must be aligned on a boundary equal to the size of
161 * the table, we provide a nice macro for doing this based upon
162 * the significant bits in the context register.
163 */
164 #define SRMMU_CTP_ADDR_MASK 0xfffffffc
165 #define SRMMU_CTP_ADDR_PADDR_SHIFT 0x4
166 #define SRMMU_CTP_RESV_MASK 0x00000003
167
168 #define SRMMU_SIGBITS_TO_ALIGNMENT(numbits) ((1 << (numbits + 2)))
169
170
171 /* Set the address of the context table. You pass this routine
172 * the physical address, we do the magic shifting for you.
173 */
174 extern inline void srmmu_set_ctable_ptr(unsigned long paddr)
/* ![[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)
*/
175 {
176 unsigned long ctp;
177
178 ctp = (paddr >> SRMMU_CTP_ADDR_PADDR_SHIFT);
179 ctp &= SRMMU_CTP_ADDR_MASK;
180
181 __asm__ __volatile__("sta %0, [%1] %2\n\t" : :
182 "r" (ctp), "r" (SRMMU_CTXTBL_PTR),
183 "i" (ASI_M_MMUREGS) :
184 "memory");
185 return;
186 }
187
188
189 /* Get the address of the context table. We return the physical
190 * address of the table, again we do the shifting here.
191 */
192 extern inline unsigned long srmmu_get_ctable_ptr(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)
*/
193 {
194 register unsigned int retval;
195
196 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
197 "=r" (retval) :
198 "r" (SRMMU_CTXTBL_PTR),
199 "i" (ASI_M_MMUREGS));
200
201 retval &= SRMMU_CTP_ADDR_MASK;
202 retval = (retval << SRMMU_CTP_ADDR_PADDR_SHIFT);
203 return retval;
204 }
205
206 /* Set the context on an SRMMU */
207 extern inline void srmmu_set_context(int context)
/* ![[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)
*/
208 {
209 __asm__ __volatile__("sta %0, [%1] %2\n\t" : :
210 "r" (context), "r" (SRMMU_CTX_REG),
211 "i" (ASI_M_MMUREGS) : "memory");
212 return;
213 }
214
215 /* Get the context on an SRMMU */
216 extern inline int srmmu_get_context(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)
*/
217 {
218 register int retval;
219 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
220 "=r" (retval) :
221 "r" (SRMMU_CTX_REG),
222 "i" (ASI_M_MMUREGS));
223 return retval;
224 }
225
226 /* SRMMU diagnostic register:
227 * --------------------------------------------------------
228 * | Virtual Address | PDC entry | DiagReg | Resv |
229 * --------------------------------------------------------
230 * 31 12 11 4 3 2 1 0
231 *
232 * An SRMMU implementation has the choice of providing this register
233 * and I don't know much about it.
234 */
235
236 #define SRMMU_DIAG_VADDR_MASK 0xfffff000
237 #define SRMMU_DIAG_PDC_MASK 0x00000ff0
238 #define SRMMU_DIAG_REG_MASK 0x0000000c
239 #define SRMMU_DIAG_RESV_MASK 0x00000003
240
241 /* SRMMU Fault Status Register:
242 * -----------------------------------------------------------
243 * | Reserved | EBE | L | AT | FT | FAV | OW |
244 * -----------------------------------------------------------
245 * 31 18 17 10 9 8 7 5 4 2 1 0
246 *
247 * WARNING!!! On certain VERY BROKEN Viking Sun4d modules this register
248 * is complete TOAST! During a fault you cannot trust the values
249 * contained in this register, you must calculate them yourself
250 * by first using the trap program counter to decode the
251 * instruction the code tried to execute (ie. load or store) and
252 * the address they tried to access. I think the Fault Virtual
253 * Address register may be ok on these chips, but who knows. Grrr.
254 *
255 * Reserved: These bits must be zero.
256 * EBE: External bus error bits, implementation dependant (at least
257 * we know what the bits mean on sun4d Viking modules) ;)
258 * L: The level in tree traversal at which the fault occured. The
259 * values are... 0 = context table
260 * 1 = level-1 page table
261 * 2 = level-2 page table
262 * 3 = level-3 page table
263 * AT: Access type field. This is decoded as follows...
264 * 0 -- Load from user data space
265 * 1 -- Load from supervisor data space
266 * 2 -- Read/Execute from user instruction space
267 * 3 -- Read/Execute from supervisor instruction space
268 * 4 -- Store to user data space
269 * 5 -- Store to supervisor data space
270 * 6 -- Store to user instruction space
271 * 7 -- Store to supervisor instruction space (emacs does this)
272 * On the Viking -- TOAST!
273 * FT: This is the fault type field. It is used to determine what was
274 * wrong in the attempted translation. It can be one of...
275 * 0 -- None
276 * 1 -- Invalid address error
277 * 2 -- Protection violation error
278 * 3 -- Priviledge violation error
279 * 4 -- Translation error (your tables are fucked up)
280 * 5 -- Bus access error (you lose)
281 * 6 -- Internal error (might as well have a Viking)
282 * 7 -- Reserved (don't touch)
283 * FAV: Fault Address Valid bit. When set to one the fault address
284 * register contents are valid. It need not be valid for text
285 * faults as the trapped PC tells us this anyway.
286 * OW: The Overwrite Bit, if set to one, this register has been
287 * written to more than once by the hardware since software did
288 * a read. This mean multiple faults have occurred and you have
289 * to a manual page table tree traversal to continue the handling
290 * of the first fault. And on the Viking module....
291 *
292 * The Fault Address Register is just a 32-bit register representing the
293 * virtual address which caused the fault. It's validity is determined
294 * by the following equation:
295 * if(module==VIKING || FSR.FAV==0) forget_it();
296 * It's ok for the FAV to be invalid for a text fault because we can
297 * use the trapped program counter, however for a data fault we are SOL.
298 * I'll probably have to write a workaround for this situation too ;-(
299 */
300
301 #define SRMMU_FSR_RESV_MASK 0xfffc0000 /* Reserved bits */
302 #define SRMMU_FSR_EBE_MASK 0x0003fc00 /* External Bus Error bits */
303 #define SRMMU_FSR_EBE_BERR 0x00000400 /* Bus Error */
304 #define SRMMU_FSR_EBE_BTIMEO 0x00000800 /* Bus Time Out */
305 #define SRMMU_FSR_EBE_UNCOR 0x00001000 /* Uncorrectable Error */
306 #define SRMMU_FSR_EBE_UNDEF 0x00002000 /* Undefined Error */
307 #define SRMMU_FSR_EBE_PARITY 0x00004000 /* Parity error */
308 #define SRMMU_FSR_EBE_TPARITY 0x00006000 /* Tsunami parity error */
309 #define SRMMU_FSR_EBE_SBUF 0x00008000 /* Store Buffer error */
310 #define SRMMU_FSR_EBE_CSA 0x00010000 /* Control space access error (bad ASI) */
311 #define SRMMU_FSR_EBE_EMRT 0x00020000 /* Viking Emergency Response Team */
312 #define SRMMU_FSR_L_MASK 0x00000300 /* Fault level bits */
313 #define SRMMU_FSR_L_CTABLE 0x00000000 /* Context table level flt/err */
314 #define SRMMU_FSR_L_ONE 0x00000100 /* Level1 ptable flt/err */
315 #define SRMMU_FSR_L_TWO 0x00000200 /* Level2 ptable flt/err */
316 #define SRMMU_FSR_L_THREE 0x00000300 /* Level3 ptable flt/err */
317 #define SRMMU_FSR_AT_MASK 0x000000e0 /* Access Type bits */
318 #define SRMMU_FSR_AT_LUD 0x00000000 /* Load from User Data space */
319 #define SRMMU_FSR_AT_LSD 0x00000020 /* What I'll need after writing this code */
320 #define SRMMU_FSR_AT_RXUI 0x00000040 /* Read/Execute from user text */
321 #define SRMMU_FSR_AT_RXSI 0x00000060 /* Read/Execute from supv text */
322 #define SRMMU_FSR_AT_SUD 0x00000080 /* Store to user data space */
323 #define SRMMU_FSR_AT_SSD 0x000000a0 /* Store to supv data space */
324 #define SRMMU_FSR_AT_SUI 0x000000c0 /* Store to user text */
325 #define SRMMU_FSR_AT_SSI 0x000000e0 /* Store to supv text */
326 #define SRMMU_FSR_FT_MASK 0x0000001c /* Fault Type bits */
327 #define SRMMU_FSR_FT_NONE 0x00000000 /* No fault occurred */
328 #define SRMMU_FSR_FT_IADDR 0x00000002 /* Invalid address */
329 #define SRMMU_FSR_FT_PROT 0x00000004 /* Protection violation */
330 #define SRMMU_FSR_FT_PRIV 0x00000008 /* Privilege violation */
331 #define SRMMU_FSR_FT_TRANS 0x0000000a /* Translation error */
332 #define SRMMU_FSR_FT_BACC 0x0000000c /* Bus Access error */
333 #define SRMMU_FSR_FT_IACC 0x0000000e /* Internal error */
334 #define SRMMU_FSR_FT_RESV 0x00000010 /* Reserved, should not get this */
335 #define SRMMU_FSR_FAV_MASK 0x00000002 /* Fault Address Valid bits */
336 #define SRMMU_FSR_OW_MASK 0x00000001 /* SFSR OverWritten bits */
337
338 /* Read the Fault Status Register on the SRMMU */
339 extern inline unsigned int srmmu_get_fstatus(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)
*/
340 {
341 register unsigned int retval;
342
343 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
344 "=r" (retval) :
345 "r" (SRMMU_FAULT_STATUS), "i" (ASI_M_MMUREGS));
346 return retval;
347 }
348
349 /* Read the Fault Address Register on the SRMMU */
350 extern inline unsigned int srmmu_get_faddr(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)
*/
351 {
352 register unsigned int retval;
353
354 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
355 "=r" (retval) :
356 "r" (SRMMU_FAULT_ADDR), "i" (ASI_M_MMUREGS));
357 return retval;
358 }
359
360 /* SRMMU Asynchronous Fault Status Register:
361 * -----------------------------------------
362 * | RESERVED |UCE|BTO|BERR|RSV|HFADDR|AFO|
363 * -----------------------------------------
364 * 31 13 12 11 10 9-8 7-4 0
365 *
366 * UCE: UnCorrectable Error
367 * BTO: Bus TimeOut
368 * BERR: Genreic Bus Error
369 * HFADDR: High 4 bits of the faulting address
370 * AFO: Asynchronous Fault Occurred
371 */
372 #define SRMMU_AFSR_RESVMASK 0xffffe000
373 #define SRMMU_AFSR_UCE 0x00001000
374 #define SRMMU_AFSR_BTO 0x00000800
375 #define SRMMU_AFSR_BERR 0x00000400
376 #define SRMMU_AFSR_HFADDR 0x000000f0
377 #define SRMMU_AFSR_AFO 0x00000001
378
379 /* Read the asynchronous fault register */
380 extern inline unsigned int srmmu_get_afstatus(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)
*/
381 {
382 register unsigned int retval;
383
384 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
385 "=r" (retval) :
386 "r" (SRMMU_AFAULT_STATUS), "i" (ASI_M_MMUREGS));
387 return retval;
388 }
389
390 /* Read the Asynchronous Fault Address Register on the SRMMU */
391 extern inline unsigned int srmmu_get_afaddr(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)
*/
392 {
393 register unsigned int retval;
394
395 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
396 "=r" (retval) :
397 "r" (SRMMU_AFAULT_ADDR), "i" (ASI_M_MMUREGS));
398 return retval;
399 }
400
401
402 /* Flush the entire TLB cache on the SRMMU. */
403 extern inline void srmmu_flush_whole_tlb(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)
*/
404 {
405 __asm__ __volatile__("sta %%g0, [%0] %1\n\t": :
406 "r" (0x400), /* Flush entire TLB!! */
407 "i" (ASI_M_FLUSH_PROBE) : "memory");
408
409 return;
410 }
411
412 /* Probe for an entry in the page-tables of the SRMMU. */
413 extern inline unsigned long srmmu_hwprobe(unsigned long vaddr)
/* ![[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)
*/
414 {
415 unsigned long retval;
416
417 __asm__ __volatile__("lda [%1] %2, %0\n\t" :
418 "=r" (retval) :
419 "r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE));
420
421 return retval;
422 }
423
424 #endif /* !(_SPARC_PGTSRMMU_H) */