~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/include/asm-mips/pgtable.h

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.