1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#ifndef _ASM_PGTABLE_H
17#define _ASM_PGTABLE_H
18
19#include <asm/mem-layout.h>
20#include <asm/setup.h>
21#include <asm/processor.h>
22
23#ifndef __ASSEMBLY__
24#include <linux/threads.h>
25#include <linux/slab.h>
26#include <linux/list.h>
27#include <linux/spinlock.h>
28#include <linux/sched.h>
29struct vm_area_struct;
30#endif
31
32#ifndef __ASSEMBLY__
33#if defined(CONFIG_HIGHPTE)
34typedef unsigned long pte_addr_t;
35#else
36typedef pte_t *pte_addr_t;
37#endif
38#endif
39
40
41
42
43
44#ifndef CONFIG_MMU
45
46#define pgd_present(pgd) (1)
47#define pgd_none(pgd) (0)
48#define pgd_bad(pgd) (0)
49#define pgd_clear(pgdp)
50#define kern_addr_valid(addr) (1)
51#define pmd_offset(a, b) ((void *) 0)
52
53#define PAGE_NONE __pgprot(0)
54#define PAGE_SHARED __pgprot(0)
55#define PAGE_COPY __pgprot(0)
56#define PAGE_READONLY __pgprot(0)
57#define PAGE_KERNEL __pgprot(0)
58
59#define __swp_type(x) (0)
60#define __swp_offset(x) (0)
61#define __swp_entry(typ,off) ((swp_entry_t) { ((typ) | ((off) << 7)) })
62#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
63#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
64
65#ifndef __ASSEMBLY__
66static inline int pte_file(pte_t pte) { return 0; }
67#endif
68
69#define ZERO_PAGE(vaddr) ({ BUG(); NULL; })
70
71#define swapper_pg_dir ((pgd_t *) NULL)
72
73#define pgtable_cache_init() do {} while (0)
74
75#include <asm-generic/pgtable.h>
76
77#else
78
79
80
81
82
83
84
85
86
87#ifndef __ASSEMBLY__
88extern unsigned long empty_zero_page;
89#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page)
90#endif
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125#define PGDIR_SHIFT 26
126#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
127#define PGDIR_MASK (~(PGDIR_SIZE - 1))
128#define PTRS_PER_PGD 64
129
130#define PUD_SHIFT 26
131#define PTRS_PER_PUD 1
132#define PUD_SIZE (1UL << PUD_SHIFT)
133#define PUD_MASK (~(PUD_SIZE - 1))
134#define PUE_SIZE 256
135
136#define PMD_SHIFT 26
137#define PMD_SIZE (1UL << PMD_SHIFT)
138#define PMD_MASK (~(PMD_SIZE - 1))
139#define PTRS_PER_PMD 1
140#define PME_SIZE 256
141
142#define __frv_PT_SIZE 256
143
144#define PTRS_PER_PTE 4096
145
146#define USER_PGDS_IN_LAST_PML4 (TASK_SIZE / PGDIR_SIZE)
147#define FIRST_USER_ADDRESS 0
148
149#define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
150#define KERNEL_PGD_PTRS (PTRS_PER_PGD - USER_PGD_PTRS)
151
152#define TWOLEVEL_PGDIR_SHIFT 26
153#define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
154#define BOOT_KERNEL_PGD_PTRS (PTRS_PER_PGD - BOOT_USER_PGD_PTRS)
155
156#ifndef __ASSEMBLY__
157
158extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
159
160#define pte_ERROR(e) \
161 printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte)
162#define pmd_ERROR(e) \
163 printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
164#define pud_ERROR(e) \
165 printk("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pmd_val(pud_val(e)))
166#define pgd_ERROR(e) \
167 printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pmd_val(pud_val(pgd_val(e))))
168
169
170
171
172
173
174#define set_pte(pteptr, pteval) \
175do { \
176 *(pteptr) = (pteval); \
177 asm volatile("dcf %M0" :: "U"(*pteptr)); \
178} while(0)
179#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
180
181
182
183
184
185#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
186
187
188
189
190
191#define pgd_offset_k(address) pgd_offset(&init_mm, address)
192
193
194
195
196
197
198static inline int pgd_none(pgd_t pgd) { return 0; }
199static inline int pgd_bad(pgd_t pgd) { return 0; }
200static inline int pgd_present(pgd_t pgd) { return 1; }
201static inline void pgd_clear(pgd_t *pgd) { }
202
203#define pgd_populate(mm, pgd, pud) do { } while (0)
204
205
206
207
208#define set_pgd(pgdptr, pgdval) \
209do { \
210 memcpy((pgdptr), &(pgdval), sizeof(pgd_t)); \
211 asm volatile("dcf %M0" :: "U"(*(pgdptr))); \
212} while(0)
213
214static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address)
215{
216 return (pud_t *) pgd;
217}
218
219#define pgd_page(pgd) (pud_page((pud_t){ pgd }))
220#define pgd_page_vaddr(pgd) (pud_page_vaddr((pud_t){ pgd }))
221
222
223
224
225
226#define pud_alloc_one(mm, address) NULL
227#define pud_free(mm, x) do { } while (0)
228#define __pud_free_tlb(tlb, x, address) do { } while (0)
229
230
231
232
233
234
235static inline int pud_none(pud_t pud) { return 0; }
236static inline int pud_bad(pud_t pud) { return 0; }
237static inline int pud_present(pud_t pud) { return 1; }
238static inline void pud_clear(pud_t *pud) { }
239
240#define pud_populate(mm, pmd, pte) do { } while (0)
241
242
243
244
245
246#define set_pud(pudptr, pudval) set_pmd((pmd_t *)(pudptr), (pmd_t) { pudval })
247
248#define pud_page(pud) (pmd_page((pmd_t){ pud }))
249#define pud_page_vaddr(pud) (pmd_page_vaddr((pmd_t){ pud }))
250
251
252
253
254
255extern void __set_pmd(pmd_t *pmdptr, unsigned long __pmd);
256
257#define set_pmd(pmdptr, pmdval) \
258do { \
259 __set_pmd((pmdptr), (pmdval).ste[0]); \
260} while(0)
261
262#define __pmd_index(address) 0
263
264static inline pmd_t *pmd_offset(pud_t *dir, unsigned long address)
265{
266 return (pmd_t *) dir + __pmd_index(address);
267}
268
269#define pte_same(a, b) ((a).pte == (b).pte)
270#define pte_page(x) (mem_map + ((unsigned long)(((x).pte >> PAGE_SHIFT))))
271#define pte_none(x) (!(x).pte)
272#define pte_pfn(x) ((unsigned long)(((x).pte >> PAGE_SHIFT)))
273#define pfn_pte(pfn, prot) __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
274#define pfn_pmd(pfn, prot) __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
275
276#define VMALLOC_VMADDR(x) ((unsigned long) (x))
277
278#endif
279
280
281
282
283#define _PAGE_BIT_PRESENT xAMPRx_V_BIT
284#define _PAGE_BIT_WP DAMPRx_WP_BIT
285#define _PAGE_BIT_NOCACHE xAMPRx_C_BIT
286#define _PAGE_BIT_SUPER xAMPRx_S_BIT
287#define _PAGE_BIT_ACCESSED xAMPRx_RESERVED8_BIT
288#define _PAGE_BIT_DIRTY xAMPRx_M_BIT
289#define _PAGE_BIT_NOTGLOBAL xAMPRx_NG_BIT
290
291#define _PAGE_PRESENT xAMPRx_V
292#define _PAGE_WP DAMPRx_WP
293#define _PAGE_NOCACHE xAMPRx_C
294#define _PAGE_SUPER xAMPRx_S
295#define _PAGE_ACCESSED xAMPRx_RESERVED8
296#define _PAGE_DIRTY xAMPRx_M
297#define _PAGE_NOTGLOBAL xAMPRx_NG
298
299#define _PAGE_RESERVED_MASK (xAMPRx_RESERVED8 | xAMPRx_RESERVED13)
300
301#define _PAGE_FILE 0x002
302#define _PAGE_PROTNONE 0x000
303
304#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
305
306#define __PGPROT_BASE \
307 (_PAGE_PRESENT | xAMPRx_SS_16Kb | xAMPRx_D | _PAGE_NOTGLOBAL | _PAGE_ACCESSED)
308
309#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
310#define PAGE_SHARED __pgprot(__PGPROT_BASE)
311#define PAGE_COPY __pgprot(__PGPROT_BASE | _PAGE_WP)
312#define PAGE_READONLY __pgprot(__PGPROT_BASE | _PAGE_WP)
313
314#define __PAGE_KERNEL (__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY)
315#define __PAGE_KERNEL_NOCACHE (__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY | _PAGE_NOCACHE)
316#define __PAGE_KERNEL_RO (__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY | _PAGE_WP)
317
318#define MAKE_GLOBAL(x) __pgprot((x) & ~_PAGE_NOTGLOBAL)
319
320#define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL)
321#define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO)
322#define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
323
324#define _PAGE_TABLE (_PAGE_PRESENT | xAMPRx_SS_16Kb)
325
326#ifndef __ASSEMBLY__
327
328
329
330
331
332
333#define __P000 PAGE_NONE
334#define __P001 PAGE_READONLY
335#define __P010 PAGE_COPY
336#define __P011 PAGE_COPY
337#define __P100 PAGE_READONLY
338#define __P101 PAGE_READONLY
339#define __P110 PAGE_COPY
340#define __P111 PAGE_COPY
341
342#define __S000 PAGE_NONE
343#define __S001 PAGE_READONLY
344#define __S010 PAGE_SHARED
345#define __S011 PAGE_SHARED
346#define __S100 PAGE_READONLY
347#define __S101 PAGE_READONLY
348#define __S110 PAGE_SHARED
349#define __S111 PAGE_SHARED
350
351
352
353
354
355#undef TEST_ACCESS_OK
356
357#define pte_present(x) (pte_val(x) & _PAGE_PRESENT)
358#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
359
360#define pmd_none(x) (!pmd_val(x))
361#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
362#define pmd_bad(x) (pmd_val(x) & xAMPRx_SS)
363#define pmd_clear(xp) do { __set_pmd(xp, 0); } while(0)
364
365#define pmd_page_vaddr(pmd) \
366 ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
367
368#ifndef CONFIG_DISCONTIGMEM
369#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
370#endif
371
372#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
373
374
375
376
377
378static inline int pte_dirty(pte_t pte) { return (pte).pte & _PAGE_DIRTY; }
379static inline int pte_young(pte_t pte) { return (pte).pte & _PAGE_ACCESSED; }
380static inline int pte_write(pte_t pte) { return !((pte).pte & _PAGE_WP); }
381static inline int pte_special(pte_t pte) { return 0; }
382
383static inline pte_t pte_mkclean(pte_t pte) { (pte).pte &= ~_PAGE_DIRTY; return pte; }
384static inline pte_t pte_mkold(pte_t pte) { (pte).pte &= ~_PAGE_ACCESSED; return pte; }
385static inline pte_t pte_wrprotect(pte_t pte) { (pte).pte |= _PAGE_WP; return pte; }
386static inline pte_t pte_mkdirty(pte_t pte) { (pte).pte |= _PAGE_DIRTY; return pte; }
387static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte |= _PAGE_ACCESSED; return pte; }
388static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte &= ~_PAGE_WP; return pte; }
389static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
390
391static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
392{
393 int i = test_and_clear_bit(_PAGE_BIT_ACCESSED, ptep);
394 asm volatile("dcf %M0" :: "U"(*ptep));
395 return i;
396}
397
398static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
399{
400 unsigned long x = xchg(&ptep->pte, 0);
401 asm volatile("dcf %M0" :: "U"(*ptep));
402 return __pte(x);
403}
404
405static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
406{
407 set_bit(_PAGE_BIT_WP, ptep);
408 asm volatile("dcf %M0" :: "U"(*ptep));
409}
410
411
412
413
414#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NOCACHE))
415
416
417
418
419
420
421#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
422#define mk_pte_huge(entry) ((entry).pte_low |= _PAGE_PRESENT | _PAGE_PSE)
423
424
425#define mk_pte_phys(physpage, pgprot) pfn_pte((physpage) >> PAGE_SHIFT, pgprot)
426
427static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
428{
429 pte.pte &= _PAGE_CHG_MASK;
430 pte.pte |= pgprot_val(newprot);
431 return pte;
432}
433
434
435#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
436#define pgd_index_k(addr) pgd_index(addr)
437
438
439#define __pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
440
441
442
443
444
445
446
447#define pte_index(address) \
448 (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
449#define pte_offset_kernel(dir, address) \
450 ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(address))
451
452#if defined(CONFIG_HIGHPTE)
453#define pte_offset_map(dir, address) \
454 ((pte_t *)kmap_atomic(pmd_page(*(dir))) + pte_index(address))
455#define pte_unmap(pte) kunmap_atomic(pte)
456#else
457#define pte_offset_map(dir, address) \
458 ((pte_t *)page_address(pmd_page(*(dir))) + pte_index(address))
459#define pte_unmap(pte) do { } while (0)
460#endif
461
462
463
464
465
466
467
468
469
470
471#define __swp_type(x) (((x).val >> 2) & 0x1f)
472#define __swp_offset(x) ((x).val >> 8)
473#define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 8) })
474#define __pte_to_swp_entry(_pte) ((swp_entry_t) { (_pte).pte })
475#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
476
477static inline int pte_file(pte_t pte)
478{
479 return pte.pte & _PAGE_FILE;
480}
481
482#define PTE_FILE_MAX_BITS 29
483
484#define pte_to_pgoff(PTE) ((PTE).pte >> 2)
485#define pgoff_to_pte(off) __pte((off) << 2 | _PAGE_FILE)
486
487
488#define PageSkip(page) (0)
489#define kern_addr_valid(addr) (1)
490
491#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
492 remap_pfn_range(vma, vaddr, pfn, size, prot)
493
494#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
495#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
496#define __HAVE_ARCH_PTEP_SET_WRPROTECT
497#define __HAVE_ARCH_PTE_SAME
498#include <asm-generic/pgtable.h>
499
500
501
502
503static inline void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
504{
505 struct mm_struct *mm;
506 unsigned long ampr;
507
508 mm = current->mm;
509 if (mm) {
510 pgd_t *pge = pgd_offset(mm, address);
511 pud_t *pue = pud_offset(pge, address);
512 pmd_t *pme = pmd_offset(pue, address);
513
514 ampr = pme->ste[0] & 0xffffff00;
515 ampr |= xAMPRx_L | xAMPRx_SS_16Kb | xAMPRx_S | xAMPRx_C |
516 xAMPRx_V;
517 } else {
518 address = ULONG_MAX;
519 ampr = 0;
520 }
521
522 asm volatile("movgs %0,scr0\n"
523 "movgs %0,scr1\n"
524 "movgs %1,dampr4\n"
525 "movgs %1,dampr5\n"
526 :
527 : "r"(address), "r"(ampr)
528 );
529}
530
531#ifdef CONFIG_PROC_FS
532extern char *proc_pid_status_frv_cxnr(struct mm_struct *mm, char *buffer);
533#endif
534
535extern void __init pgtable_cache_init(void);
536
537#endif
538#endif
539
540#ifndef __ASSEMBLY__
541extern void __init paging_init(void);
542#endif
543
544#endif
545