diff --git a/reactos/hal/halarm/generic/hal.c b/reactos/hal/halarm/generic/hal.c index 20be7201f64..88b6f7233de 100644 --- a/reactos/hal/halarm/generic/hal.c +++ b/reactos/hal/halarm/generic/hal.c @@ -16,7 +16,6 @@ #undef ExReleaseFastMutex #undef ExTryToAcquireFastMutex #undef KeAcquireSpinLock -#undef KeGetCurrentIrql #undef KeLowerIrql #undef KeRaiseIrql #undef KeReleaseSpinLock @@ -26,6 +25,7 @@ /* DATA **********************************************************************/ +ULONG HalpCurrentTimeIncrement, HalpNextTimeIncrement, HalpNextIntervalCount; ULONG _KdComPortInUse = 0; ULONG HalpIrqlTable[HIGH_LEVEL + 1] = @@ -471,9 +471,25 @@ HalpClockInterrupt(VOID) // // Clear the interrupt // - //DPRINT1("CLOCK INTERRUPT!!!\n"); - WRITE_REGISTER_ULONG(TIMER0_INT_CLEAR, 1); - //while (TRUE); + ASSERT(KeGetCurrentIrql() == CLOCK2_LEVEL); + WRITE_REGISTER_ULONG(TIMER0_INT_CLEAR, 1); + + // + // FIXME: Update HAL Perf counters + // + + // + // FIXME: Check if someone changed the clockrate + // + + // + // Call the kernel + // + KeUpdateSystemTime(NULL, CLOCK2_LEVEL, HalpCurrentTimeIncrement); + + // + // We're done + // } VOID @@ -527,9 +543,6 @@ HalpInitializeInterrupts(VOID) WRITE_REGISTER_ULONG(TIMER0_CONTROL, ControlRegister.AsUlong); } -ULONG HalpCurrentTimeIncrement, HalpNextTimeIncrement, HalpNextIntervalCount; - - /* * @implemented */ @@ -1345,6 +1358,7 @@ HalSweepIcache(VOID) /* * @implemented */ +#undef KeGetCurrentIrql KIRQL NTAPI KeGetCurrentIrql(VOID) diff --git a/reactos/ntoskrnl/ke/arm/stubs.c b/reactos/ntoskrnl/ke/arm/stubs.c index 977bc4d8840..83d8f537871 100644 --- a/reactos/ntoskrnl/ke/arm/stubs.c +++ b/reactos/ntoskrnl/ke/arm/stubs.c @@ -10,6 +10,10 @@ ULONG KeProcessorLevel; ULONG KeProcessorRevision; ULONG KeFeatureBits; + +extern LONG KiTickOffset; +extern ULONG KeTimeAdjustment; + ULONG KiComputeTimerTableIndex(IN LONGLONG DueTime) { @@ -32,8 +36,121 @@ KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame, IN KIRQL Irql, IN ULONG Increment) { - UNIMPLEMENTED; - while (TRUE); + PKPRCB Prcb = KeGetPcr()->Prcb; + LARGE_INTEGER SystemTime, InterruptTime; + ULONG Hand; + + // + // Do nothing if this tick is being skipped + // + if (Prcb->SkipTick) + { + // + // Handle it next time + // + Prcb->SkipTick = FALSE; + return; + } + + // + // Add the increment time to the shared data + // + InterruptTime.HighPart = SharedUserData->InterruptTime.High1Time; + InterruptTime.LowPart = SharedUserData->InterruptTime.LowPart; + InterruptTime.QuadPart += Increment; + SharedUserData->InterruptTime.High1Time = InterruptTime.HighPart; + SharedUserData->InterruptTime.LowPart = InterruptTime.LowPart; + SharedUserData->InterruptTime.High2Time = InterruptTime.HighPart; + + // + // Update tick count + // + KiTickOffset -= Increment; + + // + // Check for incomplete tick + // + if (KiTickOffset > 0) + { + + } + else + { + // + // Update the system time + // + SystemTime.HighPart = SharedUserData->SystemTime.High1Time; + SystemTime.LowPart = SharedUserData->SystemTime.LowPart; + SystemTime.QuadPart += KeTimeAdjustment; + SharedUserData->SystemTime.High1Time = SystemTime.HighPart; + SharedUserData->SystemTime.LowPart = SystemTime.LowPart; + SharedUserData->SystemTime.High2Time = SystemTime.HighPart; + + // + // Update the tick count + // + SystemTime.HighPart = KeTickCount.High1Time; + SystemTime.LowPart = KeTickCount.LowPart; + SystemTime.QuadPart += 1; + KeTickCount.High1Time = SystemTime.HighPart; + KeTickCount.LowPart = SystemTime.LowPart; + KeTickCount.High2Time = SystemTime.HighPart; + + // + // Update it in the shared user data + // + SharedUserData->TickCount.High1Time = SystemTime.HighPart; + SharedUserData->TickCount.LowPart = SystemTime.LowPart; + SharedUserData->TickCount.High2Time = SystemTime.HighPart; + } + + // + // Check for timer expiration + // + Hand = KeTickCount.LowPart & (TIMER_TABLE_SIZE - 1); + Hand <<= 4; + if (KiTimerTableListHead[Hand].Time.QuadPart > InterruptTime.QuadPart) + { + // + // Timer has expired! + // + DPRINT1("TIMER EXPIRATION!!!\n"); + while (TRUE); + } + + // + // Check if we should request a debugger break + // + if (KdDebuggerEnabled) + { + // + // Check if we should break + // + if (KdPollBreakIn()) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C); + } + + // + // Check if this was a full tick + // + if (KiTickOffset <= 0) + { + // + // Updare the tick offset + // + KiTickOffset += KeMaximumIncrement; + + // + // Update system runtime + // + KeUpdateRunTime(NULL, CLOCK2_LEVEL); + } + else + { + // + // Increase interrupt count and exit + // + Prcb->InterruptCount++; + } } VOID