pgtable.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:22k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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