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