diff options
Diffstat (limited to 'arch/mips/mm/tlbex.c')
| -rw-r--r-- | arch/mips/mm/tlbex.c | 56 |
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) | |||
| 167 | UASM_L_LA(_leave) | 167 | UASM_L_LA(_leave) |
| 168 | UASM_L_LA(_vmalloc) | 168 | UASM_L_LA(_vmalloc) |
| 169 | UASM_L_LA(_vmalloc_done) | 169 | UASM_L_LA(_vmalloc_done) |
| 170 | UASM_L_LA(_tlbw_hazard) | 170 | /* _tlbw_hazard_x is handled differently. */ |
| 171 | UASM_L_LA(_split) | 171 | UASM_L_LA(_split) |
| 172 | UASM_L_LA(_tlbl_goaround1) | 172 | UASM_L_LA(_tlbl_goaround1) |
| 173 | UASM_L_LA(_tlbl_goaround2) | 173 | UASM_L_LA(_tlbl_goaround2) |
| @@ -181,6 +181,30 @@ UASM_L_LA(_large_segbits_fault) | |||
| 181 | UASM_L_LA(_tlb_huge_update) | 181 | UASM_L_LA(_tlb_huge_update) |
| 182 | #endif | 182 | #endif |
| 183 | 183 | ||
| 184 | static int __cpuinitdata hazard_instance; | ||
| 185 | |||
| 186 | static 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 | |||
| 197 | static 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); |
