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.

svn path=/trunk/; revision=32333
This commit is contained in:
ReactOS Portable Systems Group 2008-02-12 20:32:23 +00:00
parent 0237c83496
commit 93970a965e
4 changed files with 238 additions and 6 deletions

View file

@ -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 @@ KeSwapIrql(IN KIRQL Irql)
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 */

View file

@ -5368,7 +5368,9 @@ typedef VOID
/*
** Architecture specific structures
*/
#define PCR_MINOR_VERSION 1
#define PCR_MAJOR_VERSION 1
#ifdef _X86_
typedef ULONG PFN_NUMBER, *PPFN_NUMBER;
@ -5397,9 +5399,6 @@ typedef struct _KPCR_TIB {
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 */
struct _KPCR *Self; /* 1C */

View file

@ -99,5 +99,12 @@ KeArmInvalidateTlbEntry(IN PVOID Address)
__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

View file

@ -141,6 +141,131 @@ KeFlushTb(VOID)
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
KiInitializeSystem(IN ULONG Magic,
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
@ -281,5 +406,54 @@ KiInitializeSystem(IN ULONG Magic,
//
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);
}