- Fix some bugs in clock.S
authorAlex Ionescu <aionescu@gmail.com>
Thu, 24 Aug 2006 19:17:14 +0000 (19:17 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Thu, 24 Aug 2006 19:17:14 +0000 (19:17 +0000)
- Enable clock.S versions of KeUpdateSystem/RunTime and export them properly.
- Enable systimer.S to call into kernel's KeUpdateSystemTime.
- Enable Hal's Clock Interrupt during Phase 1.
- Remove most of the code that was still left in irq.c
- Only one large problem remains now, which is the spurious firing of the clock interrupt before we're ready to handle it... I will try to fix this today.

svn path=/trunk/; revision=23692

reactos/hal/halx86/generic/halinit.c
reactos/hal/halx86/generic/systimer.S
reactos/ntoskrnl/ke/clock.c
reactos/ntoskrnl/ke/i386/clock.S
reactos/ntoskrnl/ke/i386/irq.c
reactos/ntoskrnl/ntoskrnl.def

index 60af79f..c3c65a7 100644 (file)
@@ -32,10 +32,6 @@ DriverEntry(
        return STATUS_SUCCESS;
 }
 
-#define MAKEULONG(x, y) \
-    (((((ULONG)(x))<<16) & 0xffff0000) | \
-    ((ULONG)(y) & 0xffff))
-
 BOOLEAN STDCALL
 HalInitSystem (ULONG BootPhase,
                PLOADER_PARAMETER_BLOCK LoaderBlock)
@@ -47,14 +43,13 @@ HalInitSystem (ULONG BootPhase,
     }
   else if (BootPhase == 1)
     {
-#if 0
         /* Enable the clock interrupt */
         ((PKIPCR)KeGetPcr())->IDT[IRQ2VECTOR(0)].ExtendedOffset =
             (USHORT)(((ULONG_PTR)HalpClockInterrupt >> 16) & 0xFFFF);
         ((PKIPCR)KeGetPcr())->IDT[IRQ2VECTOR(0)].Offset =
             (USHORT)HalpClockInterrupt;
         HalEnableSystemInterrupt(IRQ2VECTOR(0), CLOCK2_LEVEL, Latched);
-#endif
+
       /* Initialize display and make the screen black */
       HalInitializeDisplay ((PROS_LOADER_PARAMETER_BLOCK)LoaderBlock);
       HalpInitBusHandlers();
index f2dfebb..170f923 100644 (file)
@@ -38,7 +38,8 @@ _HalpClockInterrupt@0:
     jz Spurious\r
 \r
     /* Do a tick */\r
-    //jmp _KeUpdateSystemTime@0\r
+    mov eax, 100000\r
+    jmp _KeUpdateSystemTime@0\r
 \r
 Spurious:\r
 \r
index f2eb528..924d2d2 100644 (file)
@@ -36,13 +36,9 @@ LARGE_INTEGER SystemBootTime = { 0 };
 #endif
 
 CHAR KiTimerSystemAuditing = 0;
-static KDPC KiExpireTimerDpc;
+KDPC KiExpireTimerDpc;
 BOOLEAN KiClockSetupComplete = FALSE;
 
-extern ULONG KiMaximumDpcQueueDepth;
-extern ULONG KiMinimumDpcRate;
-extern ULONG KiAdjustDpcThreshold;
-extern ULONG KiIdealDpcRate;
 
 /*
  * Number of timer interrupts since initialisation
@@ -82,7 +78,7 @@ KiInitializeSystemClock(VOID)
 {
     TIME_FIELDS TimeFields;
 
-    DPRINT("KiInitializeSystemClock()\n");
+    DPRINT1("KiInitializeSystemClock()\n");
     InitializeListHead(&KiTimerListHead);
     KeInitializeDpc(&KiExpireTimerDpc, (PKDEFERRED_ROUTINE)KiExpireTimers, 0);
 
@@ -101,7 +97,7 @@ KiInitializeSystemClock(VOID)
     SharedUserData->SystemTime.High1Time = SystemBootTime.u.HighPart;
 
     KiClockSetupComplete = TRUE;
-    DPRINT("Finished KiInitializeSystemClock()\n");
+    DPRINT1("Finished KiInitializeSystemClock()\n");
 }
 
 VOID
@@ -234,192 +230,6 @@ KeSetTimeUpdateNotifyRoutine(
     UNIMPLEMENTED;
 }
 
-/*
- * NOTE: On Windows this function takes exactly one parameter and EBP is
- *       guaranteed to point to KTRAP_FRAME. The function is used only
- *       by HAL, so there's no point in keeping that prototype.
- *
- * @implemented
- */
-VOID
-STDCALL
-KeUpdateRunTime(IN PKTRAP_FRAME  TrapFrame,
-                IN KIRQL  Irql)
-{
-    PKPRCB Prcb = KeGetCurrentPrcb();
-    PKTHREAD CurrentThread = Prcb->CurrentThread;
-    PKPROCESS CurrentProcess = CurrentThread->ApcState.Process;
-
-    /* Increase interrupt count */
-    Prcb->InterruptCount++;
-
-    /* Check if we came from user mode */
-    if ((TrapFrame->EFlags & EFLAGS_V86_MASK) ||
-        (TrapFrame->SegCs & MODE_MASK))
-    {
-        /* Update user times */
-        CurrentThread->UserTime++;
-        InterlockedIncrement((PLONG)&CurrentProcess->UserTime);
-        Prcb->UserTime++;
-    }
-    else
-    {
-        /* Update CPU kernel time in all cases */
-        Prcb->KernelTime++;
-
-        /* Check IRQ */
-        if (Irql > DISPATCH_LEVEL)
-        {
-            /* This was an interrupt */
-            Prcb->InterruptTime++;
-        }
-        else if ((Irql < DISPATCH_LEVEL) || !(Prcb->DpcRoutineActive))
-        {
-            /* This was normal kernel time */
-            CurrentThread->KernelTime++;
-            InterlockedIncrement((PLONG)&CurrentProcess->KernelTime);
-        }
-        else if (Irql == DISPATCH_LEVEL)
-        {
-            /* This was DPC time */
-            Prcb->DpcTime++;
-        }
-   }
-
-    /* Set the last DPC Count and request rate */
-    Prcb->DpcLastCount = Prcb->DpcData[0].DpcCount;
-    Prcb->DpcRequestRate = ((Prcb->DpcData[0].DpcCount - Prcb->DpcLastCount) +
-                             Prcb->DpcRequestRate) / 2;
-
-    /* Check if we should request a DPC */
-    if ((Prcb->DpcData[0].DpcQueueDepth) &&
-        !(Prcb->DpcRoutineActive) &&
-        !(Prcb->DpcInterruptRequested))
-    {
-        /* Request one */
-        HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
-
-        /* Update the depth if needed */
-        if ((Prcb->DpcRequestRate < KiIdealDpcRate) &&
-            (Prcb->MaximumDpcQueueDepth > 1))
-        {
-            /* Decrease the maximum depth by one */
-            Prcb->MaximumDpcQueueDepth--;
-        }
-    }
-    else
-    {
-        /* Decrease the adjustment threshold */
-        if (!(--Prcb->AdjustDpcThreshold))
-        {
-            /* We've hit 0, reset it */
-            Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
-
-            /* Check if we've hit queue maximum */
-            if (KiMaximumDpcQueueDepth != Prcb->MaximumDpcQueueDepth)
-            {
-                /* Increase maximum by one */
-                Prcb->MaximumDpcQueueDepth++;
-            }
-        }
-    }
-
-   /*
-    * If we're at end of quantum request software interrupt. The rest
-    * is handled in KiDispatchInterrupt.
-    *
-    * NOTE: If one stays at DISPATCH_LEVEL for a long time the DPC routine
-    * which checks for quantum end will not be executed and decrementing
-    * the quantum here can result in overflow. This is not a problem since
-    * we don't care about the quantum value anymore after the QuantumEnd
-    * flag is set.
-    */
-    if (((CurrentThread->Quantum -= 3) <= 0) &&
-        (Prcb->IdleThread != CurrentThread))
-    {
-        Prcb->QuantumEnd = TRUE;
-        HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
-    }
-}
-
-
-/*
- * NOTE: On Windows this function takes exactly zero parameters and EBP is
- *       guaranteed to point to KTRAP_FRAME. Also [esp+0] contains an IRQL.
- *       The function is used only by HAL, so there's no point in keeping
- *       that prototype.
- *
- * @implemented
- */
-VOID
-STDCALL
-KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame,
-                   IN KIRQL Irql,
-                   IN ULONG Increment)
-{
-    LONG OldOffset;
-    LARGE_INTEGER Time;
-    ASSERT(KeGetCurrentIrql() == PROFILE_LEVEL);
-
-    /* Update interrupt time */
-    Time.LowPart = SharedUserData->InterruptTime.LowPart;
-    Time.HighPart = SharedUserData->InterruptTime.High1Time;
-    Time.QuadPart += Increment;
-    SharedUserData->InterruptTime.High2Time = Time.u.HighPart;
-    SharedUserData->InterruptTime.LowPart = Time.u.LowPart;
-    SharedUserData->InterruptTime.High1Time = Time.u.HighPart;
-
-    /* Increase the tick offset */
-    KiTickOffset -= Increment;
-    OldOffset = KiTickOffset;
-
-    /* Check if this isn't a tick yet */
-    if (KiTickOffset > 0)
-    {
-        /* Expire timers */
-        KeInsertQueueDpc(&KiExpireTimerDpc, (PVOID)TrapFrame->Eip, 0);
-    }
-    else
-    {
-        /* Setup time structure for system time */
-        Time.LowPart = SharedUserData->SystemTime.LowPart;
-        Time.HighPart = SharedUserData->SystemTime.High1Time;
-        Time.QuadPart += KeTimeAdjustment;
-        SharedUserData->SystemTime.High2Time = Time.HighPart;
-        SharedUserData->SystemTime.LowPart = Time.LowPart;
-        SharedUserData->SystemTime.High1Time = Time.HighPart;
-
-        /* Setup time structure for tick time */
-        Time.LowPart = KeTickCount.LowPart;
-        Time.HighPart = KeTickCount.High1Time;
-        Time.QuadPart += 1;
-        KeTickCount.High2Time = Time.HighPart;
-        KeTickCount.LowPart = Time.LowPart;
-        KeTickCount.High1Time = Time.HighPart;
-        SharedUserData->TickCount.High2Time = Time.HighPart;
-        SharedUserData->TickCount.LowPart = Time.LowPart;
-        SharedUserData->TickCount.High1Time = Time.HighPart;
-
-        /* Update tick count in shared user data as well */
-        SharedUserData->TickCountLowDeprecated++;
-
-        /* Queue a DPC that will expire timers */
-        KeInsertQueueDpc(&KiExpireTimerDpc, (PVOID)TrapFrame->Eip, 0);
-    }
-
-    /* Update process and thread times */
-    if (OldOffset <= 0)
-    {
-        /* This was a tick, calculate the next one */
-        KiTickOffset += KeMaximumIncrement;
-        KeUpdateRunTime(TrapFrame, Irql);
-    }
-
-    /* Return from the interrupt */
-    Ke386DisableInterrupts();
-    HalEndSystemInterrupt(Irql, 0);
-}
-
 /*
  * @implemented
  */
index 6c7b7af..cb2a26b 100644 (file)
 .extern _KiTickOffset\r
 .extern _KeTickCount\r
 .extern _KeMaximumIncrement\r
+.extern _KiExpireTimerDpc\r
 \r
 /* FUNCTIONS ******************************************************************/\r
 \r
-.globl _KeUpdateRunTime2@0\r
-.func KeUpdateRunTime2@0\r
-_KeUpdateRunTime2@0:\r
+.globl _KeUpdateRunTime@4\r
+.func KeUpdateRunTime@4\r
+_KeUpdateRunTime@4:\r
 \r
     /* Get KPCR */\r
     mov eax, [fs:KPCR_SELF]\r
@@ -155,9 +156,9 @@ QuantumNotEmpty:
     ret 4\r
 .endfunc\r
 \r
-.globl _KeUpdateSystemTime2@0\r
-.func KeUpdateSystemTime2@0\r
-_KeUpdateSystemTime2@0:\r
+.globl _KeUpdateSystemTime@0\r
+.func KeUpdateSystemTime@0\r
+_KeUpdateSystemTime@0:\r
 \r
     /* Get shared data in ECX */\r
     mov ecx, USER_SHARED_DATA\r
@@ -185,8 +186,8 @@ _KeUpdateSystemTime2@0:
     mov ebx, USER_SHARED_DATA\r
 \r
     /* Get system time */\r
-    mov edi, [ebx+USER_SHARED_DATA_SYSTEM_TIME]\r
-    mov esi, [ebx+USER_SHARED_DATA_SYSTEM_TIME+4]\r
+    mov ecx, [ebx+USER_SHARED_DATA_SYSTEM_TIME]\r
+    mov edx, [ebx+USER_SHARED_DATA_SYSTEM_TIME+4]\r
 \r
     /* Add the increment and get the carry */\r
     add ecx, _KeTimeAdjustment\r
@@ -218,9 +219,16 @@ _KeUpdateSystemTime2@0:
     mov [USER_SHARED_DATA+USER_SHARED_DATA_TICK_COUNT], ecx\r
     mov [USER_SHARED_DATA+USER_SHARED_DATA_TICK_COUNT+4], edx\r
 \r
+    /* FIXME: HACK */\r
+    mov [USER_SHARED_DATA], ecx\r
+\r
 IncompleteTick:\r
 \r
-    /* Queue DPC to handle registered timers */\r
+    /* FIXME: NASTY Queue DPC to handle registered timers */\r
+    push 0\r
+    push [esp+KTRAP_FRAME_EIP]\r
+    push offset _KiExpireTimerDpc\r
+    call _KeInsertQueueDpc@12\r
 \r
     /* Check if this was a full tick */\r
     cmp dword ptr _KiTickOffset, 0\r
@@ -231,8 +239,8 @@ IncompleteTick:
     add _KiTickOffset, eax\r
 \r
     /* Update system run time */\r
-    push esp\r
-    call _KeUpdateRunTime@8\r
+    push [esp]\r
+    call _KeUpdateRunTime@4\r
     jmp Done\r
 \r
 IncompleteTick2:\r
index 158cd16..edda59b 100644 (file)
@@ -83,29 +83,6 @@ KeInitInterrupts (VOID)
                             I486_INTERRUPT_GATE;
 }
 
-STATIC VOID
-KeIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame,
-                          PKTRAP_FRAME TrapFrame)
-{
-   TrapFrame->SegGs     = (USHORT)IrqTrapFrame->Gs;
-   TrapFrame->SegFs     = (USHORT)IrqTrapFrame->Fs;
-   TrapFrame->SegEs     = (USHORT)IrqTrapFrame->Es;
-   TrapFrame->SegDs     = (USHORT)IrqTrapFrame->Ds;
-   TrapFrame->Eax    = IrqTrapFrame->Eax;
-   TrapFrame->Ecx    = IrqTrapFrame->Ecx;
-   TrapFrame->Edx    = IrqTrapFrame->Edx;
-   TrapFrame->Ebx    = IrqTrapFrame->Ebx;
-   TrapFrame->HardwareEsp    = IrqTrapFrame->Esp;
-   TrapFrame->Ebp    = IrqTrapFrame->Ebp;
-   TrapFrame->Esi    = IrqTrapFrame->Esi;
-   TrapFrame->Edi    = IrqTrapFrame->Edi;
-   TrapFrame->Eip    = IrqTrapFrame->Eip;
-   TrapFrame->SegCs     = IrqTrapFrame->Cs;
-   TrapFrame->EFlags = IrqTrapFrame->Eflags;
-}
-
-extern BOOLEAN KiClockSetupComplete;
-
 VOID
 KiInterruptDispatch (ULONG vector, PKIRQ_TRAPFRAME Trapframe)
 /*
@@ -115,23 +92,6 @@ KiInterruptDispatch (ULONG vector, PKIRQ_TRAPFRAME Trapframe)
  */
 {
    KIRQL old_level;
-   KTRAP_FRAME KernelTrapFrame;
-   ASSERT(vector == 0x30);
-#if 0
-   PULONG Frame;
-   DPRINT1("Received Interrupt: %lx\n", vector);
-   DPRINT1("My trap frame: %p\n", Trapframe);
-   DPRINT1("Stack trace\n");
-   __asm__("mov %%ebp, %0" : "=r" (Frame) : );
-   DPRINT1("Stack trace: %p %p %p %p\n", Frame, *Frame, Frame[1], *(PULONG)Frame[1]);
-   DPRINT1("Clock setup: %lx\n", KiClockSetupComplete);
-      if (KiClockSetupComplete) while(TRUE);
-#endif
-
-   /*
-    * At this point we have interrupts disabled, nothing has been done to
-    * the PIC.
-    */
    KeGetCurrentPrcb()->InterruptCount++;
 
    /*
@@ -145,23 +105,7 @@ KiInterruptDispatch (ULONG vector, PKIRQ_TRAPFRAME Trapframe)
        return;
      }
 
-
-   /*
-    * Enable interrupts
-    * NOTE: Only higher priority interrupts will get through
-    */
    Ke386EnableInterrupts();
-
-       //DPRINT1("Tick\n");
-   if (KiClockSetupComplete)
-   {
-      KeIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
-      return KeUpdateSystemTime(&KernelTrapFrame, old_level, 100000);
-   }
-
-   /*
-    * End the system interrupt.
-    */
    Ke386DisableInterrupts();
    HalEndSystemInterrupt (old_level, 0);
 }
index 6cacb7a..f287368 100644 (file)
@@ -647,8 +647,8 @@ KeSynchronizeExecution@12
 KeTerminateThread@4
 KeTickCount DATA
 @KeTryToAcquireGuardedMutex@4
-KeUpdateRunTime@8
-KeUpdateSystemTime@12
+KeUpdateRunTime@4
+KeUpdateSystemTime@0
 KeUnstackDetachProcess@4
 KeUserModeCallback@20
 KeWaitForMultipleObjects@32