aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm/tlbex.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/mm/tlbex.c')
-rw-r--r--arch/mips/mm/tlbex.c56
1 files changed, 38 insertions, 18 deletions
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 658a520364ce..2833dcb67b5a 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -148,8 +148,8 @@ enum label_id {
148 label_leave, 148 label_leave,
149 label_vmalloc, 149 label_vmalloc,
150 label_vmalloc_done, 150 label_vmalloc_done,
151 label_tlbw_hazard, 151 label_tlbw_hazard_0,
152 label_split, 152 label_split = label_tlbw_hazard_0 + 8,
153 label_tlbl_goaround1, 153 label_tlbl_goaround1,
154 label_tlbl_goaround2, 154 label_tlbl_goaround2,
155 label_nopage_tlbl, 155 label_nopage_tlbl,
@@ -167,7 +167,7 @@ UASM_L_LA(_second_part)
167UASM_L_LA(_leave) 167UASM_L_LA(_leave)
168UASM_L_LA(_vmalloc) 168UASM_L_LA(_vmalloc)
169UASM_L_LA(_vmalloc_done) 169UASM_L_LA(_vmalloc_done)
170UASM_L_LA(_tlbw_hazard) 170/* _tlbw_hazard_x is handled differently. */
171UASM_L_LA(_split) 171UASM_L_LA(_split)
172UASM_L_LA(_tlbl_goaround1) 172UASM_L_LA(_tlbl_goaround1)
173UASM_L_LA(_tlbl_goaround2) 173UASM_L_LA(_tlbl_goaround2)
@@ -181,6 +181,30 @@ UASM_L_LA(_large_segbits_fault)
181UASM_L_LA(_tlb_huge_update) 181UASM_L_LA(_tlb_huge_update)
182#endif 182#endif
183 183
184static int __cpuinitdata hazard_instance;
185
186static void uasm_bgezl_hazard(u32 **p, struct uasm_reloc **r, int instance)
187{
188 switch (instance) {
189 case 0 ... 7:
190 uasm_il_bgezl(p, r, 0, label_tlbw_hazard_0 + instance);
191 return;
192 default:
193 BUG();
194 }
195}
196
197static void uasm_bgezl_label(struct uasm_label **l, u32 **p, int instance)
198{
199 switch (instance) {
200 case 0 ... 7:
201 uasm_build_label(l, *p, label_tlbw_hazard_0 + instance);
202 break;
203 default:
204 BUG();
205 }
206}
207
184/* 208/*
185 * For debug purposes. 209 * For debug purposes.
186 */ 210 */
@@ -478,21 +502,28 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
478 * This branch uses up a mtc0 hazard nop slot and saves 502 * This branch uses up a mtc0 hazard nop slot and saves
479 * two nops after the tlbw instruction. 503 * two nops after the tlbw instruction.
480 */ 504 */
481 uasm_il_bgezl(p, r, 0, label_tlbw_hazard); 505 uasm_bgezl_hazard(p, r, hazard_instance);
482 tlbw(p); 506 tlbw(p);
483 uasm_l_tlbw_hazard(l, *p); 507 uasm_bgezl_label(l, p, hazard_instance);
508 hazard_instance++;
484 uasm_i_nop(p); 509 uasm_i_nop(p);
485 break; 510 break;
486 511
487 case CPU_R4600: 512 case CPU_R4600:
488 case CPU_R4700: 513 case CPU_R4700:
489 case CPU_R5000:
490 case CPU_R5000A:
491 uasm_i_nop(p); 514 uasm_i_nop(p);
492 tlbw(p); 515 tlbw(p);
493 uasm_i_nop(p); 516 uasm_i_nop(p);
494 break; 517 break;
495 518
519 case CPU_R5000:
520 case CPU_R5000A:
521 case CPU_NEVADA:
522 uasm_i_nop(p); /* QED specifies 2 nops hazard */
523 uasm_i_nop(p); /* QED specifies 2 nops hazard */
524 tlbw(p);
525 break;
526
496 case CPU_R4300: 527 case CPU_R4300:
497 case CPU_5KC: 528 case CPU_5KC:
498 case CPU_TX49XX: 529 case CPU_TX49XX:
@@ -526,17 +557,6 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
526 tlbw(p); 557 tlbw(p);
527 break; 558 break;
528 559
529 case CPU_NEVADA:
530 uasm_i_nop(p); /* QED specifies 2 nops hazard */
531 /*
532 * This branch uses up a mtc0 hazard nop slot and saves
533 * a nop after the tlbw instruction.
534 */
535 uasm_il_bgezl(p, r, 0, label_tlbw_hazard);
536 tlbw(p);
537 uasm_l_tlbw_hazard(l, *p);
538 break;
539
540 case CPU_RM7000: 560 case CPU_RM7000:
541 uasm_i_nop(p); 561 uasm_i_nop(p);
542 uasm_i_nop(p); 562 uasm_i_nop(p);