[NTOS:MM] Quick fix: use SIZE_T instead of ULONG, because ULONG is 32-bit and on...
[reactos.git] / ntoskrnl / ke / powerpc / kiinit.c
1 /*
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)
8 */
9
10 /* INCLUDES *****************************************************************/
11
12 #include <ntoskrnl.h>
13
14 //#define NDEBUG
15 #include <debug.h>
16 #include "ppcmmu/mmu.h"
17
18 /* GLOBALS *******************************************************************/
19
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
23
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];
31
32 /* FUNCTIONS *****************************************************************/
33 /*
34 * Trap frame:
35 * r0 .. r32
36 * lr, ctr, srr0, srr1, dsisr
37 */
38
39 extern int syscall_start[], syscall_end, KiDecrementerTrapHandler[],
40 KiDecrementerTrapHandlerEnd;
41
42 VOID
43 NTAPI
44 KiSetupSyscallHandler(VOID)
45 {
46 paddr_t handler_target;
47 int *source;
48 for(source = syscall_start, handler_target = 0xc00;
49 source < &syscall_end;
50 source++, handler_target += sizeof(int))
51 {
52 SetPhys(handler_target, *source);
53 }
54 }
55
56 VOID
57 NTAPI
58 KiSetupDecrementerTrap(VOID)
59 {
60 paddr_t handler_target;
61 int *source;
62
63 /* Turn off EE bit while redefining dec trap */
64 _disable();
65
66 for(source = KiDecrementerTrapHandler, handler_target = 0x900;
67 source != &KiDecrementerTrapHandlerEnd;
68 source++, handler_target += sizeof(int))
69 SetPhys(handler_target, *source);
70
71 DPRINT("CurrentThread %08x IdleThread %08x\n",
72 KeGetCurrentThread(), KeGetCurrentPrcb()->IdleThread);
73
74 /* Kick decmrenter! */
75 __asm__("mtdec %0" : : "r" (0));
76
77 /* Enable interrupts! */
78 _enable();
79 }
80
81 VOID
82 NTAPI
83 KiInitializePcr(IN ULONG ProcessorNumber,
84 IN PKIPCR Pcr,
85 IN PKTHREAD IdleThread,
86 IN PVOID DpcStack)
87 {
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;
96 #if DBG
97 Pcr->PrcbData->BuildType = PRCB_BUILD_DEBUG;
98 #else
99 Pcr->PrcbData->BuildType = 0;
100 #endif
101 Pcr->PrcbData->DpcStack = DpcStack;
102 KeGetPcr()->Prcb = Pcr->PrcbData;
103 KiProcessorBlock[ProcessorNumber] = Pcr->PrcbData;
104 }
105
106 extern ULONG KiGetFeatureBits();
107 extern VOID KiSetProcessorType();
108 extern VOID KiGetCacheInformation();
109
110 VOID
111 NTAPI
112 KiInitializeKernel(IN PKPROCESS InitProcess,
113 IN PKTHREAD InitThread,
114 IN PVOID IdleStack,
115 IN PKPRCB Prcb,
116 IN CCHAR Number,
117 IN PLOADER_PARAMETER_BLOCK LoaderBlock)
118 {
119 ULONG FeatureBits;
120 LARGE_INTEGER PageDirectory;
121 PVOID DpcStack;
122
123 /* Detect and set the CPU Type */
124 KiSetProcessorType();
125
126 /* Initialize the Power Management Support for this PRCB */
127 PoInitializePrcb(Prcb);
128
129 /* Get the processor features for the CPU */
130 FeatureBits = KiGetFeatureBits();
131
132 /* Save feature bits */
133 Prcb->FeatureBits = FeatureBits;
134
135 /* Get cache line information for this CPU */
136 KiGetCacheInformation();
137
138 /* Initialize spinlocks and DPC data */
139 KiInitSpinLocks(Prcb, Number);
140
141 /* Check if this is the Boot CPU */
142 if (!Number)
143 {
144 /* Set Node Data */
145 KeNodeBlock[0] = &KiNode0;
146 Prcb->ParentNode = KeNodeBlock[0];
147 KeNodeBlock[0]->ProcessorMask = Prcb->SetMember;
148
149 /* Set boot-level flags */
150 KeProcessorArchitecture = 0;
151 KeProcessorLevel = (USHORT)Prcb->CpuType;
152 KeFeatureBits = FeatureBits;
153
154 /* Set the current MP Master KPRCB to the Boot PRCB */
155 Prcb->MultiThreadSetMaster = Prcb;
156
157 /* Lower to APC_LEVEL */
158 KeLowerIrql(APC_LEVEL);
159
160 /* Initialize portable parts of the OS */
161 KiInitSystem();
162
163 /* Initialize the Idle Process and the Process Listhead */
164 InitializeListHead(&KiProcessListHead);
165 PageDirectory.QuadPart = 0;
166 KeInitializeProcess(InitProcess,
167 0,
168 0xFFFFFFFF,
169 &PageDirectory,
170 TRUE);
171 InitProcess->QuantumReset = MAXCHAR;
172 }
173 else
174 {
175 /* FIXME */
176 DPRINT1("SMP Boot support not yet present\n");
177 }
178
179 /* Setup the Idle Thread */
180 KeInitializeThread(InitProcess,
181 InitThread,
182 NULL,
183 NULL,
184 NULL,
185 NULL,
186 NULL,
187 IdleStack);
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;
194
195 /* HACK for MmUpdatePageDir */
196 ((PETHREAD)InitThread)->ThreadsProcess = (PEPROCESS)InitProcess;
197
198 /* Set up the thread-related fields in the PRCB */
199 Prcb->CurrentThread = InitThread;
200 Prcb->NextThread = NULL;
201 Prcb->IdleThread = InitThread;
202
203 /* Initialize Kernel Memory Address Space */
204 MmInit1(MmFreeLdrFirstKrnlPhysAddr,
205 MmFreeLdrLastKrnlPhysAddr,
206 MmFreeLdrLastKernelAddress,
207 KeMemoryMap,
208 KeMemoryMapRangeCount,
209 4096);
210
211 /* Initialize the Kernel Executive */
212 ExpInitializeExecutive(0, LoaderBlock);
213
214 /* Only do this on the boot CPU */
215 if (!Number)
216 {
217 /* Calculate the time reciprocal */
218 KiTimeIncrementReciprocal =
219 KiComputeReciprocal(KeMaximumIncrement,
220 &KiTimeIncrementShiftCount);
221
222 /* Update DPC Values in case they got updated by the executive */
223 Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
224 Prcb->MinimumDpcRate = KiMinimumDpcRate;
225 Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
226
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;
231 }
232
233 KfRaiseIrql(DISPATCH_LEVEL);
234
235 KeSetPriorityThread(InitThread, 0);
236 /* Setup decrementer exception */
237 KiSetupDecrementerTrap();
238
239 KfLowerIrql(PASSIVE_LEVEL);
240
241 /* Should not return */
242 while(1)
243 {
244 NtYieldExecution();
245 }
246 }
247
248 extern int KiPageFaultTrap();
249 KTRAP_FRAME KiInitialTrapFrame;
250
251 /* Use this for early boot additions to the page table */
252 VOID
253 NTAPI
254 KiSystemStartupReal(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
255 {
256 ULONG Cpu;
257 ppc_map_info_t info[4];
258 PKIPCR Pcr = (PKIPCR)KPCR_BASE;
259 PKPRCB Prcb;
260
261 __asm__("mr 13,%0" : : "r" (KPCR_BASE));
262
263 /* Set the page fault handler to the kernel */
264 MmuSetTrapHandler(3,KiPageFaultTrap);
265 MmuSetTrapHandler(4,KiPageFaultTrap);
266
267 // Make 0xf... special
268 MmuAllocVsid(2, 0x8000);
269 MmuSetVsid(15,16,2);
270
271 /* Get the current CPU */
272 Cpu = KeNumberProcessors;
273 if (!Cpu)
274 {
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.
277 */
278 info[0].phys = 0;
279 info[0].proc = 2;
280 info[0].addr = (vaddr_t)Pcr;
281 info[0].flags = MMU_KRW_UR;
282 info[1].phys = 0;
283 info[1].proc = 2;
284 info[1].addr = ((vaddr_t)Pcr) + (1 << PAGE_SHIFT);
285 info[1].flags = MMU_KRW_UR;
286 info[2].phys = 0;
287 info[2].proc = 2;
288 info[2].addr = (vaddr_t)KI_USER_SHARED_DATA;
289 info[2].flags = MMU_KRW_UR;
290 info[3].phys = 0;
291 info[3].proc = 2;
292 info[3].addr = (vaddr_t)KIP0PCRADDRESS;
293 info[3].flags = MMU_KRW_UR;
294 MmuMapPage(info, 4);
295 }
296
297 /* Skip initial setup if this isn't the Boot CPU */
298 if (Cpu) goto AppCpuInit;
299
300 /* Initialize the PCR */
301 RtlZeroMemory(Pcr, PAGE_SIZE);
302 KiInitializePcr(Cpu,
303 Pcr,
304 &KiInitialThread.Tcb,
305 KiDoubleFaultStack);
306
307 /* Set us as the current process */
308 KiInitialThread.Tcb.ApcState.Process = &KiInitialProcess.Pcb;
309 KiInitialThread.Tcb.TrapFrame = &KiInitialTrapFrame;
310
311 /* Setup CPU-related fields */
312 AppCpuInit:
313 Pcr->Number = Cpu;
314 Pcr->SetMember = 1 << Cpu;
315 Prcb = KeGetCurrentPrcb();
316 Prcb->SetMember = 1 << Cpu;
317
318 /* Initialize the Processor with HAL */
319 HalInitializeProcessor(Cpu, LoaderBlock);
320
321 /* Set active processors */
322 KeActiveProcessors |= Pcr->SetMember;
323 KeNumberProcessors++;
324
325 /* Initialize the Debugger for the Boot CPU */
326 if (!Cpu) KdInitSystem (0, LoaderBlock);
327
328 /* Check for break-in */
329 if (KdPollBreakIn())
330 {
331 DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
332 }
333
334 /* Raise to HIGH_LEVEL */
335 KfRaiseIrql(HIGH_LEVEL);
336
337 /* Call main kernel intialization */
338 KiInitializeKernel(&KiInitialProcess.Pcb,
339 &KiInitialThread.Tcb,
340 P0BootStack,
341 Prcb,
342 Cpu,
343 (PVOID)LoaderBlock);
344 }
345
346 VOID
347 NTAPI
348 KiInitMachineDependent(VOID)
349 {
350 }
351
352 void abort(VOID)
353 {
354 KeBugCheck(KMODE_EXCEPTION_NOT_HANDLED);
355 while(1);
356 }