1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * Copyright (C) 2003, 04, 07 Ralf Baechle <ralf@linux-mips.org> 7 * Copyright (C) MIPS Technologies, Inc. 8 * written by Ralf Baechle <ralf@linux-mips.org> 9 */ 10#ifndef _ASM_HAZARDS_H 11#define _ASM_HAZARDS_H 12 13#include <linux/stringify.h> 14 15#define ___ssnop \ 16 sll $0, $0, 1 17 18#define ___ehb \ 19 sll $0, $0, 3 20 21/* 22 * TLB hazards 23 */ 24#if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_CPU_CAVIUM_OCTEON) 25 26/* 27 * MIPSR2 defines ehb for hazard avoidance 28 */ 29 30#define __mtc0_tlbw_hazard \ 31 ___ehb 32 33#define __tlbw_use_hazard \ 34 ___ehb 35 36#define __tlb_probe_hazard \ 37 ___ehb 38 39#define __irq_enable_hazard \ 40 ___ehb 41 42#define __irq_disable_hazard \ 43 ___ehb 44 45#define __back_to_back_c0_hazard \ 46 ___ehb 47 48/* 49 * gcc has a tradition of misscompiling the previous construct using the 50 * address of a label as argument to inline assembler. Gas otoh has the 51 * annoying difference between la and dla which are only usable for 32-bit 52 * rsp. 64-bit code, so can't be used without conditional compilation. 53 * The alterantive is switching the assembler to 64-bit code which happens 54 * to work right even for 32-bit code ... 55 */ 56#define instruction_hazard() \ 57do { \ 58 unsigned long tmp; \ 59 \ 60 __asm__ __volatile__( \ 61 " .set mips64r2 \n" \ 62 " dla %0, 1f \n" \ 63 " jr.hb %0 \n" \ 64 " .set mips0 \n" \ 65 "1: \n" \ 66 : "=r" (tmp)); \ 67} while (0) 68 69#elif (defined(CONFIG_CPU_MIPSR1) && !defined(CONFIG_MIPS_ALCHEMY)) || \ 70 defined(CONFIG_CPU_BMIPS) 71 72/* 73 * These are slightly complicated by the fact that we guarantee R1 kernels to 74 * run fine on R2 processors. 75 */ 76 77#define __mtc0_tlbw_hazard \ 78 ___ssnop; \ 79 ___ssnop; \ 80 ___ehb 81 82#define __tlbw_use_hazard \ 83 ___ssnop; \ 84 ___ssnop; \ 85 ___ssnop; \ 86 ___ehb 87 88#define __tlb_probe_hazard \ 89 ___ssnop; \ 90 ___ssnop; \ 91 ___ssnop; \ 92 ___ehb 93 94#define __irq_enable_hazard \ 95 ___ssnop; \ 96 ___ssnop; \ 97 ___ssnop; \ 98 ___ehb 99 100#define __irq_disable_hazard \ 101 ___ssnop; \ 102 ___ssnop; \ 103 ___ssnop; \ 104 ___ehb 105 106#define __back_to_back_c0_hazard \ 107 ___ssnop; \ 108 ___ssnop; \ 109 ___ssnop; \ 110 ___ehb 111 112/* 113 * gcc has a tradition of misscompiling the previous construct using the 114 * address of a label as argument to inline assembler. Gas otoh has the 115 * annoying difference between la and dla which are only usable for 32-bit 116 * rsp. 64-bit code, so can't be used without conditional compilation. 117 * The alterantive is switching the assembler to 64-bit code which happens 118 * to work right even for 32-bit code ... 119 */ 120#define __instruction_hazard() \ 121do { \ 122 unsigned long tmp; \ 123 \ 124 __asm__ __volatile__( \ 125 " .set mips64r2 \n" \ 126 " dla %0, 1f \n" \ 127 " jr.hb %0 \n" \ 128 " .set mips0 \n" \ 129 "1: \n" \ 130 : "=r" (tmp)); \ 131} while (0) 132 133#define instruction_hazard() \ 134do { \ 135 if (cpu_has_mips_r2) \ 136 __instruction_hazard(); \ 137} while (0) 138 139#elif defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \ 140 defined(CONFIG_CPU_LOONGSON2) || defined(CONFIG_CPU_R10000) || \ 141 defined(CONFIG_CPU_R5500) || defined(CONFIG_CPU_XLR) 142 143/* 144 * R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer. 145 */ 146 147#define __mtc0_tlbw_hazard 148 149#define __tlbw_use_hazard 150 151#define __tlb_probe_hazard 152 153#define __irq_enable_hazard 154 155#define __irq_disable_hazard 156 157#define __back_to_back_c0_hazard 158 159#define instruction_hazard() do { } while (0) 160 161#elif defined(CONFIG_CPU_SB1) 162 163/* 164 * Mostly like R4000 for historic reasons 165 */ 166#define __mtc0_tlbw_hazard 167 168#define __tlbw_use_hazard 169 170#define __tlb_probe_hazard 171 172#define __irq_enable_hazard 173 174#define __irq_disable_hazard \ 175 ___ssnop; \ 176 ___ssnop; \ 177 ___ssnop 178 179#define __back_to_back_c0_hazard 180 181#define instruction_hazard() do { } while (0) 182 183#else 184 185/* 186 * Finally the catchall case for all other processors including R4000, R4400, 187 * R4600, R4700, R5000, RM7000, NEC VR41xx etc. 188 * 189 * The taken branch will result in a two cycle penalty for the two killed 190 * instructions on R4000 / R4400. Other processors only have a single cycle 191 * hazard so this is nice trick to have an optimal code for a range of 192 * processors. 193 */ 194#define __mtc0_tlbw_hazard \ 195 nop; \ 196 nop 197 198#define __tlbw_use_hazard \ 199 nop; \ 200 nop; \ 201 nop 202 203#define __tlb_probe_hazard \ 204 nop; \ 205 nop; \ 206 nop 207 208#define __irq_enable_hazard \ 209 ___ssnop; \ 210 ___ssnop; \ 211 ___ssnop 212 213#define __irq_disable_hazard \ 214 nop; \ 215 nop; \ 216 nop 217 218#define __back_to_back_c0_hazard \ 219 ___ssnop; \ 220 ___ssnop; \ 221 ___ssnop 222 223#define instruction_hazard() do { } while (0) 224 225#endif 226 227 228/* FPU hazards */ 229 230#if defined(CONFIG_CPU_SB1) 231 232#define __enable_fpu_hazard \ 233 .set push; \ 234 .set mips64; \ 235 .set noreorder; \ 236 ___ssnop; \ 237 bnezl $0, .+4; \ 238 ___ssnop; \ 239 .set pop 240 241#define __disable_fpu_hazard 242 243#elif defined(CONFIG_CPU_MIPSR2) 244 245#define __enable_fpu_hazard \ 246 ___ehb 247 248#define __disable_fpu_hazard \ 249 ___ehb 250 251#else 252 253#define __enable_fpu_hazard \ 254 nop; \ 255 nop; \ 256 nop; \ 257 nop 258 259#define __disable_fpu_hazard \ 260 ___ehb 261 262#endif 263 264#ifdef __ASSEMBLY__ 265 266#define _ssnop ___ssnop 267#define _ehb ___ehb 268#define mtc0_tlbw_hazard __mtc0_tlbw_hazard 269#define tlbw_use_hazard __tlbw_use_hazard 270#define tlb_probe_hazard __tlb_probe_hazard 271#define irq_enable_hazard __irq_enable_hazard 272#define irq_disable_hazard __irq_disable_hazard 273#define back_to_back_c0_hazard __back_to_back_c0_hazard 274#define enable_fpu_hazard __enable_fpu_hazard 275#define disable_fpu_hazard __disable_fpu_hazard 276 277#else 278 279#define _ssnop() \ 280do { \ 281 __asm__ __volatile__( \ 282 __stringify(___ssnop) \ 283 ); \ 284} while (0) 285 286#define _ehb() \ 287do { \ 288 __asm__ __volatile__( \ 289 __stringify(___ehb) \ 290 ); \ 291} while (0) 292 293 294#define mtc0_tlbw_hazard() \ 295do { \ 296 __asm__ __volatile__( \ 297 __stringify(__mtc0_tlbw_hazard) \ 298 ); \ 299} while (0) 300 301 302#define tlbw_use_hazard() \ 303do { \ 304 __asm__ __volatile__( \ 305 __stringify(__tlbw_use_hazard) \ 306 ); \ 307} while (0) 308 309 310#define tlb_probe_hazard() \ 311do { \ 312 __asm__ __volatile__( \ 313 __stringify(__tlb_probe_hazard) \ 314 ); \ 315} while (0) 316 317 318#define irq_enable_hazard() \ 319do { \ 320 __asm__ __volatile__( \ 321 __stringify(__irq_enable_hazard) \ 322 ); \ 323} while (0) 324 325 326#define irq_disable_hazard() \ 327do { \ 328 __asm__ __volatile__( \ 329 __stringify(__irq_disable_hazard) \ 330 ); \ 331} while (0) 332 333 334#define back_to_back_c0_hazard() \ 335do { \ 336 __asm__ __volatile__( \ 337 __stringify(__back_to_back_c0_hazard) \ 338 ); \ 339} while (0) 340 341 342#define enable_fpu_hazard() \ 343do { \ 344 __asm__ __volatile__( \ 345 __stringify(__enable_fpu_hazard) \ 346 ); \ 347} while (0) 348 349 350#define disable_fpu_hazard() \ 351do { \ 352 __asm__ __volatile__( \ 353 __stringify(__disable_fpu_hazard) \ 354 ); \ 355} while (0) 356 357/* 358 * MIPS R2 instruction hazard barrier. Needs to be called as a subroutine. 359 */ 360extern void mips_ihb(void); 361 362#endif /* __ASSEMBLY__ */ 363 364#endif /* _ASM_HAZARDS_H */ 365