diff options
author | Leonid Yegoshin <Leonid.Yegoshin@imgtec.com> | 2013-11-14 11:12:31 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2014-01-22 14:19:00 -0500 |
commit | 75b5b5e0a262790fa11043fe45700499c7e3d818 (patch) | |
tree | 3c5af9caa9c5478668159ff34db0ab34b51d7511 /arch | |
parent | 601cfa7b6fb657cff9e8f77bbcce79f75dd7ab74 (diff) |
MIPS: Add support for FTLBs
The Fixed Page Size TLB (FTLB) is a set-associative dual entry TLB. Its
purpose is to reduce the number of TLB misses by increasing the effective
TLB size and keep the implementation complexity to minimum levels.
A supported core can have both VTLB and FTLB.
Reviewed-by: James Hogan <james.hogan@imgtec.com>
Reviewed-by: Paul Burton <paul.burton@imgtec.com>
Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com>
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
Signed-off-by: John Crispin <blogic@openwrt.org>
Patchwork: http://patchwork.linux-mips.org/patch/6139/
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mips/include/asm/cpu-info.h | 3 | ||||
-rw-r--r-- | arch/mips/include/asm/mipsregs.h | 2 | ||||
-rw-r--r-- | arch/mips/include/asm/page.h | 25 | ||||
-rw-r--r-- | arch/mips/kernel/cpu-probe.c | 79 | ||||
-rw-r--r-- | arch/mips/kernel/genex.S | 1 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 30 | ||||
-rw-r--r-- | arch/mips/mm/tlb-r4k.c | 29 |
7 files changed, 155 insertions, 14 deletions
diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h index 21c8e29c8f91..8f7adf0ac1e3 100644 --- a/arch/mips/include/asm/cpu-info.h +++ b/arch/mips/include/asm/cpu-info.h | |||
@@ -52,6 +52,9 @@ struct cpuinfo_mips { | |||
52 | unsigned int cputype; | 52 | unsigned int cputype; |
53 | int isa_level; | 53 | int isa_level; |
54 | int tlbsize; | 54 | int tlbsize; |
55 | int tlbsizevtlb; | ||
56 | int tlbsizeftlbsets; | ||
57 | int tlbsizeftlbways; | ||
55 | struct cache_desc icache; /* Primary I-cache */ | 58 | struct cache_desc icache; /* Primary I-cache */ |
56 | struct cache_desc dcache; /* Primary D or combined I/D cache */ | 59 | struct cache_desc dcache; /* Primary D or combined I/D cache */ |
57 | struct cache_desc scache; /* Secondary cache */ | 60 | struct cache_desc scache; /* Secondary cache */ |
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index d9910a1e754a..cb57e07faa24 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h | |||
@@ -645,6 +645,8 @@ | |||
645 | #define MIPS_CONF5_K (_ULCAST_(1) << 30) | 645 | #define MIPS_CONF5_K (_ULCAST_(1) << 30) |
646 | 646 | ||
647 | #define MIPS_CONF6_SYND (_ULCAST_(1) << 13) | 647 | #define MIPS_CONF6_SYND (_ULCAST_(1) << 13) |
648 | /* proAptiv FTLB on/off bit */ | ||
649 | #define MIPS_CONF6_FTLBEN (_ULCAST_(1) << 15) | ||
648 | 650 | ||
649 | #define MIPS_CONF7_WII (_ULCAST_(1) << 31) | 651 | #define MIPS_CONF7_WII (_ULCAST_(1) << 31) |
650 | 652 | ||
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index f6be4741f7e8..5e08bcc74897 100644 --- a/arch/mips/include/asm/page.h +++ b/arch/mips/include/asm/page.h | |||
@@ -11,6 +11,8 @@ | |||
11 | 11 | ||
12 | #include <spaces.h> | 12 | #include <spaces.h> |
13 | #include <linux/const.h> | 13 | #include <linux/const.h> |
14 | #include <linux/kernel.h> | ||
15 | #include <asm/mipsregs.h> | ||
14 | 16 | ||
15 | /* | 17 | /* |
16 | * PAGE_SHIFT determines the page size | 18 | * PAGE_SHIFT determines the page size |
@@ -33,6 +35,29 @@ | |||
33 | #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) | 35 | #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) |
34 | #define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) | 36 | #define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) |
35 | 37 | ||
38 | /* | ||
39 | * This is used for calculating the real page sizes | ||
40 | * for FTLB or VTLB + FTLB confugrations. | ||
41 | */ | ||
42 | static inline unsigned int page_size_ftlb(unsigned int mmuextdef) | ||
43 | { | ||
44 | switch (mmuextdef) { | ||
45 | case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT: | ||
46 | if (PAGE_SIZE == (1 << 30)) | ||
47 | return 5; | ||
48 | if (PAGE_SIZE == (1llu << 32)) | ||
49 | return 6; | ||
50 | if (PAGE_SIZE > (256 << 10)) | ||
51 | return 7; /* reserved */ | ||
52 | /* fall through */ | ||
53 | case MIPS_CONF4_MMUEXTDEF_VTLBSIZEEXT: | ||
54 | return (PAGE_SHIFT - 10) / 2; | ||
55 | default: | ||
56 | panic("Invalid FTLB configuration with Conf4_mmuextdef=%d value\n", | ||
57 | mmuextdef >> 14); | ||
58 | } | ||
59 | } | ||
60 | |||
36 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT | 61 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT |
37 | #define HPAGE_SHIFT (PAGE_SHIFT + PAGE_SHIFT - 3) | 62 | #define HPAGE_SHIFT (PAGE_SHIFT + PAGE_SHIFT - 3) |
38 | #define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT) | 63 | #define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT) |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index f86414ebe05e..65b61bb8882d 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -163,6 +163,25 @@ static void set_isa(struct cpuinfo_mips *c, unsigned int isa) | |||
163 | static char unknown_isa[] = KERN_ERR \ | 163 | static char unknown_isa[] = KERN_ERR \ |
164 | "Unsupported ISA type, c0.config0: %d."; | 164 | "Unsupported ISA type, c0.config0: %d."; |
165 | 165 | ||
166 | static void set_ftlb_enable(struct cpuinfo_mips *c, int enable) | ||
167 | { | ||
168 | unsigned int config6; | ||
169 | /* | ||
170 | * Config6 is implementation dependent and it's currently only | ||
171 | * used by proAptiv | ||
172 | */ | ||
173 | if (c->cputype == CPU_PROAPTIV) { | ||
174 | config6 = read_c0_config6(); | ||
175 | if (enable) | ||
176 | /* Enable FTLB */ | ||
177 | write_c0_config6(config6 | MIPS_CONF6_FTLBEN); | ||
178 | else | ||
179 | /* Disable FTLB */ | ||
180 | write_c0_config6(config6 & ~MIPS_CONF6_FTLBEN); | ||
181 | back_to_back_c0_hazard(); | ||
182 | } | ||
183 | } | ||
184 | |||
166 | static inline unsigned int decode_config0(struct cpuinfo_mips *c) | 185 | static inline unsigned int decode_config0(struct cpuinfo_mips *c) |
167 | { | 186 | { |
168 | unsigned int config0; | 187 | unsigned int config0; |
@@ -170,8 +189,13 @@ static inline unsigned int decode_config0(struct cpuinfo_mips *c) | |||
170 | 189 | ||
171 | config0 = read_c0_config(); | 190 | config0 = read_c0_config(); |
172 | 191 | ||
173 | if (((config0 & MIPS_CONF_MT) >> 7) == 1) | 192 | /* |
193 | * Look for Standard TLB or Dual VTLB and FTLB | ||
194 | */ | ||
195 | if ((((config0 & MIPS_CONF_MT) >> 7) == 1) || | ||
196 | (((config0 & MIPS_CONF_MT) >> 7) == 4)) | ||
174 | c->options |= MIPS_CPU_TLB; | 197 | c->options |= MIPS_CPU_TLB; |
198 | |||
175 | isa = (config0 & MIPS_CONF_AT) >> 13; | 199 | isa = (config0 & MIPS_CONF_AT) >> 13; |
176 | switch (isa) { | 200 | switch (isa) { |
177 | case 0: | 201 | case 0: |
@@ -226,8 +250,11 @@ static inline unsigned int decode_config1(struct cpuinfo_mips *c) | |||
226 | c->options |= MIPS_CPU_FPU; | 250 | c->options |= MIPS_CPU_FPU; |
227 | c->options |= MIPS_CPU_32FPR; | 251 | c->options |= MIPS_CPU_32FPR; |
228 | } | 252 | } |
229 | if (cpu_has_tlb) | 253 | if (cpu_has_tlb) { |
230 | c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1; | 254 | c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1; |
255 | c->tlbsizevtlb = c->tlbsize; | ||
256 | c->tlbsizeftlbsets = 0; | ||
257 | } | ||
231 | 258 | ||
232 | return config1 & MIPS_CONF_M; | 259 | return config1 & MIPS_CONF_M; |
233 | } | 260 | } |
@@ -281,16 +308,50 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c) | |||
281 | static inline unsigned int decode_config4(struct cpuinfo_mips *c) | 308 | static inline unsigned int decode_config4(struct cpuinfo_mips *c) |
282 | { | 309 | { |
283 | unsigned int config4; | 310 | unsigned int config4; |
311 | unsigned int newcf4; | ||
312 | unsigned int mmuextdef; | ||
313 | unsigned int ftlb_page = MIPS_CONF4_FTLBPAGESIZE; | ||
284 | 314 | ||
285 | config4 = read_c0_config4(); | 315 | config4 = read_c0_config4(); |
286 | 316 | ||
287 | if ((config4 & MIPS_CONF4_MMUEXTDEF) == MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT | ||
288 | && cpu_has_tlb) | ||
289 | c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40; | ||
290 | |||
291 | if (cpu_has_tlb) { | 317 | if (cpu_has_tlb) { |
292 | if (((config4 & MIPS_CONF4_IE) >> 29) == 2) | 318 | if (((config4 & MIPS_CONF4_IE) >> 29) == 2) |
293 | c->options |= MIPS_CPU_TLBINV; | 319 | c->options |= MIPS_CPU_TLBINV; |
320 | mmuextdef = config4 & MIPS_CONF4_MMUEXTDEF; | ||
321 | switch (mmuextdef) { | ||
322 | case MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT: | ||
323 | c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40; | ||
324 | c->tlbsizevtlb = c->tlbsize; | ||
325 | break; | ||
326 | case MIPS_CONF4_MMUEXTDEF_VTLBSIZEEXT: | ||
327 | c->tlbsizevtlb += | ||
328 | ((config4 & MIPS_CONF4_VTLBSIZEEXT) >> | ||
329 | MIPS_CONF4_VTLBSIZEEXT_SHIFT) * 0x40; | ||
330 | c->tlbsize = c->tlbsizevtlb; | ||
331 | ftlb_page = MIPS_CONF4_VFTLBPAGESIZE; | ||
332 | /* fall through */ | ||
333 | case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT: | ||
334 | newcf4 = (config4 & ~ftlb_page) | | ||
335 | (page_size_ftlb(mmuextdef) << | ||
336 | MIPS_CONF4_FTLBPAGESIZE_SHIFT); | ||
337 | write_c0_config4(newcf4); | ||
338 | back_to_back_c0_hazard(); | ||
339 | config4 = read_c0_config4(); | ||
340 | if (config4 != newcf4) { | ||
341 | pr_err("PAGE_SIZE 0x%lx is not supported by FTLB (config4=0x%x)\n", | ||
342 | PAGE_SIZE, config4); | ||
343 | /* Switch FTLB off */ | ||
344 | set_ftlb_enable(c, 0); | ||
345 | break; | ||
346 | } | ||
347 | c->tlbsizeftlbsets = 1 << | ||
348 | ((config4 & MIPS_CONF4_FTLBSETS) >> | ||
349 | MIPS_CONF4_FTLBSETS_SHIFT); | ||
350 | c->tlbsizeftlbways = ((config4 & MIPS_CONF4_FTLBWAYS) >> | ||
351 | MIPS_CONF4_FTLBWAYS_SHIFT) + 2; | ||
352 | c->tlbsize += c->tlbsizeftlbways * c->tlbsizeftlbsets; | ||
353 | break; | ||
354 | } | ||
294 | } | 355 | } |
295 | 356 | ||
296 | c->kscratch_mask = (config4 >> 16) & 0xff; | 357 | c->kscratch_mask = (config4 >> 16) & 0xff; |
@@ -319,6 +380,9 @@ static void decode_configs(struct cpuinfo_mips *c) | |||
319 | 380 | ||
320 | c->scache.flags = MIPS_CACHE_NOT_PRESENT; | 381 | c->scache.flags = MIPS_CACHE_NOT_PRESENT; |
321 | 382 | ||
383 | /* Enable FTLB if present */ | ||
384 | set_ftlb_enable(c, 1); | ||
385 | |||
322 | ok = decode_config0(c); /* Read Config registers. */ | 386 | ok = decode_config0(c); /* Read Config registers. */ |
323 | BUG_ON(!ok); /* Arch spec violation! */ | 387 | BUG_ON(!ok); /* Arch spec violation! */ |
324 | if (ok) | 388 | if (ok) |
@@ -682,7 +746,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
682 | 746 | ||
683 | static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) | 747 | static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) |
684 | { | 748 | { |
685 | decode_configs(c); | ||
686 | switch (c->processor_id & PRID_IMP_MASK) { | 749 | switch (c->processor_id & PRID_IMP_MASK) { |
687 | case PRID_IMP_4KC: | 750 | case PRID_IMP_4KC: |
688 | c->cputype = CPU_4KC; | 751 | c->cputype = CPU_4KC; |
@@ -756,6 +819,8 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) | |||
756 | break; | 819 | break; |
757 | } | 820 | } |
758 | 821 | ||
822 | decode_configs(c); | ||
823 | |||
759 | spram_config(); | 824 | spram_config(); |
760 | } | 825 | } |
761 | 826 | ||
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 47d7583cd67f..d84f6a509502 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S | |||
@@ -476,6 +476,7 @@ NESTED(nmi_handler, PT_SIZE, sp) | |||
476 | BUILD_HANDLER ov ov sti silent /* #12 */ | 476 | BUILD_HANDLER ov ov sti silent /* #12 */ |
477 | BUILD_HANDLER tr tr sti silent /* #13 */ | 477 | BUILD_HANDLER tr tr sti silent /* #13 */ |
478 | BUILD_HANDLER fpe fpe fpe silent /* #15 */ | 478 | BUILD_HANDLER fpe fpe fpe silent /* #15 */ |
479 | BUILD_HANDLER ftlb ftlb none silent /* #16 */ | ||
479 | BUILD_HANDLER mdmx mdmx sti silent /* #22 */ | 480 | BUILD_HANDLER mdmx mdmx sti silent /* #22 */ |
480 | #ifdef CONFIG_HARDWARE_WATCHPOINTS | 481 | #ifdef CONFIG_HARDWARE_WATCHPOINTS |
481 | /* | 482 | /* |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index e98f3ab2a018..39370e1d4362 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -78,6 +78,7 @@ extern asmlinkage void handle_cpu(void); | |||
78 | extern asmlinkage void handle_ov(void); | 78 | extern asmlinkage void handle_ov(void); |
79 | extern asmlinkage void handle_tr(void); | 79 | extern asmlinkage void handle_tr(void); |
80 | extern asmlinkage void handle_fpe(void); | 80 | extern asmlinkage void handle_fpe(void); |
81 | extern asmlinkage void handle_ftlb(void); | ||
81 | extern asmlinkage void handle_mdmx(void); | 82 | extern asmlinkage void handle_mdmx(void); |
82 | extern asmlinkage void handle_watch(void); | 83 | extern asmlinkage void handle_watch(void); |
83 | extern asmlinkage void handle_mt(void); | 84 | extern asmlinkage void handle_mt(void); |
@@ -1460,6 +1461,34 @@ asmlinkage void cache_parity_error(void) | |||
1460 | panic("Can't handle the cache error!"); | 1461 | panic("Can't handle the cache error!"); |
1461 | } | 1462 | } |
1462 | 1463 | ||
1464 | asmlinkage void do_ftlb(void) | ||
1465 | { | ||
1466 | const int field = 2 * sizeof(unsigned long); | ||
1467 | unsigned int reg_val; | ||
1468 | |||
1469 | /* For the moment, report the problem and hang. */ | ||
1470 | if (cpu_has_mips_r2 && | ||
1471 | ((current_cpu_data.processor_id && 0xff0000) == PRID_COMP_MIPS)) { | ||
1472 | pr_err("FTLB error exception, cp0_ecc=0x%08x:\n", | ||
1473 | read_c0_ecc()); | ||
1474 | pr_err("cp0_errorepc == %0*lx\n", field, read_c0_errorepc()); | ||
1475 | reg_val = read_c0_cacheerr(); | ||
1476 | pr_err("c0_cacheerr == %08x\n", reg_val); | ||
1477 | |||
1478 | if ((reg_val & 0xc0000000) == 0xc0000000) { | ||
1479 | pr_err("Decoded c0_cacheerr: FTLB parity error\n"); | ||
1480 | } else { | ||
1481 | pr_err("Decoded c0_cacheerr: %s cache fault in %s reference.\n", | ||
1482 | reg_val & (1<<30) ? "secondary" : "primary", | ||
1483 | reg_val & (1<<31) ? "data" : "insn"); | ||
1484 | } | ||
1485 | } else { | ||
1486 | pr_err("FTLB error exception\n"); | ||
1487 | } | ||
1488 | /* Just print the cacheerr bits for now */ | ||
1489 | cache_parity_error(); | ||
1490 | } | ||
1491 | |||
1463 | /* | 1492 | /* |
1464 | * SDBBP EJTAG debug exception handler. | 1493 | * SDBBP EJTAG debug exception handler. |
1465 | * We skip the instruction and return to the next instruction. | 1494 | * We skip the instruction and return to the next instruction. |
@@ -2009,6 +2038,7 @@ void __init trap_init(void) | |||
2009 | if (cpu_has_fpu && !cpu_has_nofpuex) | 2038 | if (cpu_has_fpu && !cpu_has_nofpuex) |
2010 | set_except_vector(15, handle_fpe); | 2039 | set_except_vector(15, handle_fpe); |
2011 | 2040 | ||
2041 | set_except_vector(16, handle_ftlb); | ||
2012 | set_except_vector(22, handle_mdmx); | 2042 | set_except_vector(22, handle_mdmx); |
2013 | 2043 | ||
2014 | if (cpu_has_mcheck) | 2044 | if (cpu_has_mcheck) |
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 427dcacca586..ae4ca2450707 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c | |||
@@ -72,7 +72,7 @@ void local_flush_tlb_all(void) | |||
72 | { | 72 | { |
73 | unsigned long flags; | 73 | unsigned long flags; |
74 | unsigned long old_ctx; | 74 | unsigned long old_ctx; |
75 | int entry; | 75 | int entry, ftlbhighset; |
76 | 76 | ||
77 | ENTER_CRITICAL(flags); | 77 | ENTER_CRITICAL(flags); |
78 | /* Save old context and create impossible VPN2 value */ | 78 | /* Save old context and create impossible VPN2 value */ |
@@ -83,10 +83,21 @@ void local_flush_tlb_all(void) | |||
83 | entry = read_c0_wired(); | 83 | entry = read_c0_wired(); |
84 | 84 | ||
85 | /* Blast 'em all away. */ | 85 | /* Blast 'em all away. */ |
86 | if (cpu_has_tlbinv && current_cpu_data.tlbsize) { | 86 | if (cpu_has_tlbinv) { |
87 | write_c0_index(0); | 87 | if (current_cpu_data.tlbsizevtlb) { |
88 | mtc0_tlbw_hazard(); | 88 | write_c0_index(0); |
89 | tlbinvf(); /* invalidate VTLB */ | 89 | mtc0_tlbw_hazard(); |
90 | tlbinvf(); /* invalidate VTLB */ | ||
91 | } | ||
92 | ftlbhighset = current_cpu_data.tlbsizevtlb + | ||
93 | current_cpu_data.tlbsizeftlbsets; | ||
94 | for (entry = current_cpu_data.tlbsizevtlb; | ||
95 | entry < ftlbhighset; | ||
96 | entry++) { | ||
97 | write_c0_index(entry); | ||
98 | mtc0_tlbw_hazard(); | ||
99 | tlbinvf(); /* invalidate one FTLB set */ | ||
100 | } | ||
90 | } else { | 101 | } else { |
91 | while (entry < current_cpu_data.tlbsize) { | 102 | while (entry < current_cpu_data.tlbsize) { |
92 | /* Make sure all entries differ. */ | 103 | /* Make sure all entries differ. */ |
@@ -134,7 +145,9 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
134 | start = round_down(start, PAGE_SIZE << 1); | 145 | start = round_down(start, PAGE_SIZE << 1); |
135 | end = round_up(end, PAGE_SIZE << 1); | 146 | end = round_up(end, PAGE_SIZE << 1); |
136 | size = (end - start) >> (PAGE_SHIFT + 1); | 147 | size = (end - start) >> (PAGE_SHIFT + 1); |
137 | if (size <= current_cpu_data.tlbsize/2) { | 148 | if (size <= (current_cpu_data.tlbsizeftlbsets ? |
149 | current_cpu_data.tlbsize / 8 : | ||
150 | current_cpu_data.tlbsize / 2)) { | ||
138 | int oldpid = read_c0_entryhi(); | 151 | int oldpid = read_c0_entryhi(); |
139 | int newpid = cpu_asid(cpu, mm); | 152 | int newpid = cpu_asid(cpu, mm); |
140 | 153 | ||
@@ -173,7 +186,9 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) | |||
173 | ENTER_CRITICAL(flags); | 186 | ENTER_CRITICAL(flags); |
174 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; | 187 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; |
175 | size = (size + 1) >> 1; | 188 | size = (size + 1) >> 1; |
176 | if (size <= current_cpu_data.tlbsize / 2) { | 189 | if (size <= (current_cpu_data.tlbsizeftlbsets ? |
190 | current_cpu_data.tlbsize / 8 : | ||
191 | current_cpu_data.tlbsize / 2)) { | ||
177 | int pid = read_c0_entryhi(); | 192 | int pid = read_c0_entryhi(); |
178 | 193 | ||
179 | start &= (PAGE_MASK << 1); | 194 | start &= (PAGE_MASK << 1); |