linux/arch/mips/include/asm/pgtable-bits.h
<<
>>
Prefs
   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 - 2002 by Ralf Baechle
   7 * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
   8 * Copyright (C) 2002  Maciej W. Rozycki
   9 */
  10#ifndef _ASM_PGTABLE_BITS_H
  11#define _ASM_PGTABLE_BITS_H
  12
  13
  14/*
  15 * Note that we shift the lower 32bits of each EntryLo[01] entry
  16 * 6 bits to the left. That way we can convert the PFN into the
  17 * physical address by a single 'and' operation and gain 6 additional
  18 * bits for storing information which isn't present in a normal
  19 * MIPS page table.
  20 *
  21 * Similar to the Alpha port, we need to keep track of the ref
  22 * and mod bits in software.  We have a software "yeah you can read
  23 * from this page" bit, and a hardware one which actually lets the
  24 * process read from the page.  On the same token we have a software
  25 * writable bit and the real hardware one which actually lets the
  26 * process write to the page, this keeps a mod bit via the hardware
  27 * dirty bit.
  28 *
  29 * Certain revisions of the R4000 and R5000 have a bug where if a
  30 * certain sequence occurs in the last 3 instructions of an executable
  31 * page, and the following page is not mapped, the cpu can do
  32 * unpredictable things.  The code (when it is written) to deal with
  33 * this problem will be in the update_mmu_cache() code for the r4k.
  34 */
  35#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
  36
  37#define _PAGE_PRESENT               (1<<6)  /* implemented in software */
  38#define _PAGE_READ                  (1<<7)  /* implemented in software */
  39#define _PAGE_WRITE                 (1<<8)  /* implemented in software */
  40#define _PAGE_ACCESSED              (1<<9)  /* implemented in software */
  41#define _PAGE_MODIFIED              (1<<10) /* implemented in software */
  42#define _PAGE_FILE                  (1<<10) /* set:pagecache unset:swap */
  43
  44#define _PAGE_R4KBUG                (1<<0)  /* workaround for r4k bug  */
  45#define _PAGE_GLOBAL                (1<<0)
  46#define _PAGE_VALID                 (1<<1)
  47#define _PAGE_SILENT_READ           (1<<1)  /* synonym                 */
  48#define _PAGE_DIRTY                 (1<<2)  /* The MIPS dirty bit      */
  49#define _PAGE_SILENT_WRITE          (1<<2)
  50#define _CACHE_SHIFT                3
  51#define _CACHE_MASK                 (7<<3)
  52
  53#elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
  54
  55#define _PAGE_PRESENT               (1<<0)  /* implemented in software */
  56#define _PAGE_READ                  (1<<1)  /* implemented in software */
  57#define _PAGE_WRITE                 (1<<2)  /* implemented in software */
  58#define _PAGE_ACCESSED              (1<<3)  /* implemented in software */
  59#define _PAGE_MODIFIED              (1<<4)  /* implemented in software */
  60#define _PAGE_FILE                  (1<<4)  /* set:pagecache unset:swap */
  61
  62#define _PAGE_GLOBAL                (1<<8)
  63#define _PAGE_VALID                 (1<<9)
  64#define _PAGE_SILENT_READ           (1<<9)  /* synonym                 */
  65#define _PAGE_DIRTY                 (1<<10) /* The MIPS dirty bit      */
  66#define _PAGE_SILENT_WRITE          (1<<10)
  67#define _CACHE_UNCACHED             (1<<11)
  68#define _CACHE_MASK                 (1<<11)
  69
  70#else /* 'Normal' r4K case */
  71/*
  72 * When using the RI/XI bit support, we have 13 bits of flags below
  73 * the physical address. The RI/XI bits are placed such that a SRL 5
  74 * can strip off the software bits, then a ROTR 2 can move the RI/XI
  75 * into bits [63:62]. This also limits physical address to 56 bits,
  76 * which is more than we need right now.
  77 */
  78
  79/* implemented in software */
  80#define _PAGE_PRESENT_SHIFT     (0)
  81#define _PAGE_PRESENT           (1 << _PAGE_PRESENT_SHIFT)
  82/* implemented in software, should be unused if kernel_uses_smartmips_rixi. */
  83#define _PAGE_READ_SHIFT        (kernel_uses_smartmips_rixi ? _PAGE_PRESENT_SHIFT : _PAGE_PRESENT_SHIFT + 1)
  84#define _PAGE_READ ({if (kernel_uses_smartmips_rixi) BUG(); 1 << _PAGE_READ_SHIFT; })
  85/* implemented in software */
  86#define _PAGE_WRITE_SHIFT       (_PAGE_READ_SHIFT + 1)
  87#define _PAGE_WRITE             (1 << _PAGE_WRITE_SHIFT)
  88/* implemented in software */
  89#define _PAGE_ACCESSED_SHIFT    (_PAGE_WRITE_SHIFT + 1)
  90#define _PAGE_ACCESSED          (1 << _PAGE_ACCESSED_SHIFT)
  91/* implemented in software */
  92#define _PAGE_MODIFIED_SHIFT    (_PAGE_ACCESSED_SHIFT + 1)
  93#define _PAGE_MODIFIED          (1 << _PAGE_MODIFIED_SHIFT)
  94/* set:pagecache unset:swap */
  95#define _PAGE_FILE              (_PAGE_MODIFIED)
  96
  97#ifdef CONFIG_HUGETLB_PAGE
  98/* huge tlb page */
  99#define _PAGE_HUGE_SHIFT        (_PAGE_MODIFIED_SHIFT + 1)
 100#define _PAGE_HUGE              (1 << _PAGE_HUGE_SHIFT)
 101#else
 102#define _PAGE_HUGE_SHIFT        (_PAGE_MODIFIED_SHIFT)
 103#define _PAGE_HUGE              ({BUG(); 1; })  /* Dummy value */
 104#endif
 105
 106/* Page cannot be executed */
 107#define _PAGE_NO_EXEC_SHIFT     (kernel_uses_smartmips_rixi ? _PAGE_HUGE_SHIFT + 1 : _PAGE_HUGE_SHIFT)
 108#define _PAGE_NO_EXEC           ({if (!kernel_uses_smartmips_rixi) BUG(); 1 << _PAGE_NO_EXEC_SHIFT; })
 109
 110/* Page cannot be read */
 111#define _PAGE_NO_READ_SHIFT     (kernel_uses_smartmips_rixi ? _PAGE_NO_EXEC_SHIFT + 1 : _PAGE_NO_EXEC_SHIFT)
 112#define _PAGE_NO_READ           ({if (!kernel_uses_smartmips_rixi) BUG(); 1 << _PAGE_NO_READ_SHIFT; })
 113
 114#define _PAGE_GLOBAL_SHIFT      (_PAGE_NO_READ_SHIFT + 1)
 115#define _PAGE_GLOBAL            (1 << _PAGE_GLOBAL_SHIFT)
 116
 117#define _PAGE_VALID_SHIFT       (_PAGE_GLOBAL_SHIFT + 1)
 118#define _PAGE_VALID             (1 << _PAGE_VALID_SHIFT)
 119/* synonym                 */
 120#define _PAGE_SILENT_READ       (_PAGE_VALID)
 121
 122/* The MIPS dirty bit      */
 123#define _PAGE_DIRTY_SHIFT       (_PAGE_VALID_SHIFT + 1)
 124#define _PAGE_DIRTY             (1 << _PAGE_DIRTY_SHIFT)
 125#define _PAGE_SILENT_WRITE      (_PAGE_DIRTY)
 126
 127#define _CACHE_SHIFT            (_PAGE_DIRTY_SHIFT + 1)
 128#define _CACHE_MASK             (7 << _CACHE_SHIFT)
 129
 130#define _PFN_SHIFT              (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3)
 131
 132#endif /* defined(CONFIG_64BIT_PHYS_ADDR && defined(CONFIG_CPU_MIPS32) */
 133
 134#ifndef _PFN_SHIFT
 135#define _PFN_SHIFT                  PAGE_SHIFT
 136#endif
 137#define _PFN_MASK               (~((1 << (_PFN_SHIFT)) - 1))
 138
 139#ifndef _PAGE_NO_READ
 140#define _PAGE_NO_READ ({BUG(); 0; })
 141#define _PAGE_NO_READ_SHIFT ({BUG(); 0; })
 142#endif
 143#ifndef _PAGE_NO_EXEC
 144#define _PAGE_NO_EXEC ({BUG(); 0; })
 145#endif
 146#ifndef _PAGE_GLOBAL_SHIFT
 147#define _PAGE_GLOBAL_SHIFT ilog2(_PAGE_GLOBAL)
 148#endif
 149
 150
 151#ifndef __ASSEMBLY__
 152/*
 153 * pte_to_entrylo converts a page table entry (PTE) into a Mips
 154 * entrylo0/1 value.
 155 */
 156static inline uint64_t pte_to_entrylo(unsigned long pte_val)
 157{
 158        if (kernel_uses_smartmips_rixi) {
 159                int sa;
 160#ifdef CONFIG_32BIT
 161                sa = 31 - _PAGE_NO_READ_SHIFT;
 162#else
 163                sa = 63 - _PAGE_NO_READ_SHIFT;
 164#endif
 165                /*
 166                 * C has no way to express that this is a DSRL
 167                 * _PAGE_NO_EXEC_SHIFT followed by a ROTR 2.  Luckily
 168                 * in the fast path this is done in assembly
 169                 */
 170                return (pte_val >> _PAGE_GLOBAL_SHIFT) |
 171                        ((pte_val & (_PAGE_NO_EXEC | _PAGE_NO_READ)) << sa);
 172        }
 173
 174        return pte_val >> _PAGE_GLOBAL_SHIFT;
 175}
 176#endif
 177
 178/*
 179 * Cache attributes
 180 */
 181#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
 182
 183#define _CACHE_CACHABLE_NONCOHERENT 0
 184
 185#elif defined(CONFIG_CPU_SB1)
 186
 187/* No penalty for being coherent on the SB1, so just
 188   use it for "noncoherent" spaces, too.  Shouldn't hurt. */
 189
 190#define _CACHE_UNCACHED             (2<<_CACHE_SHIFT)
 191#define _CACHE_CACHABLE_COW         (5<<_CACHE_SHIFT)
 192#define _CACHE_CACHABLE_NONCOHERENT (5<<_CACHE_SHIFT)
 193#define _CACHE_UNCACHED_ACCELERATED (7<<_CACHE_SHIFT)
 194
 195#elif defined(CONFIG_CPU_RM9000)
 196
 197#define _CACHE_WT                   (0<<_CACHE_SHIFT)
 198#define _CACHE_WTWA                 (1<<_CACHE_SHIFT)
 199#define _CACHE_UC_B                 (2<<_CACHE_SHIFT)
 200#define _CACHE_WB                   (3<<_CACHE_SHIFT)
 201#define _CACHE_CWBEA                (4<<_CACHE_SHIFT)
 202#define _CACHE_CWB                  (5<<_CACHE_SHIFT)
 203#define _CACHE_UCNB                 (6<<_CACHE_SHIFT)
 204#define _CACHE_FPC                  (7<<_CACHE_SHIFT)
 205
 206#define _CACHE_UNCACHED             _CACHE_UC_B
 207#define _CACHE_CACHABLE_NONCOHERENT _CACHE_WB
 208
 209#else
 210
 211#define _CACHE_CACHABLE_NO_WA       (0<<_CACHE_SHIFT)  /* R4600 only      */
 212#define _CACHE_CACHABLE_WA          (1<<_CACHE_SHIFT)  /* R4600 only      */
 213#define _CACHE_UNCACHED             (2<<_CACHE_SHIFT)  /* R4[0246]00      */
 214#define _CACHE_CACHABLE_NONCOHERENT (3<<_CACHE_SHIFT)  /* R4[0246]00      */
 215#define _CACHE_CACHABLE_CE          (4<<_CACHE_SHIFT)  /* R4[04]00MC only */
 216#define _CACHE_CACHABLE_COW         (5<<_CACHE_SHIFT)  /* R4[04]00MC only */
 217#define _CACHE_CACHABLE_COHERENT    (5<<_CACHE_SHIFT)  /* MIPS32R2 CMP    */
 218#define _CACHE_CACHABLE_CUW         (6<<_CACHE_SHIFT)  /* R4[04]00MC only */
 219#define _CACHE_UNCACHED_ACCELERATED (7<<_CACHE_SHIFT)  /* R10000 only     */
 220
 221#endif
 222
 223#define __READABLE      (_PAGE_SILENT_READ | _PAGE_ACCESSED | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ))
 224#define __WRITEABLE     (_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
 225
 226#define _PAGE_CHG_MASK  (_PFN_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK)
 227
 228#endif /* _ASM_PGTABLE_BITS_H */
 229