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