2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/ke/powerpc/kiinit.c
5 * PURPOSE: Kernel Initialization for x86 CPUs
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 * Art Yerkes (ayerkes@speakeasy.net)
10 /* INCLUDES *****************************************************************/
16 #include "ppcmmu/mmu.h"
18 /* GLOBALS *******************************************************************/
20 /* Ku bit should be set, so that we get the best options for page protection */
21 #define PPC_SEG_Ku 0x40000000
22 #define PPC_SEG_Ks 0x20000000
24 extern LOADER_MODULE KeLoaderModules
[64];
25 extern ULONG KeLoaderModuleCount
;
26 extern ULONG_PTR MmFreeLdrLastKernelAddress
;
27 KPRCB PrcbData
[MAXIMUM_PROCESSORS
];
28 /* BIOS Memory Map. Not NTLDR-compliant yet */
29 extern ULONG KeMemoryMapRangeCount
;
30 extern ADDRESS_RANGE KeMemoryMap
[64];
32 /* FUNCTIONS *****************************************************************/
36 * lr, ctr, srr0, srr1, dsisr
39 extern int syscall_start
[], syscall_end
, KiDecrementerTrapHandler
[],
40 KiDecrementerTrapHandlerEnd
;
44 KiSetupSyscallHandler(VOID
)
46 paddr_t handler_target
;
48 for(source
= syscall_start
, handler_target
= 0xc00;
49 source
< &syscall_end
;
50 source
++, handler_target
+= sizeof(int))
52 SetPhys(handler_target
, *source
);
58 KiSetupDecrementerTrap(VOID
)
60 paddr_t handler_target
;
63 /* Turn off EE bit while redefining dec trap */
66 for(source
= KiDecrementerTrapHandler
, handler_target
= 0x900;
67 source
!= &KiDecrementerTrapHandlerEnd
;
68 source
++, handler_target
+= sizeof(int))
69 SetPhys(handler_target
, *source
);
71 DPRINT("CurrentThread %08x IdleThread %08x\n",
72 KeGetCurrentThread(), KeGetCurrentPrcb()->IdleThread
);
74 /* Kick decmrenter! */
75 __asm__("mtdec %0" : : "r" (0));
77 /* Enable interrupts! */
83 KiInitializePcr(IN ULONG ProcessorNumber
,
85 IN PKTHREAD IdleThread
,
88 Pcr
->MajorVersion
= PCR_MAJOR_VERSION
;
89 Pcr
->MinorVersion
= PCR_MINOR_VERSION
;
90 Pcr
->CurrentIrql
= PASSIVE_LEVEL
;
91 Pcr
->PrcbData
= &PrcbData
[ProcessorNumber
];
92 Pcr
->PrcbData
->MajorVersion
= PRCB_MAJOR_VERSION
;
93 Pcr
->PrcbData
->MinorVersion
= 0;
94 Pcr
->PrcbData
->Number
= 0; /* UP for now */
95 Pcr
->PrcbData
->SetMember
= 1;
97 Pcr
->PrcbData
->BuildType
= PRCB_BUILD_DEBUG
;
99 Pcr
->PrcbData
->BuildType
= 0;
101 Pcr
->PrcbData
->DpcStack
= DpcStack
;
102 KeGetPcr()->Prcb
= Pcr
->PrcbData
;
103 KiProcessorBlock
[ProcessorNumber
] = Pcr
->PrcbData
;
106 extern ULONG
KiGetFeatureBits();
107 extern VOID
KiSetProcessorType();
108 extern VOID
KiGetCacheInformation();
112 KiInitializeKernel(IN PKPROCESS InitProcess
,
113 IN PKTHREAD InitThread
,
117 IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
120 LARGE_INTEGER PageDirectory
;
123 /* Detect and set the CPU Type */
124 KiSetProcessorType();
126 /* Initialize the Power Management Support for this PRCB */
127 PoInitializePrcb(Prcb
);
129 /* Get the processor features for the CPU */
130 FeatureBits
= KiGetFeatureBits();
132 /* Save feature bits */
133 Prcb
->FeatureBits
= FeatureBits
;
135 /* Get cache line information for this CPU */
136 KiGetCacheInformation();
138 /* Initialize spinlocks and DPC data */
139 KiInitSpinLocks(Prcb
, Number
);
141 /* Check if this is the Boot CPU */
145 KeNodeBlock
[0] = &KiNode0
;
146 Prcb
->ParentNode
= KeNodeBlock
[0];
147 KeNodeBlock
[0]->ProcessorMask
= Prcb
->SetMember
;
149 /* Set boot-level flags */
150 KeProcessorArchitecture
= 0;
151 KeProcessorLevel
= (USHORT
)Prcb
->CpuType
;
152 KeFeatureBits
= FeatureBits
;
154 /* Set the current MP Master KPRCB to the Boot PRCB */
155 Prcb
->MultiThreadSetMaster
= Prcb
;
157 /* Lower to APC_LEVEL */
158 KeLowerIrql(APC_LEVEL
);
160 /* Initialize portable parts of the OS */
163 /* Initialize the Idle Process and the Process Listhead */
164 InitializeListHead(&KiProcessListHead
);
165 PageDirectory
.QuadPart
= 0;
166 KeInitializeProcess(InitProcess
,
171 InitProcess
->QuantumReset
= MAXCHAR
;
176 DPRINT1("SMP Boot support not yet present\n");
179 /* Setup the Idle Thread */
180 KeInitializeThread(InitProcess
,
188 InitThread
->NextProcessor
= Number
;
189 InitThread
->Priority
= HIGH_PRIORITY
;
190 InitThread
->State
= Running
;
191 InitThread
->Affinity
= 1 << Number
;
192 InitThread
->WaitIrql
= DISPATCH_LEVEL
;
193 InitProcess
->ActiveProcessors
= 1 << Number
;
195 /* HACK for MmUpdatePageDir */
196 ((PETHREAD
)InitThread
)->ThreadsProcess
= (PEPROCESS
)InitProcess
;
198 /* Set up the thread-related fields in the PRCB */
199 Prcb
->CurrentThread
= InitThread
;
200 Prcb
->NextThread
= NULL
;
201 Prcb
->IdleThread
= InitThread
;
203 /* Initialize Kernel Memory Address Space */
204 MmInit1(MmFreeLdrFirstKrnlPhysAddr
,
205 MmFreeLdrLastKrnlPhysAddr
,
206 MmFreeLdrLastKernelAddress
,
208 KeMemoryMapRangeCount
,
211 /* Initialize the Kernel Executive */
212 ExpInitializeExecutive(0, LoaderBlock
);
214 /* Only do this on the boot CPU */
217 /* Calculate the time reciprocal */
218 KiTimeIncrementReciprocal
=
219 KiComputeReciprocal(KeMaximumIncrement
,
220 &KiTimeIncrementShiftCount
);
222 /* Update DPC Values in case they got updated by the executive */
223 Prcb
->MaximumDpcQueueDepth
= KiMaximumDpcQueueDepth
;
224 Prcb
->MinimumDpcRate
= KiMinimumDpcRate
;
225 Prcb
->AdjustDpcThreshold
= KiAdjustDpcThreshold
;
227 /* Allocate the DPC Stack */
228 DpcStack
= MmCreateKernelStack(FALSE
, 0);
229 if (!DpcStack
) KeBugCheckEx(NO_PAGES_AVAILABLE
, 1, 0, 0, 0);
230 Prcb
->DpcStack
= DpcStack
;
233 KfRaiseIrql(DISPATCH_LEVEL
);
235 KeSetPriorityThread(InitThread
, 0);
236 /* Setup decrementer exception */
237 KiSetupDecrementerTrap();
239 KfLowerIrql(PASSIVE_LEVEL
);
241 /* Should not return */
248 extern int KiPageFaultTrap();
249 KTRAP_FRAME KiInitialTrapFrame
;
251 /* Use this for early boot additions to the page table */
254 KiSystemStartupReal(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
257 ppc_map_info_t info
[4];
258 PKIPCR Pcr
= (PKIPCR
)KPCR_BASE
;
261 __asm__("mr 13,%0" : : "r" (KPCR_BASE
));
263 /* Set the page fault handler to the kernel */
264 MmuSetTrapHandler(3,KiPageFaultTrap
);
265 MmuSetTrapHandler(4,KiPageFaultTrap
);
267 // Make 0xf... special
268 MmuAllocVsid(2, 0x8000);
271 /* Get the current CPU */
272 Cpu
= KeNumberProcessors
;
275 /* We'll allocate a page from the end of the kernel area for KPCR. This code will probably
276 * change when we get SMP support.
280 info
[0].addr
= (vaddr_t
)Pcr
;
281 info
[0].flags
= MMU_KRW_UR
;
284 info
[1].addr
= ((vaddr_t
)Pcr
) + (1 << PAGE_SHIFT
);
285 info
[1].flags
= MMU_KRW_UR
;
288 info
[2].addr
= (vaddr_t
)KI_USER_SHARED_DATA
;
289 info
[2].flags
= MMU_KRW_UR
;
292 info
[3].addr
= (vaddr_t
)KIP0PCRADDRESS
;
293 info
[3].flags
= MMU_KRW_UR
;
297 /* Skip initial setup if this isn't the Boot CPU */
298 if (Cpu
) goto AppCpuInit
;
300 /* Initialize the PCR */
301 RtlZeroMemory(Pcr
, PAGE_SIZE
);
304 &KiInitialThread
.Tcb
,
307 /* Set us as the current process */
308 KiInitialThread
.Tcb
.ApcState
.Process
= &KiInitialProcess
.Pcb
;
309 KiInitialThread
.Tcb
.TrapFrame
= &KiInitialTrapFrame
;
311 /* Setup CPU-related fields */
314 Pcr
->SetMember
= 1 << Cpu
;
315 Prcb
= KeGetCurrentPrcb();
316 Prcb
->SetMember
= 1 << Cpu
;
318 /* Initialize the Processor with HAL */
319 HalInitializeProcessor(Cpu
, LoaderBlock
);
321 /* Set active processors */
322 KeActiveProcessors
|= Pcr
->SetMember
;
323 KeNumberProcessors
++;
325 /* Initialize the Debugger for the Boot CPU */
326 if (!Cpu
) KdInitSystem (0, LoaderBlock
);
328 /* Check for break-in */
331 DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C
);
334 /* Raise to HIGH_LEVEL */
335 KfRaiseIrql(HIGH_LEVEL
);
337 /* Call main kernel intialization */
338 KiInitializeKernel(&KiInitialProcess
.Pcb
,
339 &KiInitialThread
.Tcb
,
348 KiInitMachineDependent(VOID
)
354 KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED
);