update for HEAD-2003091401
[reactos.git] / 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 }