root/include/asm-sparc/page.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. get_segmap
  2. put_segmap
  3. get_pte
  4. put_pte
  5. get_context
  6. set_context

   1 /* $Id: page.h,v 1.22 1995/11/25 02:32:16 davem Exp $
   2  * page.h:  Various defines and such for MMU operations on the Sparc for
   3  *          the Linux kernel.
   4  *
   5  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
   6  */
   7 
   8 #ifndef _SPARC_PAGE_H
   9 #define _SPARC_PAGE_H
  10 
  11 #include <asm/asi.h>        /* for get/set segmap/pte routines */
  12 #include <asm/contregs.h>   /* for switch_to_context */
  13 #include <asm/head.h>       /* for KERNBASE */
  14 
  15 #define PAGE_SHIFT   12             /* This is the virtual page... */
  16 #define PAGE_OFFSET  KERNBASE
  17 #define PAGE_SIZE    (1 << PAGE_SHIFT)
  18 
  19 /* to mask away the intra-page address bits */
  20 #define PAGE_MASK    (~(PAGE_SIZE-1))
  21 
  22 #ifdef __KERNEL__
  23 #ifndef __ASSEMBLY__
  24 
  25 #include <asm/processor.h>
  26 
  27 /* The following structure is used to hold the physical
  28  * memory configuration of the machine.  This is filled in
  29  * probe_memory() and is later used by mem_init() to set up
  30  * mem_map[].  We statically allocate SPARC_PHYS_BANKS of
  31  * these structs, this is arbitrary.  The entry after the
  32  * last valid one has num_bytes==0.
  33  */
  34 
  35 struct sparc_phys_banks {
  36   unsigned long base_addr;
  37   unsigned long num_bytes;
  38 };
  39 
  40 #define SPARC_PHYS_BANKS 32
  41 
  42 extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS];
  43 
  44 #define STRICT_MM_TYPECHECKS
  45 
  46 #ifdef STRICT_MM_TYPECHECKS
  47 /*
  48  * These are used to make use of C type-checking..
  49  */
  50 typedef struct { unsigned long pte; } pte_t;
  51 typedef struct { unsigned long pmd; } pmd_t;
  52 typedef struct { unsigned long pgd; } pgd_t;
  53 typedef struct { unsigned long pgprot; } pgprot_t;
  54 
  55 #define pte_val(x)      ((x).pte)
  56 #define pmd_val(x)      ((x).pmd)
  57 #define pgd_val(x)      ((x).pgd)
  58 #define pgprot_val(x)   ((x).pgprot)
  59 
  60 #define __pte(x)        ((pte_t) { (x) } )
  61 #define __pmd(x)        ((pmd_t) { (x) } )
  62 #define __pgd(x)        ((pgd_t) { (x) } )
  63 #define __pgprot(x)     ((pgprot_t) { (x) } )
  64 
  65 #else
  66 /*
  67  * .. while these make it easier on the compiler
  68  */
  69 typedef unsigned long pte_t;
  70 typedef unsigned long pmd_t;
  71 typedef unsigned long pgd_t;
  72 typedef unsigned long pgprot_t;
  73 
  74 #define pte_val(x)      (x)
  75 #define pmd_val(x)      (x)
  76 #define pgd_val(x)      (x)
  77 #define pgprot_val(x)   (x)
  78 
  79 #define __pte(x)        (x)
  80 #define __pmd(x)        (x)
  81 #define __pgd(x)        (x)
  82 #define __pgprot(x)     (x)
  83 
  84 #endif
  85 
  86 /* The current va context is global and known, so all that is needed to
  87  * do an invalidate is flush the VAC on a sun4c or call the ASI flushing
  88  * routines on a SRMMU.
  89  */
  90 
  91 extern void (*invalidate)(void);
  92 
  93 /* Certain architectures need to do special things when pte's
  94  * within a page table are directly modified.  Thus, the following
  95  * hook is made available.
  96  */
  97 extern void (*set_pte)(pte_t *pteptr, pte_t pteval);
  98 
  99 /* to align the pointer to the (next) page boundary */
 100 #define PAGE_ALIGN(addr)  (((addr)+PAGE_SIZE-1)&PAGE_MASK)
 101 
 102 /* We now put the free page pool mapped contiguously in high memory above
 103  * the kernel.
 104  */
 105 #define MAP_NR(addr) ((((unsigned long) (addr)) - PAGE_OFFSET) >> PAGE_SHIFT)
 106 
 107 #endif /* !(__ASSEMBLY__) */
 108 
 109 /* The rest is kind of funky because on the sparc, the offsets into the mmu 
 110  * entries are encoded in magic alternate address space tables. I will 
 111  * probably find some nifty inline assembly routines to do the equivalent. 
 112  * Much thought must go into this code.   (davem@caip.rutgers.edu)
 113  */
 114 
 115 /* Bitfields within a Sparc sun4c PTE (page table entry). */
 116 
 117 #define PTE_V     0x80000000   /* valid bit */
 118 #define PTE_ACC   0x60000000   /* access bits */
 119 #define PTE_W     0x40000000   /* writable bit */
 120 #define PTE_P     0x20000000   /* privileged page */
 121 #define PTE_NC    0x10000000   /* page is non-cacheable */
 122 #define PTE_TYP   0x0c000000   /* page type field */
 123 #define PTE_RMEM  0x00000000   /* type == on board real memory */
 124 #define PTE_IO    0x04000000   /* type == i/o area */
 125 #define PTE_VME16 0x08000000   /* type == 16-bit VME area */
 126 #define PTE_VME32 0x0c000000   /* type == 32-bit VME area */
 127 #define PTE_R     0x02000000   /* page has been referenced */
 128 #define PTE_M     0x01000000   /* page has been modified */
 129 #define PTE_RESV  0x00f80000   /* reserved bits */
 130 #define PTE_PHYPG 0x0007ffff   /* phys pg number, sun4c only uses 16bits */
 131 
 132 /* SRMMU defines */
 133 /* The fields in an srmmu virtual address when it gets translated.
 134  *
 135  *  -------------------------------------------------------------
 136  *  |   INDEX 1   |   INDEX 2   |   INDEX 3   |   PAGE OFFSET   |
 137  *  -------------------------------------------------------------
 138  *  31          24 23        18  17         12  11              0
 139  */
 140 #define SRMMU_IDX1_SHIFT      24
 141 #define SRMMU_IDX1_MASK       0xff000000
 142 #define SRMMU_IDX2_SHIFT      18
 143 #define SRMMU_IDX2_MASK       0x00fc0000
 144 #define SRMMU_IDX3_SHIFT      12
 145 #define SRMMU_IDX3_MASK       0x0003f000
 146 
 147 #define SRMMU_PGOFFSET_MASK   0x00000fff
 148 /* The page table sizes for the various levels in bytes. */
 149 #define SRMMU_LV1_PTSIZE      1024
 150 #define SRMMU_LV2_PTSIZE      256
 151 #define SRMMU_LV3_PTSIZE      256
 152 
 153 /* Definition of the values in the ET field of PTD's and PTE's */
 154 #define SRMMU_ET_INVALID      0x0
 155 #define SRMMU_ET_PTD          0x1
 156 #define SRMMU_ET_PTE          0x2
 157 #define SRMMU_ET_RESV         0x3
 158 #define SRMMU_ET_PTDBAD       0x3   /* Upward compatability my butt. */
 159 
 160 /* Page table directory bits.
 161  *
 162  * ----------------
 163  * |  PTP    | ET |
 164  * ----------------
 165  * 31       2 1  0
 166  *
 167  * PTP:  The physical page table pointer.  This value appears on
 168  *       bits 35->6 on the physical address bus during translation.
 169  *
 170  * ET:   Entry type field.  Must be 1 for a PTD.
 171  */
 172 
 173 #define SRMMU_PTD_PTP_SHIFT         0x2
 174 #define SRMMU_PTD_PTP_MASK          0xfffffffc
 175 #define SRMMU_PTD_PTP_PADDR_SHIFT   0x4
 176 #define SRMMU_PTD_ET_SHIFT          0x0
 177 #define SRMMU_PTD_ET_MASK           0x00000003
 178 
 179 /* Page table entry bits.
 180  *
 181  * -------------------------------------------------
 182  * |  Physical Page Number  | C | M | R | ACC | ET |
 183  * -------------------------------------------------
 184  * 31                     8   7   6   5  4   2  1  0
 185  *
 186  * PPN: Physical page number, high order 24 bits of the 36-bit
 187  *      physical address, thus is you mask off all the non
 188  *      PPN bits you have the physical address of your page.
 189  *      No shifting necessary.
 190  *
 191  * C:   Whether the page is cacheable in the mmu TLB or not.  If
 192  *      not set the CPU cannot cache values to these addresses. For
 193  *      IO space translations this bit should be clear.
 194  *
 195  * M:   Modified.  This tells whether the page has been written to
 196  *      since the bit was last cleared.  NOTE: this does not include
 197  *      accesses via the ASI physical page pass through since that does
 198  *      not use the MMU.
 199  *
 200  * R:   References.  This tells whether the page has been referenced
 201  *      in any way shape or form since the last clearing of the bit.
 202  *      NOTE: this does not include accesses via the ASI physical page
 203  *      pass through since that does not use the MMU.
 204  *
 205  * ACC: Access permissions for this page.  This is further explained below
 206  *      with appropriate macros.
 207  */
 208 
 209 #define SRMMU_PTE_PPN_SHIFT         0x8
 210 #define SRMMU_PTE_PPN_MASK          0xffffff00
 211 #define SRMMU_PTE_PPN_PADDR_SHIFT   0x4
 212 #define SRMMU_PTE_C_SHIFT           0x7
 213 #define SRMMU_PTE_C_MASK            0x00000080
 214 #define SRMMU_PTE_M_SHIFT           0x6
 215 #define SRMMU_PTE_M_MASK            0x00000040
 216 #define SRMMU_PTE_R_SHIFT           0x5
 217 #define SRMMU_PTE_R_MASK            0x00000020
 218 #define SRMMU_PTE_ACC_SHIFT         0x2
 219 #define SRMMU_PTE_ACC_MASK          0x0000001c
 220 #define SRMMU_PTE_ET_SHIFT          0x0
 221 #define SRMMU_PTE_ET_MASK           0x00000003
 222 
 223 /* SRMMU pte access bits.
 224  *
 225  * BIT    USER ACCESS          SUPERVISOR ACCESS
 226  * ---    --------------       -----------------
 227  * 0x0    read only            read only
 228  * 0x1    read&write           read&write
 229  * 0x2    read&execute         read&execute
 230  * 0x3    read&write&execute   read&write&execute
 231  * 0x4    execute only         execute only
 232  * 0x5    read only            read&write
 233  * 0x6    ACCESS DENIED        read&execute
 234  * 0x7    ACCESS DENIED        read&write&execute
 235  *
 236  * All these values are shifted left two bits.
 237  */
 238 
 239 #define SRMMU_ACC_US_RDONLY      0x00
 240 #define SRMMU_ACC_US_RDWR        0x04
 241 #define SRMMU_ACC_US_RDEXEC      0x08
 242 #define SRMMU_ACC_US_RDWREXEC    0x0c
 243 #define SRMMU_ACC_US_EXECONLY    0x10
 244 #define SRMMU_ACC_U_RDONLY       0x14
 245 #define SRMMU_ACC_S_RDWR         0x14
 246 #define SRMMU_ACC_U_ACCDENIED    0x18
 247 #define SRMMU_ACC_S_RDEXEC       0x18
 248 #define SRMMU_ACC_U_ACCDENIED2   0x1c
 249 #define SRMMU_ACC_S_RDWREXEC     0x1c
 250 
 251 #ifndef __ASSEMBLY__
 252 
 253 /* SUN4C pte, segmap, and context manipulation */
 254 extern __inline__ unsigned long get_segmap(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 255 {
 256   register unsigned long entry;
 257 
 258   __asm__ __volatile__("\n\tlduba [%1] %2, %0\n\t" : 
 259                        "=r" (entry) :
 260                        "r" (addr), "i" (ASI_SEGMAP));
 261 
 262   return entry;
 263 }
 264 
 265 extern __inline__ void put_segmap(unsigned long addr, unsigned long entry)
     /* [previous][next][first][last][top][bottom][index][help] */
 266 {
 267 
 268   __asm__ __volatile__("\n\tstba %1, [%0] %2\n\t" : :
 269                        "r" (addr), "r" (entry),
 270                        "i" (ASI_SEGMAP));
 271 
 272   return;
 273 }
 274 
 275 extern __inline__ unsigned long get_pte(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 276 {
 277   register unsigned long entry;
 278 
 279   __asm__ __volatile__("\n\tlda [%1] %2, %0\n\t" : 
 280                        "=r" (entry) :
 281                        "r" (addr), "i" (ASI_PTE));
 282   return entry;
 283 }
 284 
 285 extern __inline__ void put_pte(unsigned long addr, unsigned long entry)
     /* [previous][next][first][last][top][bottom][index][help] */
 286 {
 287   __asm__ __volatile__("\n\tsta %1, [%0] %2\n\t" : :
 288                        "r" (addr), 
 289                        "r" (entry), "i" (ASI_PTE));
 290 
 291   return;
 292 }
 293 
 294 extern void (*switch_to_context)(void *tsk);
 295 
 296 extern __inline__ int get_context(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 297 {
 298   register int ctx;
 299 
 300   __asm__ __volatile__("\n\tlduba [%1] %2, %0\n\t" :
 301                        "=r" (ctx) :
 302                        "r" (AC_CONTEXT), "i" (ASI_CONTROL));
 303 
 304   return ctx;
 305 }
 306 
 307 extern __inline__ int set_context(int ctx)
     /* [previous][next][first][last][top][bottom][index][help] */
 308 {
 309   __asm__ __volatile__("\n\tstba %0, [%1] %2\n\t" : :
 310                        "r" (ctx), "r" (AC_CONTEXT), "i" (ASI_CONTROL));
 311 
 312   return ctx;
 313 }
 314 
 315 #endif /* __ASSEMBLY__ */
 316 
 317 #endif /* __KERNEL__ */
 318 
 319 #endif /* _SPARC_PAGE_H */

/* [previous][next][first][last][top][bottom][index][help] */