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?re... ============================================================================== --- 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=32... ============================================================================== --- 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/a... ============================================================================== --- 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?re... ============================================================================== --- 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); }