- 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:
Alex Ionescu
2007-03-04 19:06:34 +00:00
parent 3e6fa8fd31
commit 12e7593f24
6 changed files with 66 additions and 14 deletions

View File

@@ -100,9 +100,9 @@ LoopPostInt:
/* Check if someone updated the counter */
cmp eax, ebx
jne LoopPostInt
jnz LoopPostInt
cmp edx, esi
jne LoopPostInt
jnz LoopPostInt
/* Check if the current 8254 value causes rollover */
neg ecx
@@ -180,21 +180,35 @@ BelowHigh:
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 esi, [esp]
mov ecx, [esp]
popf
/* Check if interrupts were enabled and try again */
test esi, EFLAGS_INTERRUPT_MASK
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@0

View File

@@ -48,6 +48,7 @@ HalpInitializeClock(VOID)
PKPRCB Prcb = KeGetCurrentPrcb();
ULONG Increment;
USHORT RollOver;
ULONG Flags = 0;
/* Check the CPU Type */
if (Prcb->CpuType <= 4)
@@ -66,6 +67,7 @@ HalpInitializeClock(VOID)
KeSetTimeIncrement(Increment, HalpRolloverTable[0].HighPart);
/* Disable interrupts */
Ke386SaveFlags(Flags);
_disable();
/* Set the rollover */
@@ -73,8 +75,8 @@ HalpInitializeClock(VOID)
__outbyte(TIMER_DATA_PORT0, RollOver & 0xFF);
__outbyte(TIMER_DATA_PORT0, RollOver >> 8);
/* Restore interrupts */
_enable();
/* Restore interrupts if they were previously enabled */
Ke386RestoreFlags(Flags);
/* Save rollover and return */
HalpCurrentRollOver = RollOver;
@@ -90,18 +92,20 @@ NTAPI
HalCalibratePerformanceCounter(IN volatile PLONG Count,
IN ULONGLONG NewCount)
{
ULONG Flags = 0;
/* Disable interrupts */
Ke386SaveFlags(Flags);
_disable();
/* Do a decrement for this CPU */
//_InterlockedDecrement(Count);
InterlockedDecrement(Count);
_InterlockedDecrement(Count);
/* Wait for other CPUs */
while (*Count);
/* Bring interrupts back */
_enable();
/* Restore interrupts if they were previously enabled */
Ke386RestoreFlags(Flags);
}
/*

View File

@@ -202,6 +202,7 @@ Author:
#define KPCR_PRCB_DEBUG_DPC_TIME 0x654
#define KPCR_PRCB_INTERRUPT_TIME 0x658
#define KPCR_PRCB_ADJUST_DPC_THRESHOLD 0x65C
#define KPCR_PRCB_SKIP_TICK 0x664
#define KPCR_SYSTEM_CALLS 0x6B8
#define KPCR_PRCB_DPC_QUEUE_DEPTH 0xA4C
#define KPCR_PRCB_DPC_COUNT 0xA50

View File

@@ -142,7 +142,7 @@ vDbgPrintExWithPrefixInternal(IN LPCSTR Prefix,
if (Status == STATUS_BREAKPOINT)
{
/* Breakpoint */
DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
//DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
Status = STATUS_SUCCESS;
}
}

View File

@@ -237,7 +237,7 @@ KiInitMachineDependent(VOID)
if (KeFeatureBits & KF_MTRR)
{
/* 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 */

View File

@@ -59,6 +59,10 @@ _KeUpdateRunTime@4:
/* Get KPCR */
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 */
push ebx
@@ -84,11 +88,12 @@ _KeUpdateRunTime@4:
ja AboveDispatch
/* 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
/* At dispatch, increase DPC time */
inc dword ptr [eax+KPCR_PRCB_DPC_TIME]
inc dword ptr [eax+KPCR_PRCB_DEBUG_DPC_TIME]
jmp AfterSet
AboveDispatch:
@@ -185,12 +190,21 @@ QuantumNotEmpty:
/* Restore ebx and return */
pop ebx
ret 4
SkipTick:
/* Disable skipping the next tick and return */
mov byte ptr [eax+KPCR_PRCB_SKIP_TICK], 0
ret 4
.endfunc
.globl _KeUpdateSystemTime@0
.func 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 */
mov ecx, USER_SHARED_DATA
@@ -296,9 +310,12 @@ TimerExpired:
call @HalRequestSoftwareInterrupt@4
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 */
NoDebug:
cmp dword ptr _KiTickOffset, 0
jg IncompleteTick2
@@ -320,4 +337,20 @@ Done:
cli
call _HalEndSystemInterrupt@8
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