diff options
author | Matt Fleming <matt@console-pimps.org> | 2009-11-17 17:03:41 -0500 |
---|---|---|
committer | Matt Fleming <matt@console-pimps.org> | 2010-01-16 09:29:23 -0500 |
commit | 07cad4dc1bfdaefd20c6329e9d8179ad1c600e92 (patch) | |
tree | 1ca1e2758dc14245315fc9a9d7334d739d3f0816 /arch/sh/mm | |
parent | 24ef7fc4dcc57afa0c33166c25bfe7676ffd4296 (diff) |
sh: Generalise the pte handling code for the fixmap path
Generalise the code for setting and clearing pte's and allow TLB entries
to be pinned and unpinned if the _PAGE_WIRED flag is present.
Signed-off-by: Matt Fleming <matt@console-pimps.org>
Diffstat (limited to 'arch/sh/mm')
-rw-r--r-- | arch/sh/mm/init.c | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index d5fb014279ad..30a9b530d456 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c | |||
@@ -39,7 +39,7 @@ unsigned long cached_to_uncached = P2SEG - P1SEG; | |||
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | #ifdef CONFIG_MMU | 41 | #ifdef CONFIG_MMU |
42 | static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) | 42 | static pte_t *__get_pte_phys(unsigned long addr) |
43 | { | 43 | { |
44 | pgd_t *pgd; | 44 | pgd_t *pgd; |
45 | pud_t *pud; | 45 | pud_t *pud; |
@@ -49,22 +49,30 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) | |||
49 | pgd = pgd_offset_k(addr); | 49 | pgd = pgd_offset_k(addr); |
50 | if (pgd_none(*pgd)) { | 50 | if (pgd_none(*pgd)) { |
51 | pgd_ERROR(*pgd); | 51 | pgd_ERROR(*pgd); |
52 | return; | 52 | return NULL; |
53 | } | 53 | } |
54 | 54 | ||
55 | pud = pud_alloc(NULL, pgd, addr); | 55 | pud = pud_alloc(NULL, pgd, addr); |
56 | if (unlikely(!pud)) { | 56 | if (unlikely(!pud)) { |
57 | pud_ERROR(*pud); | 57 | pud_ERROR(*pud); |
58 | return; | 58 | return NULL; |
59 | } | 59 | } |
60 | 60 | ||
61 | pmd = pmd_alloc(NULL, pud, addr); | 61 | pmd = pmd_alloc(NULL, pud, addr); |
62 | if (unlikely(!pmd)) { | 62 | if (unlikely(!pmd)) { |
63 | pmd_ERROR(*pmd); | 63 | pmd_ERROR(*pmd); |
64 | return; | 64 | return NULL; |
65 | } | 65 | } |
66 | 66 | ||
67 | pte = pte_offset_kernel(pmd, addr); | 67 | pte = pte_offset_kernel(pmd, addr); |
68 | return pte; | ||
69 | } | ||
70 | |||
71 | static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) | ||
72 | { | ||
73 | pte_t *pte; | ||
74 | |||
75 | pte = __get_pte_phys(addr); | ||
68 | if (!pte_none(*pte)) { | 76 | if (!pte_none(*pte)) { |
69 | pte_ERROR(*pte); | 77 | pte_ERROR(*pte); |
70 | return; | 78 | return; |
@@ -72,6 +80,22 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) | |||
72 | 80 | ||
73 | set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot)); | 81 | set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot)); |
74 | local_flush_tlb_one(get_asid(), addr); | 82 | local_flush_tlb_one(get_asid(), addr); |
83 | |||
84 | if (pgprot_val(prot) & _PAGE_WIRED) | ||
85 | tlb_wire_entry(NULL, addr, *pte); | ||
86 | } | ||
87 | |||
88 | static void clear_pte_phys(unsigned long addr, pgprot_t prot) | ||
89 | { | ||
90 | pte_t *pte; | ||
91 | |||
92 | pte = __get_pte_phys(addr); | ||
93 | |||
94 | if (pgprot_val(prot) & _PAGE_WIRED) | ||
95 | tlb_unwire_entry(); | ||
96 | |||
97 | set_pte(pte, pfn_pte(0, __pgprot(0))); | ||
98 | local_flush_tlb_one(get_asid(), addr); | ||
75 | } | 99 | } |
76 | 100 | ||
77 | /* | 101 | /* |
@@ -101,6 +125,18 @@ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) | |||
101 | set_pte_phys(address, phys, prot); | 125 | set_pte_phys(address, phys, prot); |
102 | } | 126 | } |
103 | 127 | ||
128 | void __clear_fixmap(enum fixed_addresses idx, pgprot_t prot) | ||
129 | { | ||
130 | unsigned long address = __fix_to_virt(idx); | ||
131 | |||
132 | if (idx >= __end_of_fixed_addresses) { | ||
133 | BUG(); | ||
134 | return; | ||
135 | } | ||
136 | |||
137 | clear_pte_phys(address, prot); | ||
138 | } | ||
139 | |||
104 | void __init page_table_range_init(unsigned long start, unsigned long end, | 140 | void __init page_table_range_init(unsigned long start, unsigned long end, |
105 | pgd_t *pgd_base) | 141 | pgd_t *pgd_base) |
106 | { | 142 | { |