delay.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:1k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Precise Delay Loops for i386
  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. The additional
  9.  * jump magic is needed to get the timing stable on all the CPU's
  10.  * we have to worry about.
  11.  */
  12. #include <linux/config.h>
  13. #include <linux/sched.h>
  14. #include <linux/delay.h>
  15. #include <asm/processor.h>
  16. #include <asm/delay.h>
  17. #ifdef CONFIG_SMP
  18. #include <asm/smp.h>
  19. #endif
  20. int x86_udelay_tsc = 0; /* Delay via TSC */
  21. /*
  22.  * Do a udelay using the TSC for any CPU that happens
  23.  * to have one that we trust.
  24.  */
  25. static void __rdtsc_delay(unsigned long loops)
  26. {
  27. unsigned long bclock, now;
  28. rdtscl(bclock);
  29. do
  30. {
  31. rep_nop();
  32. rdtscl(now);
  33. } while ((now-bclock) < loops);
  34. }
  35. /*
  36.  * Non TSC based delay loop for 386, 486, MediaGX
  37.  */
  38.  
  39. static void __loop_delay(unsigned long loops)
  40. {
  41. int d0;
  42. __asm__ __volatile__(
  43. "tjmp 1fn"
  44. ".align 16n"
  45. "1:tjmp 2fn"
  46. ".align 16n"
  47. "2:tdecl %0ntjns 2b"
  48. :"=&a" (d0)
  49. :"0" (loops));
  50. }
  51. void __delay(unsigned long loops)
  52. {
  53. if (x86_udelay_tsc)
  54. __rdtsc_delay(loops);
  55. else
  56. __loop_delay(loops);
  57. }
  58. inline void __const_udelay(unsigned long xloops)
  59. {
  60. int d0;
  61. __asm__("mull %0"
  62. :"=d" (xloops), "=&a" (d0)
  63. :"1" (xloops),"0" (current_cpu_data.loops_per_jiffy));
  64.         __delay(xloops * HZ);
  65. }
  66. void __udelay(unsigned long usecs)
  67. {
  68. __const_udelay(usecs * 0x000010c6);  /* 2**32 / 1000000 */
  69. }