2003-06-05 Casper S. Hornstrup <chorns@users.sourceforge.net>
[reactos.git] / reactos / ntoskrnl / ke / i386 / kernel.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /*
20 * PROJECT: ReactOS kernel
21 * FILE: ntoskrnl/ke/i386/kernel.c
22 * PURPOSE: Initializes the kernel
23 * PROGRAMMER: David Welch (welch@mcmail.com)
24 * UPDATE HISTORY:
25 * Created 22/05/98
26 */
27
28 /* INCLUDES *****************************************************************/
29
30 #include <ddk/ntddk.h>
31 #include <internal/ke.h>
32 #include <internal/mm.h>
33 #include <internal/ps.h>
34 #include <internal/i386/fpu.h>
35
36 #define NDEBUG
37 #include <internal/debug.h>
38
39 /* GLOBALS *******************************************************************/
40
41 ULONG KiPcrInitDone = 0;
42 static ULONG PcrsAllocated = 0;
43 static PHYSICAL_ADDRESS PcrPages[MAXIMUM_PROCESSORS];
44
45 /* FUNCTIONS *****************************************************************/
46
47 VOID
48 KePrepareForApplicationProcessorInit(ULONG Id)
49 {
50 MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &PcrPages[Id]);
51 KiGdtPrepareForApplicationProcessorInit(Id);
52 }
53
54 VOID
55 KeApplicationProcessorInit(VOID)
56 {
57 PKPCR KPCR;
58 ULONG Offset;
59
60 /*
61 * Create a PCR for this processor
62 */
63 Offset = InterlockedIncrement((LONG *)&PcrsAllocated) - 1;
64 KPCR = (PKPCR)(KPCR_BASE + (Offset * PAGE_SIZE));
65 MmCreateVirtualMappingForKernel((PVOID)KPCR,
66 PAGE_READWRITE,
67 PcrPages[Offset]);
68 memset(KPCR, 0, PAGE_SIZE);
69 KPCR->ProcessorNumber = Offset;
70 KPCR->Self = KPCR;
71 KPCR->Irql = HIGH_LEVEL;
72
73 /* Mark the end of the exception handler list */
74 KPCR->Tib.ExceptionList = (PVOID)-1;
75
76 /*
77 * Initialize the GDT
78 */
79 KiInitializeGdt(KPCR);
80
81 /*
82 * It is now safe to process interrupts
83 */
84 KeLowerIrql(DISPATCH_LEVEL);
85
86 /*
87 * Initialize the TSS
88 */
89 Ki386ApplicationProcessorInitializeTSS();
90
91 /*
92 * Initialize a default LDT
93 */
94 Ki386InitializeLdt();
95
96 __asm__ __volatile__ ("sti\n\t");
97 }
98
99 VOID
100 KeInit1(VOID)
101 {
102 PKPCR KPCR;
103 extern USHORT KiBootGdt[];
104 extern KTSS KiBootTss;
105
106 KiCheckFPU();
107
108 KiInitializeGdt (NULL);
109 Ki386BootInitializeTSS();
110 KeInitExceptions ();
111 KeInitInterrupts ();
112
113 /*
114 * Initialize the initial PCR region. We can't allocate a page
115 * with MmAllocPage() here because MmInit1() has not yet been
116 * called, so we use a predefined page in low memory
117 */
118 KPCR = (PKPCR)KPCR_BASE;
119 memset(KPCR, 0, PAGE_SIZE);
120 KPCR->Self = (PKPCR)KPCR_BASE;
121 KPCR->Irql = HIGH_LEVEL;
122 KPCR->GDT = (PUSHORT)&KiBootGdt;
123 KPCR->IDT = (PUSHORT)&KiIdt;
124 KPCR->TSS = &KiBootTss;
125 KPCR->ProcessorNumber = 0;
126 KiPcrInitDone = 1;
127 PcrsAllocated++;
128
129 /* Mark the end of the exception handler list */
130 KPCR->Tib.ExceptionList = (PVOID)-1;
131
132 Ki386InitializeLdt();
133 }
134
135 VOID
136 KeInit2(VOID)
137 {
138 KeInitDpc();
139 KeInitializeBugCheck();
140 KeInitializeDispatcher();
141 KeInitializeTimerImpl();
142 }