diff options
Diffstat (limited to 'arch/mips/mm/init.c')
-rw-r--r-- | arch/mips/mm/init.c | 82 |
1 files changed, 17 insertions, 65 deletions
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 4fc74c78265a..6e4413330e36 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
@@ -44,27 +44,6 @@ | |||
44 | #include <asm/tlb.h> | 44 | #include <asm/tlb.h> |
45 | #include <asm/fixmap.h> | 45 | #include <asm/fixmap.h> |
46 | 46 | ||
47 | /* Atomicity and interruptability */ | ||
48 | #ifdef CONFIG_MIPS_MT_SMTC | ||
49 | |||
50 | #include <asm/mipsmtregs.h> | ||
51 | |||
52 | #define ENTER_CRITICAL(flags) \ | ||
53 | { \ | ||
54 | unsigned int mvpflags; \ | ||
55 | local_irq_save(flags);\ | ||
56 | mvpflags = dvpe() | ||
57 | #define EXIT_CRITICAL(flags) \ | ||
58 | evpe(mvpflags); \ | ||
59 | local_irq_restore(flags); \ | ||
60 | } | ||
61 | #else | ||
62 | |||
63 | #define ENTER_CRITICAL(flags) local_irq_save(flags) | ||
64 | #define EXIT_CRITICAL(flags) local_irq_restore(flags) | ||
65 | |||
66 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
67 | |||
68 | /* | 47 | /* |
69 | * We have up to 8 empty zeroed pages so we can map one of the right colour | 48 | * We have up to 8 empty zeroed pages so we can map one of the right colour |
70 | * when needed. This is necessary only on R4000 / R4400 SC and MC versions | 49 | * when needed. This is necessary only on R4000 / R4400 SC and MC versions |
@@ -100,21 +79,7 @@ void setup_zero_pages(void) | |||
100 | zero_page_mask = ((PAGE_SIZE << order) - 1) & PAGE_MASK; | 79 | zero_page_mask = ((PAGE_SIZE << order) - 1) & PAGE_MASK; |
101 | } | 80 | } |
102 | 81 | ||
103 | #ifdef CONFIG_MIPS_MT_SMTC | 82 | static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot) |
104 | static pte_t *kmap_coherent_pte; | ||
105 | static void __init kmap_coherent_init(void) | ||
106 | { | ||
107 | unsigned long vaddr; | ||
108 | |||
109 | /* cache the first coherent kmap pte */ | ||
110 | vaddr = __fix_to_virt(FIX_CMAP_BEGIN); | ||
111 | kmap_coherent_pte = kmap_get_fixmap_pte(vaddr); | ||
112 | } | ||
113 | #else | ||
114 | static inline void kmap_coherent_init(void) {} | ||
115 | #endif | ||
116 | |||
117 | void *kmap_coherent(struct page *page, unsigned long addr) | ||
118 | { | 83 | { |
119 | enum fixed_addresses idx; | 84 | enum fixed_addresses idx; |
120 | unsigned long vaddr, flags, entrylo; | 85 | unsigned long vaddr, flags, entrylo; |
@@ -126,58 +91,48 @@ void *kmap_coherent(struct page *page, unsigned long addr) | |||
126 | 91 | ||
127 | pagefault_disable(); | 92 | pagefault_disable(); |
128 | idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1); | 93 | idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1); |
129 | #ifdef CONFIG_MIPS_MT_SMTC | ||
130 | idx += FIX_N_COLOURS * smp_processor_id() + | ||
131 | (in_interrupt() ? (FIX_N_COLOURS * NR_CPUS) : 0); | ||
132 | #else | ||
133 | idx += in_interrupt() ? FIX_N_COLOURS : 0; | 94 | idx += in_interrupt() ? FIX_N_COLOURS : 0; |
134 | #endif | ||
135 | vaddr = __fix_to_virt(FIX_CMAP_END - idx); | 95 | vaddr = __fix_to_virt(FIX_CMAP_END - idx); |
136 | pte = mk_pte(page, PAGE_KERNEL); | 96 | pte = mk_pte(page, prot); |
137 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 97 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) |
138 | entrylo = pte.pte_high; | 98 | entrylo = pte.pte_high; |
139 | #else | 99 | #else |
140 | entrylo = pte_to_entrylo(pte_val(pte)); | 100 | entrylo = pte_to_entrylo(pte_val(pte)); |
141 | #endif | 101 | #endif |
142 | 102 | ||
143 | ENTER_CRITICAL(flags); | 103 | local_irq_save(flags); |
144 | old_ctx = read_c0_entryhi(); | 104 | old_ctx = read_c0_entryhi(); |
145 | write_c0_entryhi(vaddr & (PAGE_MASK << 1)); | 105 | write_c0_entryhi(vaddr & (PAGE_MASK << 1)); |
146 | write_c0_entrylo0(entrylo); | 106 | write_c0_entrylo0(entrylo); |
147 | write_c0_entrylo1(entrylo); | 107 | write_c0_entrylo1(entrylo); |
148 | #ifdef CONFIG_MIPS_MT_SMTC | ||
149 | set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte); | ||
150 | /* preload TLB instead of local_flush_tlb_one() */ | ||
151 | mtc0_tlbw_hazard(); | ||
152 | tlb_probe(); | ||
153 | tlb_probe_hazard(); | ||
154 | tlbidx = read_c0_index(); | ||
155 | mtc0_tlbw_hazard(); | ||
156 | if (tlbidx < 0) | ||
157 | tlb_write_random(); | ||
158 | else | ||
159 | tlb_write_indexed(); | ||
160 | #else | ||
161 | tlbidx = read_c0_wired(); | 108 | tlbidx = read_c0_wired(); |
162 | write_c0_wired(tlbidx + 1); | 109 | write_c0_wired(tlbidx + 1); |
163 | write_c0_index(tlbidx); | 110 | write_c0_index(tlbidx); |
164 | mtc0_tlbw_hazard(); | 111 | mtc0_tlbw_hazard(); |
165 | tlb_write_indexed(); | 112 | tlb_write_indexed(); |
166 | #endif | ||
167 | tlbw_use_hazard(); | 113 | tlbw_use_hazard(); |
168 | write_c0_entryhi(old_ctx); | 114 | write_c0_entryhi(old_ctx); |
169 | EXIT_CRITICAL(flags); | 115 | local_irq_restore(flags); |
170 | 116 | ||
171 | return (void*) vaddr; | 117 | return (void*) vaddr; |
172 | } | 118 | } |
173 | 119 | ||
120 | void *kmap_coherent(struct page *page, unsigned long addr) | ||
121 | { | ||
122 | return __kmap_pgprot(page, addr, PAGE_KERNEL); | ||
123 | } | ||
124 | |||
125 | void *kmap_noncoherent(struct page *page, unsigned long addr) | ||
126 | { | ||
127 | return __kmap_pgprot(page, addr, PAGE_KERNEL_NC); | ||
128 | } | ||
129 | |||
174 | void kunmap_coherent(void) | 130 | void kunmap_coherent(void) |
175 | { | 131 | { |
176 | #ifndef CONFIG_MIPS_MT_SMTC | ||
177 | unsigned int wired; | 132 | unsigned int wired; |
178 | unsigned long flags, old_ctx; | 133 | unsigned long flags, old_ctx; |
179 | 134 | ||
180 | ENTER_CRITICAL(flags); | 135 | local_irq_save(flags); |
181 | old_ctx = read_c0_entryhi(); | 136 | old_ctx = read_c0_entryhi(); |
182 | wired = read_c0_wired() - 1; | 137 | wired = read_c0_wired() - 1; |
183 | write_c0_wired(wired); | 138 | write_c0_wired(wired); |
@@ -189,8 +144,7 @@ void kunmap_coherent(void) | |||
189 | tlb_write_indexed(); | 144 | tlb_write_indexed(); |
190 | tlbw_use_hazard(); | 145 | tlbw_use_hazard(); |
191 | write_c0_entryhi(old_ctx); | 146 | write_c0_entryhi(old_ctx); |
192 | EXIT_CRITICAL(flags); | 147 | local_irq_restore(flags); |
193 | #endif | ||
194 | pagefault_enable(); | 148 | pagefault_enable(); |
195 | } | 149 | } |
196 | 150 | ||
@@ -256,7 +210,7 @@ EXPORT_SYMBOL_GPL(copy_from_user_page); | |||
256 | void __init fixrange_init(unsigned long start, unsigned long end, | 210 | void __init fixrange_init(unsigned long start, unsigned long end, |
257 | pgd_t *pgd_base) | 211 | pgd_t *pgd_base) |
258 | { | 212 | { |
259 | #if defined(CONFIG_HIGHMEM) || defined(CONFIG_MIPS_MT_SMTC) | 213 | #ifdef CONFIG_HIGHMEM |
260 | pgd_t *pgd; | 214 | pgd_t *pgd; |
261 | pud_t *pud; | 215 | pud_t *pud; |
262 | pmd_t *pmd; | 216 | pmd_t *pmd; |
@@ -327,8 +281,6 @@ void __init paging_init(void) | |||
327 | #ifdef CONFIG_HIGHMEM | 281 | #ifdef CONFIG_HIGHMEM |
328 | kmap_init(); | 282 | kmap_init(); |
329 | #endif | 283 | #endif |
330 | kmap_coherent_init(); | ||
331 | |||
332 | #ifdef CONFIG_ZONE_DMA | 284 | #ifdef CONFIG_ZONE_DMA |
333 | max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN; | 285 | max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN; |
334 | #endif | 286 | #endif |