File: /usr/src/linux/include/asm-mips/pgtable.h
1 /*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1994, 95, 96, 97, 98, 99, 2000 by Ralf Baechle at alii
7 * Copyright (C) 1999 Silicon Graphics, Inc.
8 */
9 #ifndef _ASM_PGTABLE_H
10 #define _ASM_PGTABLE_H
11
12 #include <asm/addrspace.h>
13 #include <asm/page.h>
14
15 #ifndef _LANGUAGE_ASSEMBLY
16
17 #include <linux/linkage.h>
18 #include <asm/cachectl.h>
19 #include <linux/config.h>
20
21 /* Cache flushing:
22 *
23 * - flush_cache_all() flushes entire cache
24 * - flush_cache_mm(mm) flushes the specified mm context's cache lines
25 * - flush_cache_page(mm, vmaddr) flushes a single page
26 * - flush_cache_range(mm, start, end) flushes a range of pages
27 * - flush_page_to_ram(page) write back kernel page to ram
28 * - flush_icache_range(start, end) flush a range of instructions
29 */
30 extern void (*_flush_cache_all)(void);
31 extern void (*___flush_cache_all)(void);
32 extern void (*_flush_cache_mm)(struct mm_struct *mm);
33 extern void (*_flush_cache_range)(struct mm_struct *mm, unsigned long start,
34 unsigned long end);
35 extern void (*_flush_cache_page)(struct vm_area_struct *vma, unsigned long page);
36 extern void (*_flush_cache_sigtramp)(unsigned long addr);
37 extern void (*_flush_page_to_ram)(struct page * page);
38 extern void (*_flush_icache_range)(unsigned long start, unsigned long end);
39 extern void (*_flush_icache_page)(struct vm_area_struct *vma,
40 struct page *page);
41
42 #define flush_dcache_page(page) do { } while (0)
43
44 #define flush_cache_all() _flush_cache_all()
45 #define __flush_cache_all() ___flush_cache_all()
46 #define flush_cache_mm(mm) _flush_cache_mm(mm)
47 #define flush_cache_range(mm,start,end) _flush_cache_range(mm,start,end)
48 #define flush_cache_page(vma,page) _flush_cache_page(vma, page)
49 #define flush_cache_sigtramp(addr) _flush_cache_sigtramp(addr)
50 #define flush_page_to_ram(page) _flush_page_to_ram(page)
51
52 #define flush_icache_range(start, end) _flush_icache_range(start,end)
53 #define flush_icache_page(vma, page) _flush_icache_page(vma, page)
54
55
56 /*
57 * - add_wired_entry() add a fixed TLB entry, and move wired register
58 */
59 extern void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
60 unsigned long entryhi, unsigned long pagemask);
61
62 /*
63 * - add_temporary_entry() add a temporary TLB entry. We use TLB entries
64 * starting at the top and working down. This is for populating the
65 * TLB before trap_init() puts the TLB miss handler in place. It
66 * should be used only for entries matching the actual page tables,
67 * to prevent inconsistencies.
68 */
69 extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
70 unsigned long entryhi, unsigned long pagemask);
71
72
73 /* Basically we have the same two-level (which is the logical three level
74 * Linux page table layout folded) page tables as the i386. Some day
75 * when we have proper page coloring support we can have a 1% quicker
76 * tlb refill handling mechanism, but for now it is a bit slower but
77 * works even with the cache aliasing problem the R4k and above have.
78 */
79
80 #endif /* !defined (_LANGUAGE_ASSEMBLY) */
81
82 /* PMD_SHIFT determines the size of the area a second-level page table can map */
83 #define PMD_SHIFT 22
84 #define PMD_SIZE (1UL << PMD_SHIFT)
85 #define PMD_MASK (~(PMD_SIZE-1))
86
87 /* PGDIR_SHIFT determines what a third-level page table entry can map */
88 #define PGDIR_SHIFT 22
89 #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
90 #define PGDIR_MASK (~(PGDIR_SIZE-1))
91
92 /* Entries per page directory level: we use two-level, so
93 * we don't really have any PMD directory physically.
94 */
95 #define PTRS_PER_PTE 1024
96 #define PTRS_PER_PMD 1
97 #define PTRS_PER_PGD 1024
98 #define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE)
99 #define FIRST_USER_PGD_NR 0
100
101 #define VMALLOC_START KSEG2
102 #define VMALLOC_VMADDR(x) ((unsigned long)(x))
103 #define VMALLOC_END KSEG3
104
105 /* Note that we shift the lower 32bits of each EntryLo[01] entry
106 * 6 bits to the left. That way we can convert the PFN into the
107 * physical address by a single 'and' operation and gain 6 additional
108 * bits for storing information which isn't present in a normal
109 * MIPS page table.
110 *
111 * Similar to the Alpha port, we need to keep track of the ref
112 * and mod bits in software. We have a software "yeah you can read
113 * from this page" bit, and a hardware one which actually lets the
114 * process read from the page. On the same token we have a software
115 * writable bit and the real hardware one which actually lets the
116 * process write to the page, this keeps a mod bit via the hardware
117 * dirty bit.
118 *
119 * Certain revisions of the R4000 and R5000 have a bug where if a
120 * certain sequence occurs in the last 3 instructions of an executable
121 * page, and the following page is not mapped, the cpu can do
122 * unpredictable things. The code (when it is written) to deal with
123 * this problem will be in the update_mmu_cache() code for the r4k.
124 */
125 #define _PAGE_PRESENT (1<<0) /* implemented in software */
126 #define _PAGE_READ (1<<1) /* implemented in software */
127 #define _PAGE_WRITE (1<<2) /* implemented in software */
128 #define _PAGE_ACCESSED (1<<3) /* implemented in software */
129 #define _PAGE_MODIFIED (1<<4) /* implemented in software */
130
131 #if defined(CONFIG_CPU_R3000)
132
133 #define _PAGE_GLOBAL (1<<8)
134 #define _PAGE_VALID (1<<9)
135 #define _PAGE_SILENT_READ (1<<9) /* synonym */
136 #define _PAGE_DIRTY (1<<10) /* The MIPS dirty bit */
137 #define _PAGE_SILENT_WRITE (1<<10)
138 #define _CACHE_UNCACHED (1<<11) /* R4[0246]00 */
139 #define _CACHE_MASK (1<<11)
140 #define _CACHE_CACHABLE_NONCOHERENT 0
141
142 #else
143 #define _PAGE_R4KBUG (1<<5) /* workaround for r4k bug */
144 #define _PAGE_GLOBAL (1<<6)
145 #define _PAGE_VALID (1<<7)
146 #define _PAGE_SILENT_READ (1<<7) /* synonym */
147 #define _PAGE_DIRTY (1<<8) /* The MIPS dirty bit */
148 #define _PAGE_SILENT_WRITE (1<<8)
149 #define _CACHE_MASK (7<<9)
150
151 #if defined(CONFIG_CPU_SB1)
152
153 /* No penalty for being coherent on the SB1, so just
154 use it for "noncoherent" spaces, too. Shouldn't hurt. */
155
156 #define _CACHE_UNCACHED (2<<9)
157 #define _CACHE_CACHABLE_COW (5<<9)
158 #define _CACHE_CACHABLE_NONCOHERENT (5<<9)
159
160 #else
161
162 #define _CACHE_CACHABLE_NO_WA (0<<9) /* R4600 only */
163 #define _CACHE_CACHABLE_WA (1<<9) /* R4600 only */
164 #define _CACHE_UNCACHED (2<<9) /* R4[0246]00 */
165 #define _CACHE_CACHABLE_NONCOHERENT (3<<9) /* R4[0246]00 */
166 #define _CACHE_CACHABLE_CE (4<<9) /* R4[04]00 only */
167 #define _CACHE_CACHABLE_COW (5<<9) /* R4[04]00 only */
168 #define _CACHE_CACHABLE_CUW (6<<9) /* R4[04]00 only */
169 #define _CACHE_CACHABLE_ACCELERATED (7<<9) /* R10000 only */
170
171 #endif
172 #endif
173
174 #define __READABLE (_PAGE_READ | _PAGE_SILENT_READ | _PAGE_ACCESSED)
175 #define __WRITEABLE (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
176
177 #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK)
178
179 #ifdef CONFIG_MIPS_UNCACHED
180 #define PAGE_CACHABLE_DEFAULT _CACHE_UNCACHED
181 #else
182 #ifdef CONFIG_CPU_SB1
183 #define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_COW
184 #else
185 #define PAGE_CACHABLE_DEFAULT _CACHE_CACHABLE_NONCOHERENT
186 #endif
187 #endif
188
189 #define PAGE_NONE __pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT)
190 #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
191 PAGE_CACHABLE_DEFAULT)
192 #define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_READ | \
193 PAGE_CACHABLE_DEFAULT)
194 #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_READ | \
195 PAGE_CACHABLE_DEFAULT)
196 #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
197 PAGE_CACHABLE_DEFAULT)
198 #define PAGE_USERIO __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
199 PAGE_CACHABLE_DEFAULT)
200 #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
201 _CACHE_UNCACHED)
202
203 /*
204 * MIPS can't do page protection for execute, and considers that the same like
205 * read. Also, write permissions imply read permissions. This is the closest
206 * we can get by reasonable means..
207 */
208 #define __P000 PAGE_NONE
209 #define __P001 PAGE_READONLY
210 #define __P010 PAGE_COPY
211 #define __P011 PAGE_COPY
212 #define __P100 PAGE_READONLY
213 #define __P101 PAGE_READONLY
214 #define __P110 PAGE_COPY
215 #define __P111 PAGE_COPY
216
217 #define __S000 PAGE_NONE
218 #define __S001 PAGE_READONLY
219 #define __S010 PAGE_SHARED
220 #define __S011 PAGE_SHARED
221 #define __S100 PAGE_READONLY
222 #define __S101 PAGE_READONLY
223 #define __S110 PAGE_SHARED
224 #define __S111 PAGE_SHARED
225
226 #if !defined (_LANGUAGE_ASSEMBLY)
227
228 #define pte_ERROR(e) \
229 printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
230 #define pmd_ERROR(e) \
231 printk("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e))
232 #define pgd_ERROR(e) \
233 printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e))
234
235 extern unsigned long empty_zero_page;
236 extern unsigned long zero_page_mask;
237
238 #define ZERO_PAGE(vaddr) \
239 (virt_to_page(empty_zero_page + (((unsigned long)(vaddr)) & zero_page_mask)))
240
241 /* number of bits that fit into a memory pointer */
242 #define BITS_PER_PTR (8*sizeof(unsigned long))
243
244 /* to align the pointer to a pointer address */
245 #define PTR_MASK (~(sizeof(void*)-1))
246
247 /*
248 * sizeof(void*) == (1 << SIZEOF_PTR_LOG2)
249 */
250 #define SIZEOF_PTR_LOG2 2
251
252 /* to find an entry in a page-table */
253 #define PAGE_PTR(address) \
254 ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
255
256 extern void load_pgd(unsigned long pg_dir);
257
258 extern pmd_t invalid_pte_table[PAGE_SIZE/sizeof(pmd_t)];
259
260 /*
261 * Conversion functions: convert a page and protection to a page entry,
262 * and a page entry and page directory to the page they refer to.
263 */
264 extern inline unsigned long pmd_page(pmd_t pmd)
265 {
266 return pmd_val(pmd);
267 }
268
269 extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
270 {
271 pmd_val(*pmdp) = (((unsigned long) ptep) & PAGE_MASK);
272 }
273
274 extern inline int pte_none(pte_t pte) { return !pte_val(pte); }
275 extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; }
276
277 /* Certain architectures need to do special things when pte's
278 * within a page table are directly modified. Thus, the following
279 * hook is made available.
280 */
281 extern inline void set_pte(pte_t *ptep, pte_t pteval)
282 {
283 *ptep = pteval;
284 }
285
286 extern inline void pte_clear(pte_t *ptep)
287 {
288 set_pte(ptep, __pte(0));
289 }
290
291 /*
292 * (pmds are folded into pgds so this doesnt get actually called,
293 * but the define is needed for a generic inline function.)
294 */
295 #define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
296 #define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval)
297
298 /*
299 * Empty pgd/pmd entries point to the invalid_pte_table.
300 */
301 extern inline int pmd_none(pmd_t pmd)
302 {
303 return pmd_val(pmd) == (unsigned long) invalid_pte_table;
304 }
305
306 extern inline int pmd_bad(pmd_t pmd)
307 {
308 return ((pmd_page(pmd) > (unsigned long) high_memory) ||
309 (pmd_page(pmd) < PAGE_OFFSET));
310 }
311
312 extern inline int pmd_present(pmd_t pmd)
313 {
314 return (pmd_val(pmd) != (unsigned long) invalid_pte_table);
315 }
316
317 extern inline void pmd_clear(pmd_t *pmdp)
318 {
319 pmd_val(*pmdp) = ((unsigned long) invalid_pte_table);
320 }
321
322 /*
323 * The "pgd_xxx()" functions here are trivial for a folded two-level
324 * setup: the pgd is never bad, and a pmd always exists (as it's folded
325 * into the pgd entry)
326 */
327 extern inline int pgd_none(pgd_t pgd) { return 0; }
328 extern inline int pgd_bad(pgd_t pgd) { return 0; }
329 extern inline int pgd_present(pgd_t pgd) { return 1; }
330 extern inline void pgd_clear(pgd_t *pgdp) { }
331
332 /*
333 * Permanent address of a page. On MIPS we never have highmem, so this
334 * is simple.
335 */
336 #define page_address(page) ((page)->virtual)
337 #ifdef CONFIG_CPU_VR41XX
338 #define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> (PAGE_SHIFT + 2))))
339 #else
340 #define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> PAGE_SHIFT)))
341 #endif
342
343 /*
344 * The following only work if pte_present() is true.
345 * Undefined behaviour if not..
346 */
347 extern inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_READ; }
348 extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; }
349 extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_MODIFIED; }
350 extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
351
352 extern inline pte_t pte_wrprotect(pte_t pte)
353 {
354 pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
355 return pte;
356 }
357
358 extern inline pte_t pte_rdprotect(pte_t pte)
359 {
360 pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ);
361 return pte;
362 }
363
364 extern inline pte_t pte_mkclean(pte_t pte)
365 {
366 pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE);
367 return pte;
368 }
369
370 extern inline pte_t pte_mkold(pte_t pte)
371 {
372 pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ);
373 return pte;
374 }
375
376 extern inline pte_t pte_mkwrite(pte_t pte)
377 {
378 pte_val(pte) |= _PAGE_WRITE;
379 if (pte_val(pte) & _PAGE_MODIFIED)
380 pte_val(pte) |= _PAGE_SILENT_WRITE;
381 return pte;
382 }
383
384 extern inline pte_t pte_mkread(pte_t pte)
385 {
386 pte_val(pte) |= _PAGE_READ;
387 if (pte_val(pte) & _PAGE_ACCESSED)
388 pte_val(pte) |= _PAGE_SILENT_READ;
389 return pte;
390 }
391
392 extern inline pte_t pte_mkdirty(pte_t pte)
393 {
394 pte_val(pte) |= _PAGE_MODIFIED;
395 if (pte_val(pte) & _PAGE_WRITE)
396 pte_val(pte) |= _PAGE_SILENT_WRITE;
397 return pte;
398 }
399
400 /*
401 * Macro to make mark a page protection value as "uncacheable". Note
402 * that "protection" is really a misnomer here as the protection value
403 * contains the memory attribute bits, dirty bits, and various other
404 * bits as well.
405 */
406 #define pgprot_noncached pgprot_noncached
407
408 static inline pgprot_t pgprot_noncached(pgprot_t _prot)
409 {
410 unsigned long prot = pgprot_val(_prot);
411
412 prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED;
413
414 return __pgprot(prot);
415 }
416
417 extern inline pte_t pte_mkyoung(pte_t pte)
418 {
419 pte_val(pte) |= _PAGE_ACCESSED;
420 if (pte_val(pte) & _PAGE_READ)
421 pte_val(pte) |= _PAGE_SILENT_READ;
422 return pte;
423 }
424
425 /*
426 * Conversion functions: convert a page and protection to a page entry,
427 * and a page entry and page directory to the page they refer to.
428 */
429 #ifdef CONFIG_CPU_VR41XX
430 #define mk_pte(page, pgprot) \
431 ({ \
432 pte_t __pte; \
433 \
434 pte_val(__pte) = ((unsigned long)(page - mem_map) << (PAGE_SHIFT + 2)) | \
435 pgprot_val(pgprot); \
436 \
437 __pte; \
438 })
439 #else
440 #define mk_pte(page, pgprot) \
441 ({ \
442 pte_t __pte; \
443 \
444 pte_val(__pte) = ((unsigned long)(page - mem_map) << PAGE_SHIFT) | \
445 pgprot_val(pgprot); \
446 \
447 __pte; \
448 })
449 #endif
450
451 extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
452 {
453 #ifdef CONFIG_CPU_VR41XX
454 return __pte((physpage << 2) | pgprot_val(pgprot));
455 #else
456 return __pte(physpage | pgprot_val(pgprot));
457 #endif
458 }
459
460 extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
461 {
462 return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot));
463 }
464
465 #define page_pte(page) page_pte_prot(page, __pgprot(0))
466
467 /* to find an entry in a kernel page-table-directory */
468 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
469
470 #define pgd_index(address) ((address) >> PGDIR_SHIFT)
471
472 /* to find an entry in a page-table-directory */
473 extern inline pgd_t *pgd_offset(struct mm_struct *mm, unsigned long address)
474 {
475 return mm->pgd + pgd_index(address);
476 }
477
478 /* Find an entry in the second-level page table.. */
479 extern inline pmd_t *pmd_offset(pgd_t *dir, unsigned long address)
480 {
481 return (pmd_t *) dir;
482 }
483
484 /* Find an entry in the third-level page table.. */
485 extern inline pte_t *pte_offset(pmd_t * dir, unsigned long address)
486 {
487 return (pte_t *) (pmd_page(*dir)) +
488 ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
489 }
490
491 extern int do_check_pgt_cache(int, int);
492
493 extern pgd_t swapper_pg_dir[1024];
494 extern void paging_init(void);
495
496 extern void update_mmu_cache(struct vm_area_struct *vma,
497 unsigned long address, pte_t pte);
498
499 #define SWP_TYPE(x) (((x).val >> 1) & 0x3f)
500 #define SWP_OFFSET(x) ((x).val >> 8)
501 #define SWP_ENTRY(type,offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
502 #define pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
503 #define swp_entry_to_pte(x) ((pte_t) { (x).val })
504
505
506 /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
507 #define PageSkip(page) (0)
508 #define kern_addr_valid(addr) (1)
509
510 /* TLB operations. */
511 extern inline void tlb_probe(void)
512 {
513 __asm__ __volatile__(
514 ".set push\n\t"
515 ".set reorder\n\t"
516 "tlbp\n\t"
517 ".set pop");
518 }
519
520 extern inline void tlb_read(void)
521 {
522 __asm__ __volatile__(
523 ".set push\n\t"
524 ".set reorder\n\t"
525 "tlbr\n\t"
526 ".set pop");
527 }
528
529 extern inline void tlb_write_indexed(void)
530 {
531 __asm__ __volatile__(
532 ".set push\n\t"
533 ".set reorder\n\t"
534 "tlbwi\n\t"
535 ".set pop");
536 }
537
538 extern inline void tlb_write_random(void)
539 {
540 __asm__ __volatile__(
541 ".set push\n\t"
542 ".set reorder\n\t"
543 "tlbwr\n\t"
544 ".set pop");
545 }
546
547 /* Dealing with various CP0 mmu/cache related registers. */
548
549 /* CP0_PAGEMASK register */
550 extern inline unsigned long get_pagemask(void)
551 {
552 unsigned long val;
553
554 __asm__ __volatile__(
555 ".set push\n\t"
556 ".set reorder\n\t"
557 "mfc0 %0, $5\n\t"
558 ".set pop"
559 : "=r" (val));
560 return val;
561 }
562
563 extern inline void set_pagemask(unsigned long val)
564 {
565 __asm__ __volatile__(
566 ".set push\n\t"
567 ".set reorder\n\t"
568 "mtc0 %z0, $5\n\t"
569 ".set pop"
570 : : "Jr" (val));
571 }
572
573 /* CP0_ENTRYLO0 and CP0_ENTRYLO1 registers */
574 extern inline unsigned long get_entrylo0(void)
575 {
576 unsigned long val;
577
578 __asm__ __volatile__(
579 ".set push\n\t"
580 ".set reorder\n\t"
581 "mfc0 %0, $2\n\t"
582 ".set pop"
583 : "=r" (val));
584 return val;
585 }
586
587 extern inline void set_entrylo0(unsigned long val)
588 {
589 __asm__ __volatile__(
590 ".set push\n\t"
591 ".set reorder\n\t"
592 "mtc0 %z0, $2\n\t"
593 ".set pop"
594 : : "Jr" (val));
595 }
596
597 extern inline unsigned long get_entrylo1(void)
598 {
599 unsigned long val;
600
601 __asm__ __volatile__(
602 ".set push\n\t"
603 ".set reorder\n\t"
604 "mfc0 %0, $3\n\t"
605 ".set pop" : "=r" (val));
606
607 return val;
608 }
609
610 extern inline void set_entrylo1(unsigned long val)
611 {
612 __asm__ __volatile__(
613 ".set push\n\t"
614 ".set reorder\n\t"
615 "mtc0 %z0, $3\n\t"
616 ".set pop"
617 : : "Jr" (val));
618 }
619
620 /* CP0_ENTRYHI register */
621 extern inline unsigned long get_entryhi(void)
622 {
623 unsigned long val;
624
625 __asm__ __volatile__(
626 ".set push\n\t"
627 ".set reorder\n\t"
628 "mfc0 %0, $10\n\t"
629 ".set pop"
630 : "=r" (val));
631
632 return val;
633 }
634
635 extern inline void set_entryhi(unsigned long val)
636 {
637 __asm__ __volatile__(
638 ".set push\n\t"
639 ".set reorder\n\t"
640 "mtc0 %z0, $10\n\t"
641 ".set pop"
642 : : "Jr" (val));
643 }
644
645 /* CP0_INDEX register */
646 extern inline unsigned long get_index(void)
647 {
648 unsigned long val;
649
650 __asm__ __volatile__(
651 ".set push\n\t"
652 ".set reorder\n\t"
653 "mfc0 %0, $0\n\t"
654 ".set pop"
655 : "=r" (val));
656 return val;
657 }
658
659 extern inline void set_index(unsigned long val)
660 {
661 __asm__ __volatile__(
662 ".set push\n\t"
663 ".set reorder\n\t"
664 "mtc0 %z0, $0\n\t"
665 ".set pop"
666 : : "Jr" (val));
667 }
668
669 /* CP0_WIRED register */
670 extern inline unsigned long get_wired(void)
671 {
672 unsigned long val;
673
674 __asm__ __volatile__(
675 ".set push\n\t"
676 ".set reorder\n\t"
677 "mfc0 %0, $6\n\t"
678 ".set pop"
679 : "=r" (val));
680 return val;
681 }
682
683 extern inline void set_wired(unsigned long val)
684 {
685 __asm__ __volatile__(
686 ".set push\n\t"
687 ".set reorder\n\t"
688 "mtc0 %z0, $6\n\t"
689 ".set pop"
690 : : "Jr" (val));
691 }
692
693 extern inline unsigned long get_info(void)
694 {
695 unsigned long val;
696
697 __asm__(
698 ".set push\n\t"
699 ".set reorder\n\t"
700 "mfc0 %0, $7\n\t"
701 ".set pop"
702 : "=r" (val));
703 return val;
704 }
705
706 /* CP0_TAGLO and CP0_TAGHI registers */
707 extern inline unsigned long get_taglo(void)
708 {
709 unsigned long val;
710
711 __asm__ __volatile__(
712 ".set push\n\t"
713 ".set reorder\n\t"
714 "mfc0 %0, $28\n\t"
715 ".set pop"
716 : "=r" (val));
717 return val;
718 }
719
720 extern inline void set_taglo(unsigned long val)
721 {
722 __asm__ __volatile__(
723 ".set push\n\t"
724 ".set reorder\n\t"
725 "mtc0 %z0, $28\n\t"
726 ".set pop"
727 : : "Jr" (val));
728 }
729
730 extern inline unsigned long get_taghi(void)
731 {
732 unsigned long val;
733
734 __asm__ __volatile__(
735 ".set push\n\t"
736 ".set reorder\n\t"
737 "mfc0 %0, $29\n\t"
738 ".set pop"
739 : "=r" (val));
740 return val;
741 }
742
743 extern inline void set_taghi(unsigned long val)
744 {
745 __asm__ __volatile__(
746 ".set push\n\t"
747 ".set reorder\n\t"
748 "mtc0 %z0, $29\n\t"
749 ".set pop"
750 : : "Jr" (val));
751 }
752
753 /* CP0_CONTEXT register */
754 extern inline unsigned long get_context(void)
755 {
756 unsigned long val;
757
758 __asm__ __volatile__(
759 ".set push\n\t"
760 ".set reorder\n\t"
761 "mfc0 %0, $4\n\t"
762 ".set pop"
763 : "=r" (val));
764
765 return val;
766 }
767
768 extern inline void set_context(unsigned long val)
769 {
770 __asm__ __volatile__(
771 ".set push\n\t"
772 ".set reorder\n\t"
773 "mtc0 %z0, $4\n\t"
774 ".set pop"
775 : : "Jr" (val));
776 }
777
778 #include <asm-generic/pgtable.h>
779
780 #endif /* !defined (_LANGUAGE_ASSEMBLY) */
781
782 #define io_remap_page_range remap_page_range
783
784 /*
785 * No page table caches to initialise
786 */
787 #define pgtable_cache_init() do { } while (0)
788
789 #endif /* _ASM_PGTABLE_H */
790