sync with trunk head (34904)
[reactos.git] / reactos / boot / freeldr / freeldr / arch / amd64 / loader.c
1 /*
2 * FreeLoader
3 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
4 * Copyright (C) 2005 Alex Ionescu <alex@relsoft.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20 #define _NTSYSTEM_
21 #include <freeldr.h>
22
23 #define NDEBUG
24 #include <debug.h>
25 #undef DbgPrint
26
27 /* Page Directory and Tables for non-PAE Systems */
28 extern PAGE_DIRECTORY_X86 startup_pagedirectory;
29 extern PAGE_DIRECTORY_X86 lowmem_pagetable;
30 extern PAGE_DIRECTORY_X86 kernel_pagetable;
31 extern PAGE_DIRECTORY_X86 hyperspace_pagetable;
32 extern PAGE_DIRECTORY_X86 apic_pagetable;
33 extern PAGE_DIRECTORY_X86 kpcr_pagetable;
34 extern PAGE_DIRECTORY_X86 kuser_pagetable;
35 extern ULONG_PTR KernelBase;
36 extern ROS_KERNEL_ENTRY_POINT KernelEntryPoint;
37 /* FUNCTIONS *****************************************************************/
38
39 /*++
40 * FrLdrStartup
41 * INTERNAL
42 *
43 * Prepares the system for loading the Kernel.
44 *
45 * Params:
46 * Magic - Multiboot Magic
47 *
48 * Returns:
49 * None.
50 *
51 * Remarks:
52 * None.
53 *
54 *--*/
55 VOID
56 NTAPI
57 FrLdrStartup(ULONG Magic)
58 {
59 ASSERT(FALSE);
60 #if 0
61 /* Disable Interrupts */
62 _disable();
63
64 /* Re-initalize EFLAGS */
65 Ke386EraseFlags();
66
67 /* Initialize the page directory */
68 FrLdrSetupPageDirectory();
69
70 /* Initialize Paging, Write-Protection and Load NTOSKRNL */
71 FrLdrSetupPae(Magic);
72 #endif
73 }
74
75 /*++
76 * FrLdrSetupPae
77 * INTERNAL
78 *
79 * Configures PAE on a MP System, and sets the PDBR if it's supported, or if
80 * the system is UP.
81 *
82 * Params:
83 * Magic - Multiboot Magic
84 *
85 * Returns:
86 * None.
87 *
88 * Remarks:
89 * None.
90 *
91 *--*/
92 VOID
93 FASTCALL
94 FrLdrSetupPae(ULONG Magic)
95 {
96 #if 0
97 ULONG_PTR PageDirectoryBaseAddress = (ULONG_PTR)&startup_pagedirectory;
98
99 /* Set the PDBR */
100 __writecr3(PageDirectoryBaseAddress);
101
102 /* Enable Paging and Write Protect*/
103 __writecr0(__readcr0() | X86_CR0_PG | X86_CR0_WP);
104
105 /* Jump to Kernel */
106 (*KernelEntryPoint)(Magic, &LoaderBlock);
107 #endif
108 }
109
110 /*++
111 * FrLdrSetupPageDirectory
112 * INTERNAL
113 *
114 * Sets up the ReactOS Startup Page Directory.
115 *
116 * Params:
117 * None.
118 *
119 * Returns:
120 * None.
121 *
122 * Remarks:
123 * We are setting PDEs, but using the equvivalent (for our purpose) PTE structure.
124 * As such, please note that PageFrameNumber == PageEntryNumber.
125 *
126 *--*/
127 VOID
128 FASTCALL
129 FrLdrSetupPageDirectory(VOID)
130 {
131 #if 0
132 PPAGE_DIRECTORY_X86 PageDir;
133 ULONG KernelPageTableIndex;
134 ULONG i;
135
136 /* Get the Kernel Table Index */
137 KernelPageTableIndex = KernelBase >> PDE_SHIFT;
138
139 /* Get the Startup Page Directory */
140 PageDir = (PPAGE_DIRECTORY_X86)&startup_pagedirectory;
141
142 /* Set up the Low Memory PDE */
143 PageDir->Pde[LowMemPageTableIndex].Valid = 1;
144 PageDir->Pde[LowMemPageTableIndex].Write = 1;
145 PageDir->Pde[LowMemPageTableIndex].PageFrameNumber = PaPtrToPfn(lowmem_pagetable);
146
147 /* Set up the Kernel PDEs */
148 PageDir->Pde[KernelPageTableIndex].Valid = 1;
149 PageDir->Pde[KernelPageTableIndex].Write = 1;
150 PageDir->Pde[KernelPageTableIndex].PageFrameNumber = PaPtrToPfn(kernel_pagetable);
151 PageDir->Pde[KernelPageTableIndex + 1].Valid = 1;
152 PageDir->Pde[KernelPageTableIndex + 1].Write = 1;
153 PageDir->Pde[KernelPageTableIndex + 1].PageFrameNumber = PaPtrToPfn(kernel_pagetable + 4096);
154
155 /* Set up the Startup PDE */
156 PageDir->Pde[StartupPageTableIndex].Valid = 1;
157 PageDir->Pde[StartupPageTableIndex].Write = 1;
158 PageDir->Pde[StartupPageTableIndex].PageFrameNumber = PaPtrToPfn(startup_pagedirectory);
159
160 /* Set up the Hyperspace PDE */
161 PageDir->Pde[HyperspacePageTableIndex].Valid = 1;
162 PageDir->Pde[HyperspacePageTableIndex].Write = 1;
163 PageDir->Pde[HyperspacePageTableIndex].PageFrameNumber = PaPtrToPfn(hyperspace_pagetable);
164
165 /* Set up the HAL PDE */
166 PageDir->Pde[HalPageTableIndex].Valid = 1;
167 PageDir->Pde[HalPageTableIndex].Write = 1;
168 PageDir->Pde[HalPageTableIndex].PageFrameNumber = PaPtrToPfn(apic_pagetable);
169
170 /* Set up Low Memory PTEs */
171 PageDir = (PPAGE_DIRECTORY_X86)&lowmem_pagetable;
172 for (i=0; i<1024; i++)
173 {
174 PageDir->Pde[i].Valid = 1;
175 PageDir->Pde[i].Write = 1;
176 PageDir->Pde[i].Owner = 1;
177 PageDir->Pde[i].PageFrameNumber = PaToPfn(i * PAGE_SIZE);
178 }
179
180 /* Set up Kernel PTEs */
181 PageDir = (PPAGE_DIRECTORY_X86)&kernel_pagetable;
182 for (i=0; i<1536; i++)
183 {
184 PageDir->Pde[i].Valid = 1;
185 PageDir->Pde[i].Write = 1;
186 PageDir->Pde[i].PageFrameNumber = PaToPfn(KERNEL_BASE_PHYS + i * PAGE_SIZE);
187 }
188
189 /* Setup APIC Base */
190 PageDir = (PPAGE_DIRECTORY_X86)&apic_pagetable;
191 PageDir->Pde[0].Valid = 1;
192 PageDir->Pde[0].Write = 1;
193 PageDir->Pde[0].CacheDisable = 1;
194 PageDir->Pde[0].WriteThrough = 1;
195 PageDir->Pde[0].PageFrameNumber = PaToPfn(HAL_BASE);
196 PageDir->Pde[0x200].Valid = 1;
197 PageDir->Pde[0x200].Write = 1;
198 PageDir->Pde[0x200].CacheDisable = 1;
199 PageDir->Pde[0x200].WriteThrough = 1;
200 PageDir->Pde[0x200].PageFrameNumber = PaToPfn(HAL_BASE + KERNEL_BASE_PHYS);
201
202 /* Setup KUSER_SHARED_DATA Base */
203 PageDir->Pde[0x1F0].Valid = 1;
204 PageDir->Pde[0x1F0].Write = 1;
205 PageDir->Pde[0x1F0].PageFrameNumber = 2;
206
207 /* Setup KPCR Base*/
208 PageDir->Pde[0x1FF].Valid = 1;
209 PageDir->Pde[0x1FF].Write = 1;
210 PageDir->Pde[0x1FF].PageFrameNumber = 1;
211
212 /* Zero shared data */
213 RtlZeroMemory((PVOID)(2 << MM_PAGE_SHIFT), PAGE_SIZE);
214 #endif
215 }
216