This source file includes following definitions.
- flush_tlb_mm
- flush_tlb_page
- flush_tlb_range
- flush_tlb_current_task
- flush_tlb_mm
- flush_tlb_page
- flush_tlb_range
- flush_tlb_mm
- flush_tlb_page
- flush_tlb_range
- pte_none
- pte_present
- pte_clear
- pmd_none
- pmd_bad
- pmd_present
- pmd_clear
- pgd_none
- pgd_bad
- pgd_present
- pgd_clear
- pte_read
- pte_write
- pte_exec
- pte_dirty
- pte_young
- pte_wrprotect
- pte_rdprotect
- pte_exprotect
- pte_mkclean
- pte_mkold
- pte_mkwrite
- pte_mkread
- pte_mkexec
- pte_mkdirty
- pte_mkyoung
- mk_pte
- pte_modify
- pte_page
- pmd_page
- pgd_offset
- pmd_offset
- pte_offset
- pte_free_kernel
- pte_alloc_kernel
- pmd_free_kernel
- pmd_alloc_kernel
- pte_free
- pte_alloc
- pmd_free
- pmd_alloc
- pgd_free
- pgd_alloc
- update_mmu_cache
1 #ifndef _I386_PGTABLE_H
2 #define _I386_PGTABLE_H
3
4 #include <linux/config.h>
5
6
7
8
9
10 #define USE_PENTIUM_MM 1
11
12
13
14
15
16
17
18
19
20
21
22
23 #define flush_cache_all() do { } while (0)
24 #define flush_cache_mm(mm) do { } while (0)
25 #define flush_cache_range(mm, start, end) do { } while (0)
26 #define flush_cache_page(vma, vmaddr) do { } while (0)
27 #define flush_page_to_ram(page) do { } while (0)
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 #define __flush_tlb() \
43 __asm__ __volatile__("movl %%cr3,%%eax\n\tmovl %%eax,%%cr3": : :"ax")
44
45 #ifdef CONFIG_M386
46 #define __flush_tlb_one(addr) flush_tlb()
47 #else
48 #define __flush_tlb_one(addr) \
49 __asm__ __volatile__("invlpg %0": :"m" (*(char *) addr))
50 #endif
51
52 #ifndef __SMP__
53
54 #define flush_tlb() __flush_tlb()
55 #define flush_tlb_all() __flush_tlb()
56
57 static inline void flush_tlb_mm(struct mm_struct *mm)
58 {
59 if (mm == current->mm)
60 __flush_tlb();
61 }
62
63 static inline void flush_tlb_page(struct vm_area_struct *vma,
64 unsigned long addr)
65 {
66 if (vma->vm_mm == current->mm)
67 __flush_tlb_one(addr);
68 }
69
70 static inline void flush_tlb_range(struct mm_struct *mm,
71 unsigned long start, unsigned long end)
72 {
73 if (mm == current->mm)
74 __flush_tlb();
75 }
76
77 #else
78
79
80
81
82
83
84 #include <asm/smp.h>
85
86 #define local_flush_tlb() \
87 __flush_tlb()
88
89
90 #undef CLEVER_SMP_INVALIDATE
91 #ifdef CLEVER_SMP_INVALIDATE
92
93
94
95
96
97
98
99
100
101
102
103
104 static inline void flush_tlb_current_task(void)
105 {
106 if (current->mm->count == 1)
107 local_flush_tlb();
108 else
109 smp_flush_tlb();
110 }
111
112 #define flush_tlb() flush_tlb_current_task()
113
114 #define flush_tlb_all() smp_flush_tlb()
115
116 static inline void flush_tlb_mm(struct mm_struct * mm)
117 {
118 if (mm == current->mm && mm->count == 1)
119 local_flush_tlb();
120 else
121 smp_flush_tlb();
122 }
123
124 static inline void flush_tlb_page(struct vm_area_struct * vma,
125 unsigned long va)
126 {
127 if (vma->vm_mm == current->mm && current->mm->count == 1)
128 __flush_tlb_one(va);
129 else
130 smp_flush_tlb();
131 }
132
133 static inline void flush_tlb_range(struct mm_struct * mm,
134 unsigned long start, unsigned long end)
135 {
136 flush_tlb_mm(mm);
137 }
138
139
140 #else
141
142 #define flush_tlb() \
143 smp_flush_tlb()
144
145 #define flush_tlb_all() flush_tlb()
146
147 static inline void flush_tlb_mm(struct mm_struct *mm)
148 {
149 flush_tlb();
150 }
151
152 static inline void flush_tlb_page(struct vm_area_struct *vma,
153 unsigned long addr)
154 {
155 flush_tlb();
156 }
157
158 static inline void flush_tlb_range(struct mm_struct *mm,
159 unsigned long start, unsigned long end)
160 {
161 flush_tlb();
162 }
163 #endif
164 #endif
165
166
167
168
169
170
171 #define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
172
173
174 #define PMD_SHIFT 22
175 #define PMD_SIZE (1UL << PMD_SHIFT)
176 #define PMD_MASK (~(PMD_SIZE-1))
177
178
179 #define PGDIR_SHIFT 22
180 #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
181 #define PGDIR_MASK (~(PGDIR_SIZE-1))
182
183
184
185
186
187 #define PTRS_PER_PTE 1024
188 #define PTRS_PER_PMD 1
189 #define PTRS_PER_PGD 1024
190
191
192
193
194
195
196
197
198 #define VMALLOC_OFFSET (8*1024*1024)
199 #define VMALLOC_START ((high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
200 #define VMALLOC_VMADDR(x) (TASK_SIZE + (unsigned long)(x))
201
202
203
204
205
206
207
208
209 #define _PAGE_PRESENT 0x001
210 #define _PAGE_RW 0x002
211 #define _PAGE_USER 0x004
212 #define _PAGE_PCD 0x010
213 #define _PAGE_ACCESSED 0x020
214 #define _PAGE_DIRTY 0x040
215 #define _PAGE_4M 0x080
216
217 #define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
218 #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
219
220 #define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
221 #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
222 #define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
223 #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
224 #define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
225
226
227
228
229
230 #define __P000 PAGE_NONE
231 #define __P001 PAGE_READONLY
232 #define __P010 PAGE_COPY
233 #define __P011 PAGE_COPY
234 #define __P100 PAGE_READONLY
235 #define __P101 PAGE_READONLY
236 #define __P110 PAGE_COPY
237 #define __P111 PAGE_COPY
238
239 #define __S000 PAGE_NONE
240 #define __S001 PAGE_READONLY
241 #define __S010 PAGE_SHARED
242 #define __S011 PAGE_SHARED
243 #define __S100 PAGE_READONLY
244 #define __S101 PAGE_READONLY
245 #define __S110 PAGE_SHARED
246 #define __S111 PAGE_SHARED
247
248
249
250
251
252
253 #undef TEST_VERIFY_AREA
254
255
256 extern unsigned long pg0[1024];
257
258 extern unsigned long empty_zero_page[1024];
259
260
261
262
263
264
265
266
267 extern pte_t __bad_page(void);
268 extern pte_t * __bad_pagetable(void);
269
270 #define BAD_PAGETABLE __bad_pagetable()
271 #define BAD_PAGE __bad_page()
272 #define ZERO_PAGE ((unsigned long) empty_zero_page)
273
274
275 #define BITS_PER_PTR (8*sizeof(unsigned long))
276
277
278 #define PTR_MASK (~(sizeof(void*)-1))
279
280
281
282 #define SIZEOF_PTR_LOG2 2
283
284
285 #define PAGE_PTR(address) \
286 ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
287
288
289 #define SET_PAGE_DIR(tsk,pgdir) \
290 do { \
291 (tsk)->tss.cr3 = (unsigned long) (pgdir); \
292 if ((tsk) == current) \
293 __asm__ __volatile__("movl %0,%%cr3": :"a" ((tsk)->tss.cr3)); \
294 } while (0)
295
296 extern inline int pte_none(pte_t pte) { return !pte_val(pte); }
297 extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; }
298 extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; }
299
300 extern inline int pmd_none(pmd_t pmd) { return !pmd_val(pmd); }
301 extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) & ~PAGE_MASK) != _PAGE_TABLE || pmd_val(pmd) > high_memory; }
302 extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _PAGE_PRESENT; }
303 extern inline void pmd_clear(pmd_t * pmdp) { pmd_val(*pmdp) = 0; }
304
305
306
307
308
309
310 extern inline int pgd_none(pgd_t pgd) { return 0; }
311 extern inline int pgd_bad(pgd_t pgd) { return 0; }
312 extern inline int pgd_present(pgd_t pgd) { return 1; }
313 extern inline void pgd_clear(pgd_t * pgdp) { }
314
315
316
317
318
319 extern inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
320 extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
321 extern inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
322 extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
323 extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
324
325 extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_RW; return pte; }
326 extern inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; }
327 extern inline pte_t pte_exprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; }
328 extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
329 extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
330 extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_RW; return pte; }
331 extern inline pte_t pte_mkread(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; }
332 extern inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; }
333 extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; }
334 extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
335
336
337
338
339
340 extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot)
341 { pte_t pte; pte_val(pte) = page | pgprot_val(pgprot); return pte; }
342
343 extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
344 { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
345
346 extern inline unsigned long pte_page(pte_t pte)
347 { return pte_val(pte) & PAGE_MASK; }
348
349 extern inline unsigned long pmd_page(pmd_t pmd)
350 { return pmd_val(pmd) & PAGE_MASK; }
351
352
353 extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
354 {
355 return mm->pgd + (address >> PGDIR_SHIFT);
356 }
357
358
359 extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
360 {
361 return (pmd_t *) dir;
362 }
363
364
365 extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
366 {
367 return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
368 }
369
370
371
372
373
374
375 extern inline void pte_free_kernel(pte_t * pte)
376 {
377 free_page((unsigned long) pte);
378 }
379
380 extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
381 {
382 address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
383 if (pmd_none(*pmd)) {
384 pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
385 if (pmd_none(*pmd)) {
386 if (page) {
387 pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
388 return page + address;
389 }
390 pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
391 return NULL;
392 }
393 free_page((unsigned long) page);
394 }
395 if (pmd_bad(*pmd)) {
396 printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
397 pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
398 return NULL;
399 }
400 return (pte_t *) pmd_page(*pmd) + address;
401 }
402
403
404
405
406
407 extern inline void pmd_free_kernel(pmd_t * pmd)
408 {
409 pmd_val(*pmd) = 0;
410 }
411
412 extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address)
413 {
414 return (pmd_t *) pgd;
415 }
416
417 extern inline void pte_free(pte_t * pte)
418 {
419 free_page((unsigned long) pte);
420 }
421
422 extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
423 {
424 address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
425 if (pmd_none(*pmd)) {
426 pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
427 if (pmd_none(*pmd)) {
428 if (page) {
429 pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
430 return page + address;
431 }
432 pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
433 return NULL;
434 }
435 free_page((unsigned long) page);
436 }
437 if (pmd_bad(*pmd)) {
438 printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
439 pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
440 return NULL;
441 }
442 return (pte_t *) pmd_page(*pmd) + address;
443 }
444
445
446
447
448
449 extern inline void pmd_free(pmd_t * pmd)
450 {
451 pmd_val(*pmd) = 0;
452 }
453
454 extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address)
455 {
456 return (pmd_t *) pgd;
457 }
458
459 extern inline void pgd_free(pgd_t * pgd)
460 {
461 free_page((unsigned long) pgd);
462 }
463
464 extern inline pgd_t * pgd_alloc(void)
465 {
466 return (pgd_t *) get_free_page(GFP_KERNEL);
467 }
468
469 extern pgd_t swapper_pg_dir[1024];
470
471
472
473
474
475 extern inline void update_mmu_cache(struct vm_area_struct * vma,
476 unsigned long address, pte_t pte)
477 {
478 }
479
480 #define SWP_TYPE(entry) (((entry) >> 1) & 0x7f)
481 #define SWP_OFFSET(entry) ((entry) >> 8)
482 #define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8))
483
484 #endif