at v2.6.12 400 lines 11 kB view raw
1#ifndef _ASM_M32R_PGTABLE_H 2#define _ASM_M32R_PGTABLE_H 3 4#include <asm-generic/4level-fixup.h> 5 6#ifdef __KERNEL__ 7/* 8 * The Linux memory management assumes a three-level page table setup. On 9 * the M32R, we use that, but "fold" the mid level into the top-level page 10 * table, so that we physically have the same two-level page table as the 11 * M32R mmu expects. 12 * 13 * This file contains the functions and defines necessary to modify and use 14 * the M32R page table tree. 15 */ 16 17/* CAUTION!: If you change macro definitions in this file, you might have to 18 * change arch/m32r/mmu.S manually. 19 */ 20 21#ifndef __ASSEMBLY__ 22 23#include <linux/config.h> 24#include <linux/threads.h> 25#include <asm/processor.h> 26#include <asm/addrspace.h> 27#include <asm/bitops.h> 28#include <asm/page.h> 29 30extern pgd_t swapper_pg_dir[1024]; 31extern void paging_init(void); 32 33/* 34 * ZERO_PAGE is a global shared page that is always zero: used 35 * for zero-mapped memory areas etc.. 36 */ 37extern unsigned long empty_zero_page[1024]; 38#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) 39 40#endif /* !__ASSEMBLY__ */ 41 42#ifndef __ASSEMBLY__ 43#include <asm/pgtable-2level.h> 44#endif 45 46#define pgtable_cache_init() do { } while (0) 47 48#define PMD_SIZE (1UL << PMD_SHIFT) 49#define PMD_MASK (~(PMD_SIZE - 1)) 50#define PGDIR_SIZE (1UL << PGDIR_SHIFT) 51#define PGDIR_MASK (~(PGDIR_SIZE - 1)) 52 53#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE) 54#define FIRST_USER_ADDRESS 0 55 56#ifndef __ASSEMBLY__ 57/* Just any arbitrary offset to the start of the vmalloc VM area: the 58 * current 8MB value just means that there will be a 8MB "hole" after the 59 * physical memory until the kernel virtual memory starts. That means that 60 * any out-of-bounds memory accesses will hopefully be caught. 61 * The vmalloc() routines leaves a hole of 4kB between each vmalloced 62 * area for the same reason. ;) 63 */ 64#define VMALLOC_START KSEG2 65#define VMALLOC_END KSEG3 66 67/* 68 * M32R TLB format 69 * 70 * [0] [1:19] [20:23] [24:31] 71 * +-----------------------+----+-------------+ 72 * | VPN |0000| ASID | 73 * +-----------------------+----+-------------+ 74 * +-+---------------------+----+-+---+-+-+-+-+ 75 * |0 PPN |0000|N|AC |L|G|V| | 76 * +-+---------------------+----+-+---+-+-+-+-+ 77 * RWX 78 */ 79 80#define _PAGE_BIT_DIRTY 0 /* software: page changed */ 81#define _PAGE_BIT_FILE 0 /* when !present: nonlinear file 82 mapping */ 83#define _PAGE_BIT_PRESENT 1 /* Valid: page is valid */ 84#define _PAGE_BIT_GLOBAL 2 /* Global */ 85#define _PAGE_BIT_LARGE 3 /* Large */ 86#define _PAGE_BIT_EXEC 4 /* Execute */ 87#define _PAGE_BIT_WRITE 5 /* Write */ 88#define _PAGE_BIT_READ 6 /* Read */ 89#define _PAGE_BIT_NONCACHABLE 7 /* Non cachable */ 90#define _PAGE_BIT_ACCESSED 8 /* software: page referenced */ 91#define _PAGE_BIT_PROTNONE 9 /* software: if not present */ 92 93#define _PAGE_DIRTY (1UL << _PAGE_BIT_DIRTY) 94#define _PAGE_FILE (1UL << _PAGE_BIT_FILE) 95#define _PAGE_PRESENT (1UL << _PAGE_BIT_PRESENT) 96#define _PAGE_GLOBAL (1UL << _PAGE_BIT_GLOBAL) 97#define _PAGE_LARGE (1UL << _PAGE_BIT_LARGE) 98#define _PAGE_EXEC (1UL << _PAGE_BIT_EXEC) 99#define _PAGE_WRITE (1UL << _PAGE_BIT_WRITE) 100#define _PAGE_READ (1UL << _PAGE_BIT_READ) 101#define _PAGE_NONCACHABLE (1UL << _PAGE_BIT_NONCACHABLE) 102#define _PAGE_ACCESSED (1UL << _PAGE_BIT_ACCESSED) 103#define _PAGE_PROTNONE (1UL << _PAGE_BIT_PROTNONE) 104 105#define _PAGE_TABLE \ 106 ( _PAGE_PRESENT | _PAGE_WRITE | _PAGE_READ | _PAGE_ACCESSED \ 107 | _PAGE_DIRTY ) 108#define _KERNPG_TABLE \ 109 ( _PAGE_PRESENT | _PAGE_WRITE | _PAGE_READ | _PAGE_ACCESSED \ 110 | _PAGE_DIRTY ) 111#define _PAGE_CHG_MASK \ 112 ( PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY ) 113 114#ifdef CONFIG_MMU 115#define PAGE_NONE \ 116 __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) 117#define PAGE_SHARED \ 118 __pgprot(_PAGE_PRESENT | _PAGE_WRITE | _PAGE_READ | _PAGE_ACCESSED) 119#define PAGE_SHARED_EXEC \ 120 __pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_WRITE | _PAGE_READ \ 121 | _PAGE_ACCESSED) 122#define PAGE_COPY \ 123 __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_ACCESSED) 124#define PAGE_COPY_EXEC \ 125 __pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_ACCESSED) 126#define PAGE_READONLY \ 127 __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_ACCESSED) 128#define PAGE_READONLY_EXEC \ 129 __pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_ACCESSED) 130 131#define __PAGE_KERNEL \ 132 ( _PAGE_PRESENT | _PAGE_EXEC | _PAGE_WRITE | _PAGE_READ | _PAGE_DIRTY \ 133 | _PAGE_ACCESSED ) 134#define __PAGE_KERNEL_RO ( __PAGE_KERNEL & ~_PAGE_WRITE ) 135#define __PAGE_KERNEL_NOCACHE ( __PAGE_KERNEL | _PAGE_NONCACHABLE) 136 137#define MAKE_GLOBAL(x) __pgprot((x) | _PAGE_GLOBAL) 138 139#define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL) 140#define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO) 141#define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE) 142 143#else 144#define PAGE_NONE __pgprot(0) 145#define PAGE_SHARED __pgprot(0) 146#define PAGE_SHARED_EXEC __pgprot(0) 147#define PAGE_COPY __pgprot(0) 148#define PAGE_COPY_EXEC __pgprot(0) 149#define PAGE_READONLY __pgprot(0) 150#define PAGE_READONLY_EXEC __pgprot(0) 151 152#define PAGE_KERNEL __pgprot(0) 153#define PAGE_KERNEL_RO __pgprot(0) 154#define PAGE_KERNEL_NOCACHE __pgprot(0) 155#endif /* CONFIG_MMU */ 156 157 /* xwr */ 158#define __P000 PAGE_NONE 159#define __P001 PAGE_READONLY 160#define __P010 PAGE_COPY 161#define __P011 PAGE_COPY 162#define __P100 PAGE_READONLY_EXEC 163#define __P101 PAGE_READONLY_EXEC 164#define __P110 PAGE_COPY_EXEC 165#define __P111 PAGE_COPY_EXEC 166 167#define __S000 PAGE_NONE 168#define __S001 PAGE_READONLY 169#define __S010 PAGE_SHARED 170#define __S011 PAGE_SHARED 171#define __S100 PAGE_READONLY_EXEC 172#define __S101 PAGE_READONLY_EXEC 173#define __S110 PAGE_SHARED_EXEC 174#define __S111 PAGE_SHARED_EXEC 175 176/* page table for 0-4MB for everybody */ 177 178#define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE)) 179#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0) 180 181#define pmd_none(x) (!pmd_val(x)) 182#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) 183#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) 184#define pmd_bad(x) ((pmd_val(x) & ~PAGE_MASK) != _KERNPG_TABLE) 185 186#define pages_to_mb(x) ((x) >> (20 - PAGE_SHIFT)) 187 188/* 189 * The following only work if pte_present() is true. 190 * Undefined behaviour if not.. 191 */ 192static inline int pte_read(pte_t pte) 193{ 194 return pte_val(pte) & _PAGE_READ; 195} 196 197static inline int pte_exec(pte_t pte) 198{ 199 return pte_val(pte) & _PAGE_EXEC; 200} 201 202static inline int pte_dirty(pte_t pte) 203{ 204 return pte_val(pte) & _PAGE_DIRTY; 205} 206 207static inline int pte_young(pte_t pte) 208{ 209 return pte_val(pte) & _PAGE_ACCESSED; 210} 211 212static inline int pte_write(pte_t pte) 213{ 214 return pte_val(pte) & _PAGE_WRITE; 215} 216 217/* 218 * The following only works if pte_present() is not true. 219 */ 220static inline int pte_file(pte_t pte) 221{ 222 return pte_val(pte) & _PAGE_FILE; 223} 224 225static inline pte_t pte_rdprotect(pte_t pte) 226{ 227 pte_val(pte) &= ~_PAGE_READ; 228 return pte; 229} 230 231static inline pte_t pte_exprotect(pte_t pte) 232{ 233 pte_val(pte) &= ~_PAGE_EXEC; 234 return pte; 235} 236 237static inline pte_t pte_mkclean(pte_t pte) 238{ 239 pte_val(pte) &= ~_PAGE_DIRTY; 240 return pte; 241} 242 243static inline pte_t pte_mkold(pte_t pte) 244{ 245 pte_val(pte) &= ~_PAGE_ACCESSED; 246 return pte; 247} 248 249static inline pte_t pte_wrprotect(pte_t pte) 250{ 251 pte_val(pte) &= ~_PAGE_WRITE; 252 return pte; 253} 254 255static inline pte_t pte_mkread(pte_t pte) 256{ 257 pte_val(pte) |= _PAGE_READ; 258 return pte; 259} 260 261static inline pte_t pte_mkexec(pte_t pte) 262{ 263 pte_val(pte) |= _PAGE_EXEC; 264 return pte; 265} 266 267static inline pte_t pte_mkdirty(pte_t pte) 268{ 269 pte_val(pte) |= _PAGE_DIRTY; 270 return pte; 271} 272 273static inline pte_t pte_mkyoung(pte_t pte) 274{ 275 pte_val(pte) |= _PAGE_ACCESSED; 276 return pte; 277} 278 279static inline pte_t pte_mkwrite(pte_t pte) 280{ 281 pte_val(pte) |= _PAGE_WRITE; 282 return pte; 283} 284 285static inline int ptep_test_and_clear_dirty(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) 286{ 287 return test_and_clear_bit(_PAGE_BIT_DIRTY, ptep); 288} 289 290static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) 291{ 292 return test_and_clear_bit(_PAGE_BIT_ACCESSED, ptep); 293} 294 295static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) 296{ 297 clear_bit(_PAGE_BIT_WRITE, ptep); 298} 299 300/* 301 * Macro and implementation to make a page protection as uncachable. 302 */ 303static inline pgprot_t pgprot_noncached(pgprot_t _prot) 304{ 305 unsigned long prot = pgprot_val(_prot); 306 307 prot |= _PAGE_NONCACHABLE; 308 return __pgprot(prot); 309} 310 311#define pgprot_writecombine(prot) pgprot_noncached(prot) 312 313/* 314 * Conversion functions: convert a page and protection to a page entry, 315 * and a page entry and page directory to the page they refer to. 316 */ 317#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), pgprot) 318 319static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 320{ 321 set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) \ 322 | pgprot_val(newprot))); 323 324 return pte; 325} 326 327#define page_pte(page) page_pte_prot(page, __pgprot(0)) 328 329/* 330 * Conversion functions: convert a page and protection to a page entry, 331 * and a page entry and page directory to the page they refer to. 332 */ 333 334static inline void pmd_set(pmd_t * pmdp, pte_t * ptep) 335{ 336 pmd_val(*pmdp) = (((unsigned long) ptep) & PAGE_MASK); 337} 338 339#define pmd_page_kernel(pmd) \ 340 ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) 341 342#ifndef CONFIG_DISCONTIGMEM 343#define pmd_page(pmd) (mem_map + ((pmd_val(pmd) >> PAGE_SHIFT) - PFN_BASE)) 344#endif /* !CONFIG_DISCONTIGMEM */ 345 346/* to find an entry in a page-table-directory. */ 347#define pgd_index(address) \ 348 (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) 349 350#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) 351 352/* to find an entry in a kernel page-table-directory */ 353#define pgd_offset_k(address) pgd_offset(&init_mm, address) 354 355#define pmd_index(address) \ 356 (((address) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)) 357 358#define pte_index(address) \ 359 (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) 360#define pte_offset_kernel(dir, address) \ 361 ((pte_t *)pmd_page_kernel(*(dir)) + pte_index(address)) 362#define pte_offset_map(dir, address) \ 363 ((pte_t *)page_address(pmd_page(*(dir))) + pte_index(address)) 364#define pte_offset_map_nested(dir, address) pte_offset_map(dir, address) 365#define pte_unmap(pte) do { } while (0) 366#define pte_unmap_nested(pte) do { } while (0) 367 368/* Encode and de-code a swap entry */ 369#define __swp_type(x) (((x).val >> 2) & 0x3f) 370#define __swp_offset(x) ((x).val >> 10) 371#define __swp_entry(type, offset) \ 372 ((swp_entry_t) { ((type) << 2) | ((offset) << 10) }) 373#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) 374#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) 375 376#endif /* !__ASSEMBLY__ */ 377 378/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ 379#define kern_addr_valid(addr) (1) 380 381#define io_remap_page_range(vma, vaddr, paddr, size, prot) \ 382 remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) 383 384#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ 385 remap_pfn_range(vma, vaddr, pfn, size, prot) 386 387#define MK_IOSPACE_PFN(space, pfn) (pfn) 388#define GET_IOSPACE(pfn) 0 389#define GET_PFN(pfn) (pfn) 390 391#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG 392#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY 393#define __HAVE_ARCH_PTEP_GET_AND_CLEAR 394#define __HAVE_ARCH_PTEP_SET_WRPROTECT 395#define __HAVE_ARCH_PTE_SAME 396#include <asm-generic/pgtable.h> 397 398#endif /* __KERNEL__ */ 399 400#endif /* _ASM_M32R_PGTABLE_H */