1 /* page.h: Various defines and such for MMU operations on the Sparc for 2 * the Linux kernel. 3 * 4 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 5 */ 6
7 #ifndef_SPARC_PAGE_H 8 #define_SPARC_PAGE_H 9
10 #include <asm/asi.h> /* for get/set segmap/pte routines */ 11 #include <asm/contregs.h> /* for switch_to_context */ 12 #include <asm/head.h> /* for KERNBASE */ 13
14 #definePAGE_SHIFT 12 /* This is the virtual page... */ 15 #definePAGE_OFFSETKERNBASE 16 #definePAGE_SIZE (1 << PAGE_SHIFT)
17
18 /* to mask away the intra-page address bits */ 19 #definePAGE_MASK (~(PAGE_SIZE-1))
20
21 #ifdef__KERNEL__ 22 #ifndef__ASSEMBLY__ 23
24 /* The following structure is used to hold the physical 25 * memory configuration of the machine. This is filled in 26 * probe_memory() and is later used by mem_init() to set up 27 * mem_map[]. We statically allocate SPARC_PHYS_BANKS of 28 * these structs, this is arbitrary. The entry after the 29 * last valid one has num_bytes==0. 30 */ 31
32 structsparc_phys_banks{ 33 unsignedlongbase_addr;
34 unsignedlongnum_bytes;
35 };
36
37 #defineSPARC_PHYS_BANKS 32
38
39 externstructsparc_phys_bankssp_banks[SPARC_PHYS_BANKS];
40
41 #defineCONFIG_STRICT_MM_TYPECHECKS 42
43 #ifdefCONFIG_STRICT_MM_TYPECHECKS 44 /* 45 * These are used to make use of C type-checking.. 46 */ 47 typedefstruct{unsignedlongpte; }pte_t;
48 typedefstruct{unsignedlongpmd; }pmd_t;
49 typedefstruct{unsignedlongpgd; }pgd_t;
50 typedefstruct{unsignedlongpgprot; }pgprot_t;
51
52 #definepte_val(x) ((x).pte)
53 #definepmd_val(x) ((x).pmd)
54 #definepgd_val(x) ((x).pgd)
55 #definepgprot_val(x) ((x).pgprot)
56
57 #define __pte(x) ((pte_t) { (x) } )
58 #define __pmd(x) ((pmd_t) { (x) } )
59 #define __pgd(x) ((pgd_t) { (x) } )
60 #define__pgprot(x) ((pgprot_t) { (x) } )
61
62 #else 63 /* 64 * .. while these make it easier on the compiler 65 */ 66 typedefunsignedlongpte_t;
67 typedefunsignedlongpmd_t;
68 typedefunsignedlongpgd_t;
69 typedefunsignedlongpgprot_t;
70
71 #definepte_val(x) (x)
72 #definepmd_val(x) (x)
73 #definepgd_val(x) (x)
74 #definepgprot_val(x) (x)
75
76 #define __pte(x) (x)
77 #define __pmd(x) (x)
78 #define __pgd(x) (x)
79 #define__pgprot(x) (x)
80
81 #endif 82
83 /* The current va context is global and known, so all that is needed to 84 * do an invalidate is flush the VAC on a sun4c or call the ASI flushing 85 * routines on a SRMMU. 86 */ 87
88 externvoid (*invalidate)(void);
89
90 /* to align the pointer to the (next) page boundary */ 91 #definePAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
92
93 /* We now put the free page pool mapped contiguously in high memory above 94 * the kernel. 95 */ 96 #defineMAP_NR(addr) ((((unsignedlong)addr) - PAGE_OFFSET) >> PAGE_SHIFT)
97 #defineMAP_PAGE_RESERVED (1<<15)
98
99
100 #endif/* !(__ASSEMBLY__) */ 101
102 /* The rest is kind of funky because on the sparc, the offsets into the mmu 103 * entries are encoded in magic alternate address space tables. I will 104 * probably find some nifty inline assembly routines to do the equivalent. 105 * Much thought must go into this code. (davem@caip.rutgers.edu) 106 */ 107
108 /* Bitfields within a Sparc sun4c PTE (page table entry). */ 109
110 #definePTE_V 0x80000000 /* valid bit */ 111 #definePTE_ACC 0x60000000 /* access bits */ 112 #definePTE_W 0x40000000 /* writable bit */ 113 #definePTE_P 0x20000000 /* privileged page */ 114 #definePTE_NC 0x10000000 /* page is non-cacheable */ 115 #define PTE_TYP 0x0c000000 /* page type field */ 116 #define PTE_RMEM 0x00000000 /* type == on board real memory */ 117 #definePTE_IO 0x04000000 /* type == i/o area */ 118 #define PTE_VME16 0x08000000 /* type == 16-bit VME area */ 119 #define PTE_VME32 0x0c000000 /* type == 32-bit VME area */ 120 #define PTE_R 0x02000000 /* page has been referenced */ 121 #define PTE_M 0x01000000 /* page has been modified */ 122 #definePTE_RESV 0x00f80000 /* reserved bits */ 123 #define PTE_PHYPG 0x0007ffff /* phys pg number, sun4c only uses 16bits */ 124
125 /* SRMMU defines */ 126 /* The fields in an srmmu virtual address when it gets translated. 127 * 128 * ------------------------------------------------------------- 129 * | INDEX 1 | INDEX 2 | INDEX 3 | PAGE OFFSET | 130 * ------------------------------------------------------------- 131 * 31 24 23 18 17 12 11 0 132 */ 133 #defineSRMMU_IDX1_SHIFT 24
134 #defineSRMMU_IDX1_MASK 0xff000000
135 #defineSRMMU_IDX2_SHIFT 18
136 #defineSRMMU_IDX2_MASK 0x00fc0000
137 #defineSRMMU_IDX3_SHIFT 12
138 #defineSRMMU_IDX3_MASK 0x0003f000
139
140 #define SRMMU_PGOFFSET_MASK 0x00000fff
141 /* The page table sizes for the various levels in bytes. */ 142 #define SRMMU_LV1_PTSIZE 1024
143 #define SRMMU_LV2_PTSIZE 256
144 #define SRMMU_LV3_PTSIZE 256
145
146 /* Definition of the values in the ET field of PTD's and PTE's */ 147 #defineSRMMU_ET_INVALID 0x0
148 #defineSRMMU_ET_PTD 0x1
149 #defineSRMMU_ET_PTE 0x2
150 #define SRMMU_ET_RESV 0x3
151 #defineSRMMU_ET_PTDBAD 0x3 /* Upward compatability my butt. */ 152
153 /* Page table directory bits. 154 * 155 * ---------------- 156 * | PTP | ET | 157 * ---------------- 158 * 31 2 1 0 159 * 160 * PTP: The physical page table pointer. This value appears on 161 * bits 35->6 on the physical address bus during translation. 162 * 163 * ET: Entry type field. Must be 1 for a PTD. 164 */ 165
166 #define SRMMU_PTD_PTP_SHIFT 0x2
167 #defineSRMMU_PTD_PTP_MASK 0xfffffffc
168 #defineSRMMU_PTD_PTP_PADDR_SHIFT 0x4
169 #define SRMMU_PTD_ET_SHIFT 0x0
170 #define SRMMU_PTD_ET_MASK 0x00000003
171
172 /* Page table entry bits. 173 * 174 * ------------------------------------------------- 175 * | Physical Page Number | C | M | R | ACC | ET | 176 * ------------------------------------------------- 177 * 31 8 7 6 5 4 2 1 0 178 * 179 * PPN: Physical page number, high order 24 bits of the 36-bit 180 * physical address, thus is you mask off all the non 181 * PPN bits you have the physical address of your page. 182 * No shifting necessary. 183 * 184 * C: Whether the page is cacheable in the mmu TLB or not. If 185 * not set the CPU cannot cache values to these addresses. For 186 * IO space translations this bit should be clear. 187 * 188 * M: Modified. This tells whether the page has been written to 189 * since the bit was last cleared. NOTE: this does not include 190 * accesses via the ASI physical page pass through since that does 191 * not use the MMU. 192 * 193 * R: References. This tells whether the page has been referenced 194 * in any way shape or form since the last clearing of the bit. 195 * NOTE: this does not include accesses via the ASI physical page 196 * pass through since that does not use the MMU. 197 * 198 * ACC: Access permissions for this page. This is further explained below 199 * with appropriate macros. 200 */ 201
202 #define SRMMU_PTE_PPN_SHIFT 0x8
203 #defineSRMMU_PTE_PPN_MASK 0xffffff00
204 #defineSRMMU_PTE_PPN_PADDR_SHIFT 0x4
205 #define SRMMU_PTE_C_SHIFT 0x7
206 #defineSRMMU_PTE_C_MASK 0x00000080
207 #define SRMMU_PTE_M_SHIFT 0x6
208 #defineSRMMU_PTE_M_MASK 0x00000040
209 #define SRMMU_PTE_R_SHIFT 0x5
210 #defineSRMMU_PTE_R_MASK 0x00000020
211 #define SRMMU_PTE_ACC_SHIFT 0x2
212 #defineSRMMU_PTE_ACC_MASK 0x0000001c
213 #define SRMMU_PTE_ET_SHIFT 0x0
214 #defineSRMMU_PTE_ET_MASK 0x00000003
215
216 /* SRMMU pte access bits. 217 * 218 * BIT USER ACCESS SUPERVISOR ACCESS 219 * --- -------------- ----------------- 220 * 0x0 read only read only 221 * 0x1 read&write read&write 222 * 0x2 read&execute read&execute 223 * 0x3 read&write&execute read&write&execute 224 * 0x4 execute only execute only 225 * 0x5 read only read&write 226 * 0x6 ACCESS DENIED read&execute 227 * 0x7 ACCESS DENIED read&write&execute 228 * 229 * All these values are shifted left two bits. 230 */ 231
232 #defineSRMMU_ACC_US_RDONLY 0x00
233 #defineSRMMU_ACC_US_RDWR 0x04
234 #defineSRMMU_ACC_US_RDEXEC 0x08
235 #define SRMMU_ACC_US_RDWREXEC 0x0c
236 #define SRMMU_ACC_US_EXECONLY 0x10
237 #defineSRMMU_ACC_U_RDONLY 0x14
238 #defineSRMMU_ACC_S_RDWR 0x14
239 #defineSRMMU_ACC_U_ACCDENIED 0x18
240 #defineSRMMU_ACC_S_RDEXEC 0x18
241 #define SRMMU_ACC_U_ACCDENIED2 0x1c
242 #defineSRMMU_ACC_S_RDWREXEC 0x1c
243
244 #ifndef__ASSEMBLY__ 245
246 /* SUN4C pte, segmap, and context manipulation */ 247 extern__inline__unsignedlongget_segmap(unsignedlongaddr)
/* */ 248 { 249 registerunsignedlongentry;
250
251 __asm____volatile__("lduba [%1] %2, %0" :
252 "=r" (entry) :
253 "r" (addr), "i" (ASI_SEGMAP));
254
255 return (entry&0xff);
256 } 257
258 extern__inline__voidput_segmap(unsignedlongaddr, unsignedlongentry)
/* */ 259 { 260
261 __asm____volatile__("stba %1, [%0] %2" : : "r" (addr), "r" (entry&0xff),
262 "i" (ASI_SEGMAP));
263
264 return;
265 } 266
267 extern__inline__unsignedlongget_pte(unsignedlongaddr)
/* */ 268 { 269 registerunsignedlongentry;
270
271 __asm____volatile__("lda [%1] %2, %0" :
272 "=r" (entry) :
273 "r" (addr), "i" (ASI_PTE));
274 returnentry;
275 } 276
277 extern__inline__voidput_pte(unsignedlongaddr, unsignedlongentry)
/* */ 278 { 279 __asm____volatile__("sta %1, [%0] %2" : :
280 "r" (addr),
281 "r" (entry), "i" (ASI_PTE));
282
283 return;
284 } 285
286 externvoid (*switch_to_context)(int);
287
288 extern__inline__int get_context(void)
/* */ 289 { 290 registerintctx;
291
292 __asm____volatile__("lduba [%1] %2, %0" :
293 "=r" (ctx) :
294 "r" (AC_CONTEXT), "i" (ASI_CONTROL));
295
296 returnctx;
297 } 298
299 typedefunsignedshortmem_map_t;
300
301 #endif/* __ASSEMBLY__ */ 302
303 #endif/* __KERNEL__ */ 304
305 #endif/* _SPARC_PAGE_H */