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