[NTOS]: Some more ARM build and linker fixes, moving some of the new x86 C code into...
authorSir Richard <sir_richard@svn.reactos.org>
Wed, 24 Nov 2010 17:49:52 +0000 (17:49 +0000)
committerSir Richard <sir_richard@svn.reactos.org>
Wed, 24 Nov 2010 17:49:52 +0000 (17:49 +0000)
[NTOS]: Totally broke thread context switching on ARM for now. It's a Good Thing.

svn path=/trunk/; revision=49781

reactos/ntoskrnl/ke/arm/cpu.c
reactos/ntoskrnl/ke/arm/ctxswtch.s
reactos/ntoskrnl/ke/arm/thrdini.c
reactos/ntoskrnl/ntoskrnl.pspec

index 275df6c..37d8a15 100644 (file)
@@ -57,6 +57,15 @@ KeFlushCurrentTb(VOID)
     KeFlushTb();
 }
 
+VOID
+FASTCALL
+KeZeroPages(IN PVOID Address,
+            IN ULONG Size)
+{
+    /* Not using XMMI in this routine */
+    RtlZeroMemory(Address, Size);
+}
+
 VOID
 NTAPI
 KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)
index a8f391f..0d6bb54 100644 (file)
     TEXTAREA
     NESTED_ENTRY KiSwapContext
     PROLOG_END KiSwapContext
+
+       // BUSTEDDDD
+       b .
+
     //
     // a1 = Old Thread
     // a2 = New Thread
     b .
     
     ENTRY_END KiThreadStartup
+
+    NESTED_ENTRY KiSwitchThreads
+    PROLOG_END KiSwitchThreads
+
+       // BUSTEDDDD
+       b .
+
+    ENTRY_END KiSwitchThreads
+
+    NESTED_ENTRY KiSwapContextInternal
+    PROLOG_END KiSwapContextInternal
+
+       // BUSTEDDDD
+       b .
+
+    ENTRY_END KiSwapContextInternal
index 16700f5..cae9b75 100644 (file)
 
 /* GLOBALS ********************************************************************/
 
+typedef struct _KSWITCHFRAME
+{
+    PVOID ExceptionList;
+    BOOLEAN ApcBypassDisable;
+    PVOID RetAddr;
+} KSWITCHFRAME, *PKSWITCHFRAME;
+
 typedef struct _KUINIT_FRAME
 {
     KEXCEPTION_FRAME CtxSwitchFrame;
@@ -32,6 +39,15 @@ VOID
 NTAPI
 KiThreadStartup(VOID);
 
+VOID
+FASTCALL
+KiSwitchThreads(
+    IN PKTHREAD OldThread,
+    IN PKTHREAD NewThread
+);
+
+
+/* FIXME: THIS IS TOTALLY BUSTED NOW */
 VOID
 NTAPI
 KiInitializeContextThread(IN PKTHREAD Thread,
@@ -131,3 +147,217 @@ KiInitializeContextThread(IN PKTHREAD Thread,
     //
     Thread->KernelStack = (PVOID)CtxSwitchFrame;
 }
+
+VOID
+FASTCALL
+KiIdleLoop(VOID)
+{
+    PKPRCB Prcb = KeGetCurrentPrcb();
+    PKTHREAD OldThread, NewThread;
+
+    /* Initialize the idle loop: disable interrupts */
+    _enable();
+    YieldProcessor();
+    YieldProcessor();
+    _disable();
+
+    /* Now loop forever */
+    while (TRUE)
+    {
+        /* Check for pending timers, pending DPCs, or pending ready threads */
+        if ((Prcb->DpcData[0].DpcQueueDepth) ||
+            (Prcb->TimerRequest) ||
+            (Prcb->DeferredReadyListHead.Next))
+        {
+            /* Quiesce the DPC software interrupt */
+            HalClearSoftwareInterrupt(DISPATCH_LEVEL);
+
+            /* Handle it */
+            KiRetireDpcList(Prcb);
+        }
+
+        /* Check if a new thread is scheduled for execution */
+        if (Prcb->NextThread)
+        {
+            /* Enable interupts */
+            _enable();
+
+            /* Capture current thread data */
+            OldThread = Prcb->CurrentThread;
+            NewThread = Prcb->NextThread;
+
+            /* Set new thread data */
+            Prcb->NextThread = NULL;
+            Prcb->CurrentThread = NewThread;
+
+            /* The thread is now running */
+            NewThread->State = Running;
+
+            /* Switch away from the idle thread */
+            KiSwapContext(APC_LEVEL, OldThread);
+
+            /* We are back in the idle thread -- disable interrupts again */
+            _enable();
+            YieldProcessor();
+            YieldProcessor();
+            _disable();
+        }
+        else
+        {
+            /* Continue staying idle. Note the HAL returns with interrupts on */
+            Prcb->PowerState.IdleFunction(&Prcb->PowerState);
+        }
+    }
+}
+
+BOOLEAN
+FASTCALL
+KiSwapContextExit(IN PKTHREAD OldThread,
+                  IN PKSWITCHFRAME SwitchFrame)
+{
+    PKIPCR Pcr = (PKIPCR)KeGetPcr();
+    PKPROCESS OldProcess, NewProcess;
+    PKTHREAD NewThread;
+    ARM_TTB_REGISTER TtbRegister;
+
+    /* We are on the new thread stack now */
+    NewThread = Pcr->PrcbData.CurrentThread;
+
+    /* Now we are the new thread. Check if it's in a new process */
+    OldProcess = OldThread->ApcState.Process;
+    NewProcess = NewThread->ApcState.Process;
+    if (OldProcess != NewProcess)
+    {
+        TtbRegister.AsUlong = NewProcess->DirectoryTableBase[0];
+        ASSERT(TtbRegister.Reserved == 0);
+        KeArmTranslationTableRegisterSet(TtbRegister);
+    }
+
+    /* Increase thread context switches */
+    NewThread->ContextSwitches++;
+
+    /* Load data from switch frame */
+    Pcr->NtTib.ExceptionList = SwitchFrame->ExceptionList;
+
+    /* DPCs shouldn't be active */
+    if (Pcr->PrcbData.DpcRoutineActive)
+    {
+        /* Crash the machine */
+        KeBugCheckEx(ATTEMPTED_SWITCH_FROM_DPC,
+                     (ULONG_PTR)OldThread,
+                     (ULONG_PTR)NewThread,
+                     (ULONG_PTR)OldThread->InitialStack,
+                     0);
+    }
+
+    /* Kernel APCs may be pending */
+    if (NewThread->ApcState.KernelApcPending)
+    {
+        /* Are APCs enabled? */
+        if (!NewThread->SpecialApcDisable)
+        {
+            /* Request APC delivery */
+            if (SwitchFrame->ApcBypassDisable) HalRequestSoftwareInterrupt(APC_LEVEL);
+            return TRUE;
+        }
+    }
+
+    /* Return */
+    return FALSE;
+}
+
+VOID
+FASTCALL
+KiSwapContextEntry(IN PKSWITCHFRAME SwitchFrame,
+                   IN ULONG_PTR OldThreadAndApcFlag)
+{
+    PKIPCR Pcr = (PKIPCR)KeGetPcr();
+    PKTHREAD OldThread, NewThread;
+
+    /* Save APC bypass disable */
+    SwitchFrame->ApcBypassDisable = OldThreadAndApcFlag & 3;
+    SwitchFrame->ExceptionList = Pcr->NtTib.ExceptionList;
+
+    /* Increase context switch count and check if tracing is enabled */
+    Pcr->ContextSwitches++;
+    if (Pcr->PerfGlobalGroupMask)
+    {
+        /* We don't support this yet on x86 either */
+        DPRINT1("WMI Tracing not supported\n");
+        ASSERT(FALSE);
+    }
+
+    /* Get thread pointers */
+    OldThread = (PKTHREAD)(OldThreadAndApcFlag & ~3);
+    NewThread = Pcr->PrcbData.CurrentThread;
+
+    /* Get the old thread and set its kernel stack */
+    OldThread->KernelStack = SwitchFrame;
+
+    /* Do the switch */
+    KiSwitchThreads(OldThread, NewThread->KernelStack);
+}
+
+VOID
+NTAPI
+KiDispatchInterrupt(VOID)
+{
+    PKIPCR Pcr = (PKIPCR)KeGetPcr();
+    PKPRCB Prcb = &Pcr->PrcbData;
+    PVOID OldHandler;
+    PKTHREAD NewThread, OldThread;
+
+    /* Disable interrupts */
+    _disable();
+
+    /* Check for pending timers, pending DPCs, or pending ready threads */
+    if ((Prcb->DpcData[0].DpcQueueDepth) ||
+        (Prcb->TimerRequest) ||
+        (Prcb->DeferredReadyListHead.Next))
+    {
+        /* Switch to safe execution context */
+        OldHandler = Pcr->NtTib.ExceptionList;
+        Pcr->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
+
+        /* Retire DPCs while under the DPC stack */
+        //KiRetireDpcListInDpcStack(Prcb, Prcb->DpcStack);
+        // FIXME!!! //
+        KiRetireDpcList(Prcb);
+
+        /* Restore context */
+        Pcr->NtTib.ExceptionList = OldHandler;
+    }
+
+    /* Re-enable interrupts */
+    _enable();
+
+    /* Check for quantum end */
+    if (Prcb->QuantumEnd)
+    {
+        /* Handle quantum end */
+        Prcb->QuantumEnd = FALSE;
+        KiQuantumEnd();
+    }
+    else if (Prcb->NextThread)
+    {       
+        /* Capture current thread data */
+        OldThread = Prcb->CurrentThread;
+        NewThread = Prcb->NextThread;
+
+        /* Set new thread data */
+        Prcb->NextThread = NULL;
+        Prcb->CurrentThread = NewThread;
+
+        /* The thread is now running */
+        NewThread->State = Running;
+        OldThread->WaitReason = WrDispatchInt;
+
+        /* Make the old thread ready */
+        KxQueueReadyThread(OldThread, Prcb);
+
+        /* Swap to the new thread */
+        KiSwapContext(APC_LEVEL, OldThread);
+    }
+}
+
+/* EOF */
index 12a4139..1c65cc2 100644 (file)
 @ FASTCALL ExInterlockedAddLargeStatistic(ptr long)
 #endif
 @ stdcall ExInterlockedAddUlong(ptr long ptr)
-#ifndef __x86_64__
+#ifdef __x86__
 @ FASTCALL ExInterlockedCompareExchange64(ptr ptr ptr ptr)
 @ stdcall ExInterlockedDecrementLong(ptr ptr)
 @ stdcall ExInterlockedExchangeUlong(ptr long ptr)