mirror of
https://github.com/reactos/reactos.git
synced 2024-07-27 14:49:22 +00:00
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:
parent
0237c83496
commit
93970a965e
|
@ -17,6 +17,8 @@
|
||||||
#include <ndk/halfuncs.h>
|
#include <ndk/halfuncs.h>
|
||||||
#include <ndk/iofuncs.h>
|
#include <ndk/iofuncs.h>
|
||||||
#include <ndk/kdfuncs.h>
|
#include <ndk/kdfuncs.h>
|
||||||
|
#include <internal/arm/ke.h>
|
||||||
|
#include <internal/arm/intrin_i.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
@ -1090,16 +1092,66 @@ KeSwapIrql(IN KIRQL Irql)
|
||||||
return 0;
|
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
|
VOID
|
||||||
HalSweepDcache(VOID)
|
HalSweepDcache(VOID)
|
||||||
{
|
{
|
||||||
|
//
|
||||||
|
// 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;
|
UNIMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
HalSweepIcache(VOID)
|
HalSweepIcache(VOID)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
//
|
||||||
|
// All ARM cores support the same Icache flush command, no need for HAL work
|
||||||
|
//
|
||||||
|
KeArmFlushIcache();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -5368,6 +5368,8 @@ typedef VOID
|
||||||
/*
|
/*
|
||||||
** Architecture specific structures
|
** Architecture specific structures
|
||||||
*/
|
*/
|
||||||
|
#define PCR_MINOR_VERSION 1
|
||||||
|
#define PCR_MAJOR_VERSION 1
|
||||||
|
|
||||||
#ifdef _X86_
|
#ifdef _X86_
|
||||||
|
|
||||||
|
@ -5397,9 +5399,6 @@ typedef struct _KPCR_TIB {
|
||||||
struct _KPCR_TIB *Self; /* 18 */
|
struct _KPCR_TIB *Self; /* 18 */
|
||||||
} KPCR_TIB, *PKPCR_TIB; /* 1C */
|
} KPCR_TIB, *PKPCR_TIB; /* 1C */
|
||||||
|
|
||||||
#define PCR_MINOR_VERSION 1
|
|
||||||
#define PCR_MAJOR_VERSION 1
|
|
||||||
|
|
||||||
typedef struct _KPCR {
|
typedef struct _KPCR {
|
||||||
KPCR_TIB Tib; /* 00 */
|
KPCR_TIB Tib; /* 00 */
|
||||||
struct _KPCR *Self; /* 1C */
|
struct _KPCR *Self; /* 1C */
|
||||||
|
|
|
@ -99,5 +99,12 @@ KeArmInvalidateTlbEntry(IN PVOID Address)
|
||||||
__asm__ __volatile__ ("mcr p15, 0, %0, c8, c7, 1" : : "r"(Address) : "cc");
|
__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
|
#endif
|
||||||
|
|
|
@ -141,6 +141,131 @@ KeFlushTb(VOID)
|
||||||
KeArmFlushTlb();
|
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
|
VOID
|
||||||
KiInitializeSystem(IN ULONG Magic,
|
KiInitializeSystem(IN ULONG Magic,
|
||||||
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||||
|
@ -281,5 +406,54 @@ KiInitializeSystem(IN ULONG Magic,
|
||||||
//
|
//
|
||||||
HalSweepIcache();
|
HalSweepIcache();
|
||||||
HalSweepDcache();
|
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);
|
while (TRUE);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue