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()
46 paddr_t handler_target
;
48 for(source
= syscall_start
, handler_target
= 0xc00;
49 source
< &syscall_end
;
50 source
++, handler_target
+= sizeof(int))
51 SetPhys(handler_target
, *source
);
56 KiSetupDecrementerTrap()
58 paddr_t handler_target
;
61 /* Turn off EE bit while redefining dec trap */
64 for(source
= KiDecrementerTrapHandler
, handler_target
= 0x900;
65 source
!= &KiDecrementerTrapHandlerEnd
;
66 source
++, handler_target
+= sizeof(int))
67 SetPhys(handler_target
, *source
);
69 DPRINT("CurrentThread %08x IdleThread %08x\n",
70 KeGetCurrentThread(), KeGetCurrentPrcb()->IdleThread
);
72 /* Kick decmrenter! */
73 __asm__("mtdec %0" : : "r" (0));
75 /* Enable interrupts! */
81 KiInitializePcr(IN ULONG ProcessorNumber
,
83 IN PKTHREAD IdleThread
,
86 Pcr
->MajorVersion
= PCR_MAJOR_VERSION
;
87 Pcr
->MinorVersion
= PCR_MINOR_VERSION
;
88 Pcr
->CurrentIrql
= PASSIVE_LEVEL
;
89 Pcr
->PrcbData
= &PrcbData
[ProcessorNumber
];
90 Pcr
->PrcbData
->MajorVersion
= PRCB_MAJOR_VERSION
;
91 Pcr
->PrcbData
->MinorVersion
= 0;
92 Pcr
->PrcbData
->Number
= 0; /* UP for now */
93 Pcr
->PrcbData
->SetMember
= 1;
95 Pcr
->PrcbData
->BuildType
= PRCB_BUILD_DEBUG
;
97 Pcr
->PrcbData
->BuildType
= 0;
99 Pcr
->PrcbData
->DpcStack
= DpcStack
;
100 KeGetPcr()->Prcb
= Pcr
->PrcbData
;
101 KiProcessorBlock
[ProcessorNumber
] = Pcr
->PrcbData
;
104 extern ULONG
KiGetFeatureBits();
105 extern VOID
KiSetProcessorType();
106 extern VOID
KiGetCacheInformation();
110 KiInitializeKernel(IN PKPROCESS InitProcess
,
111 IN PKTHREAD InitThread
,
115 IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
118 LARGE_INTEGER PageDirectory
;
121 /* Detect and set the CPU Type */
122 KiSetProcessorType();
124 /* Initialize the Power Management Support for this PRCB */
125 PoInitializePrcb(Prcb
);
127 /* Get the processor features for the CPU */
128 FeatureBits
= KiGetFeatureBits();
130 /* Save feature bits */
131 Prcb
->FeatureBits
= FeatureBits
;
133 /* Get cache line information for this CPU */
134 KiGetCacheInformation();
136 /* Initialize spinlocks and DPC data */
137 KiInitSpinLocks(Prcb
, Number
);
139 /* Check if this is the Boot CPU */
143 KeNodeBlock
[0] = &KiNode0
;
144 Prcb
->ParentNode
= KeNodeBlock
[0];
145 KeNodeBlock
[0]->ProcessorMask
= Prcb
->SetMember
;
147 /* Set boot-level flags */
148 KeProcessorArchitecture
= 0;
149 KeProcessorLevel
= (USHORT
)Prcb
->CpuType
;
150 KeFeatureBits
= FeatureBits
;
152 /* Set the current MP Master KPRCB to the Boot PRCB */
153 Prcb
->MultiThreadSetMaster
= Prcb
;
155 /* Lower to APC_LEVEL */
156 KeLowerIrql(APC_LEVEL
);
158 /* Initialize portable parts of the OS */
161 /* Initialize the Idle Process and the Process Listhead */
162 InitializeListHead(&KiProcessListHead
);
163 PageDirectory
.QuadPart
= 0;
164 KeInitializeProcess(InitProcess
,
169 InitProcess
->QuantumReset
= MAXCHAR
;
174 DPRINT1("SMP Boot support not yet present\n");
177 /* Setup the Idle Thread */
178 KeInitializeThread(InitProcess
,
186 InitThread
->NextProcessor
= Number
;
187 InitThread
->Priority
= HIGH_PRIORITY
;
188 InitThread
->State
= Running
;
189 InitThread
->Affinity
= 1 << Number
;
190 InitThread
->WaitIrql
= DISPATCH_LEVEL
;
191 InitProcess
->ActiveProcessors
= 1 << Number
;
193 /* HACK for MmUpdatePageDir */
194 ((PETHREAD
)InitThread
)->ThreadsProcess
= (PEPROCESS
)InitProcess
;
196 /* Set up the thread-related fields in the PRCB */
197 Prcb
->CurrentThread
= InitThread
;
198 Prcb
->NextThread
= NULL
;
199 Prcb
->IdleThread
= InitThread
;
201 /* Initialize Kernel Memory Address Space */
202 MmInit1(MmFreeLdrFirstKrnlPhysAddr
,
203 MmFreeLdrLastKrnlPhysAddr
,
204 MmFreeLdrLastKernelAddress
,
206 KeMemoryMapRangeCount
,
209 /* Initialize the Kernel Executive */
210 ExpInitializeExecutive(0, LoaderBlock
);
212 /* Only do this on the boot CPU */
215 /* Calculate the time reciprocal */
216 KiTimeIncrementReciprocal
=
217 KiComputeReciprocal(KeMaximumIncrement
,
218 &KiTimeIncrementShiftCount
);
220 /* Update DPC Values in case they got updated by the executive */
221 Prcb
->MaximumDpcQueueDepth
= KiMaximumDpcQueueDepth
;
222 Prcb
->MinimumDpcRate
= KiMinimumDpcRate
;
223 Prcb
->AdjustDpcThreshold
= KiAdjustDpcThreshold
;
225 /* Allocate the DPC Stack */
226 DpcStack
= MmCreateKernelStack(FALSE
, 0);
227 if (!DpcStack
) KeBugCheckEx(NO_PAGES_AVAILABLE
, 1, 0, 0, 0);
228 Prcb
->DpcStack
= DpcStack
;
231 /* Free Initial Memory */
232 // MiFreeInitMemory();
234 KfRaiseIrql(DISPATCH_LEVEL
);
236 KeSetPriorityThread(InitThread
, 0);
237 /* Setup decrementer exception */
238 KiSetupDecrementerTrap();
240 KfLowerIrql(PASSIVE_LEVEL
);
242 /* Should not return */
249 extern int KiPageFaultTrap();
250 KTRAP_FRAME KiInitialTrapFrame
;
252 /* Use this for early boot additions to the page table */
255 KiSystemStartupReal(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
258 ppc_map_info_t info
[4];
259 PKIPCR Pcr
= (PKIPCR
)KPCR_BASE
;
262 __asm__("mr 13,%0" : : "r" (KPCR_BASE
));
264 /* Set the page fault handler to the kernel */
265 MmuSetTrapHandler(3,KiPageFaultTrap
);
266 MmuSetTrapHandler(4,KiPageFaultTrap
);
268 // Make 0xf... special
269 MmuAllocVsid(2, 0x8000);
272 /* Get the current CPU */
273 Cpu
= KeNumberProcessors
;
276 /* We'll allocate a page from the end of the kernel area for KPCR. This code will probably
277 * change when we get SMP support.
281 info
[0].addr
= (vaddr_t
)Pcr
;
282 info
[0].flags
= MMU_KRW_UR
;
285 info
[1].addr
= ((vaddr_t
)Pcr
) + (1 << PAGE_SHIFT
);
286 info
[1].flags
= MMU_KRW_UR
;
289 info
[2].addr
= (vaddr_t
)KI_USER_SHARED_DATA
;
290 info
[2].flags
= MMU_KRW_UR
;
293 info
[3].addr
= (vaddr_t
)KIP0PCRADDRESS
;
294 info
[3].flags
= MMU_KRW_UR
;
298 /* Skip initial setup if this isn't the Boot CPU */
299 if (Cpu
) goto AppCpuInit
;
301 /* Initialize the PCR */
302 RtlZeroMemory(Pcr
, PAGE_SIZE
);
305 &KiInitialThread
.Tcb
,
308 /* Set us as the current process */
309 KiInitialThread
.Tcb
.ApcState
.Process
= &KiInitialProcess
.Pcb
;
310 KiInitialThread
.Tcb
.TrapFrame
= &KiInitialTrapFrame
;
312 /* Setup CPU-related fields */
315 Pcr
->SetMember
= 1 << Cpu
;
316 Prcb
= KeGetCurrentPrcb();
317 Prcb
->SetMember
= 1 << Cpu
;
319 /* Initialize the Processor with HAL */
320 HalInitializeProcessor(Cpu
, LoaderBlock
);
322 /* Set active processors */
323 KeActiveProcessors
|= Pcr
->SetMember
;
324 KeNumberProcessors
++;
326 /* Initialize the Debugger for the Boot CPU */
327 if (!Cpu
) KdInitSystem (0, LoaderBlock
);
329 /* Check for break-in */
332 DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C
);
335 /* Raise to HIGH_LEVEL */
336 KfRaiseIrql(HIGH_LEVEL
);
338 /* Call main kernel intialization */
339 KiInitializeKernel(&KiInitialProcess
.Pcb
,
340 &KiInitialThread
.Tcb
,
349 KiInitMachineDependent(VOID
)
355 KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED
);