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 <linux/config.h>
20#include <asm/mem-layout.h>
21#include <asm/setup.h>
22#include <asm/processor.h>
23
24#ifndef __ASSEMBLY__
25#include <linux/threads.h>
26#include <linux/slab.h>
27#include <linux/list.h>
28#include <linux/spinlock.h>
29#endif
30
31#ifndef __ASSEMBLY__
32#if defined(CONFIG_HIGHPTE)
33typedef unsigned long pte_addr_t;
34#else
35typedef pte_t *pte_addr_t;
36#endif
37#endif
38
39
40
41
42
43#ifndef CONFIG_MMU
44
45#define pgd_present(pgd) (1)
46#define pgd_none(pgd) (0)
47#define pgd_bad(pgd) (0)
48#define pgd_clear(pgdp)
49#define kern_addr_valid(addr) (1)
50#define pmd_offset(a, b) ((void *) 0)
51
52#define PAGE_NONE __pgprot(0)
53#define PAGE_SHARED __pgprot(0)
54#define PAGE_COPY __pgprot(0)
55#define PAGE_READONLY __pgprot(0)
56#define PAGE_KERNEL __pgprot(0)
57
58#define __swp_type(x) (0)
59#define __swp_offset(x) (0)
60#define __swp_entry(typ,off) ((swp_entry_t) { ((typ) | ((off) << 7)) })
61#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
62#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
63
64#ifndef __ASSEMBLY__
65static inline int pte_file(pte_t pte) { return 0; }
66#endif
67
68#define ZERO_PAGE(vaddr) ({ BUG(); NULL; })
69
70#define swapper_pg_dir ((pgd_t *) NULL)
71
72#define pgtable_cache_init() do {} while(0)
73
74#else
75
76
77
78
79
80
81
82
83
84#ifndef __ASSEMBLY__
85extern unsigned long empty_zero_page;
86#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page)
87#endif
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
122#define PGDIR_SHIFT 26
123#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
124#define PGDIR_MASK (~(PGDIR_SIZE - 1))
125#define PTRS_PER_PGD 64
126
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 PMD_SHIFT 26
134#define PMD_SIZE (1UL << PMD_SHIFT)
135#define PMD_MASK (~(PMD_SIZE - 1))
136#define PTRS_PER_PMD 1
137#define PME_SIZE 256
138
139#define __frv_PT_SIZE 256
140
141#define PTRS_PER_PTE 4096
142
143#define USER_PGDS_IN_LAST_PML4 (TASK_SIZE / PGDIR_SIZE)
144#define FIRST_USER_PGD_NR 0
145
146#define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
147#define KERNEL_PGD_PTRS (PTRS_PER_PGD - USER_PGD_PTRS)
148
149#define TWOLEVEL_PGDIR_SHIFT 26
150#define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
151#define BOOT_KERNEL_PGD_PTRS (PTRS_PER_PGD - BOOT_USER_PGD_PTRS)
152
153#ifndef __ASSEMBLY__
154
155extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
156
157#define pte_ERROR(e) \
158 printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte)
159#define pmd_ERROR(e) \
160 printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e))
161#define pud_ERROR(e) \
162 printk("%s:%d: bad pud %08lx.\n", __FILE__, __LINE__, pmd_val(pud_val(e)))
163#define pgd_ERROR(e) \
164 printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pmd_val(pud_val(pgd_val(e))))
165
166
167
168
169
170
171#define set_pte(pteptr, pteval) \
172do { \
173 *(pteptr) = (pteval); \
174 asm volatile("dcf %M0" :: "U"(*pteptr)); \
175} while(0)
176
177#define set_pte_atomic(pteptr, pteval) set_pte((pteptr), (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_kernel(pgd) (pud_page_kernel((pud_t){ pgd }))
219
220
221
222
223
224#define pud_alloc_one(mm, address) NULL
225#define pud_free(x) do { } while (0)
226#define __pud_free_tlb(tlb, x) 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_kernel(pud) (pmd_page_kernel((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_FILE 0x002
300#define _PAGE_PROTNONE 0x000
301
302#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
303
304#define __PGPROT_BASE \
305 (_PAGE_PRESENT | xAMPRx_SS_16Kb | xAMPRx_D | _PAGE_NOTGLOBAL | _PAGE_ACCESSED)
306
307#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
308#define PAGE_SHARED __pgprot(__PGPROT_BASE)
309#define PAGE_COPY __pgprot(__PGPROT_BASE | _PAGE_WP)
310#define PAGE_READONLY __pgprot(__PGPROT_BASE | _PAGE_WP)
311
312#define __PAGE_KERNEL (__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY)
313#define __PAGE_KERNEL_NOCACHE (__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY | _PAGE_NOCACHE)
314#define __PAGE_KERNEL_RO (__PGPROT_BASE | _PAGE_SUPER | _PAGE_DIRTY | _PAGE_WP)
315
316#define MAKE_GLOBAL(x) __pgprot((x) & ~_PAGE_NOTGLOBAL)
317
318#define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL)
319#define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO)
320#define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
321
322#define _PAGE_TABLE (_PAGE_PRESENT | xAMPRx_SS_16Kb)
323
324#ifndef __ASSEMBLY__
325
326
327
328
329
330
331#define __P000 PAGE_NONE
332#define __P001 PAGE_READONLY
333#define __P010 PAGE_COPY
334#define __P011 PAGE_COPY
335#define __P100 PAGE_READONLY
336#define __P101 PAGE_READONLY
337#define __P110 PAGE_COPY
338#define __P111 PAGE_COPY
339
340#define __S000 PAGE_NONE
341#define __S001 PAGE_READONLY
342#define __S010 PAGE_SHARED
343#define __S011 PAGE_SHARED
344#define __S100 PAGE_READONLY
345#define __S101 PAGE_READONLY
346#define __S110 PAGE_SHARED
347#define __S111 PAGE_SHARED
348
349
350
351
352
353#undef TEST_VERIFY_AREA
354
355#define pte_present(x) (pte_val(x) & _PAGE_PRESENT)
356#define pte_clear(xp) do { set_pte(xp, __pte(0)); } while (0)
357
358#define pmd_none(x) (!pmd_val(x))
359#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
360#define pmd_bad(x) (pmd_val(x) & xAMPRx_SS)
361#define pmd_clear(xp) do { __set_pmd(xp, 0); } while(0)
362
363#define pmd_page_kernel(pmd) \
364 ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
365
366#ifndef CONFIG_DISCONTIGMEM
367#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
368#endif
369
370#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
371
372
373
374
375
376static inline int pte_read(pte_t pte) { return !((pte).pte & _PAGE_SUPER); }
377static inline int pte_exec(pte_t pte) { return !((pte).pte & _PAGE_SUPER); }
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); }
381
382static inline pte_t pte_rdprotect(pte_t pte) { (pte).pte |= _PAGE_SUPER; return pte; }
383static inline pte_t pte_exprotect(pte_t pte) { (pte).pte |= _PAGE_SUPER; return pte; }
384static inline pte_t pte_mkclean(pte_t pte) { (pte).pte &= ~_PAGE_DIRTY; return pte; }
385static inline pte_t pte_mkold(pte_t pte) { (pte).pte &= ~_PAGE_ACCESSED; return pte; }
386static inline pte_t pte_wrprotect(pte_t pte) { (pte).pte |= _PAGE_WP; return pte; }
387static inline pte_t pte_mkread(pte_t pte) { (pte).pte &= ~_PAGE_SUPER; return pte; }
388static inline pte_t pte_mkexec(pte_t pte) { (pte).pte &= ~_PAGE_SUPER; return pte; }
389static inline pte_t pte_mkdirty(pte_t pte) { (pte).pte |= _PAGE_DIRTY; return pte; }
390static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte |= _PAGE_ACCESSED; return pte; }
391static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte &= ~_PAGE_WP; return pte; }
392
393static inline int ptep_test_and_clear_dirty(pte_t *ptep)
394{
395 int i = test_and_clear_bit(_PAGE_BIT_DIRTY, ptep);
396 asm volatile("dcf %M0" :: "U"(*ptep));
397 return i;
398}
399
400static inline int ptep_test_and_clear_young(pte_t *ptep)
401{
402 int i = test_and_clear_bit(_PAGE_BIT_ACCESSED, ptep);
403 asm volatile("dcf %M0" :: "U"(*ptep));
404 return i;
405}
406
407static inline pte_t ptep_get_and_clear(pte_t *ptep)
408{
409 unsigned long x = xchg(&ptep->pte, 0);
410 asm volatile("dcf %M0" :: "U"(*ptep));
411 return __pte(x);
412}
413
414static inline void ptep_set_wrprotect(pte_t *ptep)
415{
416 set_bit(_PAGE_BIT_WP, ptep);
417 asm volatile("dcf %M0" :: "U"(*ptep));
418}
419
420static inline void ptep_mkdirty(pte_t *ptep)
421{
422 set_bit(_PAGE_BIT_DIRTY, ptep);
423 asm volatile("dcf %M0" :: "U"(*ptep));
424}
425
426
427
428
429
430
431#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
432#define mk_pte_huge(entry) ((entry).pte_low |= _PAGE_PRESENT | _PAGE_PSE)
433
434
435#define mk_pte_phys(physpage, pgprot) pfn_pte((physpage) >> PAGE_SHIFT, pgprot)
436
437static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
438{
439 pte.pte &= _PAGE_CHG_MASK;
440 pte.pte |= pgprot_val(newprot);
441 return pte;
442}
443
444#define page_pte(page) page_pte_prot((page), __pgprot(0))
445
446
447#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
448#define pgd_index_k(addr) pgd_index(addr)
449
450
451#define __pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
452
453
454
455
456
457
458
459#define pte_index(address) \
460 (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
461#define pte_offset_kernel(dir, address) \
462 ((pte_t *) pmd_page_kernel(*(dir)) + pte_index(address))
463
464#if defined(CONFIG_HIGHPTE)
465#define pte_offset_map(dir, address) \
466 ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE0) + pte_index(address))
467#define pte_offset_map_nested(dir, address) \
468 ((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE1) + pte_index(address))
469#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0)
470#define pte_unmap_nested(pte) kunmap_atomic((pte), KM_PTE1)
471#else
472#define pte_offset_map(dir, address) \
473 ((pte_t *)page_address(pmd_page(*(dir))) + pte_index(address))
474#define pte_offset_map_nested(dir, address) pte_offset_map((dir), (address))
475#define pte_unmap(pte) do { } while (0)
476#define pte_unmap_nested(pte) do { } while (0)
477#endif
478
479
480
481
482
483
484
485
486
487
488#define __swp_type(x) (((x).val >> 2) & 0x1f)
489#define __swp_offset(x) ((x).val >> 8)
490#define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 8) })
491#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte })
492#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
493
494static inline int pte_file(pte_t pte)
495{
496 return pte.pte & _PAGE_FILE;
497}
498
499#define PTE_FILE_MAX_BITS 29
500
501#define pte_to_pgoff(PTE) ((PTE).pte >> 2)
502#define pgoff_to_pte(off) __pte((off) << 2 | _PAGE_FILE)
503
504
505#define PageSkip(page) (0)
506#define kern_addr_valid(addr) (1)
507
508#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
509 remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
510
511#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
512#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
513#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
514#define __HAVE_ARCH_PTEP_SET_WRPROTECT
515#define __HAVE_ARCH_PTEP_MKDIRTY
516#define __HAVE_ARCH_PTE_SAME
517#include <asm-generic/pgtable.h>
518
519
520
521
522static inline void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
523{
524 unsigned long ampr;
525 pgd_t *pge = pgd_offset(current->mm, address);
526 pud_t *pue = pud_offset(pge, address);
527 pmd_t *pme = pmd_offset(pue, address);
528
529 ampr = pme->ste[0] & 0xffffff00;
530 ampr |= xAMPRx_L | xAMPRx_SS_16Kb | xAMPRx_S | xAMPRx_C | xAMPRx_V;
531
532 asm volatile("movgs %0,scr0\n"
533 "movgs %0,scr1\n"
534 "movgs %1,dampr4\n"
535 "movgs %1,dampr5\n"
536 :
537 : "r"(address), "r"(ampr)
538 );
539}
540
541#ifdef CONFIG_PROC_FS
542extern char *proc_pid_status_frv_cxnr(struct mm_struct *mm, char *buffer);
543#endif
544
545extern void __init pgtable_cache_init(void);
546
547#endif
548#endif
549
550#ifndef __ASSEMBLY__
551extern void __init paging_init(void);
552#endif
553
554#endif
555