linux/include/asm-sparc64/pgtable.h
<<
>>
Prefs
   1/* $Id: pgtable.h,v 1.156 2002/02/09 19:49:31 davem Exp $
   2 * pgtable.h: SpitFire page table operations.
   3 *
   4 * Copyright 1996,1997 David S. Miller (davem@caip.rutgers.edu)
   5 * Copyright 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
   6 */
   7
   8#ifndef _SPARC64_PGTABLE_H
   9#define _SPARC64_PGTABLE_H
  10
  11/* This file contains the functions and defines necessary to modify and use
  12 * the SpitFire page tables.
  13 */
  14
  15#include <asm-generic/pgtable-nopud.h>
  16
  17#include <linux/config.h>
  18#include <asm/spitfire.h>
  19#include <asm/asi.h>
  20#include <asm/system.h>
  21#include <asm/page.h>
  22#include <asm/processor.h>
  23#include <asm/const.h>
  24
  25/* The kernel image occupies 0x4000000 to 0x1000000 (4MB --> 16MB).
  26 * The page copy blockops use 0x1000000 to 0x18000000 (16MB --> 24MB).
  27 * The PROM resides in an area spanning 0xf0000000 to 0x100000000.
  28 * The vmalloc area spans 0x140000000 to 0x200000000.
  29 * There is a single static kernel PMD which maps from 0x0 to address
  30 * 0x400000000.
  31 */
  32#define TLBTEMP_BASE            _AC(0x0000000001000000,UL)
  33#define MODULES_VADDR           _AC(0x0000000002000000,UL)
  34#define MODULES_LEN             _AC(0x000000007e000000,UL)
  35#define MODULES_END             _AC(0x0000000080000000,UL)
  36#define VMALLOC_START           _AC(0x0000000140000000,UL)
  37#define VMALLOC_END             _AC(0x0000000200000000,UL)
  38#define LOW_OBP_ADDRESS         _AC(0x00000000f0000000,UL)
  39#define HI_OBP_ADDRESS          _AC(0x0000000100000000,UL)
  40
  41/* XXX All of this needs to be rethought so we can take advantage
  42 * XXX cheetah's full 64-bit virtual address space, ie. no more hole
  43 * XXX in the middle like on spitfire. -DaveM
  44 */
  45/*
  46 * Given a virtual address, the lowest PAGE_SHIFT bits determine offset
  47 * into the page; the next higher PAGE_SHIFT-3 bits determine the pte#
  48 * in the proper pagetable (the -3 is from the 8 byte ptes, and each page
  49 * table is a single page long). The next higher PMD_BITS determine pmd# 
  50 * in the proper pmdtable (where we must have PMD_BITS <= (PAGE_SHIFT-2) 
  51 * since the pmd entries are 4 bytes, and each pmd page is a single page 
  52 * long). Finally, the higher few bits determine pgde#.
  53 */
  54
  55/* PMD_SHIFT determines the size of the area a second-level page
  56 * table can map
  57 */
  58#define PMD_SHIFT       (PAGE_SHIFT + (PAGE_SHIFT-3))
  59#define PMD_SIZE        (1UL << PMD_SHIFT)
  60#define PMD_MASK        (~(PMD_SIZE-1))
  61#define PMD_BITS        11
  62
  63/* PGDIR_SHIFT determines what a third-level page table entry can map */
  64#define PGDIR_SHIFT     (PAGE_SHIFT + (PAGE_SHIFT-3) + PMD_BITS)
  65#define PGDIR_SIZE      (1UL << PGDIR_SHIFT)
  66#define PGDIR_MASK      (~(PGDIR_SIZE-1))
  67
  68#ifndef __ASSEMBLY__
  69
  70#include <linux/sched.h>
  71
  72/* Entries per page directory level. */
  73#define PTRS_PER_PTE            (1UL << (PAGE_SHIFT-3))
  74
  75/* We the first one in this file, what we export to the kernel
  76 * is different so we can optimize correctly for 32-bit tasks.
  77 */
  78#define REAL_PTRS_PER_PMD       (1UL << PMD_BITS)
  79
  80/* This is gross, but unless we do this gcc retests the
  81 * thread flag every interation in pmd traversal loops.
  82 */
  83extern unsigned long __ptrs_per_pmd(void) __attribute_const__;
  84#define PTRS_PER_PMD            __ptrs_per_pmd()
  85
  86/*
  87 * We cannot use the top address range because VPTE table lives there. This
  88 * formula finds the total legal virtual space in the processor, subtracts the
  89 * vpte size, then aligns it to the number of bytes mapped by one pgde, and
  90 * thus calculates the number of pgdes needed.
  91 */
  92#define PTRS_PER_PGD (((1UL << VA_BITS) - VPTE_SIZE + (1UL << (PAGE_SHIFT + \
  93                      (PAGE_SHIFT-3) + PMD_BITS)) - 1) / (1UL << (PAGE_SHIFT + \
  94                      (PAGE_SHIFT-3) + PMD_BITS)))
  95
  96/* Kernel has a separate 44bit address space. */
  97#define USER_PTRS_PER_PGD       ((const int)(test_thread_flag(TIF_32BIT)) ? \
  98                                 (1) : (PTRS_PER_PGD))
  99#define FIRST_USER_PGD_NR       0
 100
 101#define pte_ERROR(e)    __builtin_trap()
 102#define pmd_ERROR(e)    __builtin_trap()
 103#define pgd_ERROR(e)    __builtin_trap()
 104
 105#endif /* !(__ASSEMBLY__) */
 106
 107/* Spitfire/Cheetah TTE bits. */
 108#define _PAGE_VALID     _AC(0x8000000000000000,UL) /* Valid TTE              */
 109#define _PAGE_R         _AC(0x8000000000000000,UL) /* Keep ref bit up to date*/
 110#define _PAGE_SZ4MB     _AC(0x6000000000000000,UL) /* 4MB Page               */
 111#define _PAGE_SZ512K    _AC(0x4000000000000000,UL) /* 512K Page              */
 112#define _PAGE_SZ64K     _AC(0x2000000000000000,UL) /* 64K Page               */
 113#define _PAGE_SZ8K      _AC(0x0000000000000000,UL) /* 8K Page                */
 114#define _PAGE_NFO       _AC(0x1000000000000000,UL) /* No Fault Only          */
 115#define _PAGE_IE        _AC(0x0800000000000000,UL) /* Invert Endianness      */
 116#define _PAGE_SOFT2     _AC(0x07FC000000000000,UL) /* Software bits, set 2   */
 117#define _PAGE_RES1      _AC(0x0003000000000000,UL) /* Reserved               */
 118#define _PAGE_SN        _AC(0x0000800000000000,UL) /* (Cheetah) Snoop        */
 119#define _PAGE_RES2      _AC(0x0000780000000000,UL) /* Reserved               */
 120#define _PAGE_PADDR_SF  _AC(0x000001FFFFFFE000,UL) /* (Spitfire) paddr[40:13]*/
 121#define _PAGE_PADDR     _AC(0x000007FFFFFFE000,UL) /* (Cheetah) paddr[42:13] */
 122#define _PAGE_SOFT      _AC(0x0000000000001F80,UL) /* Software bits          */
 123#define _PAGE_L         _AC(0x0000000000000040,UL) /* Locked TTE             */
 124#define _PAGE_CP        _AC(0x0000000000000020,UL) /* Cacheable in P-Cache   */
 125#define _PAGE_CV        _AC(0x0000000000000010,UL) /* Cacheable in V-Cache   */
 126#define _PAGE_E         _AC(0x0000000000000008,UL) /* side-Effect            */
 127#define _PAGE_P         _AC(0x0000000000000004,UL) /* Privileged Page        */
 128#define _PAGE_W         _AC(0x0000000000000002,UL) /* Writable               */
 129#define _PAGE_G         _AC(0x0000000000000001,UL) /* Global                 */
 130
 131/* Here are the SpitFire software bits we use in the TTE's.
 132 *
 133 * WARNING: If you are going to try and start using some
 134 *          of the soft2 bits, you will need to make
 135 *          modifications to the swap entry implementation.
 136 *          For example, one thing that could happen is that
 137 *          swp_entry_to_pte() would BUG_ON() if you tried
 138 *          to use one of the soft2 bits for _PAGE_FILE.
 139 *
 140 * Like other architectures, I have aliased _PAGE_FILE with
 141 * _PAGE_MODIFIED.  This works because _PAGE_FILE is never
 142 * interpreted that way unless _PAGE_PRESENT is clear.
 143 */
 144#define _PAGE_EXEC      _AC(0x0000000000001000,UL)      /* Executable SW bit */
 145#define _PAGE_MODIFIED  _AC(0x0000000000000800,UL)      /* Modified (dirty)  */
 146#define _PAGE_FILE      _AC(0x0000000000000800,UL)      /* Pagecache page    */
 147#define _PAGE_ACCESSED  _AC(0x0000000000000400,UL)      /* Accessed (ref'd)  */
 148#define _PAGE_READ      _AC(0x0000000000000200,UL)      /* Readable SW Bit   */
 149#define _PAGE_WRITE     _AC(0x0000000000000100,UL)      /* Writable SW Bit   */
 150#define _PAGE_PRESENT   _AC(0x0000000000000080,UL)      /* Present           */
 151
 152#if PAGE_SHIFT == 13
 153#define _PAGE_SZBITS    _PAGE_SZ8K
 154#elif PAGE_SHIFT == 16
 155#define _PAGE_SZBITS    _PAGE_SZ64K
 156#elif PAGE_SHIFT == 19
 157#define _PAGE_SZBITS    _PAGE_SZ512K
 158#elif PAGE_SHIFT == 22
 159#define _PAGE_SZBITS    _PAGE_SZ4MB
 160#else
 161#error Wrong PAGE_SHIFT specified
 162#endif
 163
 164#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
 165#define _PAGE_SZHUGE    _PAGE_SZ4MB
 166#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
 167#define _PAGE_SZHUGE    _PAGE_SZ512K
 168#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
 169#define _PAGE_SZHUGE    _PAGE_SZ64K
 170#endif
 171
 172#define _PAGE_CACHE     (_PAGE_CP | _PAGE_CV)
 173
 174#define __DIRTY_BITS    (_PAGE_MODIFIED | _PAGE_WRITE | _PAGE_W)
 175#define __ACCESS_BITS   (_PAGE_ACCESSED | _PAGE_READ | _PAGE_R)
 176#define __PRIV_BITS     _PAGE_P
 177
 178#define PAGE_NONE       __pgprot (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_CACHE)
 179
 180/* Don't set the TTE _PAGE_W bit here, else the dirty bit never gets set. */
 181#define PAGE_SHARED     __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
 182                                  __ACCESS_BITS | _PAGE_WRITE | _PAGE_EXEC)
 183
 184#define PAGE_COPY       __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
 185                                  __ACCESS_BITS | _PAGE_EXEC)
 186
 187#define PAGE_READONLY   __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
 188                                  __ACCESS_BITS | _PAGE_EXEC)
 189
 190#define PAGE_KERNEL     __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \
 191                                  __PRIV_BITS | \
 192                                  __ACCESS_BITS | __DIRTY_BITS | _PAGE_EXEC)
 193
 194#define PAGE_SHARED_NOEXEC      __pgprot (_PAGE_PRESENT | _PAGE_VALID | \
 195                                          _PAGE_CACHE | \
 196                                          __ACCESS_BITS | _PAGE_WRITE)
 197
 198#define PAGE_COPY_NOEXEC        __pgprot (_PAGE_PRESENT | _PAGE_VALID | \
 199                                          _PAGE_CACHE | __ACCESS_BITS)
 200
 201#define PAGE_READONLY_NOEXEC    __pgprot (_PAGE_PRESENT | _PAGE_VALID | \
 202                                          _PAGE_CACHE | __ACCESS_BITS)
 203
 204#define _PFN_MASK       _PAGE_PADDR
 205
 206#define pg_iobits (_PAGE_VALID | _PAGE_PRESENT | __DIRTY_BITS | \
 207                   __ACCESS_BITS | _PAGE_E)
 208
 209#define __P000  PAGE_NONE
 210#define __P001  PAGE_READONLY_NOEXEC
 211#define __P010  PAGE_COPY_NOEXEC
 212#define __P011  PAGE_COPY_NOEXEC
 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_NOEXEC
 220#define __S010  PAGE_SHARED_NOEXEC
 221#define __S011  PAGE_SHARED_NOEXEC
 222#define __S100  PAGE_READONLY
 223#define __S101  PAGE_READONLY
 224#define __S110  PAGE_SHARED
 225#define __S111  PAGE_SHARED
 226
 227#ifndef __ASSEMBLY__
 228
 229extern unsigned long phys_base;
 230extern unsigned long pfn_base;
 231
 232extern struct page *mem_map_zero;
 233#define ZERO_PAGE(vaddr)        (mem_map_zero)
 234
 235/* PFNs are real physical page numbers.  However, mem_map only begins to record
 236 * per-page information starting at pfn_base.  This is to handle systems where
 237 * the first physical page in the machine is at some huge physical address, such
 238 * as 4GB.   This is common on a partitioned E10000, for example.
 239 */
 240
 241#define pfn_pte(pfn, prot)      \
 242        __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot) | _PAGE_SZBITS)
 243#define mk_pte(page, pgprot)    pfn_pte(page_to_pfn(page), (pgprot))
 244
 245#define pte_pfn(x)              ((pte_val(x) & _PAGE_PADDR)>>PAGE_SHIFT)
 246#define pte_page(x)             pfn_to_page(pte_pfn(x))
 247
 248#define page_pte_prot(page, prot)       mk_pte(page, prot)
 249#define page_pte(page)                  page_pte_prot(page, __pgprot(0))
 250
 251static inline pte_t pte_modify(pte_t orig_pte, pgprot_t new_prot)
 252{
 253        pte_t __pte;
 254        const unsigned long preserve_mask = (_PFN_MASK |
 255                                             _PAGE_MODIFIED | _PAGE_ACCESSED |
 256                                             _PAGE_CACHE | _PAGE_E |
 257                                             _PAGE_PRESENT | _PAGE_SZBITS);
 258
 259        pte_val(__pte) = (pte_val(orig_pte) & preserve_mask) |
 260                (pgprot_val(new_prot) & ~preserve_mask);
 261
 262        return __pte;
 263}
 264#define pmd_set(pmdp, ptep)     \
 265        (pmd_val(*(pmdp)) = (__pa((unsigned long) (ptep)) >> 11UL))
 266#define pud_set(pudp, pmdp)     \
 267        (pud_val(*(pudp)) = (__pa((unsigned long) (pmdp)) >> 11UL))
 268#define __pmd_page(pmd)         \
 269        ((unsigned long) __va((((unsigned long)pmd_val(pmd))<<11UL)))
 270#define pmd_page(pmd)                   virt_to_page((void *)__pmd_page(pmd))
 271#define pud_page(pud)           \
 272        ((unsigned long) __va((((unsigned long)pud_val(pud))<<11UL)))
 273#define pte_none(pte)                   (!pte_val(pte))
 274#define pte_present(pte)                (pte_val(pte) & _PAGE_PRESENT)
 275#define pmd_none(pmd)                   (!pmd_val(pmd))
 276#define pmd_bad(pmd)                    (0)
 277#define pmd_present(pmd)                (pmd_val(pmd) != 0U)
 278#define pmd_clear(pmdp)                 (pmd_val(*(pmdp)) = 0U)
 279#define pud_none(pud)                   (!pud_val(pud))
 280#define pud_bad(pud)                    (0)
 281#define pud_present(pud)                (pud_val(pud) != 0U)
 282#define pud_clear(pudp)                 (pud_val(*(pudp)) = 0U)
 283
 284/* The following only work if pte_present() is true.
 285 * Undefined behaviour if not..
 286 */
 287#define pte_read(pte)           (pte_val(pte) & _PAGE_READ)
 288#define pte_exec(pte)           (pte_val(pte) & _PAGE_EXEC)
 289#define pte_write(pte)          (pte_val(pte) & _PAGE_WRITE)
 290#define pte_dirty(pte)          (pte_val(pte) & _PAGE_MODIFIED)
 291#define pte_young(pte)          (pte_val(pte) & _PAGE_ACCESSED)
 292#define pte_wrprotect(pte)      (__pte(pte_val(pte) & ~(_PAGE_WRITE|_PAGE_W)))
 293#define pte_rdprotect(pte)      \
 294        (__pte(((pte_val(pte)<<1UL)>>1UL) & ~_PAGE_READ))
 295#define pte_mkclean(pte)        \
 296        (__pte(pte_val(pte) & ~(_PAGE_MODIFIED|_PAGE_W)))
 297#define pte_mkold(pte)          \
 298        (__pte(((pte_val(pte)<<1UL)>>1UL) & ~_PAGE_ACCESSED))
 299
 300/* Permanent address of a page. */
 301#define __page_address(page)    page_address(page)
 302
 303/* Be very careful when you change these three, they are delicate. */
 304#define pte_mkyoung(pte)        (__pte(pte_val(pte) | _PAGE_ACCESSED | _PAGE_R))
 305#define pte_mkwrite(pte)        (__pte(pte_val(pte) | _PAGE_WRITE))
 306#define pte_mkdirty(pte)        (__pte(pte_val(pte) | _PAGE_MODIFIED | _PAGE_W))
 307
 308/* to find an entry in a page-table-directory. */
 309#define pgd_index(address)      (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD))
 310#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
 311
 312/* to find an entry in a kernel page-table-directory */
 313#define pgd_offset_k(address) pgd_offset(&init_mm, address)
 314
 315/* extract the pgd cache used for optimizing the tlb miss
 316 * slow path when executing 32-bit compat processes
 317 */
 318#define get_pgd_cache(pgd)      ((unsigned long) pgd_val(*pgd) << 11)
 319
 320/* Find an entry in the second-level page table.. */
 321#define pmd_offset(pudp, address)       \
 322        ((pmd_t *) pud_page(*(pudp)) + \
 323         (((address) >> PMD_SHIFT) & (REAL_PTRS_PER_PMD-1)))
 324
 325/* Find an entry in the third-level page table.. */
 326#define pte_index(dir, address) \
 327        ((pte_t *) __pmd_page(*(dir)) + \
 328         ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)))
 329#define pte_offset_kernel               pte_index
 330#define pte_offset_map                  pte_index
 331#define pte_offset_map_nested           pte_index
 332#define pte_unmap(pte)                  do { } while (0)
 333#define pte_unmap_nested(pte)           do { } while (0)
 334
 335/* Actual page table PTE updates.  */
 336extern void tlb_batch_add(pte_t *ptep, pte_t orig);
 337
 338static inline void set_pte(pte_t *ptep, pte_t pte)
 339{
 340        pte_t orig = *ptep;
 341
 342        *ptep = pte;
 343        if (pte_present(orig))
 344                tlb_batch_add(ptep, orig);
 345}
 346
 347#define pte_clear(ptep)         set_pte((ptep), __pte(0UL))
 348
 349extern pgd_t swapper_pg_dir[1];
 350
 351/* These do nothing with the way I have things setup. */
 352#define mmu_lockarea(vaddr, len)                (vaddr)
 353#define mmu_unlockarea(vaddr, len)              do { } while(0)
 354
 355struct vm_area_struct;
 356extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
 357
 358/* Make a non-present pseudo-TTE. */
 359static inline pte_t mk_pte_io(unsigned long page, pgprot_t prot, int space)
 360{
 361        pte_t pte;
 362        pte_val(pte) = (((page) | pgprot_val(prot) | _PAGE_E) &
 363                        ~(unsigned long)_PAGE_CACHE);
 364        pte_val(pte) |= (((unsigned long)space) << 32);
 365        return pte;
 366}
 367
 368/* Encode and de-code a swap entry */
 369#define __swp_type(entry)       (((entry).val >> PAGE_SHIFT) & 0xffUL)
 370#define __swp_offset(entry)     ((entry).val >> (PAGE_SHIFT + 8UL))
 371#define __swp_entry(type, offset)       \
 372        ( (swp_entry_t) \
 373          { \
 374                (((long)(type) << PAGE_SHIFT) | \
 375                 ((long)(offset) << (PAGE_SHIFT + 8UL))) \
 376          } )
 377#define __pte_to_swp_entry(pte)         ((swp_entry_t) { pte_val(pte) })
 378#define __swp_entry_to_pte(x)           ((pte_t) { (x).val })
 379
 380/* File offset in PTE support. */
 381#define pte_file(pte)           (pte_val(pte) & _PAGE_FILE)
 382#define pte_to_pgoff(pte)       (pte_val(pte) >> PAGE_SHIFT)
 383#define pgoff_to_pte(off)       (__pte(((off) << PAGE_SHIFT) | _PAGE_FILE))
 384#define PTE_FILE_MAX_BITS       (64UL - PAGE_SHIFT - 1UL)
 385
 386extern unsigned long prom_virt_to_phys(unsigned long, int *);
 387
 388static __inline__ unsigned long
 389sun4u_get_pte (unsigned long addr)
 390{
 391        pgd_t *pgdp;
 392        pud_t *pudp;
 393        pmd_t *pmdp;
 394        pte_t *ptep;
 395
 396        if (addr >= PAGE_OFFSET)
 397                return addr & _PAGE_PADDR;
 398        if ((addr >= LOW_OBP_ADDRESS) && (addr < HI_OBP_ADDRESS))
 399                return prom_virt_to_phys(addr, NULL);
 400        pgdp = pgd_offset_k(addr);
 401        pudp = pud_offset(pgdp, addr);
 402        pmdp = pmd_offset(pudp, addr);
 403        ptep = pte_offset_kernel(pmdp, addr);
 404        return pte_val(*ptep) & _PAGE_PADDR;
 405}
 406
 407static __inline__ unsigned long
 408__get_phys (unsigned long addr)
 409{
 410        return sun4u_get_pte (addr);
 411}
 412
 413static __inline__ int
 414__get_iospace (unsigned long addr)
 415{
 416        return ((sun4u_get_pte (addr) & 0xf0000000) >> 28);
 417}
 418
 419extern unsigned long *sparc64_valid_addr_bitmap;
 420
 421/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
 422#define kern_addr_valid(addr)   \
 423        (test_bit(__pa((unsigned long)(addr))>>22, sparc64_valid_addr_bitmap))
 424
 425extern int io_remap_page_range(struct vm_area_struct *vma, unsigned long from,
 426                               unsigned long offset,
 427                               unsigned long size, pgprot_t prot, int space);
 428
 429#include <asm-generic/pgtable.h>
 430
 431/* We provide our own get_unmapped_area to cope with VA holes for userland */
 432#define HAVE_ARCH_UNMAPPED_AREA
 433
 434/* We provide a special get_unmapped_area for framebuffer mmaps to try and use
 435 * the largest alignment possible such that larget PTEs can be used.
 436 */
 437extern unsigned long get_fb_unmapped_area(struct file *filp, unsigned long,
 438                                          unsigned long, unsigned long,
 439                                          unsigned long);
 440#define HAVE_ARCH_FB_UNMAPPED_AREA
 441
 442/*
 443 * No page table caches to initialise
 444 */
 445#define pgtable_cache_init()    do { } while (0)
 446
 447extern void check_pgt_cache(void);
 448
 449#endif /* !(__ASSEMBLY__) */
 450
 451#endif /* !(_SPARC64_PGTABLE_H) */
 452
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.