ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

kiinit.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Kernel
00003  * LICENSE:         BSD - See COPYING.ARM in the top level directory
00004  * FILE:            ntoskrnl/ke/arm/kiinit.c
00005  * PURPOSE:         Implements the kernel entry point for ARM machines
00006  * PROGRAMMERS:     ReactOS Portable Systems Group
00007  */
00008 
00009 /* INCLUDES *******************************************************************/
00010 
00011 #include <ntoskrnl.h>
00012 #define NDEBUG
00013 #include <debug.h>
00014 
00015 /* GLOBALS ********************************************************************/
00016 
00017 KINTERRUPT KxUnexpectedInterrupt;
00018 BOOLEAN KeIsArmV6;
00019 ULONG KeNumberProcessIds;
00020 ULONG KeNumberTbEntries;
00021 ULONG ProcessCount; // PERF
00022 extern PVOID KiArmVectorTable;
00023 #define __ARMV6__ KeIsArmV6
00024 
00025 /* FUNCTIONS ******************************************************************/
00026 
00027 VOID
00028 NTAPI
00029 KiInitMachineDependent(VOID)
00030 {
00031     /* There is nothing to do on ARM */
00032     return;
00033 }
00034 
00035 VOID
00036 NTAPI
00037 KiInitializeKernel(IN PKPROCESS InitProcess,
00038                    IN PKTHREAD InitThread,
00039                    IN PVOID IdleStack,
00040                    IN PKPRCB Prcb,
00041                    IN CCHAR Number,
00042                    IN PLOADER_PARAMETER_BLOCK LoaderBlock)
00043 {
00044     PKIPCR Pcr = (PKIPCR)KeGetPcr();
00045     ULONG PageDirectory[2];
00046     ULONG i;
00047     
00048     /* Set the default NX policy (opt-in) */
00049     SharedUserData->NXSupportPolicy = NX_SUPPORT_POLICY_OPTIN;
00050 
00051     /* Initialize spinlocks and DPC data */
00052     KiInitSpinLocks(Prcb, Number);
00053     
00054     /* Set stack pointers */
00055     Pcr->InitialStack = IdleStack;
00056 
00057     /* Check if this is the Boot CPU */
00058     if (!Number)
00059     {
00060         /* Setup the unexpected interrupt */
00061         KxUnexpectedInterrupt.DispatchAddress = KiUnexpectedInterrupt;
00062         for (i = 0; i < 4; i++)
00063         {
00064             /* Copy the template code */
00065             KxUnexpectedInterrupt.DispatchCode[i] = ((PULONG)KiInterruptTemplate)[i];
00066         }
00067         
00068         /* Set DMA coherency */
00069         KiDmaIoCoherency = 0;
00070         
00071         /* Sweep D-Cache */
00072         HalSweepDcache();
00073         
00074         /* Set boot-level flags */
00075         KeProcessorArchitecture = PROCESSOR_ARCHITECTURE_ARM;
00076         KeFeatureBits = 0;
00077         KeProcessorLevel = (USHORT)(Pcr->ProcessorId >> 8);
00078         KeProcessorRevision = (USHORT)(Pcr->ProcessorId & 0xFF);
00079 
00080         /* Set the current MP Master KPRCB to the Boot PRCB */
00081         Prcb->MultiThreadSetMaster = Prcb;
00082 
00083         /* Lower to APC_LEVEL */
00084         KeLowerIrql(APC_LEVEL);
00085 
00086         /* Initialize portable parts of the OS */
00087         KiInitSystem();
00088 
00089         /* Initialize the Idle Process and the Process Listhead */
00090         InitializeListHead(&KiProcessListHead);
00091         PageDirectory[0] = 0;
00092         PageDirectory[1] = 0;
00093         KeInitializeProcess(InitProcess,
00094                             0,
00095                             0xFFFFFFFF,
00096                             PageDirectory,
00097                             FALSE);
00098         InitProcess->QuantumReset = MAXCHAR;
00099     }
00100     else
00101     {
00102         /* FIXME-V6: See if we want to support MP */
00103         DPRINT1("ARM MPCore not supported\n");
00104     }
00105 
00106     /* Setup the Idle Thread */
00107     KeInitializeThread(InitProcess,
00108                        InitThread,
00109                        NULL,
00110                        NULL,
00111                        NULL,
00112                        NULL,
00113                        NULL,
00114                        IdleStack);
00115     InitThread->NextProcessor = Number;
00116     InitThread->Priority = HIGH_PRIORITY;
00117     InitThread->State = Running;
00118     InitThread->Affinity = 1 << Number;
00119     InitThread->WaitIrql = DISPATCH_LEVEL;
00120     InitProcess->ActiveProcessors = 1 << Number;
00121 
00122     /* HACK for MmUpdatePageDir */
00123     ((PETHREAD)InitThread)->ThreadsProcess = (PEPROCESS)InitProcess;
00124 
00125     /* Set up the thread-related fields in the PRCB */
00126     Prcb->CurrentThread = InitThread;
00127     Prcb->NextThread = NULL;
00128     Prcb->IdleThread = InitThread;
00129 
00130     /* Initialize the Kernel Executive */
00131     ExpInitializeExecutive(Number, LoaderBlock);
00132 
00133     /* Only do this on the boot CPU */
00134     if (!Number)
00135     {
00136         /* Calculate the time reciprocal */
00137         KiTimeIncrementReciprocal =
00138             KiComputeReciprocal(KeMaximumIncrement,
00139                                 &KiTimeIncrementShiftCount);
00140 
00141         /* Update DPC Values in case they got updated by the executive */
00142         Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
00143         Prcb->MinimumDpcRate = KiMinimumDpcRate;
00144         Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
00145     }
00146 
00147     /* Raise to Dispatch */
00148     KfRaiseIrql(DISPATCH_LEVEL);
00149 
00150     /* Set the Idle Priority to 0. This will jump into Phase 1 */
00151     KeSetPriorityThread(InitThread, 0);
00152 
00153     /* If there's no thread scheduled, put this CPU in the Idle summary */
00154     KiAcquirePrcbLock(Prcb);
00155     if (!Prcb->NextThread) KiIdleSummary |= 1 << Number;
00156     KiReleasePrcbLock(Prcb);
00157 
00158     /* Raise back to HIGH_LEVEL and clear the PRCB for the loader block */
00159     KfRaiseIrql(HIGH_LEVEL);
00160     LoaderBlock->Prcb = 0;
00161 }
00162 
00163 C_ASSERT((PKIPCR)KeGetPcr() == (PKIPCR)0xFFDFF000);
00164 C_ASSERT((FIELD_OFFSET(KIPCR, FirstLevelDcacheSize) & 4) == 0);
00165 C_ASSERT(sizeof(KIPCR) <= PAGE_SIZE);
00166 
00167 VOID
00168 NTAPI
00169 KiInitializePcr(IN ULONG ProcessorNumber,
00170                 IN PKIPCR Pcr,
00171                 IN PKTHREAD IdleThread,
00172                 IN PVOID PanicStack,
00173                 IN PVOID InterruptStack)
00174 {
00175     ULONG i;
00176     
00177     /* Set the Current Thread */
00178     Pcr->PrcbData.CurrentThread = IdleThread;
00179 
00180     /* Set pointers to ourselves */
00181     Pcr->Self = (PKPCR)Pcr;
00182     Pcr->Prcb = &Pcr->PrcbData;
00183 
00184     /* Set the PCR Version */
00185     Pcr->MajorVersion = PCR_MAJOR_VERSION;
00186     Pcr->MinorVersion = PCR_MINOR_VERSION;
00187 
00188     /* Set the PCRB Version */
00189     Pcr->PrcbData.MajorVersion = 1;
00190     Pcr->PrcbData.MinorVersion = 1;
00191 
00192     /* Set the Build Type */
00193     Pcr->PrcbData.BuildType = 0;
00194 #ifndef CONFIG_SMP
00195     Pcr->PrcbData.BuildType |= PRCB_BUILD_UNIPROCESSOR;
00196 #endif
00197 #if DBG
00198     Pcr->PrcbData.BuildType |= PRCB_BUILD_DEBUG;
00199 #endif
00200 
00201     /* Set the Processor Number and current Processor Mask */
00202     Pcr->PrcbData.Number = (UCHAR)ProcessorNumber;
00203     Pcr->PrcbData.SetMember = 1 << ProcessorNumber;
00204 
00205     /* Set the PRCB for this Processor */
00206     KiProcessorBlock[ProcessorNumber] = Pcr->Prcb;
00207 
00208     /* Start us out at PASSIVE_LEVEL */
00209     Pcr->Irql = PASSIVE_LEVEL;
00210 
00211     /* Set the stacks */
00212     Pcr->PanicStack = PanicStack;
00213     Pcr->InterruptStack = InterruptStack;
00214 
00215     /* Setup the processor set */
00216     Pcr->PrcbData.MultiThreadProcessorSet = Pcr->PrcbData.SetMember;
00217     
00218     /* Copy cache information from the loader block */
00219     Pcr->FirstLevelDcacheSize = KeLoaderBlock->u.Arm.FirstLevelDcacheSize;
00220     Pcr->SecondLevelDcacheSize = KeLoaderBlock->u.Arm.SecondLevelDcacheSize;
00221     Pcr->FirstLevelIcacheSize = KeLoaderBlock->u.Arm.FirstLevelIcacheSize;
00222     Pcr->SecondLevelIcacheSize = KeLoaderBlock->u.Arm.SecondLevelIcacheSize;
00223     Pcr->FirstLevelDcacheFillSize = KeLoaderBlock->u.Arm.FirstLevelDcacheFillSize;
00224     Pcr->SecondLevelDcacheFillSize = KeLoaderBlock->u.Arm.SecondLevelDcacheFillSize;
00225     Pcr->FirstLevelIcacheFillSize = KeLoaderBlock->u.Arm.FirstLevelIcacheFillSize;
00226     Pcr->SecondLevelIcacheFillSize = KeLoaderBlock->u.Arm.SecondLevelIcacheFillSize;
00227 
00228     /* Set global d-cache fill and alignment values */
00229     if (!Pcr->SecondLevelDcacheSize)
00230     {
00231         /* Use the first level */
00232         Pcr->DcacheFillSize = Pcr->FirstLevelDcacheSize;
00233     }
00234     else
00235     {
00236         /* Use the second level */
00237         Pcr->DcacheFillSize = Pcr->SecondLevelDcacheSize;
00238     }
00239     
00240     /* Set the alignment */
00241     Pcr->DcacheAlignment = Pcr->DcacheFillSize - 1;
00242     
00243     /* Set global i-cache fill and alignment values */
00244     if (!Pcr->SecondLevelIcacheSize)
00245     {
00246         /* Use the first level */
00247         Pcr->IcacheFillSize = Pcr->FirstLevelIcacheSize;
00248     }
00249     else
00250     {
00251         /* Use the second level */
00252         Pcr->IcacheFillSize = Pcr->SecondLevelIcacheSize;
00253     }
00254     
00255     /* Set the alignment */
00256     Pcr->IcacheAlignment = Pcr->IcacheFillSize - 1;
00257     
00258     /* Set processor information */
00259     Pcr->ProcessorId = KeArmIdCodeRegisterGet().AsUlong;
00260     
00261     /* Set all interrupt routines to unexpected interrupts as well */
00262     for (i = 0; i < MAXIMUM_VECTOR; i++)
00263     {
00264         /* Point to the same template */
00265         Pcr->InterruptRoutine[i] = (PVOID)&KxUnexpectedInterrupt.DispatchCode;
00266     }
00267 
00268     /* Set default stall factor */
00269     Pcr->StallScaleFactor = 50;
00270     
00271     /* Setup software interrupts */
00272     Pcr->InterruptRoutine[PASSIVE_LEVEL] = KiPassiveRelease;
00273     Pcr->InterruptRoutine[APC_LEVEL] = KiApcInterrupt;
00274     Pcr->InterruptRoutine[DISPATCH_LEVEL] = KiDispatchInterrupt;
00275     Pcr->ReservedVectors = (1 << PASSIVE_LEVEL) |
00276                            (1 << APC_LEVEL) |
00277                            (1 << DISPATCH_LEVEL) |
00278                            (1 << IPI_LEVEL);
00279 }
00280 
00281 VOID
00282 KiInitializeMachineType(VOID)
00283 {
00284     /* Detect ARM version */
00285     KeIsArmV6 = KeArmIdCodeRegisterGet().Architecture >= 7;
00286     
00287     /* Set the number of TLB entries and ASIDs */
00288     KeNumberTbEntries = 64;
00289     if (__ARMV6__)
00290     {
00291         /* 256 ASIDs on v6/v7 */
00292         KeNumberProcessIds = 256;
00293     }
00294     else
00295     {
00296         /* The TLB is VIVT on v4/v5 */
00297         KeNumberProcessIds = 0;
00298     }
00299 }
00300 
00301 VOID
00302 KiInitializeSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
00303 {
00304     ULONG Cpu;
00305     PKTHREAD InitialThread;
00306     PKPROCESS InitialProcess;
00307     ARM_CONTROL_REGISTER ControlRegister;
00308     PKIPCR Pcr = (PKIPCR)KeGetPcr();
00309     PKTHREAD Thread;
00310 
00311     /* Flush the TLB */
00312     KeFlushTb();
00313     
00314     /* Save the loader block and get the current CPU */
00315     KeLoaderBlock = LoaderBlock;
00316     Cpu = KeNumberProcessors;
00317 
00318     /* Save the initial thread and process */
00319     InitialThread = (PKTHREAD)LoaderBlock->Thread;
00320     InitialProcess = (PKPROCESS)LoaderBlock->Process;
00321 
00322     /* Clean the APC List Head */
00323     InitializeListHead(&InitialThread->ApcState.ApcListHead[KernelMode]);
00324 
00325     /* Initialize the machine type */
00326     KiInitializeMachineType();
00327 
00328     /* Skip initial setup if this isn't the Boot CPU */
00329     if (Cpu) goto AppCpuInit;
00330     
00331     /* Initialize the PCR */
00332     RtlZeroMemory(Pcr, PAGE_SIZE);
00333     KiInitializePcr(Cpu,
00334                     Pcr,
00335                     InitialThread,
00336                     (PVOID)LoaderBlock->u.Arm.PanicStack,
00337                     (PVOID)LoaderBlock->u.Arm.InterruptStack);
00338 
00339     /* Now sweep caches */
00340     HalSweepIcache();
00341     HalSweepDcache();
00342     
00343     /* Set us as the current process */
00344     InitialThread->ApcState.Process = InitialProcess;
00345     
00346 AppCpuInit:
00347     /* Setup CPU-related fields */
00348     Pcr->Number = Cpu;
00349     Pcr->SetMember = 1 << Cpu;
00350     Pcr->SetMemberCopy = 1 << Cpu;
00351     Pcr->PrcbData.SetMember = 1 << Cpu;
00352     
00353     /* Initialize the Processor with HAL */
00354     HalInitializeProcessor(Cpu, KeLoaderBlock);
00355 
00356     /* Set active processors */
00357     KeActiveProcessors |= Pcr->SetMember;
00358     KeNumberProcessors++;
00359 
00360     /* Check if this is the boot CPU */
00361     if (!Cpu)
00362     {
00363         /* Initialize debugging system */
00364         KdInitSystem(0, KeLoaderBlock);
00365 
00366         /* Check for break-in */
00367         if (KdPollBreakIn()) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
00368     }
00369 
00370     /* Raise to HIGH_LEVEL */
00371     KfRaiseIrql(HIGH_LEVEL);
00372     
00373     /* Set the exception address to high */
00374     ControlRegister = KeArmControlRegisterGet();
00375     ControlRegister.HighVectors = TRUE;
00376     KeArmControlRegisterSet(ControlRegister);
00377     
00378     /* Setup the exception vector table */
00379     RtlCopyMemory((PVOID)0xFFFF0000, &KiArmVectorTable, 14 * sizeof(PVOID));
00380 
00381     /* Initialize the rest of the kernel now */
00382     KiInitializeKernel((PKPROCESS)LoaderBlock->Process,
00383                        (PKTHREAD)LoaderBlock->Thread,
00384                        (PVOID)LoaderBlock->KernelStack,
00385                        Pcr->Prcb,
00386                        Pcr->Prcb->Number,
00387                        KeLoaderBlock);
00388 
00389     /* Set the priority of this thread to 0 */
00390     Thread = KeGetCurrentThread();
00391     Thread->Priority = 0;
00392 
00393     /* Force interrupts enabled and lower IRQL back to DISPATCH_LEVEL */
00394     _enable();
00395     KfLowerIrql(DISPATCH_LEVEL);
00396 
00397     /* Set the right wait IRQL */
00398     Thread->WaitIrql = DISPATCH_LEVEL;
00399 
00400     /* Jump into the idle loop */
00401     KiIdleLoop();
00402 }
00403 
00404 ULONG
00405 DbgPrintEarly(const char *fmt, ...)
00406 {
00407     va_list args;
00408     unsigned int i;
00409     char Buffer[1024];
00410     PCHAR String = Buffer;
00411 
00412     va_start(args, fmt);
00413     i = vsprintf(Buffer, fmt, args);
00414     va_end(args);
00415     
00416     /* Output the message */
00417     while (*String != 0)
00418     {
00419         if (*String == '\n')
00420         {
00421             KdPortPutByteEx(NULL, '\r');
00422         }
00423         KdPortPutByteEx(NULL, *String);
00424         String++;
00425     }
00426     
00427     return STATUS_SUCCESS;
00428 }

Generated on Fri May 25 2012 04:35:54 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.