]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - IntelFrameworkModulePkg/Universal/BdsDxe/BdsEntry.c
Rollback the change to EFI_BOOT_KEY_DATA structure since UEFI Spec adds the clarifica...
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BdsEntry.c
... / ...
CommitLineData
1/** @file\r
2 This module produce main entry for BDS phase - BdsEntry.\r
3 When this module was dispatched by DxeCore, gEfiBdsArchProtocolGuid will be installed\r
4 which contains interface of BdsEntry.\r
5 After DxeCore finish DXE phase, gEfiBdsArchProtocolGuid->BdsEntry will be invoked\r
6 to enter BDS phase.\r
7\r
8Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>\r
9This program and the accompanying materials\r
10are licensed and made available under the terms and conditions of the BSD License\r
11which accompanies this distribution. The full text of the license may be found at\r
12http://opensource.org/licenses/bsd-license.php\r
13\r
14THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
15WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
16\r
17**/\r
18\r
19#include "Bds.h"\r
20#include "Language.h"\r
21#include "FrontPage.h"\r
22#include "Hotkey.h"\r
23#include "HwErrRecSupport.h"\r
24\r
25///\r
26/// BDS arch protocol instance initial value.\r
27///\r
28/// Note: Current BDS not directly get the BootMode, DefaultBoot,\r
29/// TimeoutDefault, MemoryTestLevel value from the BDS arch protocol.\r
30/// Please refer to the library useage of BdsLibGetBootMode, BdsLibGetTimeout\r
31/// and PlatformBdsDiagnostics in BdsPlatform.c\r
32///\r
33EFI_HANDLE gBdsHandle = NULL;\r
34\r
35EFI_BDS_ARCH_PROTOCOL gBds = {\r
36 BdsEntry\r
37};\r
38\r
39UINT16 *mBootNext = NULL;\r
40\r
41///\r
42/// The read-only variables defined in UEFI Spec.\r
43///\r
44CHAR16 *mReadOnlyVariables[] = {\r
45 L"PlatformLangCodes",\r
46 L"LangCodes",\r
47 L"BootOptionSupport",\r
48 L"HwErrRecSupport",\r
49 L"OsIndicationsSupported"\r
50 };\r
51\r
52/**\r
53\r
54 Install Boot Device Selection Protocol\r
55\r
56 @param ImageHandle The image handle.\r
57 @param SystemTable The system table.\r
58\r
59 @retval EFI_SUCEESS BDS has finished initializing.\r
60 Return the dispatcher and recall BDS.Entry\r
61 @retval Other Return status from AllocatePool() or gBS->InstallProtocolInterface\r
62\r
63**/\r
64EFI_STATUS\r
65EFIAPI\r
66BdsInitialize (\r
67 IN EFI_HANDLE ImageHandle,\r
68 IN EFI_SYSTEM_TABLE *SystemTable\r
69 )\r
70{\r
71 EFI_STATUS Status;\r
72\r
73 //\r
74 // Install protocol interface\r
75 //\r
76 Status = gBS->InstallMultipleProtocolInterfaces (\r
77 &gBdsHandle,\r
78 &gEfiBdsArchProtocolGuid, &gBds,\r
79 NULL\r
80 );\r
81 ASSERT_EFI_ERROR (Status);\r
82\r
83 return Status;\r
84}\r
85\r
86\r
87/**\r
88 An empty function to pass error checking of CreateEventEx ().\r
89\r
90 @param Event Event whose notification function is being invoked.\r
91 @param Context Pointer to the notification function's context,\r
92 which is implementation-dependent.\r
93\r
94**/\r
95VOID\r
96EFIAPI\r
97BdsEmptyCallbackFunction (\r
98 IN EFI_EVENT Event,\r
99 IN VOID *Context\r
100 )\r
101{\r
102}\r
103\r
104/**\r
105\r
106 This function attempts to boot for the boot order specified\r
107 by platform policy.\r
108\r
109**/\r
110VOID\r
111BdsBootDeviceSelect (\r
112 VOID\r
113 )\r
114{\r
115 EFI_STATUS Status;\r
116 LIST_ENTRY *Link;\r
117 BDS_COMMON_OPTION *BootOption;\r
118 UINTN ExitDataSize;\r
119 CHAR16 *ExitData;\r
120 UINT16 Timeout;\r
121 LIST_ENTRY BootLists;\r
122 CHAR16 Buffer[20];\r
123 BOOLEAN BootNextExist;\r
124 LIST_ENTRY *LinkBootNext;\r
125 EFI_EVENT ConnectConInEvent;\r
126\r
127 //\r
128 // Got the latest boot option\r
129 //\r
130 BootNextExist = FALSE;\r
131 LinkBootNext = NULL;\r
132 ConnectConInEvent = NULL;\r
133 InitializeListHead (&BootLists);\r
134\r
135 //\r
136 // First check the boot next option\r
137 //\r
138 ZeroMem (Buffer, sizeof (Buffer));\r
139\r
140 //\r
141 // Create Event to signal ConIn connection request\r
142 //\r
143 if (PcdGetBool (PcdConInConnectOnDemand)) {\r
144 Status = gBS->CreateEventEx (\r
145 EVT_NOTIFY_SIGNAL,\r
146 TPL_CALLBACK,\r
147 BdsEmptyCallbackFunction,\r
148 NULL,\r
149 &gConnectConInEventGuid,\r
150 &ConnectConInEvent\r
151 );\r
152 if (EFI_ERROR(Status)) {\r
153 ConnectConInEvent = NULL;\r
154 }\r
155 }\r
156\r
157 if (mBootNext != NULL) {\r
158 //\r
159 // Indicate we have the boot next variable, so this time\r
160 // boot will always have this boot option\r
161 //\r
162 BootNextExist = TRUE;\r
163\r
164 //\r
165 // Clear the this variable so it's only exist in this time boot\r
166 //\r
167 gRT->SetVariable (\r
168 L"BootNext",\r
169 &gEfiGlobalVariableGuid,\r
170 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
171 0,\r
172 mBootNext\r
173 );\r
174\r
175 //\r
176 // Add the boot next boot option\r
177 //\r
178 UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *mBootNext);\r
179 BootOption = BdsLibVariableToOption (&BootLists, Buffer);\r
180\r
181 //\r
182 // If fail to get boot option from variable, just return and do nothing.\r
183 //\r
184 if (BootOption == NULL) {\r
185 return;\r
186 }\r
187\r
188 BootOption->BootCurrent = *mBootNext;\r
189 }\r
190 //\r
191 // Parse the boot order to get boot option\r
192 //\r
193 BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");\r
194\r
195 //\r
196 // When we didn't have chance to build boot option variables in the first \r
197 // full configuration boot (e.g.: Reset in the first page or in Device Manager),\r
198 // we have no boot options in the following mini configuration boot.\r
199 // Give the last chance to enumerate the boot options.\r
200 //\r
201 if (IsListEmpty (&BootLists)) {\r
202 BdsLibEnumerateAllBootOption (&BootLists);\r
203 }\r
204\r
205 Link = BootLists.ForwardLink;\r
206\r
207 //\r
208 // Parameter check, make sure the loop will be valid\r
209 //\r
210 if (Link == NULL) {\r
211 return ;\r
212 }\r
213 //\r
214 // Here we make the boot in a loop, every boot success will\r
215 // return to the front page\r
216 //\r
217 for (;;) {\r
218 //\r
219 // Check the boot option list first\r
220 //\r
221 if (Link == &BootLists) {\r
222 //\r
223 // When LazyConIn enabled, signal connect ConIn event before enter UI\r
224 //\r
225 if (PcdGetBool (PcdConInConnectOnDemand) && ConnectConInEvent != NULL) {\r
226 gBS->SignalEvent (ConnectConInEvent);\r
227 }\r
228\r
229 //\r
230 // There are two ways to enter here:\r
231 // 1. There is no active boot option, give user chance to\r
232 // add new boot option\r
233 // 2. All the active boot option processed, and there is no\r
234 // one is success to boot, then we back here to allow user\r
235 // add new active boot option\r
236 //\r
237 Timeout = 0xffff;\r
238 PlatformBdsEnterFrontPage (Timeout, FALSE);\r
239 InitializeListHead (&BootLists);\r
240 BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");\r
241 Link = BootLists.ForwardLink;\r
242 continue;\r
243 }\r
244 //\r
245 // Get the boot option from the link list\r
246 //\r
247 BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE);\r
248\r
249 //\r
250 // According to EFI Specification, if a load option is not marked\r
251 // as LOAD_OPTION_ACTIVE, the boot manager will not automatically\r
252 // load the option.\r
253 //\r
254 if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) {\r
255 //\r
256 // skip the header of the link list, because it has no boot option\r
257 //\r
258 Link = Link->ForwardLink;\r
259 continue;\r
260 }\r
261 //\r
262 // Make sure the boot option device path connected,\r
263 // but ignore the BBS device path\r
264 //\r
265 if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) {\r
266 //\r
267 // Notes: the internal shell can not been connected with device path\r
268 // so we do not check the status here\r
269 //\r
270 BdsLibConnectDevicePath (BootOption->DevicePath);\r
271 }\r
272\r
273 //\r
274 // Restore to original mode before launching boot option.\r
275 //\r
276 BdsSetConsoleMode (FALSE);\r
277 \r
278 //\r
279 // All the driver options should have been processed since\r
280 // now boot will be performed.\r
281 //\r
282 Status = BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData);\r
283 if (Status != EFI_SUCCESS) {\r
284 //\r
285 // Call platform action to indicate the boot fail\r
286 //\r
287 BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_FAILED));\r
288 PlatformBdsBootFail (BootOption, Status, ExitData, ExitDataSize);\r
289\r
290 //\r
291 // Check the next boot option\r
292 //\r
293 Link = Link->ForwardLink;\r
294\r
295 } else {\r
296 //\r
297 // Call platform action to indicate the boot success\r
298 //\r
299 BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED));\r
300 PlatformBdsBootSuccess (BootOption);\r
301\r
302 //\r
303 // Boot success, then stop process the boot order, and\r
304 // present the boot manager menu, front page\r
305 //\r
306\r
307 //\r
308 // When LazyConIn enabled, signal connect ConIn Event before enter UI\r
309 //\r
310 if (PcdGetBool (PcdConInConnectOnDemand) && ConnectConInEvent != NULL) {\r
311 gBS->SignalEvent (ConnectConInEvent);\r
312 }\r
313\r
314 Timeout = 0xffff;\r
315 PlatformBdsEnterFrontPage (Timeout, FALSE);\r
316\r
317 //\r
318 // Rescan the boot option list, avoid potential risk of the boot\r
319 // option change in front page\r
320 //\r
321 if (BootNextExist) {\r
322 LinkBootNext = BootLists.ForwardLink;\r
323 }\r
324\r
325 InitializeListHead (&BootLists);\r
326 if (LinkBootNext != NULL) {\r
327 //\r
328 // Reserve the boot next option\r
329 //\r
330 InsertTailList (&BootLists, LinkBootNext);\r
331 }\r
332\r
333 BdsLibBuildOptionFromVar (&BootLists, L"BootOrder");\r
334 Link = BootLists.ForwardLink;\r
335 }\r
336 }\r
337\r
338}\r
339\r
340/**\r
341\r
342 Validate input console variable data. \r
343\r
344 If found the device path is not a valid device path, remove the variable.\r
345 \r
346 @param VariableName Input console variable name.\r
347\r
348**/\r
349VOID\r
350BdsFormalizeConsoleVariable (\r
351 IN CHAR16 *VariableName\r
352 )\r
353{\r
354 EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
355 UINTN VariableSize;\r
356 EFI_STATUS Status;\r
357\r
358 DevicePath = BdsLibGetVariableAndSize (\r
359 VariableName,\r
360 &gEfiGlobalVariableGuid,\r
361 &VariableSize\r
362 );\r
363 if ((DevicePath != NULL) && !IsDevicePathValid (DevicePath, VariableSize)) { \r
364 Status = gRT->SetVariable (\r
365 VariableName,\r
366 &gEfiGlobalVariableGuid,\r
367 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
368 0,\r
369 NULL\r
370 );\r
371 ASSERT_EFI_ERROR (Status);\r
372 }\r
373}\r
374\r
375/**\r
376\r
377 Formalize Bds global variables. \r
378\r
379 1. For ConIn/ConOut/ConErr, if found the device path is not a valid device path, remove the variable.\r
380 2. For OsIndicationsSupported, Create a BS/RT/UINT64 variable to report caps \r
381 3. Delete OsIndications variable if it is not NV/BS/RT UINT64\r
382 Item 3 is used to solve case when OS corrupts OsIndications. Here simply delete this NV variable.\r
383 \r
384**/\r
385VOID \r
386BdsFormalizeEfiGlobalVariable (\r
387 VOID\r
388 )\r
389{\r
390 EFI_STATUS Status;\r
391 UINT64 OsIndicationSupport;\r
392 UINT64 OsIndication;\r
393 UINTN DataSize;\r
394 UINT32 Attributes;\r
395 \r
396 //\r
397 // Validate Console variable.\r
398 //\r
399 BdsFormalizeConsoleVariable (L"ConIn");\r
400 BdsFormalizeConsoleVariable (L"ConOut");\r
401 BdsFormalizeConsoleVariable (L"ErrOut");\r
402\r
403 //\r
404 // OS indicater support variable\r
405 //\r
406 OsIndicationSupport = EFI_OS_INDICATIONS_BOOT_TO_FW_UI \\r
407 | EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED;\r
408\r
409 Status = gRT->SetVariable (\r
410 L"OsIndicationsSupported",\r
411 &gEfiGlobalVariableGuid,\r
412 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
413 sizeof(UINT64),\r
414 &OsIndicationSupport\r
415 );\r
416 ASSERT_EFI_ERROR (Status);\r
417\r
418 //\r
419 // If OsIndications is invalid, remove it.\r
420 // Invalid case\r
421 // 1. Data size != UINT64\r
422 // 2. OsIndication value inconsistence\r
423 // 3. OsIndication attribute inconsistence\r
424 //\r
425 OsIndication = 0;\r
426 Attributes = 0;\r
427 DataSize = sizeof(UINT64);\r
428 Status = gRT->GetVariable (\r
429 L"OsIndications",\r
430 &gEfiGlobalVariableGuid,\r
431 &Attributes,\r
432 &DataSize,\r
433 &OsIndication\r
434 );\r
435\r
436 if (!EFI_ERROR(Status)) {\r
437 if (DataSize != sizeof(UINT64) ||\r
438 (OsIndication & ~OsIndicationSupport) != 0 ||\r
439 Attributes != (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE)){\r
440\r
441 DEBUG ((EFI_D_ERROR, "Unformalized OsIndications variable exists. Delete it\n"));\r
442 Status = gRT->SetVariable (\r
443 L"OsIndications",\r
444 &gEfiGlobalVariableGuid,\r
445 Attributes,\r
446 0,\r
447 &OsIndication\r
448 );\r
449 ASSERT_EFI_ERROR (Status);\r
450 }\r
451 }\r
452\r
453}\r
454\r
455/**\r
456\r
457 Allocate a block of memory that will contain performance data to OS.\r
458\r
459**/\r
460VOID\r
461BdsAllocateMemoryForPerformanceData (\r
462 VOID\r
463 )\r
464{\r
465 EFI_STATUS Status;\r
466 EFI_PHYSICAL_ADDRESS AcpiLowMemoryBase;\r
467 EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock;\r
468\r
469 AcpiLowMemoryBase = 0x0FFFFFFFFULL;\r
470\r
471 //\r
472 // Allocate a block of memory that will contain performance data to OS.\r
473 //\r
474 Status = gBS->AllocatePages (\r
475 AllocateMaxAddress,\r
476 EfiReservedMemoryType,\r
477 EFI_SIZE_TO_PAGES (PERF_DATA_MAX_LENGTH),\r
478 &AcpiLowMemoryBase\r
479 );\r
480 if (!EFI_ERROR (Status)) {\r
481 //\r
482 // Save the pointer to variable for use in S3 resume.\r
483 //\r
484 Status = gRT->SetVariable (\r
485 L"PerfDataMemAddr",\r
486 &gPerformanceProtocolGuid,\r
487 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
488 sizeof (EFI_PHYSICAL_ADDRESS),\r
489 &AcpiLowMemoryBase\r
490 );\r
491 ASSERT_EFI_ERROR (Status);\r
492 //\r
493 // Mark L"PerfDataMemAddr" variable to read-only if the Variable Lock protocol exists\r
494 //\r
495 Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **) &VariableLock);\r
496 if (!EFI_ERROR (Status)) {\r
497 Status = VariableLock->RequestToLock (VariableLock, L"PerfDataMemAddr", &gPerformanceProtocolGuid);\r
498 ASSERT_EFI_ERROR (Status);\r
499 }\r
500 }\r
501}\r
502\r
503/**\r
504\r
505 Service routine for BdsInstance->Entry(). Devices are connected, the\r
506 consoles are initialized, and the boot options are tried.\r
507\r
508 @param This Protocol Instance structure.\r
509\r
510**/\r
511VOID\r
512EFIAPI\r
513BdsEntry (\r
514 IN EFI_BDS_ARCH_PROTOCOL *This\r
515 )\r
516{\r
517 LIST_ENTRY DriverOptionList;\r
518 LIST_ENTRY BootOptionList;\r
519 UINTN BootNextSize;\r
520 CHAR16 *FirmwareVendor;\r
521 EFI_STATUS Status;\r
522 UINT16 BootTimeOut;\r
523 UINTN Index;\r
524 EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock;\r
525\r
526 //\r
527 // Insert the performance probe\r
528 //\r
529 PERF_END (NULL, "DXE", NULL, 0);\r
530 PERF_START (NULL, "BDS", NULL, 0);\r
531\r
532 PERF_CODE (\r
533 BdsAllocateMemoryForPerformanceData ();\r
534 );\r
535\r
536 //\r
537 // Initialize the global system boot option and driver option\r
538 //\r
539 InitializeListHead (&DriverOptionList);\r
540 InitializeListHead (&BootOptionList);\r
541\r
542 //\r
543 // Initialize hotkey service\r
544 //\r
545 InitializeHotkeyService ();\r
546\r
547 //\r
548 // Fill in FirmwareVendor and FirmwareRevision from PCDs\r
549 //\r
550 FirmwareVendor = (CHAR16 *)PcdGetPtr (PcdFirmwareVendor);\r
551 gST->FirmwareVendor = AllocateRuntimeCopyPool (StrSize (FirmwareVendor), FirmwareVendor);\r
552 ASSERT (gST->FirmwareVendor != NULL);\r
553 gST->FirmwareRevision = PcdGet32 (PcdFirmwareRevision);\r
554\r
555 //\r
556 // Fixup Tasble CRC after we updated Firmware Vendor and Revision\r
557 //\r
558 gST->Hdr.CRC32 = 0;\r
559 gBS->CalculateCrc32 ((VOID *)gST, sizeof(EFI_SYSTEM_TABLE), &gST->Hdr.CRC32);\r
560\r
561 //\r
562 // Validate Variable.\r
563 //\r
564 BdsFormalizeEfiGlobalVariable();\r
565\r
566 //\r
567 // Mark the read-only variables if the Variable Lock protocol exists\r
568 //\r
569 Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **) &VariableLock);\r
570 DEBUG ((EFI_D_INFO, "[BdsDxe] Locate Variable Lock protocol - %r\n", Status));\r
571 if (!EFI_ERROR (Status)) {\r
572 for (Index = 0; Index < sizeof (mReadOnlyVariables) / sizeof (mReadOnlyVariables[0]); Index++) {\r
573 Status = VariableLock->RequestToLock (VariableLock, mReadOnlyVariables[Index], &gEfiGlobalVariableGuid);\r
574 ASSERT_EFI_ERROR (Status);\r
575 }\r
576 }\r
577\r
578 //\r
579 // Report Status Code to indicate connecting drivers will happen\r
580 //\r
581 REPORT_STATUS_CODE (\r
582 EFI_PROGRESS_CODE,\r
583 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_BEGIN_CONNECTING_DRIVERS)\r
584 );\r
585\r
586 InitializeHwErrRecSupport();\r
587\r
588 //\r
589 // Initialize L"Timeout" EFI global variable.\r
590 //\r
591 BootTimeOut = PcdGet16 (PcdPlatformBootTimeOut);\r
592 if (BootTimeOut != 0xFFFF) {\r
593 //\r
594 // If time out value equal 0xFFFF, no need set to 0xFFFF to variable area because UEFI specification\r
595 // define same behavior between no value or 0xFFFF value for L"Timeout".\r
596 //\r
597 Status = gRT->SetVariable (\r
598 L"Timeout",\r
599 &gEfiGlobalVariableGuid,\r
600 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
601 sizeof (UINT16),\r
602 &BootTimeOut\r
603 );\r
604 ASSERT_EFI_ERROR(Status);\r
605 }\r
606\r
607 //\r
608 // bugbug: platform specific code\r
609 // Initialize the platform specific string and language\r
610 //\r
611 InitializeStringSupport ();\r
612 InitializeLanguage (TRUE);\r
613 InitializeFrontPage (TRUE);\r
614\r
615 //\r
616 // Do the platform init, can be customized by OEM/IBV\r
617 //\r
618 PERF_START (NULL, "PlatformBds", "BDS", 0);\r
619 PlatformBdsInit ();\r
620\r
621 //\r
622 // Set up the device list based on EFI 1.1 variables\r
623 // process Driver#### and Load the driver's in the\r
624 // driver option list\r
625 //\r
626 BdsLibBuildOptionFromVar (&DriverOptionList, L"DriverOrder");\r
627 if (!IsListEmpty (&DriverOptionList)) {\r
628 BdsLibLoadDrivers (&DriverOptionList);\r
629 }\r
630 //\r
631 // Check if we have the boot next option\r
632 //\r
633 mBootNext = BdsLibGetVariableAndSize (\r
634 L"BootNext",\r
635 &gEfiGlobalVariableGuid,\r
636 &BootNextSize\r
637 );\r
638\r
639 //\r
640 // Setup some platform policy here\r
641 //\r
642 PlatformBdsPolicyBehavior (&DriverOptionList, &BootOptionList, BdsProcessCapsules, BdsMemoryTest);\r
643 PERF_END (NULL, "PlatformBds", "BDS", 0);\r
644\r
645 //\r
646 // BDS select the boot device to load OS\r
647 //\r
648 BdsBootDeviceSelect ();\r
649\r
650 //\r
651 // Only assert here since this is the right behavior, we should never\r
652 // return back to DxeCore.\r
653 //\r
654 ASSERT (FALSE);\r
655\r
656 return ;\r
657}\r