[BOOTMGFW]
[reactos.git] / reactos / boot / environ / lib / bootlib.c
1 /*
2 * COPYRIGHT: See COPYING.ARM in the top level directory
3 * PROJECT: ReactOS UEFI Boot Library
4 * FILE: boot/environ/lib/bootlib.c
5 * PURPOSE: Boot Library Initialization
6 * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include "bl.h"
12
13 /* DATA VARIABLES ************************************************************/
14
15 BL_LIBRARY_PARAMETERS BlpLibraryParameters;
16 PBL_DEVICE_DESCRIPTOR BlpBootDevice;
17 PWCHAR BlpApplicationBaseDirectory;
18 PBOOT_APPLICATION_PARAMETER_BLOCK BlpApplicationParameters;
19 BL_APPLICATION_ENTRY BlpApplicationEntry;
20 BOOLEAN BlpLibraryParametersInitialized;
21
22 ULONG PdPersistAllocations;
23 LIST_ENTRY BlBadpListHead;
24
25 /* FUNCTIONS *****************************************************************/
26
27 /* HACKKKYYY */
28 EFI_SYSTEM_TABLE* g_SystemTable;
29
30 VOID
31 EarlyPrint(_In_ PWCHAR Format, ...)
32 {
33 WCHAR buffer[1024];
34 va_list args;
35
36 va_start(args, Format);
37
38 vswprintf(buffer, Format, args);
39
40 g_SystemTable->ConOut->OutputString(g_SystemTable->ConOut, L"\r");
41 g_SystemTable->ConOut->OutputString(g_SystemTable->ConOut, buffer);
42
43 g_SystemTable->BootServices->Stall(200000);
44
45 va_end(args);
46 }
47 /* END HACKKKYYY */
48
49 /*++
50 * @name InitializeLibrary
51 *
52 * The InitializeLibrary function initializes the Boot Library.
53 *
54 * @param BootParameters
55 * Pointer to the Boot Application Parameter Block.
56 *
57 * @param LibraryParameters
58 * Pointer to the Boot Library Parameters.
59 *
60 * @return NT_SUCCESS if the boot library was loaded correctly, relevant error
61 * otherwise.
62 *
63 *--*/
64 NTSTATUS
65 InitializeLibrary (
66 _In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters,
67 _In_ PBL_LIBRARY_PARAMETERS LibraryParameters
68 )
69 {
70 NTSTATUS Status;
71 PBL_MEMORY_DATA MemoryData;
72 PBL_APPLICATION_ENTRY AppEntry;
73 PBL_FIRMWARE_DESCRIPTOR FirmwareDescriptor;
74 ULONG_PTR ParamPointer = (ULONG_PTR)BootAppParameters;
75
76 /* Validate correct Boot Application data */
77 if (!(BootAppParameters) ||
78 (BootAppParameters->Signature[0] != BOOT_APPLICATION_SIGNATURE_1) ||
79 (BootAppParameters->Signature[1] != BOOT_APPLICATION_SIGNATURE_2) ||
80 (BootAppParameters->Size < sizeof(*BootAppParameters)))
81 {
82 Status = STATUS_INVALID_PARAMETER;
83 goto Quickie;
84 }
85
86 /* Get sub-structures */
87 MemoryData = (PBL_MEMORY_DATA)(ParamPointer + BootAppParameters->MemoryDataOffset);
88 FirmwareDescriptor = (PBL_FIRMWARE_DESCRIPTOR)(ParamPointer + BootAppParameters->FirmwareParametersOffset);
89 AppEntry = (PBL_APPLICATION_ENTRY)(ParamPointer + BootAppParameters->AppEntryOffset);
90 BlpBootDevice = (PBL_DEVICE_DESCRIPTOR)(ParamPointer + BootAppParameters->BootDeviceOffset);
91 BlpApplicationBaseDirectory = LibraryParameters->ApplicationBaseDirectory;
92
93 /* Initialize the firmware table */
94 Status = BlpFwInitialize(0, FirmwareDescriptor);
95 if (!NT_SUCCESS(Status))
96 {
97 goto Quickie;
98 }
99
100 /* Find boot application entry */
101 if (strncmp(AppEntry->Signature, BL_APP_ENTRY_SIGNATURE, 7))
102 {
103 Status = STATUS_INVALID_PARAMETER_9;
104 goto Quickie;
105 }
106
107 /* Read parameters */
108 BlpApplicationParameters = BootAppParameters;
109 BlpLibraryParameters = *LibraryParameters;
110
111 /* Save the application entry */
112 if (AppEntry->Flags & 2)
113 {
114 AppEntry->Flags = (AppEntry->Flags & ~0x2) | 0x80;
115 }
116 BlpApplicationEntry = *AppEntry;
117
118 /* Everything has been captured */
119 BlpLibraryParametersInitialized = TRUE;
120
121 /* Initialize the architecture (PM or RM) switching */
122 Status = BlpArchInitialize(0);
123 if (!NT_SUCCESS(Status))
124 {
125 goto Quickie;
126 }
127
128 /* Initialize the memory manager */
129 Status = BlpMmInitialize(MemoryData,
130 BootAppParameters->MemoryTranslationType,
131 LibraryParameters);
132 if (!NT_SUCCESS(Status))
133 {
134 EarlyPrint(L"MM init failed!\n");
135 goto Quickie;
136 }
137
138 /* Initialize firmware now that the heap, etc works */
139 Status = BlpFwInitialize(1, FirmwareDescriptor);
140 if (!NT_SUCCESS(Status))
141 {
142 /* Destroy memory manager in phase 1 */
143 //BlpMmDestroy(1);
144 EarlyPrint(L"Firmware2 init failed!\n");
145 return Status;
146 }
147
148 #if 0
149 /* Modern systems have an undocumented BCD system for the boot frequency */
150 Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData,
151 0x15000075,
152 &BootFrequency);
153 if (NT_SUCCESS(Status) && (BootFrequency))
154 {
155 /* Use it if present */
156 BlpTimePerformanceFrequency = BootFrequency;
157 }
158 else
159 #endif
160 {
161 /* Use the TSC for calibration */
162 Status = BlpTimeCalibratePerformanceCounter();
163 if (!NT_SUCCESS(Status))
164 {
165 /* Destroy memory manager in phase 1 */
166 EarlyPrint(L"TSC calibration failed\n");
167 //BlpMmDestroy(1);
168 return Status;
169 }
170 }
171
172 /* Now setup the rest of the architecture (IDT, etc) */
173 Status = BlpArchInitialize(1);
174 if (!NT_SUCCESS(Status))
175 {
176 /* Destroy memory manager in phase 1 */
177 EarlyPrint(L"Arch2 init failed\n");
178 //BlpMmDestroy(1);
179 return Status;
180 }
181
182 #ifdef BL_TPM_SUPPORT
183 /* Initialize support for Trusted Platform Module v1.2 */
184 BlpTpmInitialize();
185 #endif
186
187 #ifdef BL_TPM_SUPPORT
188 /* Initialize the event manager */
189 EnSubsystemInitialized = 1;
190 InitializeListHead(&EnEventNotificationList);
191 #endif
192
193 /* Initialize the I/O Manager */
194 Status = BlpIoInitialize();
195 if (!NT_SUCCESS(Status))
196 {
197 /* Destroy memory manager in phase 1 and the event manager */
198 EarlyPrint(L"IO init failed\n");
199 #ifdef BL_TPM_SUPPORT
200 if (EnSubsystemInitialized)
201 {
202 BlpEnDestroy();
203 }
204 #endif
205 //BlpMmDestroy(1);
206 return Status;
207 }
208
209 #ifdef BL_NET_SUPPORT
210 /* Initialize the network stack */
211 Status = BlNetInitialize();
212 if (!NT_SUCCESS(Status))
213 {
214 /* Destroy the I/O, event, and memory managers in phase 1 */
215 BlpIoDestroy();
216 #ifdef BL_TPM_SUPPORT
217 if (EnSubsystemInitialized)
218 {
219 BlpEnDestroy();
220 }
221 #endif
222 BlpMmDestroy(1);
223 return Status;
224 }
225 #endif
226
227 /* Initialize the utility library */
228 Status = BlUtlInitialize();
229 if (!NT_SUCCESS(Status))
230 {
231 /* Destroy the network, I/O, event, and memory managers in phase 1 */
232 #ifdef BL_NET_SUPPORT
233 BlNetDestroy();
234 #endif
235 //BlpIoDestroy();
236 #ifdef BL_TPM_SUPPORT
237 if (EnSubsystemInitialized)
238 {
239 BlpEnDestroy();
240 }
241 #endif
242 //BlpMmDestroy(1);
243 EarlyPrint(L"Util init failed\n");
244 return Status;
245 }
246
247 #ifdef BL_KD_SUPPORT
248 /* Initialize PCI Platform Support */
249 PltInitializePciConfiguration();
250 #endif
251
252 #ifdef BL_SECURE_BOOT_SUPPORT
253 /* Read the current SecureBoot Policy*/
254 Status = BlSecureBootSetActivePolicyFromPersistedData();
255 if (!NT_SUCCESS(Status))
256 {
257 /* Destroy everything that we've currently set up */
258 #ifdef BL_KD_SUPPORT
259 PltDestroyPciConfiguration();
260 #endif
261 #ifdef BL_NET_SUPPORT
262 BlNetDestroy();
263 #endif
264 BlpIoDestroy();
265 #ifdef BL_TPM_SUPPORT
266 if (EnSubsystemInitialized)
267 {
268 BlpEnDestroy();
269 }
270 #endif
271 BlpMmDestroy(1);
272 return Status;
273 }
274 #endif
275
276 #ifdef BL_TPM_SUPPORT
277 /* Initialize phase 0 of the security subsystem */
278 SipInitializePhase0();
279 #endif
280
281 #ifdef BL_KD_SUPPORT
282 /* Bring up the boot debugger, now that SecureBoot has been processed */
283 BlBdInitialize();
284 #endif
285
286 #ifdef BL_ETW_SUPPORT
287 /* Initialize internal logging */
288 BlpLogInitialize();
289 #endif
290
291 /* Are graphics enabled? */
292 if (!(LibraryParameters->LibraryFlags & BL_LIBRARY_FLAG_NO_DISPLAY))
293 {
294 /* Initialize the graphics library */
295 BlpDisplayInitialize(LibraryParameters->LibraryFlags);
296 }
297
298 /* Initialize the boot application persistent data */
299 PdPersistAllocations = 0;
300 InitializeListHead(&BlBadpListHead);
301
302 #ifdef BL_TPM_SUPPORT
303 /* Now setup the security subsystem in phase 1 */
304 BlpSiInitialize(1);
305 #endif
306
307 #if 0
308 /* Setup the text, UI and font resources */
309 Status = BlpResourceInitialize();
310 if (!NT_SUCCESS(Status))
311 {
312 /* Tear down everything if this failed */
313 if (!(LibraryParameters->LibraryFlags & BL_LIBRARY_FLAG_TEXT_MODE))
314 {
315 // BlpDisplayDestroy();
316 }
317 //BlpBdDestroy();
318 #ifdef BL_KD_SUPPORT
319 PltDestroyPciConfiguration();
320 #endif
321 #ifdef BL_NET_SUPPORT
322 BlNetDestroy();
323 #endif
324 //BlpIoDestroy();
325 #ifdef BL_TPM_SUPPORT
326 if (EnSubsystemInitialized)
327 {
328 BlpEnDestroy();
329 }
330 #endif
331 //BlpMmDestroy(1);
332 return Status;
333 }
334 #endif
335
336 #if BL_BITLOCKER_SUPPORT
337 /* Setup the boot cryptography library */
338 g_pEnvironmentData = &SymCryptEnvironmentWindowsBootLibrary;
339 if (SymCryptEnvWindowsBootLibInit)
340 {
341 SymCryptEnvWindowsBootLibInit();
342 }
343 #endif
344
345 /* We are fully initialized, remember this and exit with success */
346 BlpLibraryParameters.LibraryFlags |= BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED;
347 Status = STATUS_SUCCESS;
348
349 Quickie:
350 return Status;
351 }
352
353 /*++
354 * @name BlInitializeLibrary
355 *
356 * The BlInitializeLibrary function initializes, or re-initializes, the
357 * Boot Library.
358 *
359 * @param BootParameters
360 * Pointer to the Boot Application Parameter Block.
361 *
362 * @param LibraryParameters
363 * Pointer to the Boot Library Parameters.
364 *
365 * @return NT_SUCCESS if the boot library was loaded correctly, relevant error
366 * otherwise.
367 *
368 *--*/
369 NTSTATUS
370 BlInitializeLibrary(
371 _In_ PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters,
372 _In_ PBL_LIBRARY_PARAMETERS LibraryParameters
373 )
374 {
375 NTSTATUS Status;
376
377 /* Are we re-initializing the library? */
378 if (LibraryParameters->LibraryFlags & BL_LIBRARY_FLAG_REINITIALIZE)
379 {
380 /* From scratch? */
381 BlpLibraryParameters = *LibraryParameters;
382 if (LibraryParameters->LibraryFlags & BL_LIBRARY_FLAG_REINITIALIZE_ALL)
383 {
384 #if 0
385 /* Initialize all the core modules again */
386 BlpSiInitialize(1);
387 BlBdInitialize();
388 BlMmRemoveBadMemory();
389 BlpMmInitializeConstraints();
390
391 /* Redraw the graphics console as needed */
392 BlpDisplayInitialize(LibraryParameters->LibraryFlags);
393 BlpResourceInitialize();
394 #endif
395 }
396
397 /* Nothing to do, we're done */
398 Status = STATUS_SUCCESS;
399 }
400 else
401 {
402 /* Nope, this is first time initialization */
403 Status = InitializeLibrary(BootAppParameters, LibraryParameters);
404 }
405
406 /* Return initialization status */
407 return Status;
408 }
409