- Add more missing offsets to asm.h (as always, taken from ks386.inc)

- Fix incorrect KPCR_PRCB_DPC_ROUTINE_ACTIVE which was totally wrong (And could've caused a crash in the context swicher)
- Also fix the definition of KRCB which was off-by-4 after about offset ~0x500. It wasn't causing problems because assembly code only used < 0x500.
- Write the ASM implementation of KeUpdateRunTime (not used yet).

svn path=/trunk/; revision=23681
This commit is contained in:
Alex Ionescu 2006-08-24 07:48:50 +00:00
parent 065837f112
commit 721fa0869e
4 changed files with 159 additions and 3 deletions

View file

@ -109,6 +109,9 @@ Author:
#define KTHREAD_CALLBACK_STACK 0x114
#define KTHREAD_APC_STATE_INDEX 0x11C
#define KTHREAD_STACK_BASE 0x158
#define KTHREAD_QUANTUM 0x15D
#define KTHREAD_KERNEL_TIME 0x160
#define KTHREAD_USER_TIME 0x18C
//
// KPROCESS Offsets
@ -145,6 +148,7 @@ Author:
#define KPCR_SET_MEMBER 0x48
#define KPCR_NUMBER 0x51
#define KPCR_CURRENT_THREAD 0x124
#define KPCR_PRCB_IDLE_THREAD 0x12C
#define KPCR_PROCESSOR_NUMBER 0x130
#define KPCR_PRCB_SET_MEMBER 0x134
#define KPCR_PRCB_CPU_TYPE 0x138
@ -152,8 +156,21 @@ Author:
#define KPCR_DR6 0x428
#define KPCR_DR7 0x42C
#define KPCR_PRCB_INTERRUPT_COUNT 0x644
#define KPCR_PRCB_KERNEL_TIME 0x648
#define KPCR_PRCB_USER_TIME 0x64C
#define KPCR_PRCB_DPC_TIME 0x650
#define KPCR_PRCB_DEBUG_DPC_TIME 0x654
#define KPCR_PRCB_INTERRUPT_TIME 0x658
#define KPCR_PRCB_ADJUST_DPC_THRESHOLD 0x65C
#define KPCR_SYSTEM_CALLS 0x6B8
#define KPCR_PRCB_DPC_ROUTINE_ACTIVE 0x994
#define KPCR_PRCB_DPC_QUEUE_DEPTH 0xA4C
#define KPCR_PRCB_DPC_COUNT 0xA50
#define KPCR_PRCB_MAXIMUM_DPC_QUEUE_DEPTH 0xA6C
#define KPCR_PRCB_DPC_REQUEST_RATE 0xA70
#define KPCR_PRCB_DPC_INTERRUPT_REQUESTED 0xA78
#define KPCR_PRCB_DPC_ROUTINE_ACTIVE 0xA7A
#define KPCR_PRCB_DPC_LAST_COUNT 0xA80
#define KPCR_PRCB_QUANTUM_END 0xAA1
//
// KINTERRUPT Offsets
@ -432,6 +449,11 @@ Author:
#define DISPATCH_LEVEL 0x2
#define CLOCK2_LEVEL 0x1C
#define HIGH_LEVEL 0x1F
//
// Quantum Decrements
//
#define CLOCK_QUANTUM_DECREMENT 0x3
#endif
//

View file

@ -407,7 +407,6 @@ typedef struct _KPRCB
#endif
ULONG SpareCounter0;
#if (NTDDI_VERSION < NTDDI_LONGHORN)
ULONG KeContextSwitches;
ULONG KeDcacheFlushCount;
ULONG KeExceptionDispatchCount;
ULONG KeFirstLevelTbFills;

View file

@ -1054,7 +1054,7 @@ QSI_DEF(SystemInterruptInformation)
Prcb = ((PKPCR)KPCR_BASE)->Prcb;
for (i = 0; i < KeNumberProcessors; i++)
{
sii->ContextSwitches = Prcb->KeContextSwitches;
//sii->ContextSwitches = Prcb->KeContextSwitches;
sii->DpcCount = 0; /* FIXME */
sii->DpcRate = 0; /* FIXME */
sii->TimeIncrement = ti;

View file

@ -20,6 +20,141 @@
/* FUNCTIONS ******************************************************************/
.globl _KeUpdateRunTime2@0
.func KeUpdateRunTime2@0
_KeUpdateRunTime2@0:
/* Get KPCR */
mov eax, [fs:KPCR_SELF]
/* Save EBX */
push ebx
/* Increase interrupt count */
inc dword ptr [eax+KPCR_PRCB_INTERRUPT_COUNT]
/* Get the current thread and process */
mov ebx, [eax+KPCR_CURRENT_THREAD]
mov ecx, [ebx+KTHREAD_APCSTATE_PROCESS]
/* Check if this was V86 or user mode */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz NotKern
test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
jnz NotKern
/* Increase kernel time */
inc dword ptr [eax+KPCR_PRCB_KERNEL_TIME]
/* Check if IRQL was DISPATCH_LEVEL */
cmp byte ptr [esp+8], DISPATCH_LEVEL
jb BelowDispatch
ja AboveDispatch
/* Check if the DPC routine is active */
cmp dword ptr[eax+KPCR_PRCB_DPC_ROUTINE_ACTIVE], 0
jz BelowDispatch
/* At dispatch, increase DPC time */
inc dword ptr [eax+KPCR_PRCB_DPC_TIME]
jmp AfterSet
AboveDispatch:
/* Update interrupt time */
inc dword ptr [eax+KPCR_PRCB_INTERRUPT_TIME]
jmp AfterSet
BelowDispatch:
/* Update kernel time */
inc dword ptr [ebx+KTHREAD_KERNEL_TIME]
jmp AfterSet
NotKern:
/* Update user time */
inc dword ptr [eax+KPCR_PRCB_USER_TIME]
inc dword ptr [ebx+KTHREAD_USER_TIME]
AfterSet:
/* Get the DPC Count and last count, and set the ne wone */
mov ecx, [eax+KPCR_PRCB_DPC_COUNT]
mov edx, [eax+KPCR_PRCB_DPC_LAST_COUNT]
mov [eax+KPCR_PRCB_DPC_LAST_COUNT], ecx
/* Substract counts and add request rate, divide by two to get average */
sub ecx, edx
add ecx, [eax+KPCR_PRCB_DPC_REQUEST_RATE]
shr ecx, 1
/* Set this as the new request rate */
mov [eax+KPCR_PRCB_DPC_REQUEST_RATE], ecx
/* Check for depth > 0, DPCs to be inactive, and no other pending request */
cmp dword ptr [eax+KPCR_PRCB_DPC_QUEUE_DEPTH], 0
je DontRequest
cmp byte ptr [eax+KPCR_PRCB_DPC_ROUTINE_ACTIVE], 0
jnz DontRequest
cmp byte ptr [eax+KPCR_PRCB_DPC_INTERRUPT_REQUESTED], 0
jnz DontRequest
/* Request a DPC */
mov ecx, DISPATCH_LEVEL
call @HalRequestSoftwareInterrupt@4
/* Restore PCR address */
mov eax, [fs:KPCR_SELF]
/* Get the DPC request rate and threshold adjust, and set it */
mov ecx, [eax+KPCR_PRCB_DPC_REQUEST_RATE]
mov edx, _KiAdjustDpcThreshold
mov [eax+KPCR_PRCB_ADJUST_DPC_THRESHOLD], edx
/* Check if the rate now is not ideal */
cmp ecx, _KiIdealDpcRate
jge RateOk
cmp dword ptr [eax+KPCR_PRCB_MAXIMUM_DPC_QUEUE_DEPTH], 1
je RateOk
/* Fix the depth */
dec dword ptr [eax+KPCR_PRCB_MAXIMUM_DPC_QUEUE_DEPTH]
jmp RateOk
DontRequest:
/* We didn't request a DPC, decrease the threshold */
dec dword ptr [eax+KPCR_PRCB_ADJUST_DPC_THRESHOLD]
jnz RateOk
/* We're at 0 now, reset it */
mov ecx, _KiAdjustDpcThreshold
mov [eax+KPCR_PRCB_ADJUST_DPC_THRESHOLD], ecx
/* Get maximum depth and check it */
mov ecx, _KiMaximumDpcQueueDepth
cmp ecx, [eax+KPCR_PRCB_MAXIMUM_DPC_QUEUE_DEPTH]
je RateOk
/* Increase it, it's below maximum */
inc dword ptr [eax+KPCR_PRCB_MAXIMUM_DPC_QUEUE_DEPTH]
RateOk:
/* Decrement quantum and verify it */
sub byte ptr [ebx+KTHREAD_QUANTUM], CLOCK_QUANTUM_DECREMENT
jg QuantumNotEmpty
/* Make sure this isn't the idle thread */
cmp ebx, [eax+KPCR_PRCB_IDLE_THREAD]
jz QuantumNotEmpty
/* Set quantum end */
mov byte ptr [eax+KPCR_PRCB_QUANTUM_END], 1
mov ecx, DISPATCH_LEVEL
call @HalRequestSoftwareInterrupt@4
QuantumNotEmpty:
/* Restore ebx and return */
pop ebx
ret 4
.endfunc
.globl _KeUpdateSystemTime2@0
.func KeUpdateSystemTime2@0
_KeUpdateSystemTime2@0: