diff options
Diffstat (limited to 'arch/nios2/mm/pgtable.c')
-rw-r--r-- | arch/nios2/mm/pgtable.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/arch/nios2/mm/pgtable.c b/arch/nios2/mm/pgtable.c new file mode 100644 index 000000000000..61e24a25f71a --- /dev/null +++ b/arch/nios2/mm/pgtable.c | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 Wind River Systems Inc | ||
3 | * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com | ||
4 | * | ||
5 | * This file is subject to the terms and conditions of the GNU General Public | ||
6 | * License. See the file "COPYING" in the main directory of this archive | ||
7 | * for more details. | ||
8 | */ | ||
9 | |||
10 | #include <linux/mm.h> | ||
11 | #include <linux/sched.h> | ||
12 | |||
13 | #include <asm/pgtable.h> | ||
14 | #include <asm/cpuinfo.h> | ||
15 | |||
16 | /* pteaddr: | ||
17 | * ptbase | vpn* | zero | ||
18 | * 31-22 | 21-2 | 1-0 | ||
19 | * | ||
20 | * *vpn is preserved on double fault | ||
21 | * | ||
22 | * tlbacc: | ||
23 | * IG |*flags| pfn | ||
24 | * 31-25|24-20 | 19-0 | ||
25 | * | ||
26 | * *crwxg | ||
27 | * | ||
28 | * tlbmisc: | ||
29 | * resv |way |rd | we|pid |dbl|bad|perm|d | ||
30 | * 31-24 |23-20 |19 | 20|17-4|3 |2 |1 |0 | ||
31 | * | ||
32 | */ | ||
33 | |||
34 | /* | ||
35 | * Initialize a new pgd / pmd table with invalid pointers. | ||
36 | */ | ||
37 | static void pgd_init(pgd_t *pgd) | ||
38 | { | ||
39 | unsigned long *p = (unsigned long *) pgd; | ||
40 | int i; | ||
41 | |||
42 | for (i = 0; i < USER_PTRS_PER_PGD; i += 8) { | ||
43 | p[i + 0] = (unsigned long) invalid_pte_table; | ||
44 | p[i + 1] = (unsigned long) invalid_pte_table; | ||
45 | p[i + 2] = (unsigned long) invalid_pte_table; | ||
46 | p[i + 3] = (unsigned long) invalid_pte_table; | ||
47 | p[i + 4] = (unsigned long) invalid_pte_table; | ||
48 | p[i + 5] = (unsigned long) invalid_pte_table; | ||
49 | p[i + 6] = (unsigned long) invalid_pte_table; | ||
50 | p[i + 7] = (unsigned long) invalid_pte_table; | ||
51 | } | ||
52 | } | ||
53 | |||
54 | pgd_t *pgd_alloc(struct mm_struct *mm) | ||
55 | { | ||
56 | pgd_t *ret, *init; | ||
57 | |||
58 | ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER); | ||
59 | if (ret) { | ||
60 | init = pgd_offset(&init_mm, 0UL); | ||
61 | pgd_init(ret); | ||
62 | memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD, | ||
63 | (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); | ||
64 | } | ||
65 | |||
66 | return ret; | ||
67 | } | ||
68 | |||
69 | void __init pagetable_init(void) | ||
70 | { | ||
71 | /* Initialize the entire pgd. */ | ||
72 | pgd_init(swapper_pg_dir); | ||
73 | pgd_init(swapper_pg_dir + USER_PTRS_PER_PGD); | ||
74 | } | ||