mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 14:32:56 +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
|
* PURPOSE: Miscellanous Routines
|
||||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||||
* Eric Kohl (ekohl@abo.rhein-zeitung.de)
|
* Eric Kohl (ekohl@abo.rhein-zeitung.de)
|
||||||
|
* Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
@ -13,6 +14,8 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
LARGE_INTEGER HalpPerformanceFrequency;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS *********************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -103,3 +106,23 @@ KeFlushWriteBuffer(VOID)
|
||||||
/* Not implemented on x86 */
|
/* Not implemented on x86 */
|
||||||
return;
|
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 ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
#include <asm.h>
|
#include <asm.h>
|
||||||
#include <internal/i386/asmmacro.S>
|
#include <ndk/amd64/asmmacro.S>
|
||||||
.intel_syntax noprefix
|
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
_HalpLastPerfCounterLow: .long 0
|
.data
|
||||||
_HalpLastPerfCounterHigh: .long 0
|
|
||||||
_HalpPerfCounterLow: .long 0
|
|
||||||
_HalpPerfCounterHigh: .long 0
|
|
||||||
_HalpSystemHardwareFlags: .long 0
|
|
||||||
|
|
||||||
_UnhandledMsg:
|
_UnhandledMsg:
|
||||||
.asciz "\n\x7\x7!!! Unhandled or Unexpected Code at line: %lx!!!\n"
|
.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 *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
.text
|
||||||
|
.code64
|
||||||
|
|
||||||
.global _HalpReleaseCmosSpinLock
|
.global _HalpReleaseCmosSpinLock
|
||||||
.func HalpReleaseCmosSpinLock
|
.func HalpReleaseCmosSpinLock
|
||||||
_HalpReleaseCmosSpinLock:
|
_HalpReleaseCmosSpinLock:
|
||||||
|
@ -106,207 +109,10 @@ _HalpQuery8254Counter:
|
||||||
ret
|
ret
|
||||||
.endfunc
|
.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
|
.globl _HalpClockInterrupt
|
||||||
.func HalpClockInterrupt
|
.func HalpClockInterrupt
|
||||||
//TRAP_FIXUPS hci_a, hci_t, DoFixupV86, DoFixupAbios
|
|
||||||
_HalpClockInterrupt:
|
_HalpClockInterrupt:
|
||||||
|
UNIMPLEMENTED _HalpClockInterrupt
|
||||||
/* Enter trap */
|
iret
|
||||||
// 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
|
|
||||||
.endfunc
|
.endfunc
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue