mirror of
https://github.com/reactos/reactos.git
synced 2026-05-24 16:20:07 +08: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 */
|
||||
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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user