mirror of
https://github.com/reactos/reactos.git
synced 2025-01-12 09:07:54 +00:00
Remove the totally broken asm implementation of KeQueryPerformanceCounter and replace it with a much simpler C version using __rdtsc().
svn path=/branches/ros-amd64-bringup/; revision=44795
This commit is contained in:
parent
aea03eb5bf
commit
0752824a4b
2 changed files with 35 additions and 206 deletions
|
@ -5,6 +5,7 @@
|
|||
* PURPOSE: Miscellanous Routines
|
||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||
* Eric Kohl (ekohl@abo.rhein-zeitung.de)
|
||||
* Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
@ -13,6 +14,8 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
LARGE_INTEGER HalpPerformanceFrequency;
|
||||
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
|
||||
VOID
|
||||
|
@ -103,3 +106,23 @@ KeFlushWriteBuffer(VOID)
|
|||
/* Not implemented on x86 */
|
||||
return;
|
||||
}
|
||||
|
||||
LARGE_INTEGER
|
||||
NTAPI
|
||||
KeQueryPerformanceCounter(
|
||||
OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL)
|
||||
{
|
||||
LARGE_INTEGER Result;
|
||||
|
||||
ASSERT(HalpPerformanceFrequency.QuadPart != 0);
|
||||
|
||||
/* Does the caller want the frequency? */
|
||||
if (PerformanceFrequency)
|
||||
{
|
||||
/* Return value */
|
||||
*PerformanceFrequency = HalpPerformanceFrequency;
|
||||
}
|
||||
|
||||
Result.QuadPart = __rdtsc();
|
||||
return Result;
|
||||
}
|
||||
|
|
|
@ -8,22 +8,25 @@
|
|||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <asm.h>
|
||||
#include <internal/i386/asmmacro.S>
|
||||
.intel_syntax noprefix
|
||||
#include <ndk/amd64/asmmacro.S>
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
_HalpLastPerfCounterLow: .long 0
|
||||
_HalpLastPerfCounterHigh: .long 0
|
||||
_HalpPerfCounterLow: .long 0
|
||||
_HalpPerfCounterHigh: .long 0
|
||||
_HalpSystemHardwareFlags: .long 0
|
||||
.data
|
||||
|
||||
_UnhandledMsg:
|
||||
.asciz "\n\x7\x7!!! Unhandled or Unexpected Code at line: %lx!!!\n"
|
||||
|
||||
.global _MsgUnimplemented
|
||||
_MsgUnimplemented:
|
||||
.asciz "WARNING: %s at %s:%d is UNIMPLEMENTED!\n"
|
||||
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
.text
|
||||
.code64
|
||||
|
||||
.global _HalpReleaseCmosSpinLock
|
||||
.func HalpReleaseCmosSpinLock
|
||||
_HalpReleaseCmosSpinLock:
|
||||
|
@ -106,207 +109,10 @@ _HalpQuery8254Counter:
|
|||
ret
|
||||
.endfunc
|
||||
|
||||
|
||||
.global _KeQueryPerformanceCounter
|
||||
.func KeQueryPerformanceCounter
|
||||
_KeQueryPerformanceCounter:
|
||||
|
||||
/* Check if we were called too early */
|
||||
cmp dword ptr _HalpCurrentRollOver, 0
|
||||
je NoCount
|
||||
|
||||
/* Save volatiles */
|
||||
push rbx
|
||||
push rsi
|
||||
|
||||
LoopPreInt:
|
||||
|
||||
/* Disable interrupts */
|
||||
pushf
|
||||
cli
|
||||
|
||||
LoopPostInt:
|
||||
|
||||
/* Get the current value */
|
||||
mov ebx, _HalpPerfCounterLow
|
||||
mov esi, _HalpPerfCounterHigh
|
||||
|
||||
/* Read 8254 timer */
|
||||
mov al, 0
|
||||
out 0x43, al
|
||||
jmp $+2
|
||||
in al, 0x40
|
||||
jmp $+2
|
||||
movzx ecx, al
|
||||
in al, 0x40
|
||||
mov ch, al
|
||||
|
||||
/* Enable interrupts and do a short wait */
|
||||
popf
|
||||
nop
|
||||
jmp $+2
|
||||
|
||||
/* Disable them again */
|
||||
pushf
|
||||
cli
|
||||
|
||||
/* Get the counter value again */
|
||||
mov eax, _HalpPerfCounterLow
|
||||
mov edx, _HalpPerfCounterHigh
|
||||
|
||||
/* Check if someone updated the counter */
|
||||
cmp eax, ebx
|
||||
jnz LoopPostInt
|
||||
cmp edx, esi
|
||||
jnz LoopPostInt
|
||||
|
||||
/* Check if the current 8254 value causes rollover */
|
||||
neg ecx
|
||||
add ecx, _HalpCurrentRollOver
|
||||
jnb DoRollOver
|
||||
|
||||
SetSum:
|
||||
|
||||
/* Calculate the sum */
|
||||
add eax, ecx
|
||||
adc edx, 0
|
||||
|
||||
/* Check if we're above or below the last high value */
|
||||
cmp edx, _HalpLastPerfCounterHigh
|
||||
jb short BelowHigh
|
||||
jnz short BelowLow
|
||||
|
||||
/* Check if we're above or below the last low value */
|
||||
cmp eax, _HalpLastPerfCounterLow
|
||||
jb BelowHigh
|
||||
|
||||
BelowLow:
|
||||
|
||||
/* Update the last value and bring back interrupts */
|
||||
mov _HalpLastPerfCounterLow, eax
|
||||
mov _HalpLastPerfCounterHigh, edx
|
||||
popf
|
||||
|
||||
/* Check if caller wants frequency */
|
||||
cmp dword ptr [esp+12], 0
|
||||
jz ReturnNoFreq
|
||||
|
||||
/* Save hard-coded frequency */
|
||||
mov ecx, dword ptr [esp+12]
|
||||
mov dword ptr [ecx], 1193182
|
||||
mov dword ptr [ecx+4], 0
|
||||
|
||||
ReturnNoFreq:
|
||||
|
||||
/* Restore volatiles */
|
||||
pop rsi
|
||||
pop rbx
|
||||
ret 4
|
||||
|
||||
NoCount:
|
||||
|
||||
/* Return empty, called too soon */
|
||||
mov eax, 0
|
||||
mov edx, 0
|
||||
ret 4
|
||||
|
||||
DoRollOver:
|
||||
|
||||
/* We might have an incoming interrupt, save EFLAGS and reset rollover */
|
||||
mov esi, [esp]
|
||||
mov ecx, _HalpCurrentRollOver
|
||||
popf
|
||||
|
||||
/* Check if interrupts were enabled and try again */
|
||||
test esi, EFLAGS_INTERRUPT_MASK
|
||||
jnz LoopPreInt
|
||||
|
||||
/* They're not, continue where we left */
|
||||
pushf
|
||||
jmp SetSum
|
||||
|
||||
BelowHigh:
|
||||
|
||||
/* Get the last counter values */
|
||||
mov ebx, _HalpLastPerfCounterLow
|
||||
mov esi, _HalpLastPerfCounterHigh
|
||||
|
||||
/* Check if the previous value was 0 and go back if yes */
|
||||
mov ecx, ebx
|
||||
or ecx, esi
|
||||
jz BelowLow
|
||||
|
||||
/* Make sure that the count is still valid */
|
||||
sub ebx, eax
|
||||
sbb esi, edx
|
||||
jnz InvalidCount
|
||||
cmp ebx, _HalpCurrentRollOver
|
||||
jg InvalidCount
|
||||
|
||||
/* Fixup the count with the last known value */
|
||||
sub eax, ebx
|
||||
sbb edx, esi
|
||||
|
||||
/* We might have an incoming interrupt, save EFLAGS */
|
||||
mov ecx, [esp]
|
||||
popf
|
||||
|
||||
/* Check if interrupts were enabled and try again */
|
||||
test ecx, EFLAGS_INTERRUPT_MASK
|
||||
jnz LoopPreInt
|
||||
|
||||
/* They're not, continue where we left */
|
||||
pushf
|
||||
jmp BelowLow
|
||||
|
||||
InvalidCount:
|
||||
popf
|
||||
xor eax, eax
|
||||
mov _HalpLastPerfCounterLow, eax
|
||||
mov _HalpLastPerfCounterHigh, eax
|
||||
jmp LoopPreInt
|
||||
.endfunc
|
||||
|
||||
.globl _HalpClockInterrupt
|
||||
.func HalpClockInterrupt
|
||||
//TRAP_FIXUPS hci_a, hci_t, DoFixupV86, DoFixupAbios
|
||||
_HalpClockInterrupt:
|
||||
|
||||
/* Enter trap */
|
||||
// INT_PROLOG hci_a, hci_t, DoPushFakeErrorCode
|
||||
|
||||
/* Push vector and make stack for IRQL */
|
||||
push 0x30
|
||||
sub esp, 4
|
||||
|
||||
/* Begin the interrupt */
|
||||
push rsp
|
||||
push 0x30
|
||||
push CLOCK_LEVEL
|
||||
// call _HalBeginSystemInterrupt
|
||||
|
||||
/* Check if it's spurious */
|
||||
or al, al
|
||||
jz Spurious
|
||||
|
||||
/* Update the performance counter */
|
||||
xor ebx, ebx
|
||||
mov eax, _HalpCurrentRollOver
|
||||
add _HalpPerfCounterLow, eax
|
||||
adc _HalpPerfCounterHigh, ebx
|
||||
|
||||
/* Get the time increment and check if someone changed the clock rate */
|
||||
mov eax, _HalpCurrentTimeIncrement
|
||||
cmp _HalpClockSetMSRate, ebx
|
||||
jz _KeUpdateSystemTime
|
||||
|
||||
/* FIXME: Someone did! */
|
||||
int 3
|
||||
|
||||
Spurious:
|
||||
|
||||
/* Exit the interrupt */
|
||||
add esp, 8
|
||||
// jmp _Kei386EoiHelper
|
||||
UNIMPLEMENTED _HalpClockInterrupt
|
||||
iret
|
||||
.endfunc
|
||||
|
||||
|
|
Loading…
Reference in a new issue