delay_64.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /*
  2. * Precise Delay Loops for x86-64
  3. *
  4. * Copyright (C) 1993 Linus Torvalds
  5. * Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
  6. *
  7. * The __delay function must _NOT_ be inlined as its execution time
  8. * depends wildly on alignment on many x86 processors.
  9. */
  10. #include <linux/module.h>
  11. #include <linux/sched.h>
  12. #include <linux/timex.h>
  13. #include <linux/preempt.h>
  14. #include <linux/delay.h>
  15. #include <linux/init.h>
  16. #include <asm/delay.h>
  17. #include <asm/msr.h>
  18. #ifdef CONFIG_SMP
  19. #include <asm/smp.h>
  20. #endif
  21. /* simple loop based delay: */
  22. static void delay_loop(unsigned long loops)
  23. {
  24. asm volatile(
  25. " test %0,%0 \n"
  26. " jz 3f \n"
  27. " jmp 1f \n"
  28. ".align 16 \n"
  29. "1: jmp 2f \n"
  30. ".align 16 \n"
  31. "2: dec %0 \n"
  32. " jnz 2b \n"
  33. "3: dec %0 \n"
  34. : /* we don't need output */
  35. :"a" (loops)
  36. );
  37. }
  38. static void delay_tsc(unsigned long loops)
  39. {
  40. unsigned bclock, now;
  41. int cpu;
  42. preempt_disable();
  43. cpu = smp_processor_id();
  44. rdtscl(bclock);
  45. for (;;) {
  46. rdtscl(now);
  47. if ((now - bclock) >= loops)
  48. break;
  49. /* Allow RT tasks to run */
  50. preempt_enable();
  51. rep_nop();
  52. preempt_disable();
  53. /*
  54. * It is possible that we moved to another CPU, and
  55. * since TSC's are per-cpu we need to calculate
  56. * that. The delay must guarantee that we wait "at
  57. * least" the amount of time. Being moved to another
  58. * CPU could make the wait longer but we just need to
  59. * make sure we waited long enough. Rebalance the
  60. * counter for this CPU.
  61. */
  62. if (unlikely(cpu != smp_processor_id())) {
  63. loops -= (now - bclock);
  64. cpu = smp_processor_id();
  65. rdtscl(bclock);
  66. }
  67. }
  68. preempt_enable();
  69. }
  70. static void (*delay_fn)(unsigned long) = delay_loop;
  71. void use_tsc_delay(void)
  72. {
  73. delay_fn = delay_tsc;
  74. }
  75. int __devinit read_current_timer(unsigned long *timer_value)
  76. {
  77. if (delay_fn == delay_tsc) {
  78. rdtscll(*timer_value);
  79. return 0;
  80. }
  81. return -1;
  82. }
  83. void __delay(unsigned long loops)
  84. {
  85. delay_fn(loops);
  86. }
  87. EXPORT_SYMBOL(__delay);
  88. inline void __const_udelay(unsigned long xloops)
  89. {
  90. int d0;
  91. xloops *= 4;
  92. __asm__("mull %%edx"
  93. :"=d" (xloops), "=&a" (d0)
  94. :"1" (xloops), "0"
  95. (cpu_data(raw_smp_processor_id()).loops_per_jiffy * (HZ/4)));
  96. __delay(++xloops);
  97. }
  98. EXPORT_SYMBOL(__const_udelay);
  99. void __udelay(unsigned long usecs)
  100. {
  101. __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */
  102. }
  103. EXPORT_SYMBOL(__udelay);
  104. void __ndelay(unsigned long nsecs)
  105. {
  106. __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */
  107. }
  108. EXPORT_SYMBOL(__ndelay);