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?r…
==============================================================================
--- 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=3…
==============================================================================
--- 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/…
==============================================================================
--- 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?r…
==============================================================================
--- 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);
}