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 *****************************************************************/
13 #include <reactos/ppcboot.h>
18 #include "ppcmmu/mmu.h"
20 /* GLOBALS *******************************************************************/
22 /* Ku bit should be set, so that we get the best options for page protection */
23 #define PPC_SEG_Ku 0x40000000
24 #define PPC_SEG_Ks 0x20000000
26 extern LOADER_MODULE KeLoaderModules
[64];
27 extern ULONG KeLoaderModuleCount
;
28 extern ULONG_PTR MmFreeLdrLastKernelAddress
;
29 KPRCB PrcbData
[MAXIMUM_PROCESSORS
];
31 /* FUNCTIONS *****************************************************************/
36 * lr, ctr, srr0, srr1, dsisr
39 ".globl syscall_start\n\t"
40 ".globl syscall_end\n\t"
41 ".globl KiSystemService\n\t"
44 "lis 1,KiSystemService1@ha\n\t"
45 "addi 1,1,KiSystemService1@l\n\t"
48 "lis 1,_kernel_trap_stack@ha\n\t"
49 "addi 1,1,_kernel_trap_stack@l\n\t"
55 extern int syscall_start
[], syscall_end
, KiDecrementerTrapHandler
[],
56 KiDecrementerTrapHandlerEnd
;
60 KiSetupSyscallHandler()
62 paddr_t handler_target
;
64 for(source
= syscall_start
, handler_target
= 0xc00;
65 source
< &syscall_end
;
66 source
++, handler_target
+= sizeof(int))
67 SetPhys(handler_target
, *source
);
72 KiSetupDecrementerTrap()
74 paddr_t handler_target
;
77 /* Turn off EE bit while redefining dec trap */
80 for(source
= KiDecrementerTrapHandler
, handler_target
= 0x900;
81 source
!= &KiDecrementerTrapHandlerEnd
;
82 source
++, handler_target
+= sizeof(int))
83 SetPhys(handler_target
, *source
);
85 /* Enable interrupts! */
88 /* Kick decmrenter! */
89 __asm__("mtdec %0" : : "r" (0));
94 KiInitializePcr(IN ULONG ProcessorNumber
,
96 IN PKTHREAD IdleThread
,
99 Pcr
->MajorVersion
= PCR_MAJOR_VERSION
;
100 Pcr
->MinorVersion
= PCR_MINOR_VERSION
;
101 Pcr
->CurrentIrql
= PASSIVE_LEVEL
;
102 Pcr
->PrcbData
= &PrcbData
[ProcessorNumber
];
103 Pcr
->PrcbData
->MajorVersion
= PRCB_MAJOR_VERSION
;
104 Pcr
->PrcbData
->MinorVersion
= 0;
105 Pcr
->PrcbData
->Number
= 0; /* UP for now */
106 Pcr
->PrcbData
->SetMember
= 1;
108 Pcr
->PrcbData
->BuildType
= PRCB_BUILD_DEBUG
;
110 Pcr
->PrcbData
->BuildType
= 0;
112 Pcr
->PrcbData
->DpcStack
= DpcStack
;
113 KiProcessorBlock
[ProcessorNumber
] = Pcr
->PrcbData
;
116 extern ULONG
KiGetFeatureBits();
117 extern VOID
KiSetProcessorType();
118 extern VOID
KiGetCacheInformation();
122 KiInitializeKernel(IN PKPROCESS InitProcess
,
123 IN PKTHREAD InitThread
,
127 IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock
)
130 LARGE_INTEGER PageDirectory
;
132 boot_infos_t
*BootInfo
= ((boot_infos_t
*)LoaderBlock
->ArchExtra
);
135 /* Set the machine type in LoaderBlock for HAL */
136 KeLoaderBlock
->u
.PowerPC
.MachineType
= BootInfo
->machineType
;
139 /* Detect and set the CPU Type */
140 KiSetProcessorType();
142 /* Initialize the Power Management Support for this PRCB */
143 PoInitializePrcb(Prcb
);
145 /* Get the processor features for the CPU */
146 FeatureBits
= KiGetFeatureBits();
148 /* Save feature bits */
149 Prcb
->FeatureBits
= FeatureBits
;
151 /* Get cache line information for this CPU */
152 KiGetCacheInformation();
154 /* Initialize spinlocks and DPC data */
155 KiInitSpinLocks(Prcb
, Number
);
157 /* Check if this is the Boot CPU */
161 KeNodeBlock
[0] = &KiNode0
;
162 Prcb
->ParentNode
= KeNodeBlock
[0];
163 KeNodeBlock
[0]->ProcessorMask
= Prcb
->SetMember
;
165 /* Set boot-level flags */
166 KeProcessorArchitecture
= 0;
167 KeProcessorLevel
= (USHORT
)Prcb
->CpuType
;
168 KeFeatureBits
= FeatureBits
;
170 /* Set the current MP Master KPRCB to the Boot PRCB */
171 Prcb
->MultiThreadSetMaster
= Prcb
;
173 /* Lower to APC_LEVEL */
174 KeLowerIrql(APC_LEVEL
);
176 /* Initialize portable parts of the OS */
179 /* Initialize the Idle Process and the Process Listhead */
180 InitializeListHead(&KiProcessListHead
);
181 PageDirectory
.QuadPart
= 0;
182 KeInitializeProcess(InitProcess
,
187 InitProcess
->QuantumReset
= MAXCHAR
;
192 DPRINT1("SMP Boot support not yet present\n");
195 /* Setup the Idle Thread */
196 KeInitializeThread(InitProcess
,
204 InitThread
->NextProcessor
= Number
;
205 InitThread
->Priority
= HIGH_PRIORITY
;
206 InitThread
->State
= Running
;
207 InitThread
->Affinity
= 1 << Number
;
208 InitThread
->WaitIrql
= DISPATCH_LEVEL
;
209 InitProcess
->ActiveProcessors
= 1 << Number
;
211 /* Set up the thread-related fields in the PRCB */
212 //Prcb->CurrentThread = InitThread;
213 Prcb
->NextThread
= NULL
;
214 //Prcb->IdleThread = InitThread;
216 /* Initialize the Kernel Executive */
217 ExpInitializeExecutive(0, (PLOADER_PARAMETER_BLOCK
)LoaderBlock
);
219 /* Only do this on the boot CPU */
222 /* Calculate the time reciprocal */
223 KiTimeIncrementReciprocal
=
224 KiComputeReciprocal(KeMaximumIncrement
,
225 &KiTimeIncrementShiftCount
);
227 /* Update DPC Values in case they got updated by the executive */
228 Prcb
->MaximumDpcQueueDepth
= KiMaximumDpcQueueDepth
;
229 Prcb
->MinimumDpcRate
= KiMinimumDpcRate
;
230 Prcb
->AdjustDpcThreshold
= KiAdjustDpcThreshold
;
232 /* Allocate the DPC Stack */
233 DpcStack
= MmCreateKernelStack(FALSE
, 0);
234 if (!DpcStack
) KeBugCheckEx(NO_PAGES_AVAILABLE
, 1, 0, 0, 0);
235 Prcb
->DpcStack
= DpcStack
;
238 /* Free Initial Memory */
239 // MiFreeInitMemory();
241 /* Setup decrementer exception */
242 KiSetupDecrementerTrap();
246 LARGE_INTEGER Timeout
;
247 Timeout
.QuadPart
= 0x7fffffffffffffffLL
;
248 KeDelayExecutionThread(KernelMode
, FALSE
, &Timeout
);
252 extern int KiPageFaultHandler(int trap
, ppc_trap_frame_t
*frame
);
254 /* Use this for early boot additions to the page table */
257 KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
260 ppc_map_info_t info
[4];
261 PKIPCR Pcr
= (PKIPCR
)KPCR_BASE
;
264 __asm__("mr 13,%0" : : "r" (KPCR_BASE
));
266 /* Set the page fault handler to the kernel */
267 MmuSetTrapHandler(3,KiPageFaultHandler
);
268 MmuSetTrapHandler(4,KiPageFaultHandler
);
270 // Make 0xf... special
271 MmuAllocVsid(2, 0x8000);
274 /* Get the current CPU */
275 Cpu
= KeNumberProcessors
;
278 /* We'll allocate a page from the end of the kernel area for KPCR. This code will probably
279 * change when we get SMP support.
283 info
[0].addr
= (vaddr_t
)Pcr
;
284 info
[0].flags
= MMU_KRW_UR
;
287 info
[1].addr
= ((vaddr_t
)Pcr
) + (1 << PAGE_SHIFT
);
288 info
[1].flags
= MMU_KRW_UR
;
291 info
[2].addr
= (vaddr_t
)KI_USER_SHARED_DATA
;
292 info
[2].flags
= MMU_KRW_UR
;
295 info
[3].addr
= (vaddr_t
)KIP0PCRADDRESS
;
296 info
[3].flags
= MMU_KRW_UR
;
300 /* Skip initial setup if this isn't the Boot CPU */
301 if (Cpu
) goto AppCpuInit
;
303 /* Initialize the PCR */
304 RtlZeroMemory(Pcr
, PAGE_SIZE
);
307 &KiInitialThread
.Tcb
,
310 /* Set us as the current process */
311 KiInitialThread
.Tcb
.ApcState
.Process
= &KiInitialProcess
.Pcb
;
313 /* Setup CPU-related fields */
316 Pcr
->SetMember
= 1 << Cpu
;
317 Prcb
= KeGetCurrentPrcb();
318 Prcb
->SetMember
= 1 << Cpu
;
320 /* Initialize the Processor with HAL */
321 HalInitializeProcessor(Cpu
, LoaderBlock
);
323 /* Set active processors */
324 KeActiveProcessors
|= Pcr
->SetMember
;
325 KeNumberProcessors
++;
327 /* Initialize the Debugger for the Boot CPU */
328 if (!Cpu
) KdInitSystem (0, LoaderBlock
);
330 /* Check for break-in */
333 DbgBreakPointWithStatus(1);
336 /* Raise to HIGH_LEVEL */
337 KfRaiseIrql(HIGH_LEVEL
);
339 /* Call main kernel intialization */
340 KiInitializeKernel(&KiInitialProcess
.Pcb
,
341 &KiInitialThread
.Tcb
,
350 KiInitMachineDependent(VOID
)