Author: ros-arm-bringup
Date: Thu Jun 26 00:56:35 2008
New Revision: 34088
URL:
http://svn.reactos.org/svn/reactos?rev=34088&view=rev
Log:
- Save and restore the trap frame for the current thread when we take an interrupt, so
that ISRs can read it.
- We use this in the clock ISR, that can now actually send the trap frame to
KeUpdateSystemTime.
- Implement KeUpdateRunTime to handle time accounting and DPC rescheduling as well as
Quantum End.
- Ignore quantum end for now.
- We now have a working timebase, and we're back to our earlier checkpoint around
CmInitSystem1!.
Modified:
trunk/reactos/hal/halarm/generic/hal.c
trunk/reactos/ntoskrnl/ke/arm/stubs.c
trunk/reactos/ntoskrnl/ke/arm/trapc.c
Modified: trunk/reactos/hal/halarm/generic/hal.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halarm/generic/hal.c?r…
==============================================================================
--- trunk/reactos/hal/halarm/generic/hal.c [iso-8859-1] (original)
+++ trunk/reactos/hal/halarm/generic/hal.c [iso-8859-1] Thu Jun 26 00:56:35 2008
@@ -485,7 +485,9 @@
//
// Call the kernel
//
- KeUpdateSystemTime(NULL, CLOCK2_LEVEL, HalpCurrentTimeIncrement);
+ KeUpdateSystemTime(KeGetCurrentThread()->TrapFrame,
+ CLOCK2_LEVEL,
+ HalpCurrentTimeIncrement);
//
// We're done
Modified: trunk/reactos/ntoskrnl/ke/arm/stubs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/stubs.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/arm/stubs.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/arm/stubs.c [iso-8859-1] Thu Jun 26 00:56:35 2008
@@ -39,10 +39,6 @@
PKPRCB Prcb = KeGetPcr()->Prcb;
ULARGE_INTEGER SystemTime, InterruptTime;
ULONG Hand;
- DPRINT1("TIMEBASE: %I64d %I64d %I64d\n",
- *(PLARGE_INTEGER)&SharedUserData->InterruptTime,
- *(PLARGE_INTEGER)&SharedUserData->SystemTime,
- *(PLARGE_INTEGER)&SharedUserData->TickCount);
//
// Do nothing if this tick is being skipped
@@ -143,7 +139,7 @@
//
// Update system runtime
//
- KeUpdateRunTime(NULL, CLOCK2_LEVEL);
+ KeUpdateRunTime(TrapFrame, CLOCK2_LEVEL);
}
else
{
@@ -159,6 +155,138 @@
KeUpdateRunTime(IN PKTRAP_FRAME TrapFrame,
IN KIRQL Irql)
{
- UNIMPLEMENTED;
- while (TRUE);
+ PKTHREAD Thread = KeGetCurrentThread();
+ PKPROCESS Process = Thread->ApcState.Process;
+ PKPRCB Prcb = KeGetCurrentPrcb();
+
+ //
+ // Do nothing if this tick is being skipped
+ //
+ if (Prcb->SkipTick)
+ {
+ //
+ // Handle it next time
+ //
+ Prcb->SkipTick = FALSE;
+ return;
+ }
+
+ //
+ // Increase interrupt count
+ //
+ Prcb->InterruptCount++;
+
+ //
+ // Check if we came from user mode
+ //
+ if (0) //(TrapFrame->PreviousMode != KernelMode)
+ {
+ //
+ // Increase process user time
+ //
+ InterlockedIncrement((PLONG)&Process->UserTime);
+ Prcb->UserTime++;
+ Thread->UserTime++;
+ }
+ else
+ {
+ //
+ // See if we were in an ISR
+ //
+ if (TrapFrame->OldIrql > DISPATCH_LEVEL)
+ {
+ //
+ // Handle that
+ //
+ Prcb->InterruptTime++;
+ }
+ else if ((TrapFrame->OldIrql < DISPATCH_LEVEL) ||
+ !(Prcb->DpcRoutineActive))
+ {
+ //
+ // Handle being in kernel mode
+ //
+ Thread->KernelTime++;
+ InterlockedIncrement((PLONG)&Process->KernelTime);
+ }
+ else
+ {
+ //
+ // Handle being in a DPC
+ //
+ Prcb->DpcTime++;
+
+ //
+ // FIXME: Handle DPC checks
+ //
+ }
+ }
+
+ //
+ // Update DPC rates
+ //
+ Prcb->DpcRequestRate = ((Prcb->DpcData[0].DpcCount - Prcb->DpcLastCount) +
+ Prcb->DpcRequestRate) >> 1;
+ Prcb->DpcLastCount = Prcb->DpcData[0].DpcCount;
+
+ //
+ // Check if the queue is large enough
+ //
+ if ((Prcb->DpcData[0].DpcQueueDepth) && !(Prcb->DpcRoutineActive))
+ {
+ //
+ // Request a DPC
+ //
+ Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
+ HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
+
+ //
+ // Fix the maximum queue depth
+ //
+ if ((Prcb->DpcRequestRate < KiIdealDpcRate) &&
+ (Prcb->MaximumDpcQueueDepth > 1))
+ {
+ //
+ // Make it smaller
+ //
+ Prcb->MaximumDpcQueueDepth--;
+ }
+ }
+ else
+ {
+ //
+ // Check if we've reached the adjustment limit
+ //
+ if (!(--Prcb->AdjustDpcThreshold))
+ {
+ //
+ // Reset it, and check the queue maximum
+ //
+ Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
+ if (KiMaximumDpcQueueDepth != Prcb->MaximumDpcQueueDepth)
+ {
+ //
+ // Increase it
+ //
+ Prcb->MaximumDpcQueueDepth++;
+ }
+ }
+ }
+
+ //
+ // Decrement the thread quantum
+ //
+ Thread->Quantum -= CLOCK_QUANTUM_DECREMENT;
+
+ //
+ // Check if the time expired
+ //
+ if ((Thread->Quantum <= 0) && (Thread != Prcb->IdleThread))
+ {
+ //
+ // Schedule a quantum end
+ //
+ Prcb->QuantumEnd = 1;
+ //HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
+ }
}
Modified: trunk/reactos/ntoskrnl/ke/arm/trapc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/trapc.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/arm/trapc.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/arm/trapc.c [iso-8859-1] Thu Jun 26 00:56:35 2008
@@ -310,6 +310,7 @@
KIRQL OldIrql, Irql;
ULONG InterruptCause, InterruptMask;
PKPCR Pcr;
+ PKTRAP_FRAME OldTrapFrame;
//
// Increment interrupt count
@@ -339,12 +340,18 @@
// Raise to the new IRQL
//
KfRaiseIrql(Irql);
+
+ //
+ // The clock ISR wants the trap frame as a parameter
+ //
+ OldTrapFrame = KeGetCurrentThread()->TrapFrame;
+ KeGetCurrentThread()->TrapFrame = TrapFrame;
//
// Check if this interrupt is at DISPATCH or higher
//
if (Irql > DISPATCH_LEVEL)
- {
+ {
//
// FIXME: Switch to interrupt stack
//
@@ -358,11 +365,13 @@
//DPRINT1("[DPC/APC]\n");
HalClearSoftwareInterrupt(Irql);
}
-
+
//
// Call the registered interrupt routine
//
Pcr->InterruptRoutine[Irql]();
+ ASSERT(KeGetCurrentThread()->TrapFrame == TrapFrame);
+ KeGetCurrentThread()->TrapFrame = OldTrapFrame;
// DPRINT1("[ISR RETURN]\n");
//