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