mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 12:23:31 +00:00
- Fix a bug in KeQueryPerformanceCounter which was reading the flags in ESI instead of ECX.
- Fix a bug in KeQueryPerformanceCounter which wasn't handling the possibility of an invalid counter value. - Don't disable/enable interrupts in HalpInitializeClock and HalCalibratePerformanceCounter. Instead, save the flags, disable, and then restore flags, so that if interrupts were disabled initially, they'll remain that way. - Make KeUpdateRunTime and KeUpdateSystemTime support KPRCB->SkipTick. - Atomically check for DPC routine active by referencing fs. Also update Debug DPC time. - Add support for detecting break-in during KeUpdateSystemTime. - DPC Routine active is a BOOLEAN, not a ULONG. Fix the check in KeUpdateRunTime since this might've messed up a lot of things. - Temporarily disable DbgBreakPoint during DbgPrint. - Hang in KeQueryPerformanceCounter while WinDBG is connected is now fixed, as well as DbgPrint support. WinDBG can now remain connected and show all the DebugPrints! (But GUI doesn't boot -- yet). svn path=/trunk/; revision=25984
This commit is contained in:
@@ -100,9 +100,9 @@ LoopPostInt:
|
|||||||
|
|
||||||
/* Check if someone updated the counter */
|
/* Check if someone updated the counter */
|
||||||
cmp eax, ebx
|
cmp eax, ebx
|
||||||
jne LoopPostInt
|
jnz LoopPostInt
|
||||||
cmp edx, esi
|
cmp edx, esi
|
||||||
jne LoopPostInt
|
jnz LoopPostInt
|
||||||
|
|
||||||
/* Check if the current 8254 value causes rollover */
|
/* Check if the current 8254 value causes rollover */
|
||||||
neg ecx
|
neg ecx
|
||||||
@@ -180,21 +180,35 @@ BelowHigh:
|
|||||||
or ecx, esi
|
or ecx, esi
|
||||||
jz BelowLow
|
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 */
|
/* Fixup the count with the last known value */
|
||||||
sub eax, ebx
|
sub eax, ebx
|
||||||
sbb edx, esi
|
sbb edx, esi
|
||||||
|
|
||||||
/* We might have an incoming interrupt, save EFLAGS */
|
/* We might have an incoming interrupt, save EFLAGS */
|
||||||
mov esi, [esp]
|
mov ecx, [esp]
|
||||||
popf
|
popf
|
||||||
|
|
||||||
/* Check if interrupts were enabled and try again */
|
/* Check if interrupts were enabled and try again */
|
||||||
test esi, EFLAGS_INTERRUPT_MASK
|
test ecx, EFLAGS_INTERRUPT_MASK
|
||||||
jnz LoopPreInt
|
jnz LoopPreInt
|
||||||
|
|
||||||
/* They're not, continue where we left */
|
/* They're not, continue where we left */
|
||||||
pushf
|
pushf
|
||||||
jmp BelowLow
|
jmp BelowLow
|
||||||
|
|
||||||
|
InvalidCount:
|
||||||
|
popf
|
||||||
|
xor eax, eax
|
||||||
|
mov _HalpLastPerfCounterLow, eax
|
||||||
|
mov _HalpLastPerfCounterHigh, eax
|
||||||
|
jmp LoopPreInt
|
||||||
.endfunc
|
.endfunc
|
||||||
|
|
||||||
.globl _HalpClockInterrupt@0
|
.globl _HalpClockInterrupt@0
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ HalpInitializeClock(VOID)
|
|||||||
PKPRCB Prcb = KeGetCurrentPrcb();
|
PKPRCB Prcb = KeGetCurrentPrcb();
|
||||||
ULONG Increment;
|
ULONG Increment;
|
||||||
USHORT RollOver;
|
USHORT RollOver;
|
||||||
|
ULONG Flags = 0;
|
||||||
|
|
||||||
/* Check the CPU Type */
|
/* Check the CPU Type */
|
||||||
if (Prcb->CpuType <= 4)
|
if (Prcb->CpuType <= 4)
|
||||||
@@ -66,6 +67,7 @@ HalpInitializeClock(VOID)
|
|||||||
KeSetTimeIncrement(Increment, HalpRolloverTable[0].HighPart);
|
KeSetTimeIncrement(Increment, HalpRolloverTable[0].HighPart);
|
||||||
|
|
||||||
/* Disable interrupts */
|
/* Disable interrupts */
|
||||||
|
Ke386SaveFlags(Flags);
|
||||||
_disable();
|
_disable();
|
||||||
|
|
||||||
/* Set the rollover */
|
/* Set the rollover */
|
||||||
@@ -73,8 +75,8 @@ HalpInitializeClock(VOID)
|
|||||||
__outbyte(TIMER_DATA_PORT0, RollOver & 0xFF);
|
__outbyte(TIMER_DATA_PORT0, RollOver & 0xFF);
|
||||||
__outbyte(TIMER_DATA_PORT0, RollOver >> 8);
|
__outbyte(TIMER_DATA_PORT0, RollOver >> 8);
|
||||||
|
|
||||||
/* Restore interrupts */
|
/* Restore interrupts if they were previously enabled */
|
||||||
_enable();
|
Ke386RestoreFlags(Flags);
|
||||||
|
|
||||||
/* Save rollover and return */
|
/* Save rollover and return */
|
||||||
HalpCurrentRollOver = RollOver;
|
HalpCurrentRollOver = RollOver;
|
||||||
@@ -90,18 +92,20 @@ NTAPI
|
|||||||
HalCalibratePerformanceCounter(IN volatile PLONG Count,
|
HalCalibratePerformanceCounter(IN volatile PLONG Count,
|
||||||
IN ULONGLONG NewCount)
|
IN ULONGLONG NewCount)
|
||||||
{
|
{
|
||||||
|
ULONG Flags = 0;
|
||||||
|
|
||||||
/* Disable interrupts */
|
/* Disable interrupts */
|
||||||
|
Ke386SaveFlags(Flags);
|
||||||
_disable();
|
_disable();
|
||||||
|
|
||||||
/* Do a decrement for this CPU */
|
/* Do a decrement for this CPU */
|
||||||
//_InterlockedDecrement(Count);
|
_InterlockedDecrement(Count);
|
||||||
InterlockedDecrement(Count);
|
|
||||||
|
|
||||||
/* Wait for other CPUs */
|
/* Wait for other CPUs */
|
||||||
while (*Count);
|
while (*Count);
|
||||||
|
|
||||||
/* Bring interrupts back */
|
/* Restore interrupts if they were previously enabled */
|
||||||
_enable();
|
Ke386RestoreFlags(Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -202,6 +202,7 @@ Author:
|
|||||||
#define KPCR_PRCB_DEBUG_DPC_TIME 0x654
|
#define KPCR_PRCB_DEBUG_DPC_TIME 0x654
|
||||||
#define KPCR_PRCB_INTERRUPT_TIME 0x658
|
#define KPCR_PRCB_INTERRUPT_TIME 0x658
|
||||||
#define KPCR_PRCB_ADJUST_DPC_THRESHOLD 0x65C
|
#define KPCR_PRCB_ADJUST_DPC_THRESHOLD 0x65C
|
||||||
|
#define KPCR_PRCB_SKIP_TICK 0x664
|
||||||
#define KPCR_SYSTEM_CALLS 0x6B8
|
#define KPCR_SYSTEM_CALLS 0x6B8
|
||||||
#define KPCR_PRCB_DPC_QUEUE_DEPTH 0xA4C
|
#define KPCR_PRCB_DPC_QUEUE_DEPTH 0xA4C
|
||||||
#define KPCR_PRCB_DPC_COUNT 0xA50
|
#define KPCR_PRCB_DPC_COUNT 0xA50
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ vDbgPrintExWithPrefixInternal(IN LPCSTR Prefix,
|
|||||||
if (Status == STATUS_BREAKPOINT)
|
if (Status == STATUS_BREAKPOINT)
|
||||||
{
|
{
|
||||||
/* Breakpoint */
|
/* Breakpoint */
|
||||||
DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
|
//DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ KiInitMachineDependent(VOID)
|
|||||||
if (KeFeatureBits & KF_MTRR)
|
if (KeFeatureBits & KF_MTRR)
|
||||||
{
|
{
|
||||||
/* Then manually initialize MTRR for the CPU */
|
/* Then manually initialize MTRR for the CPU */
|
||||||
KiInitializeMTRR((BOOLEAN)i ? FALSE : TRUE);
|
KiInitializeMTRR(i ? FALSE : TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we have AMD MTRR and initialize it for the CPU */
|
/* Check if we have AMD MTRR and initialize it for the CPU */
|
||||||
|
|||||||
@@ -59,6 +59,10 @@ _KeUpdateRunTime@4:
|
|||||||
/* Get KPCR */
|
/* Get KPCR */
|
||||||
mov eax, [fs:KPCR_SELF]
|
mov eax, [fs:KPCR_SELF]
|
||||||
|
|
||||||
|
/* Check if this tick is getting skipped */
|
||||||
|
cmp byte ptr [eax+KPCR_PRCB_SKIP_TICK], 0
|
||||||
|
jnz SkipTick
|
||||||
|
|
||||||
/* Save EBX */
|
/* Save EBX */
|
||||||
push ebx
|
push ebx
|
||||||
|
|
||||||
@@ -84,11 +88,12 @@ _KeUpdateRunTime@4:
|
|||||||
ja AboveDispatch
|
ja AboveDispatch
|
||||||
|
|
||||||
/* Check if the DPC routine is active */
|
/* Check if the DPC routine is active */
|
||||||
cmp dword ptr[eax+KPCR_PRCB_DPC_ROUTINE_ACTIVE], 0
|
cmp byte ptr fs:[KPCR_PRCB_DPC_ROUTINE_ACTIVE], 0
|
||||||
jz BelowDispatch
|
jz BelowDispatch
|
||||||
|
|
||||||
/* At dispatch, increase DPC time */
|
/* At dispatch, increase DPC time */
|
||||||
inc dword ptr [eax+KPCR_PRCB_DPC_TIME]
|
inc dword ptr [eax+KPCR_PRCB_DPC_TIME]
|
||||||
|
inc dword ptr [eax+KPCR_PRCB_DEBUG_DPC_TIME]
|
||||||
jmp AfterSet
|
jmp AfterSet
|
||||||
|
|
||||||
AboveDispatch:
|
AboveDispatch:
|
||||||
@@ -185,12 +190,21 @@ QuantumNotEmpty:
|
|||||||
/* Restore ebx and return */
|
/* Restore ebx and return */
|
||||||
pop ebx
|
pop ebx
|
||||||
ret 4
|
ret 4
|
||||||
|
|
||||||
|
SkipTick:
|
||||||
|
/* Disable skipping the next tick and return */
|
||||||
|
mov byte ptr [eax+KPCR_PRCB_SKIP_TICK], 0
|
||||||
|
ret 4
|
||||||
.endfunc
|
.endfunc
|
||||||
|
|
||||||
.globl _KeUpdateSystemTime@0
|
.globl _KeUpdateSystemTime@0
|
||||||
.func KeUpdateSystemTime@0
|
.func KeUpdateSystemTime@0
|
||||||
_KeUpdateSystemTime@0:
|
_KeUpdateSystemTime@0:
|
||||||
|
|
||||||
|
/* Check if this tick is getting skipped */
|
||||||
|
cmp byte ptr fs:[KPCR_PRCB_SKIP_TICK], 0
|
||||||
|
jnz SkipTickSys
|
||||||
|
|
||||||
/* Get shared data in ECX */
|
/* Get shared data in ECX */
|
||||||
mov ecx, USER_SHARED_DATA
|
mov ecx, USER_SHARED_DATA
|
||||||
|
|
||||||
@@ -296,9 +310,12 @@ TimerExpired:
|
|||||||
call @HalRequestSoftwareInterrupt@4
|
call @HalRequestSoftwareInterrupt@4
|
||||||
|
|
||||||
DebugCheck:
|
DebugCheck:
|
||||||
/* FIXME: Check for KdDebuggerEnabled */
|
/* Check if the debugger is enabled */
|
||||||
|
cmp dword ptr __KdDebuggerEnabled, 0
|
||||||
|
jnz DebuggerEnabled
|
||||||
|
|
||||||
/* Check if this was a full tick */
|
/* Check if this was a full tick */
|
||||||
|
NoDebug:
|
||||||
cmp dword ptr _KiTickOffset, 0
|
cmp dword ptr _KiTickOffset, 0
|
||||||
jg IncompleteTick2
|
jg IncompleteTick2
|
||||||
|
|
||||||
@@ -320,4 +337,20 @@ Done:
|
|||||||
cli
|
cli
|
||||||
call _HalEndSystemInterrupt@8
|
call _HalEndSystemInterrupt@8
|
||||||
jmp _Kei386EoiHelper@0
|
jmp _Kei386EoiHelper@0
|
||||||
|
|
||||||
|
DebuggerEnabled:
|
||||||
|
/* Check for break-in request */
|
||||||
|
call _KdPollBreakIn@0
|
||||||
|
or al, al
|
||||||
|
jz NoDebug
|
||||||
|
|
||||||
|
/* Break-in requested! */
|
||||||
|
push 1
|
||||||
|
call _DbgBreakPointWithStatus@4
|
||||||
|
jmp NoDebug
|
||||||
|
|
||||||
|
SkipTickSys:
|
||||||
|
/* Disable skipping the next tick and return */
|
||||||
|
mov byte ptr fs:[KPCR_PRCB_SKIP_TICK], 0
|
||||||
|
jmp IncompleteTick2
|
||||||
.endfunc
|
.endfunc
|
||||||
|
|||||||
Reference in New Issue
Block a user