From fe22db7c05979636bfeb2cbb4bc18c72572cfd77 Mon Sep 17 00:00:00 2001 From: ReactOS Portable Systems Group Date: Sat, 14 Jun 2008 22:48:30 +0000 Subject: [PATCH] - We now implement the idle loop (thanks for fixing the interrupt code...). - We are now back to HalInitSystem just like before the previous fixes. - Now we'll implement stall calibration and switch to the clock interrupt. svn path=/trunk/; revision=33970 --- reactos/ntoskrnl/ke/arm/kiinit.c | 5 +- reactos/ntoskrnl/ke/arm/trapc.c | 98 ++++++++++++++++++++++++++++---- 2 files changed, 92 insertions(+), 11 deletions(-) diff --git a/reactos/ntoskrnl/ke/arm/kiinit.c b/reactos/ntoskrnl/ke/arm/kiinit.c index 8ee7be0b6c6..6aee533c45c 100644 --- a/reactos/ntoskrnl/ke/arm/kiinit.c +++ b/reactos/ntoskrnl/ke/arm/kiinit.c @@ -23,6 +23,9 @@ extern PVOID KiArmVectorTable; /* FUNCTIONS ******************************************************************/ +VOID +KiIdleLoop(VOID); + VOID DebugService(IN ULONG ServiceType, IN PCHAR Buffer, @@ -495,5 +498,5 @@ KiInitializeSystem(IN ULONG Magic, // // Jump to idle loop // - while (TRUE); + KiIdleLoop(); } diff --git a/reactos/ntoskrnl/ke/arm/trapc.c b/reactos/ntoskrnl/ke/arm/trapc.c index 2c061506ffa..fd32cc01ba4 100644 --- a/reactos/ntoskrnl/ke/arm/trapc.c +++ b/reactos/ntoskrnl/ke/arm/trapc.c @@ -33,6 +33,81 @@ HalGetInterruptSource(VOID); VOID FASTCALL HalClearSoftwareInterrupt(IN KIRQL Request); +VOID +KiIdleLoop(VOID) +{ + PKPCR Pcr = (PKPCR)KeGetPcr(); + PKPRCB Prcb = Pcr->Prcb; + PKTHREAD OldThread, NewThread; + + // + // Loop forever... that's why this is an idle loop + // + while (TRUE) + { + // + // Cycle interrupts + // + _disable(); + _enable(); + + // + // Check if there's DPC work to do + // + if ((Prcb->DpcData[0].DpcQueueDepth) || + (Prcb->TimerRequest) || + (Prcb->DeferredReadyListHead.Next)) + { + // + // Clear the pending interrupt + // + HalClearSoftwareInterrupt(DISPATCH_LEVEL); + + // + // FIXME: TODO + // + DPRINT1("DPC/Timer Delivery!\n"); + while (TRUE); + } + + // + // Check if there's a thread to schedule + // + if (Prcb->NextThread) + { + // + // Out with the old, in with the new... + // + OldThread = Prcb->CurrentThread; + NewThread = Prcb->NextThread; + Prcb->CurrentThread = NewThread; + Prcb->NextThread = NULL; + + // + // Update thread state + // + NewThread->State = Running; + + // + // Swap to the new thread + // On ARM we call KiSwapContext instead of KiSwapContextInternal, + // because we're calling this from C code and not assembly. + // This is similar to how it gets called for unwaiting, on x86 + // + DPRINT1("Swapping context!\n"); + KiSwapContext(OldThread, NewThread); + DPRINT1("Back\n"); + while (TRUE); + } + else + { + // + // FIXME: Wait-For-Interrupt ARM Opcode + // + } + } +} + BOOLEAN KiSwapContextInternal(IN PKTHREAD OldThread, IN PKTHREAD NewThread) @@ -155,20 +230,22 @@ VOID KiDispatchInterrupt(VOID) { PKPCR Pcr; + PKPRCB Prcb; PKTHREAD NewThread, OldThread; // // Get the PCR and disable interrupts // Pcr = (PKPCR)KeGetPcr(); + Prcb = Pcr->Prcb; _disable(); // //Check if we have to deliver DPCs, timers, or deferred threads // - if ((Pcr->Prcb->DpcData[0].DpcQueueDepth) || - (Pcr->Prcb->TimerRequest) || - (Pcr->Prcb->DeferredReadyListHead.Next)) + if ((Prcb->DpcData[0].DpcQueueDepth) || + (Prcb->TimerRequest) || + (Prcb->DeferredReadyListHead.Next)) { // // FIXME: TODO @@ -185,7 +262,7 @@ KiDispatchInterrupt(VOID) // // Check for quantum end // - if (Pcr->Prcb->QuantumEnd) + if (Prcb->QuantumEnd) { // // FIXME: TODO @@ -198,15 +275,15 @@ KiDispatchInterrupt(VOID) // // Check if we have a thread to swap to // - if (Pcr->Prcb->NextThread) + if (Prcb->NextThread) { // // Next is now current // - OldThread = Pcr->Prcb->CurrentThread; - NewThread = Pcr->Prcb->NextThread; - Pcr->Prcb->CurrentThread = NewThread; - Pcr->Prcb->NextThread = NULL; + OldThread = Prcb->CurrentThread; + NewThread = Prcb->NextThread; + Prcb->CurrentThread = NewThread; + Prcb->NextThread = NULL; // // Update thread states @@ -217,7 +294,7 @@ KiDispatchInterrupt(VOID) // // Make the old thread ready // - KxQueueReadyThread(OldThread, Pcr->Prcb); + KxQueueReadyThread(OldThread, Prcb); // // Swap to the new thread @@ -227,6 +304,7 @@ KiDispatchInterrupt(VOID) // DPRINT1("Swapping context!\n"); KiSwapContext(OldThread, NewThread); + DPRINT1("Back\n"); while (TRUE); } }