Source code of Windows XP (NT5)
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.

191 lines
3.3 KiB

  1. /*++
  2. Copyright (c) 1995 Intel Corporation
  3. Module Name:
  4. i64perfc.c copied from simperfc.c
  5. Abstract:
  6. This module implements the routines to support performance counters.
  7. Author:
  8. 14-Apr-1995
  9. Environment:
  10. Kernel mode
  11. Revision History:
  12. --*/
  13. #include "halp.h"
  14. #include "eisa.h"
  15. //
  16. // Define and initialize the 64-bit count of total system cycles used
  17. // as the performance counter.
  18. //
  19. ULONGLONG HalpCycleCount = 0;
  20. BOOLEAN HalpITCCalibrate = TRUE; // XXTF
  21. extern ULONGLONG HalpITCFrequency;
  22. extern ULONGLONG HalpClockCount;
  23. #if 0
  24. VOID
  25. HalpCheckPerformanceCounter(
  26. VOID
  27. )
  28. Routine Description:
  29. This function is called every system clock interrupt in order to
  30. check for wrap of the performance counter. The function must handle
  31. a wrap if it is detected.
  32. N.B. - This function was from the Alpha HAL.
  33. This function must be called at CLOCK_LEVEL.
  34. Arguments:
  35. None.
  36. Return Value:
  37. None.
  38. {
  39. return;
  40. } // HalpCheckPerformanceCounter()
  41. #endif // 0
  42. LARGE_INTEGER
  43. KeQueryPerformanceCounter (
  44. OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL
  45. )
  46. /*++
  47. Routine Description:
  48. This routine returns current 64-bit performance counter and,
  49. optionally, the Performance Frequency.
  50. Arguments:
  51. PerformanceFrequency - optionally, supplies the address
  52. of a variable to receive the performance counter frequency.
  53. Return Value:
  54. Current value of the performance counter will be returned.
  55. --*/
  56. {
  57. LARGE_INTEGER result;
  58. #ifndef DISABLE_ITC_WORKAROUND
  59. result.QuadPart = __getReg(CV_IA64_ApITC);
  60. while ((result.QuadPart & 0xFFFFFFFF) == 0xFFFFFFFF) {
  61. result.QuadPart = __getReg(CV_IA64_ApITC);
  62. }
  63. #else
  64. result.QuadPart = __getReg(CV_IA64_ApITC);
  65. #endif
  66. if (ARGUMENT_PRESENT(PerformanceFrequency)) {
  67. PerformanceFrequency->QuadPart = HalpITCFrequency;
  68. }
  69. return result;
  70. } // KeQueryPerformanceCounter()
  71. VOID
  72. HalCalibratePerformanceCounter (
  73. IN LONG volatile *Number,
  74. IN ULONGLONG NewCount
  75. )
  76. /*++
  77. Routine Description:
  78. This routine sets the performance counter value for the current
  79. processor to the specified valueo.
  80. The reset is done such that the resulting value is closely
  81. synchronized with other processors in the configuration.
  82. Arguments:
  83. Number - Supplies a pointer to count of the number of processors in
  84. the configuration.
  85. Return Value:
  86. None.
  87. --*/
  88. {
  89. KSPIN_LOCK Lock;
  90. KIRQL OldIrql;
  91. if ( HalpITCCalibrate ) {
  92. //
  93. // Raise IRQL to HIGH_LEVEL, decrement the number of processors, and
  94. // wait until the number is zero.
  95. //
  96. KeInitializeSpinLock(&Lock);
  97. KeRaiseIrql(HIGH_LEVEL, &OldIrql);
  98. PCR->HalReserved[CURRENT_ITM_VALUE_INDEX] = NewCount + HalpClockCount;
  99. HalpWriteITM( PCR->HalReserved[CURRENT_ITM_VALUE_INDEX] );
  100. if (ExInterlockedDecrementLong((PLONG)Number, &Lock) != RESULT_ZERO) {
  101. do {
  102. } while (*((LONG volatile *)Number) !=0);
  103. }
  104. //
  105. // Write the compare register with defined current ITM value,
  106. // and set the performance counter for the current processor
  107. // with the passed count.
  108. //
  109. HalpWriteITC( NewCount );
  110. //
  111. // Restore IRQL to its previous value and return.
  112. //
  113. KeLowerIrql(OldIrql);
  114. }
  115. else {
  116. *Number = 0;
  117. }
  118. return;
  119. } // HalCalibratePerformanceCounter()