/* * Hazards * * From the IDT errata for the QED RM5230 (Nevada), processor revision 1.0: * 2. A timing hazard exists for the TLBP instruction. * * stalling_instruction * TLBP * * The JTLB is being read for the TLBP throughout the stall generated by the * previous instruction. This is not really correct as the stalling instruction * can modify the address used to access the JTLB. The failure symptom is that * the TLBP instruction will use an address created for the stalling instruction * and not the address held in C0_ENHI and thus report the wrong results. * * The software work-around is to not allow the instruction preceding the TLBP * to stall - make it an NOP or some other instruction guaranteed not to stall. * * Errata 2 will not be fixed. This errata is also on the R5000. * * As if we MIPS hackers wouldn't know how to nop pipelines happy ... */ static __init void __attribute__((unused)) build_tlb_probe_entry(u32 **p) { switch (current_cpu_type()) { /* Found by experiment: R4600 v2.0 needs this, too. */ case CPU_R4600: case CPU_R5000: case CPU_R5000A: case CPU_NEVADA: uasm_i_nop(p); uasm_i_tlbp(p); break; default: uasm_i_tlbp(p); break; } }
/* * Hazards * * From the IDT errata for the QED RM5230 (Nevada), processor revision 1.0: * 2. A timing hazard exists for the TLBP instruction. * * stalling_instruction * TLBP * * The JTLB is being read for the TLBP throughout the stall generated by the * previous instruction. This is not really correct as the stalling instruction * can modify the address used to access the JTLB. The failure symptom is that * the TLBP instruction will use an address created for the stalling instruction * and not the address held in C0_ENHI and thus report the wrong results. * * The software work-around is to not allow the instruction preceding the TLBP * to stall - make it an NOP or some other instruction guaranteed not to stall. * * Errata 2 will not be fixed. This errata is also on the R5000. * * As if we MIPS hackers wouldn't know how to nop pipelines happy ... */ static void __cpuinit __maybe_unused build_tlb_probe_entry(u32 **p) { switch (current_cpu_type()) { /* Found by experiment: R4600 v2.0/R4700 needs this, too. */ case CPU_R4600: case CPU_R4700: case CPU_R5000: case CPU_R5000A: case CPU_NEVADA: uasm_i_nop(p); uasm_i_tlbp(p); break; default: uasm_i_tlbp(p); break; } }
static void __cpuinit build_r3000_tlbchange_handler_head(u32 **p, unsigned int pte, unsigned int ptr) { long pgdc = (long)pgd_current; uasm_i_mfc0(p, pte, C0_BADVADDR); uasm_i_lui(p, ptr, uasm_rel_hi(pgdc)); /* cp0 delay */ uasm_i_lw(p, ptr, uasm_rel_lo(pgdc), ptr); uasm_i_srl(p, pte, pte, 22); /* load delay */ uasm_i_sll(p, pte, pte, 2); uasm_i_addu(p, ptr, ptr, pte); uasm_i_mfc0(p, pte, C0_CONTEXT); uasm_i_lw(p, ptr, 0, ptr); /* cp0 delay */ uasm_i_andi(p, pte, pte, 0xffc); /* load delay */ uasm_i_addu(p, ptr, ptr, pte); uasm_i_lw(p, pte, 0, ptr); uasm_i_tlbp(p); /* load delay */ }