Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

273 lines
5.3 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. xxtimer.c
  5. Abstract:
  6. This module contains the HAL's timer-related APIs
  7. Author:
  8. Eric Nelson (enelson) July 6, 2000
  9. Revision History:
  10. --*/
  11. #include "halp.h"
  12. #include "xxtimer.h"
  13. #ifdef ALLOC_PRAGMA
  14. #pragma alloc_text(INIT, HalpSetTimerFunctions)
  15. #endif
  16. //
  17. // External function prototypes
  18. //
  19. ULONG
  20. HalpAcpiTimerSetTimeIncrement(
  21. IN ULONG DesiredIncrement
  22. );
  23. VOID
  24. HalpAcpiTimerStallExecProc(
  25. IN ULONG MicroSeconds
  26. );
  27. VOID
  28. HalpAcpiTimerCalibratePerfCount(
  29. IN LONG volatile *Number,
  30. IN ULONGLONG NewCount
  31. );
  32. VOID
  33. HalpPmTimerCalibratePerfCount(
  34. IN LONG volatile *Number,
  35. IN ULONGLONG NewCount
  36. );
  37. LARGE_INTEGER
  38. HalpAcpiTimerQueryPerfCount(
  39. OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL
  40. );
  41. LARGE_INTEGER
  42. HalpPmTimerQueryPerfCount(
  43. OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL
  44. );
  45. //
  46. // Local variables
  47. //
  48. static TIMER_FUNCTIONS HalpTimerFunctions = { HalpAcpiTimerStallExecProc,
  49. #ifdef NO_PM_KEQPC
  50. HalpAcpiTimerCalibratePerfCount,
  51. HalpAcpiTimerQueryPerfCount,
  52. #else
  53. HalpPmTimerCalibratePerfCount,
  54. HalpPmTimerQueryPerfCount,
  55. #endif
  56. HalpAcpiTimerSetTimeIncrement };
  57. VOID
  58. HalpSetTimerFunctions(
  59. IN PTIMER_FUNCTIONS TimerFunctions
  60. )
  61. /*++
  62. Routine Description:
  63. This routine can be used to override the HALs ACPI-timer functions with
  64. multimedia event timer functions
  65. Arguments:
  66. TimerFunctions - Pointer to a table of timer functions
  67. Return Value:
  68. None
  69. --*/
  70. {
  71. HalpTimerFunctions = *TimerFunctions;
  72. #if 1
  73. HalpTimerFunctions.SetTimeIncrement = HalpAcpiTimerSetTimeIncrement;
  74. #endif
  75. }
  76. ULONG
  77. HalSetTimeIncrement(
  78. IN ULONG DesiredIncrement
  79. )
  80. /*++
  81. Routine Description:
  82. This routine initialize system time clock to generate an
  83. interrupt at every DesiredIncrement interval
  84. Arguments:
  85. DesiredIncrement - Desired interval between every timer tick (in
  86. 100ns unit)
  87. Return Value:
  88. The *REAL* time increment set
  89. --*/
  90. {
  91. return (HalpTimerFunctions.SetTimeIncrement)(DesiredIncrement);
  92. }
  93. VOID
  94. HalCalibratePerformanceCounter(
  95. IN LONG volatile *Number,
  96. IN ULONGLONG NewCount
  97. )
  98. /*++
  99. Routine Description:
  100. This routine resets the performance counter value for the current
  101. processor to zero, the reset is done such that the resulting value
  102. is closely synchronized with other processors in the configuration
  103. Arguments:
  104. Number - Supplies a pointer to count of the number of processors in
  105. the configuration
  106. NewCount - Supplies the value to synchronize the counter too
  107. Return Value:
  108. None
  109. --*/
  110. {
  111. (HalpTimerFunctions.CalibratePerfCount)(Number, NewCount);
  112. }
  113. #ifdef TIMER_DBG
  114. static ULONG HalpQueryPerfLogIndex = 0;
  115. #define MAX_QUERY_LOG 10
  116. static LARGE_INTEGER HalpQueryPerfLog[MAX_QUERY_LOG];
  117. static LARGE_INTEGER HalpQueryPerfTSLog[MAX_QUERY_LOG];
  118. #endif
  119. LARGE_INTEGER
  120. KeQueryPerformanceCounter(
  121. OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL
  122. )
  123. /*++
  124. Routine Description:
  125. This routine returns current 64-bit performance counter and,
  126. optionally, the Performance Frequency
  127. N.B. The performace counter returned by this routine is
  128. not necessary the value when this routine is just entered,
  129. The value returned is actually the counter value at any point
  130. between the routine is entered and is exited
  131. Arguments:
  132. PerformanceFrequency - optionally, supplies the address of a
  133. variable to receive the performance counter
  134. frequency
  135. Return Value:
  136. Current value of the performance counter will be returned
  137. --*/
  138. {
  139. #ifdef TIMER_DBG
  140. ULONG Index;
  141. ULONG TSCounterHigh;
  142. ULONG TSCounterLow;
  143. KIRQL Irql;
  144. ULONG flags;
  145. extern BOOLEAN HalInitialized;
  146. _asm {
  147. pushfd
  148. pop eax
  149. mov flags, eax
  150. cli
  151. }
  152. Index = HalpQueryPerfLogIndex % MAX_QUERY_LOG;
  153. HalpQueryPerfLogIndex++;
  154. HalpQueryPerfLog[Index] =
  155. (HalpTimerFunctions.QueryPerfCount)(PerformanceFrequency);
  156. _asm { rdtsc
  157. mov TSCounterLow, eax
  158. mov TSCounterHigh, edx };
  159. HalpQueryPerfTSLog[Index].HighPart = TSCounterHigh;
  160. HalpQueryPerfTSLog[Index].LowPart = TSCounterLow;
  161. if (HalInitialized) {
  162. ULONG PriorIndex;
  163. PriorIndex = (Index == 0) ? MAX_QUERY_LOG - 1: Index - 1;
  164. if (HalpQueryPerfLog[Index].QuadPart <
  165. HalpQueryPerfLog[PriorIndex].QuadPart) {
  166. ASSERT(FALSE);
  167. }
  168. }
  169. _asm {
  170. mov eax, flags
  171. push eax
  172. popfd
  173. }
  174. return HalpQueryPerfLog[Index];
  175. #else
  176. return (HalpTimerFunctions.QueryPerfCount)(PerformanceFrequency);
  177. #endif
  178. }
  179. VOID
  180. KeStallExecutionProcessor(
  181. IN ULONG MicroSeconds
  182. )
  183. /*++
  184. Routine Description:
  185. This function stalls execution for the specified number of microseconds
  186. Arguments:
  187. MicroSeconds - Supplies the number of microseconds that execution is to be
  188. stalled
  189. Return Value:
  190. None
  191. --*/
  192. {
  193. (HalpTimerFunctions.StallExecProc)(MicroSeconds);
  194. }