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.

332 lines
8.1 KiB

  1. title "Query Performace Counter"
  2. ;++
  3. ;
  4. ; Copyright (c) 1989 Microsoft Corporation
  5. ;
  6. ; Module Name:
  7. ;
  8. ; mpclksup.asm
  9. ;
  10. ; Abstract:
  11. ;
  12. ; This module implements the code necessary to do
  13. ; QueryPerformaceCounter the MPS way.
  14. ;
  15. ; Author:
  16. ;
  17. ; Shie-Lin Tzong (shielint) 12-Jan-1990
  18. ;
  19. ; Environment:
  20. ;
  21. ; Kernel mode only.
  22. ;
  23. ; Revision History:
  24. ;
  25. ; bryanwi 20-Sep-90
  26. ; jakeo 12-16-97 -- moved code from mpprofil.asm
  27. ;
  28. ;--
  29. .586p
  30. .xlist
  31. include hal386.inc
  32. include callconv.inc ; calling convention macros
  33. include i386\kimacro.inc
  34. include mac386.inc
  35. include apic.inc
  36. include ntapic.inc
  37. include i386\mp8254.inc
  38. .list
  39. EXTRNP _HalpAcquireSystemHardwareSpinLock,0
  40. EXTRNP _HalpReleaseSystemHardwareSpinLock,0
  41. extrn _HalpUse8254:BYTE
  42. _DATA SEGMENT DWORD PUBLIC 'DATA'
  43. ALIGN dword
  44. ;
  45. ; counters for the performance counter
  46. ;
  47. public _HalpPerfCounterLow, _HalpPerfCounterHigh
  48. public _HalpLastPerfCounterLow, _HalpLastPerfCounterHigh
  49. _HalpPerfCounterLow dd 0
  50. _HalpPerfCounterHigh dd 0
  51. _HalpLastPerfCounterLow dd 0
  52. _HalpLastPerfCounterHigh dd 0
  53. _DATA ends
  54. _TEXT SEGMENT DWORD PUBLIC 'CODE'
  55. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  56. page ,132
  57. subttl "Query Performance Counter"
  58. ;++
  59. ;
  60. ; LARGE_INTEGER
  61. ; KeQueryPerformanceCounter (
  62. ; OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL
  63. ; )
  64. ;
  65. ; Routine Description:
  66. ;
  67. ; This routine returns current 64-bit performance counter and,
  68. ; optionally, the Performance Frequency.
  69. ;
  70. ; Note this routine can NOT be called at Profiling interrupt
  71. ; service routine. Because this routine depends on IRR0 to determine
  72. ; the actual count.
  73. ;
  74. ; Also note that the performace counter returned by this routine
  75. ; is not necessary the value when this routine is just entered.
  76. ; The value returned is actually the counter value at any point
  77. ; between the routine is entered and is exited.
  78. ;
  79. ; Arguments:
  80. ;
  81. ; PerformanceFrequency [TOS+4] - optionally, supplies the address
  82. ; of a variable to receive the performance counter frequency.
  83. ;
  84. ; Return Value:
  85. ;
  86. ; Current value of the performance counter will be returned.
  87. ;
  88. ;--
  89. ;
  90. ; Parameter definitions
  91. ;
  92. KqpcFrequency EQU [esp+4] ; User supplied Performance Frequence
  93. ifdef MMTIMER
  94. cPublicProc _HalpAcpiTimerQueryPerfCount ,1
  95. else
  96. cPublicProc _KeQueryPerformanceCounter ,1
  97. endif
  98. mov al, _HalpUse8254
  99. or al, al
  100. jnz short KqpcUse8254
  101. KqpcUseTSC:
  102. ; use time stamp counter as performance counter
  103. mov ecx, KqpcFrequency
  104. or ecx, ecx
  105. jz short kpc10
  106. mov eax, dword ptr PCR[PcHal][TSCHz] ; Frequency LowPart
  107. mov edx, dword ptr PCR[PcHal][TSCHz+4] ; Frequency HighPart
  108. mov dword ptr [ecx], eax
  109. mov dword ptr [ecx+4], edx
  110. kpc10:
  111. rdtsc
  112. add eax, PCR[PcHal.PerfCounterLow]
  113. adc edx, PCR[PcHal.PerfCounterHigh]
  114. ifdef MMTIMER
  115. stdRET _HalpAcpiTimerQueryPerfCount
  116. else
  117. stdRET _KeQueryPerformanceCounter
  118. endif
  119. KqpcUse8254:
  120. ; use 8254 as time base for performance counters
  121. mov ecx, KqpcFrequency
  122. or ecx, ecx
  123. jz short Kqpc10
  124. mov dword ptr [ecx], PERFORMANCE_FREQUENCY
  125. mov dword ptr [ecx+4], 0
  126. xor ecx, ecx
  127. Kqpc10:
  128. test al, PERF_8254_INITIALIZED
  129. jz KqpcNoInit
  130. stdCall _HalpAcquireSystemHardwareSpinLock ; intr disabled
  131. ; Read current offset from 8254 counter 0
  132. ; Counter Latch PIT Ctr 0 command
  133. mov al, COMMAND_8254_LATCH_READ+COMMAND_8254_COUNTER0
  134. out TIMER1_CONTROL_PORT0, al
  135. IODelay
  136. in al, TIMER1_DATA_PORT0 ; Read 8254 Ctr 0, LSByte.
  137. IODelay
  138. movzx edx,al ; Zero upper bytes of (EDX).
  139. in al, TIMER1_DATA_PORT0 ; Read 8254 Ctr 0, MSByte.
  140. mov dh, al ; (DX) = 8254 Ctr 0 count.
  141. neg edx ; PIT counts down, calculate interval
  142. add edx, PERFORMANCE_INTERVAL
  143. ; (edx) = offset value from most recent base value in
  144. ; _HalpPerfCounterHigh:_HalpPerfCounterLow
  145. mov eax, _HalpPerfCounterLow
  146. add eax, edx
  147. mov edx, _HalpPerfCounterHigh
  148. adc edx, ecx
  149. ; (edx:eax) = 64 bit counter value
  150. ;
  151. ; Check to see if the new value is sane - should be greater than
  152. ; the last counter value returned by KeQueryPerformanceCounter.
  153. ; Can happen only due to wrap around of the 8254. Correct by
  154. ; updating the performance counter base.
  155. cmp edx, _HalpLastPerfCounterHigh
  156. jg short KqpcContinue ; Current value > last returned value
  157. jl short KqpcCatchupPerfCounter ; Current value < last returned value
  158. ; high dwords equal, compare low dword
  159. cmp eax, _HalpLastPerfCounterLow
  160. jg short KqpcContinue ; Current value > last returned value
  161. KqpcCatchupPerfCounter:
  162. ; Current counter value is not greater than the previously returned
  163. ; counter value - can happen only due to the 8254 timer wraparound.
  164. ; Update base to account for wrap around.
  165. add eax, PERFORMANCE_INTERVAL
  166. adc edx, ecx
  167. add _HalpPerfCounterLow, PERFORMANCE_INTERVAL
  168. adc _HalpPerfCounterHigh, ecx
  169. KqpcContinue:
  170. mov _HalpLastPerfCounterLow, eax
  171. mov _HalpLastPerfCounterHigh, edx
  172. stdCall _HalpReleaseSystemHardwareSpinLock
  173. ifdef MMTIMER
  174. stdRET _HalpAcpiTimerQueryPerfCount
  175. else
  176. stdRET _KeQueryPerformanceCounter
  177. endif
  178. KqpcNoInit:
  179. ; 8254 is not yet initialized. Just return 0 for now
  180. xor eax, eax
  181. xor edx, edx
  182. ifdef MMTIMER
  183. stdRET _HalpAcpiTimerQueryPerfCount
  184. stdENDP _HalpAcpiTimerQueryPerfCount
  185. else
  186. stdRET _KeQueryPerformanceCounter
  187. stdENDP _KeQueryPerformanceCounter
  188. endif
  189. page ,132
  190. subttl "Stall Execution"
  191. ;++
  192. ;
  193. ; VOID
  194. ; KeStallExecutionProcessor (
  195. ; IN ULONG MicroSeconds
  196. ; )
  197. ;
  198. ; Routine Description:
  199. ;
  200. ; This function stalls execution for the specified number of microseconds.
  201. ; KeStallExecutionProcessor
  202. ;
  203. ; Arguments:
  204. ;
  205. ; MicroSeconds - Supplies the number of microseconds that execution is to be
  206. ; stalled.
  207. ;
  208. ; Return Value:
  209. ;
  210. ; None.
  211. ;
  212. ;--
  213. MicroSeconds equ [esp + 12]
  214. ifdef MMTIMER
  215. cPublicProc _HalpAcpiTimerStallExecProc ,1
  216. else
  217. cPublicProc _KeStallExecutionProcessor ,1
  218. endif
  219. cPublicFpo 1,2
  220. push ebx
  221. push edi
  222. ;
  223. ; Issue a CPUID to implement a "fence"
  224. ;
  225. xor eax, eax
  226. fence1: cpuid
  227. ;
  228. ; Get current TSC
  229. ;
  230. rdtsc
  231. mov ebx, eax
  232. mov edi, edx
  233. ;
  234. ; Determine ending TSC
  235. ;
  236. mov ecx, MicroSeconds ; (ecx) = Microseconds
  237. mov eax, PCR[PcStallScaleFactor] ; get per microsecond
  238. mul ecx
  239. add ebx, eax
  240. adc edi, edx
  241. ;
  242. ; Wait for ending TSC
  243. ;
  244. kese10: rdtsc
  245. cmp edi, edx
  246. ja short kese10
  247. jc short kese20
  248. cmp ebx, eax
  249. ja short kese10
  250. kese20: pop edi
  251. pop ebx
  252. ifdef MMTIMER
  253. stdRET _HalpAcpiTimerStallExecProc
  254. stdENDP _HalpAcpiTimerStallExecProc
  255. else
  256. stdRET _KeStallExecutionProcessor
  257. stdENDP _KeStallExecutionProcessor
  258. endif
  259. _TEXT ends
  260. INIT SEGMENT DWORD PUBLIC 'CODE'
  261. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  262. cPublicProc _HalpRemoveFences
  263. mov word ptr fence1, 0c98bh
  264. stdRET _HalpRemoveFences
  265. stdENDP _HalpRemoveFences
  266. INIT ends
  267. end