aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm/tlb-r4k.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2012-01-11 09:41:47 -0500
committerRalf Baechle <ralf@linux-mips.org>2012-01-11 09:41:47 -0500
commit39b741431af7f6f46b2e0e7f7f13ea2351fb4a5f (patch)
tree89355f4ae7bbb874537bb65f71ba0d19b3d468e1 /arch/mips/mm/tlb-r4k.c
parent5b0ec2efb7d373faa7b1a7632c459b93895d45cd (diff)
parentd7a887a73dec6c387b02a966a71aac767bbd9ce6 (diff)
Merge branch 'next/generic' into mips-for-linux-next
Diffstat (limited to 'arch/mips/mm/tlb-r4k.c')
-rw-r--r--arch/mips/mm/tlb-r4k.c67
1 files changed, 14 insertions, 53 deletions
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index d163455552b0..2dc625346c40 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -121,22 +121,30 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
121 121
122 if (cpu_context(cpu, mm) != 0) { 122 if (cpu_context(cpu, mm) != 0) {
123 unsigned long size, flags; 123 unsigned long size, flags;
124 int huge = is_vm_hugetlb_page(vma);
124 125
125 ENTER_CRITICAL(flags); 126 ENTER_CRITICAL(flags);
126 size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; 127 if (huge) {
127 size = (size + 1) >> 1; 128 start = round_down(start, HPAGE_SIZE);
129 end = round_up(end, HPAGE_SIZE);
130 size = (end - start) >> HPAGE_SHIFT;
131 } else {
132 start = round_down(start, PAGE_SIZE << 1);
133 end = round_up(end, PAGE_SIZE << 1);
134 size = (end - start) >> (PAGE_SHIFT + 1);
135 }
128 if (size <= current_cpu_data.tlbsize/2) { 136 if (size <= current_cpu_data.tlbsize/2) {
129 int oldpid = read_c0_entryhi(); 137 int oldpid = read_c0_entryhi();
130 int newpid = cpu_asid(cpu, mm); 138 int newpid = cpu_asid(cpu, mm);
131 139
132 start &= (PAGE_MASK << 1);
133 end += ((PAGE_SIZE << 1) - 1);
134 end &= (PAGE_MASK << 1);
135 while (start < end) { 140 while (start < end) {
136 int idx; 141 int idx;
137 142
138 write_c0_entryhi(start | newpid); 143 write_c0_entryhi(start | newpid);
139 start += (PAGE_SIZE << 1); 144 if (huge)
145 start += HPAGE_SIZE;
146 else
147 start += (PAGE_SIZE << 1);
140 mtc0_tlbw_hazard(); 148 mtc0_tlbw_hazard();
141 tlb_probe(); 149 tlb_probe();
142 tlb_probe_hazard(); 150 tlb_probe_hazard();
@@ -369,51 +377,6 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
369 EXIT_CRITICAL(flags); 377 EXIT_CRITICAL(flags);
370} 378}
371 379
372/*
373 * Used for loading TLB entries before trap_init() has started, when we
374 * don't actually want to add a wired entry which remains throughout the
375 * lifetime of the system
376 */
377
378static int temp_tlb_entry __cpuinitdata;
379
380__init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
381 unsigned long entryhi, unsigned long pagemask)
382{
383 int ret = 0;
384 unsigned long flags;
385 unsigned long wired;
386 unsigned long old_pagemask;
387 unsigned long old_ctx;
388
389 ENTER_CRITICAL(flags);
390 /* Save old context and create impossible VPN2 value */
391 old_ctx = read_c0_entryhi();
392 old_pagemask = read_c0_pagemask();
393 wired = read_c0_wired();
394 if (--temp_tlb_entry < wired) {
395 printk(KERN_WARNING
396 "No TLB space left for add_temporary_entry\n");
397 ret = -ENOSPC;
398 goto out;
399 }
400
401 write_c0_index(temp_tlb_entry);
402 write_c0_pagemask(pagemask);
403 write_c0_entryhi(entryhi);
404 write_c0_entrylo0(entrylo0);
405 write_c0_entrylo1(entrylo1);
406 mtc0_tlbw_hazard();
407 tlb_write_indexed();
408 tlbw_use_hazard();
409
410 write_c0_entryhi(old_ctx);
411 write_c0_pagemask(old_pagemask);
412out:
413 EXIT_CRITICAL(flags);
414 return ret;
415}
416
417static int __cpuinitdata ntlb; 380static int __cpuinitdata ntlb;
418static int __init set_ntlb(char *str) 381static int __init set_ntlb(char *str)
419{ 382{
@@ -451,8 +414,6 @@ void __cpuinit tlb_init(void)
451 write_c0_pagegrain(pg); 414 write_c0_pagegrain(pg);
452 } 415 }
453 416
454 temp_tlb_entry = current_cpu_data.tlbsize - 1;
455
456 /* From this point on the ARC firmware is dead. */ 417 /* From this point on the ARC firmware is dead. */
457 local_flush_tlb_all(); 418 local_flush_tlb_all();
458 419