barrier.h 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. * Copyright 2010 Tilera Corporation. All Rights Reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation, version 2.
  7. *
  8. * This program is distributed in the hope that it will be useful, but
  9. * WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  11. * NON INFRINGEMENT. See the GNU General Public License for
  12. * more details.
  13. */
  14. #ifndef _ASM_TILE_BARRIER_H
  15. #define _ASM_TILE_BARRIER_H
  16. #ifndef __ASSEMBLY__
  17. #include <linux/types.h>
  18. #include <arch/chip.h>
  19. #include <arch/spr_def.h>
  20. #include <asm/timex.h>
  21. #define __sync() __insn_mf()
  22. #include <hv/syscall_public.h>
  23. /*
  24. * Issue an uncacheable load to each memory controller, then
  25. * wait until those loads have completed.
  26. */
  27. static inline void __mb_incoherent(void)
  28. {
  29. long clobber_r10;
  30. asm volatile("swint2"
  31. : "=R10" (clobber_r10)
  32. : "R10" (HV_SYS_fence_incoherent)
  33. : "r0", "r1", "r2", "r3", "r4",
  34. "r5", "r6", "r7", "r8", "r9",
  35. "r11", "r12", "r13", "r14",
  36. "r15", "r16", "r17", "r18", "r19",
  37. "r20", "r21", "r22", "r23", "r24",
  38. "r25", "r26", "r27", "r28", "r29");
  39. }
  40. /* Fence to guarantee visibility of stores to incoherent memory. */
  41. static inline void
  42. mb_incoherent(void)
  43. {
  44. __insn_mf();
  45. {
  46. #if CHIP_HAS_TILE_WRITE_PENDING()
  47. const unsigned long WRITE_TIMEOUT_CYCLES = 400;
  48. unsigned long start = get_cycles_low();
  49. do {
  50. if (__insn_mfspr(SPR_TILE_WRITE_PENDING) == 0)
  51. return;
  52. } while ((get_cycles_low() - start) < WRITE_TIMEOUT_CYCLES);
  53. #endif /* CHIP_HAS_TILE_WRITE_PENDING() */
  54. (void) __mb_incoherent();
  55. }
  56. }
  57. #define fast_wmb() __sync()
  58. #define fast_rmb() __sync()
  59. #define fast_mb() __sync()
  60. #define fast_iob() mb_incoherent()
  61. #define wmb() fast_wmb()
  62. #define rmb() fast_rmb()
  63. #define mb() fast_mb()
  64. #define iob() fast_iob()
  65. #ifndef __tilegx__ /* 32 bit */
  66. /*
  67. * We need to barrier before modifying the word, since the _atomic_xxx()
  68. * routines just tns the lock and then read/modify/write of the word.
  69. * But after the word is updated, the routine issues an "mf" before returning,
  70. * and since it's a function call, we don't even need a compiler barrier.
  71. */
  72. #define smp_mb__before_atomic() smp_mb()
  73. #define smp_mb__after_atomic() do { } while (0)
  74. #else /* 64 bit */
  75. #define smp_mb__before_atomic() smp_mb()
  76. #define smp_mb__after_atomic() smp_mb()
  77. #endif
  78. #include <asm-generic/barrier.h>
  79. #endif /* !__ASSEMBLY__ */
  80. #endif /* _ASM_TILE_BARRIER_H */