[ros-diffs] [ros-arm-bringup] 32333: Added cache sweeping code into the HAL, for ARM926EJ-S and ARM1026EJ-S CPUs. Finished implementation of KiSystemStartup. Copied KiInitializeKernel from x86 to ARM, removing irrelevant parts. This is our current checkpoint.

ros-arm-bringup at svn.reactos.org ros-arm-bringup at svn.reactos.org
Tue Feb 12 21:32:24 CET 2008


Author: ros-arm-bringup
Date: Tue Feb 12 23:32:23 2008
New Revision: 32333

URL: http://svn.reactos.org/svn/reactos?rev=32333&view=rev
Log:
Added cache sweeping code into the HAL, for ARM926EJ-S and ARM1026EJ-S CPUs.
Finished implementation of KiSystemStartup.
Copied KiInitializeKernel from x86 to ARM, removing irrelevant parts. This is our current checkpoint.

Modified:
    trunk/reactos/hal/halarm/generic/hal.c
    trunk/reactos/include/ddk/winddk.h
    trunk/reactos/ntoskrnl/include/internal/arm/intrin_i.h
    trunk/reactos/ntoskrnl/ke/arm/kiinit.c

Modified: trunk/reactos/hal/halarm/generic/hal.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halarm/generic/hal.c?rev=32333&r1=32332&r2=32333&view=diff
==============================================================================
--- trunk/reactos/hal/halarm/generic/hal.c (original)
+++ trunk/reactos/hal/halarm/generic/hal.c Tue Feb 12 23:32:23 2008
@@ -17,6 +17,8 @@
 #include <ndk/halfuncs.h>
 #include <ndk/iofuncs.h>
 #include <ndk/kdfuncs.h>
+#include <internal/arm/ke.h>
+#include <internal/arm/intrin_i.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -1090,16 +1092,66 @@
     return 0;
 }
 
+BOOLEAN HalpProcessorIdentified;
+BOOLEAN HalpTestCleanSupported;
+
+VOID
+HalpIdentifyProcessor(VOID)
+{
+    ARM_ID_CODE_REGISTER IdRegister;
+
+    //
+    // Don't do it again
+    //
+    HalpProcessorIdentified = TRUE;
+    
+    //
+    // Read the ID Code
+    //
+    IdRegister = KeArmIdCodeRegisterGet();
+    
+    //
+    // Architecture "6" CPUs support test-and-clean (926EJ-S and 1026EJ-S)
+    //
+    HalpTestCleanSupported = (IdRegister.Architecture == 6);
+}
+
+
 VOID
 HalSweepDcache(VOID)
 {
-    UNIMPLEMENTED;
+    //
+    // We get called very early on, before HalInitSystem or any of the Hal*
+    // processor routines, so we need to figure out what CPU we're on.
+    //
+    if (!HalpProcessorIdentified) HalpIdentifyProcessor();
+    
+    //
+    // Check if we can do it the ARMv5TE-J way
+    //
+    if (HalpTestCleanSupported)
+    {
+        //
+        // Test, clean, flush D-Cache
+        //
+        __asm__ __volatile__ ("1: mrc p15, 0, pc, c7, c14, 3; bne 1b");
+    }
+    else
+    {
+        //
+        // We need to do it it by set/way
+        //
+        UNIMPLEMENTED;
+    }
 }
 
 VOID
 HalSweepIcache(VOID)
 {
-    UNIMPLEMENTED;
+    //
+    // All ARM cores support the same Icache flush command, no need for HAL work
+    //
+    KeArmFlushIcache();
 }
 
 /* EOF */

Modified: trunk/reactos/include/ddk/winddk.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ddk/winddk.h?rev=32333&r1=32332&r2=32333&view=diff
==============================================================================
--- trunk/reactos/include/ddk/winddk.h (original)
+++ trunk/reactos/include/ddk/winddk.h Tue Feb 12 23:32:23 2008
@@ -5368,7 +5368,9 @@
 /*
 ** Architecture specific structures
 */
-
+#define PCR_MINOR_VERSION 1
+#define PCR_MAJOR_VERSION 1
+    
 #ifdef _X86_
 
 typedef ULONG PFN_NUMBER, *PPFN_NUMBER;
@@ -5396,9 +5398,6 @@
   PVOID  ArbitraryUserPointer;  /* 14 */
   struct _KPCR_TIB *Self;       /* 18 */
 } KPCR_TIB, *PKPCR_TIB;         /* 1C */
-
-#define PCR_MINOR_VERSION 1
-#define PCR_MAJOR_VERSION 1
 
 typedef struct _KPCR {
   KPCR_TIB  Tib;                /* 00 */

Modified: trunk/reactos/ntoskrnl/include/internal/arm/intrin_i.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/arm/intrin_i.h?rev=32333&r1=32332&r2=32333&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/arm/intrin_i.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/arm/intrin_i.h Tue Feb 12 23:32:23 2008
@@ -99,5 +99,12 @@
     __asm__ __volatile__ ("mcr p15, 0, %0, c8, c7, 1" : : "r"(Address) : "cc");
 }
 
+FORCEINLINE
+VOID
+KeArmFlushIcache(VOID)
+{
+    __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 0" : : "r"(0) : "cc");
+}
+
 
 #endif

Modified: trunk/reactos/ntoskrnl/ke/arm/kiinit.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/kiinit.c?rev=32333&r1=32332&r2=32333&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/arm/kiinit.c (original)
+++ trunk/reactos/ntoskrnl/ke/arm/kiinit.c Tue Feb 12 23:32:23 2008
@@ -139,6 +139,131 @@
     // Flush the entire TLB
     //
     KeArmFlushTlb();
+}
+
+VOID
+NTAPI
+KiInitializeKernel(IN PKPROCESS InitProcess,
+                   IN PKTHREAD InitThread,
+                   IN PVOID IdleStack,
+                   IN PKPRCB Prcb,
+                   IN CCHAR Number,
+                   IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+    LARGE_INTEGER PageDirectory;
+    PVOID DpcStack;
+    DPRINT1("%s Process: %p Thread: %p Stack: %p PRCB: %p Number: %d LoaderBlock: %p\n",
+            __FUNCTION__, InitProcess, InitThread, IdleStack, Prcb, Number, LoaderBlock);
+
+    /* Initialize the Power Management Support for this PRCB */
+    PoInitializePrcb(Prcb);
+    
+    /* Save CPU state */
+    KiSaveProcessorControlState(&Prcb->ProcessorState);
+    
+    /* Initialize spinlocks and DPC data */
+    KiInitSpinLocks(Prcb, Number);
+    
+    /* Check if this is the Boot CPU */
+    if (!Number)
+    {
+        /* Set Node Data */
+        KeNodeBlock[0] = &KiNode0;
+        Prcb->ParentNode = KeNodeBlock[0];
+        KeNodeBlock[0]->ProcessorMask = Prcb->SetMember;
+          
+        /* Lower to APC_LEVEL */
+        KeLowerIrql(APC_LEVEL);
+        
+        /* Initialize portable parts of the OS */
+        KiInitSystem();
+        
+        /* Initialize the Idle Process and the Process Listhead */
+        InitializeListHead(&KiProcessListHead);
+        PageDirectory.QuadPart = 0;
+        KeInitializeProcess(InitProcess,
+                            0,
+                            0xFFFFFFFF,
+                            &PageDirectory,
+                            FALSE);
+        InitProcess->QuantumReset = MAXCHAR;
+    }
+    else
+    {
+        /* FIXME */
+        DPRINT1("SMP Boot support not yet present\n");
+    }
+    
+    /* Setup the Idle Thread */
+    KeInitializeThread(InitProcess,
+                       InitThread,
+                       NULL,
+                       NULL,
+                       NULL,
+                       NULL,
+                       NULL,
+                       IdleStack);
+    InitThread->NextProcessor = Number;
+    InitThread->Priority = HIGH_PRIORITY;
+    InitThread->State = Running;
+    InitThread->Affinity = 1 << Number;
+    InitThread->WaitIrql = DISPATCH_LEVEL;
+    InitProcess->ActiveProcessors = 1 << Number;
+    
+    /* HACK for MmUpdatePageDir */
+    ((PETHREAD)InitThread)->ThreadsProcess = (PEPROCESS)InitProcess;
+    
+    /* Initialize Kernel Memory Address Space */
+    MmInit1(MmFreeLdrFirstKrnlPhysAddr,
+            MmFreeLdrLastKrnlPhysAddr,
+            MmFreeLdrLastKernelAddress,
+            NULL,
+            0,
+            4096);
+    
+    /* Set basic CPU Features that user mode can read */
+    
+    /* Set up the thread-related fields in the PRCB */
+    Prcb->CurrentThread = InitThread;
+    Prcb->NextThread = NULL;
+    Prcb->IdleThread = InitThread;
+    
+    /* Initialize the Kernel Executive */
+    ExpInitializeExecutive(Number, LoaderBlock);
+    
+    /* Only do this on the boot CPU */
+    if (!Number)
+    {
+        /* Calculate the time reciprocal */
+        KiTimeIncrementReciprocal =
+        KiComputeReciprocal(KeMaximumIncrement,
+                            &KiTimeIncrementShiftCount);
+        
+        /* Update DPC Values in case they got updated by the executive */
+        Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
+        Prcb->MinimumDpcRate = KiMinimumDpcRate;
+        Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
+        
+        /* Allocate the DPC Stack */
+        DpcStack = MmCreateKernelStack(FALSE, 0);
+        if (!DpcStack) KeBugCheckEx(NO_PAGES_AVAILABLE, 1, 0, 0, 0);
+        Prcb->DpcStack = DpcStack;
+    }
+    
+    /* Raise to Dispatch */
+    KeSwapIrql(DISPATCH_LEVEL);
+    
+    /* Set the Idle Priority to 0. This will jump into Phase 1 */
+    KeSetPriorityThread(InitThread, 0);
+    
+    /* If there's no thread scheduled, put this CPU in the Idle summary */
+    KiAcquirePrcbLock(Prcb);
+    if (!Prcb->NextThread) KiIdleSummary |= 1 << Number;
+    KiReleasePrcbLock(Prcb);
+    
+    /* Raise back to HIGH_LEVEL and clear the PRCB for the loader block */
+    KeSwapIrql(HIGH_LEVEL);
+    LoaderBlock->Prcb = 0;
 }
 
 VOID
@@ -281,5 +406,54 @@
     //
     HalSweepIcache();
     HalSweepDcache();
+    
+    //
+    // Set PCR version
+    //
+    Pcr->MinorVersion = PCR_MINOR_VERSION;
+    Pcr->MajorVersion = PCR_MAJOR_VERSION;
+    
+    //
+    // Set boot PRCB
+    //
+    Pcr->Prcb = (PKPRCB)LoaderBlock->Prcb;
+    
+    //
+    // Set the different stacks
+    //
+    Pcr->InitialStack = (PVOID)LoaderBlock->KernelStack;
+    Pcr->PanicStack = (PVOID)LoaderBlock->u.Arm.PanicStack;
+    Pcr->InterruptStack = (PVOID)LoaderBlock->u.Arm.InterruptStack;
+    
+    //
+    // Set the current thread
+    //
+    Pcr->CurrentThread = (PKTHREAD)LoaderBlock->Thread;
+    
+    //
+    // Set the current IRQL to high
+    //
+    Pcr->CurrentIrql = HIGH_LEVEL;
+    
+    //
+    // Set processor information
+    //
+    Pcr->ProcessorId = KeArmIdCodeRegisterGet().AsUlong;
+    Pcr->SystemReserved[0] = KeArmControlRegisterGet().AsUlong;
+    
+    //
+    // Initialize the rest of the kernel now
+    //
+    KiInitializeKernel((PKPROCESS)LoaderBlock->Process,
+                       (PKTHREAD)LoaderBlock->Thread,
+                       (PVOID)LoaderBlock->KernelStack,
+                       (PKPRCB)LoaderBlock->Prcb,
+                       Pcr->Prcb->Number,
+                       LoaderBlock);
+    
+    
+    //
+    // Jump to idle loop
+    //
     while (TRUE);
 }




More information about the Ros-diffs mailing list