1 /** @file
2 This file include all platform action which can be customized by IBV/OEM.
3
4 Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "BdsPlatform.h"
10 #include <Guid/EventGroup.h>
11 #include <Protocol/DxeSmmReadyToLock.h>
12 #include <Protocol/FirmwareVolume2.h>
13 #include <Protocol/PciRootBridgeIo.h>
14
15 #include <Protocol/BlockIo.h>
16 #include <Protocol/PciIo.h>
17 #include <Library/IoLib.h>
18 #include <Library/PciLib.h>
19 #include <Guid/EventGroup.h>
20
21 #include <Library/Tcg2PhysicalPresenceLib.h>
22
23 #include <Library/HobLib.h>
24 #include <Protocol/UsbIo.h>
25 #include <Library/BootLogoLib.h>
26
27 #include <Library/UefiBootManagerLib.h>
28
29 GLOBAL_REMOVE_IF_UNREFERENCED EFI_BOOT_MODE gBootMode;
30
31 BOOLEAN gPPRequireUIConfirm;
32
33 extern UINTN mBootMenuOptionNumber;
34
35 GLOBAL_REMOVE_IF_UNREFERENCED USB_CLASS_FORMAT_DEVICE_PATH gUsbClassKeyboardDevicePath = {
36 {
37 {
38 MESSAGING_DEVICE_PATH,
39 MSG_USB_CLASS_DP,
40 {
41 (UINT8) (sizeof (USB_CLASS_DEVICE_PATH)),
42 (UINT8) ((sizeof (USB_CLASS_DEVICE_PATH)) >> 8)
43 }
44 },
45 0xffff, // VendorId
46 0xffff, // ProductId
47 CLASS_HID, // DeviceClass
48 SUBCLASS_BOOT, // DeviceSubClass
49 PROTOCOL_KEYBOARD // DeviceProtocol
50 },
51 gEndEntire
52 };
53
54 //
55 // Platform specific ISA serial device path
56 //
57 GLOBAL_REMOVE_IF_UNREFERENCED PLATFORM_ISA_SERIAL_DEVICE_PATH gIsaSerialDevicePath = {
58 gPciRootBridge,
59 gPciIsaBridge,
60 gPnp16550ComPort,
61 gUart(115200, 8, 1, 1),
62 gPcAnsiTerminal,
63 gEndEntire
64 };
65
66 //
67 // Internal shell mode
68 //
69 GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mShellModeColumn;
70 GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mShellModeRow;
71 GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mShellHorizontalResolution;
72 GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mShellVerticalResolution;
73 //
74 // BDS Platform Functions
75 //
76
77 BOOLEAN
IsMorBitSet(VOID)78 IsMorBitSet (
79 VOID
80 )
81 {
82 UINTN MorControl;
83 EFI_STATUS Status;
84 UINTN DataSize;
85
86 //
87 // Check if the MOR bit is set.
88 //
89 DataSize = sizeof (MorControl);
90 Status = gRT->GetVariable (
91 MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
92 &gEfiMemoryOverwriteControlDataGuid,
93 NULL,
94 &DataSize,
95 &MorControl
96 );
97 if (EFI_ERROR (Status)) {
98 DEBUG ((DEBUG_INFO, " PlatformBootMangerLib: gEfiMemoryOverwriteControlDataGuid doesn't exist!!***\n"));
99 MorControl = 0;
100 } else {
101 DEBUG ((DEBUG_INFO, " PlatformBootMangerLib: Get the gEfiMemoryOverwriteControlDataGuid = %x!!***\n", MorControl));
102 }
103
104 return (BOOLEAN) (MorControl & 0x01);
105 }
106
107 VOID
DumpDevicePath(IN CHAR16 * Name,IN EFI_DEVICE_PATH * DevicePath)108 DumpDevicePath (
109 IN CHAR16 *Name,
110 IN EFI_DEVICE_PATH *DevicePath
111 )
112 {
113 CHAR16 *Str;
114
115 Str = ConvertDevicePathToText(DevicePath, TRUE, TRUE);
116 DEBUG ((DEBUG_INFO, "%s: %s\n", Name, Str));
117 if (Str != NULL) {
118 FreePool (Str);
119 }
120 }
121
122 /**
123 An empty function to pass error checking of CreateEventEx ().
124
125 This empty function ensures that EVT_NOTIFY_SIGNAL_ALL is error
126 checked correctly since it is now mapped into CreateEventEx() in UEFI 2.0.
127
128 @param Event Event whose notification function is being invoked.
129 @param Context The pointer to the notification function's context,
130 which is implementation-dependent.
131 **/
132 VOID
133 EFIAPI
InternalBdsEmptyCallbackFuntion(IN EFI_EVENT Event,IN VOID * Context)134 InternalBdsEmptyCallbackFuntion (
135 IN EFI_EVENT Event,
136 IN VOID *Context
137 )
138 {
139 return;
140 }
141
142 VOID
ExitPmAuth(VOID)143 ExitPmAuth (
144 VOID
145 )
146 {
147 EFI_HANDLE Handle;
148 EFI_STATUS Status;
149 EFI_EVENT EndOfDxeEvent;
150
151 DEBUG((DEBUG_INFO,"ExitPmAuth ()- Start\n"));
152 //
153 // Prepare S3 information, this MUST be done before ExitPmAuth/EndOfDxe
154 //
155 //
156 // Since PI1.2.1, we need signal EndOfDxe as ExitPmAuth
157 //
158 Status = gBS->CreateEventEx (
159 EVT_NOTIFY_SIGNAL,
160 TPL_CALLBACK,
161 InternalBdsEmptyCallbackFuntion,
162 NULL,
163 &gEfiEndOfDxeEventGroupGuid,
164 &EndOfDxeEvent
165 );
166 ASSERT_EFI_ERROR (Status);
167 gBS->SignalEvent (EndOfDxeEvent);
168 gBS->CloseEvent (EndOfDxeEvent);
169 DEBUG((DEBUG_INFO,"All EndOfDxe callbacks have returned successfully\n"));
170
171 //
172 // NOTE: We need install DxeSmmReadyToLock directly here because many boot script is added via ExitPmAuth/EndOfDxe callback.
173 // If we install them at same callback, these boot script will be rejected because BootScript Driver runs first to lock them done.
174 // So we seperate them to be 2 different events, ExitPmAuth is last chance to let platform add boot script. DxeSmmReadyToLock will
175 // make boot script save driver lock down the interface.
176 //
177 Handle = NULL;
178 Status = gBS->InstallProtocolInterface (
179 &Handle,
180 &gEfiDxeSmmReadyToLockProtocolGuid,
181 EFI_NATIVE_INTERFACE,
182 NULL
183 );
184 ASSERT_EFI_ERROR (Status);
185 DEBUG((DEBUG_INFO,"ExitPmAuth ()- End\n"));
186 }
187
188 VOID
ConnectRootBridge(BOOLEAN Recursive)189 ConnectRootBridge (
190 BOOLEAN Recursive
191 )
192 {
193 UINTN RootBridgeHandleCount;
194 EFI_HANDLE *RootBridgeHandleBuffer;
195 UINTN RootBridgeIndex;
196
197 RootBridgeHandleCount = 0;
198 gBS->LocateHandleBuffer (
199 ByProtocol,
200 &gEfiPciRootBridgeIoProtocolGuid,
201 NULL,
202 &RootBridgeHandleCount,
203 &RootBridgeHandleBuffer
204 );
205 for (RootBridgeIndex = 0; RootBridgeIndex < RootBridgeHandleCount; RootBridgeIndex++) {
206 gBS->ConnectController (RootBridgeHandleBuffer[RootBridgeIndex], NULL, NULL, Recursive);
207 }
208 }
209
210
211 /**
212 Return whether the device is trusted console.
213
214 @param Device The device to be tested.
215
216 @retval TRUE The device can be trusted.
217 @retval FALSE The device cannot be trusted.
218 **/
219 BOOLEAN
IsTrustedConsole(IN CONSOLE_TYPE ConsoleType,IN EFI_DEVICE_PATH_PROTOCOL * Device)220 IsTrustedConsole (
221 IN CONSOLE_TYPE ConsoleType,
222 IN EFI_DEVICE_PATH_PROTOCOL *Device
223 )
224 {
225 VOID *TrustedConsoleDevicepath;
226 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
227 EFI_DEVICE_PATH_PROTOCOL *Instance;
228 UINTN Size;
229 EFI_DEVICE_PATH_PROTOCOL *ConsoleDevice;
230
231 if (Device == NULL) {
232 return FALSE;
233 }
234
235 ConsoleDevice = DuplicateDevicePath(Device);
236
237 TrustedConsoleDevicepath = NULL;
238
239 switch (ConsoleType) {
240 case ConIn:
241 TrustedConsoleDevicepath = PcdGetPtr (PcdTrustedConsoleInputDevicePath);
242 break;
243 case ConOut:
244 //
245 // Check GOP and remove last node
246 //
247 TempDevicePath = ConsoleDevice;
248 while (!IsDevicePathEndType (TempDevicePath)) {
249 if (DevicePathType (TempDevicePath) == ACPI_DEVICE_PATH &&
250 DevicePathSubType (TempDevicePath) == ACPI_ADR_DP) {
251 SetDevicePathEndNode (TempDevicePath);
252 break;
253 }
254 TempDevicePath = NextDevicePathNode (TempDevicePath);
255 }
256
257 TrustedConsoleDevicepath = PcdGetPtr (PcdTrustedConsoleOutputDevicePath);
258 break;
259 default:
260 ASSERT(FALSE);
261 break;
262 }
263
264 TempDevicePath = TrustedConsoleDevicepath;
265 do {
266 Instance = GetNextDevicePathInstance (&TempDevicePath, &Size);
267 if (Instance == NULL) {
268 break;
269 }
270
271 if (CompareMem (ConsoleDevice, Instance, Size - END_DEVICE_PATH_LENGTH) == 0) {
272 FreePool (Instance);
273 FreePool (ConsoleDevice);
274 return TRUE;
275 }
276
277 FreePool (Instance);
278 } while (TempDevicePath != NULL);
279
280 FreePool (ConsoleDevice);
281
282 return FALSE;
283 }
284
285 BOOLEAN
IsUsbShortForm(IN EFI_DEVICE_PATH_PROTOCOL * DevicePath)286 IsUsbShortForm (
287 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
288 )
289 {
290 if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&
291 ((DevicePathSubType (DevicePath) == MSG_USB_CLASS_DP) || (DevicePathSubType (DevicePath) == MSG_USB_WWID_DP)) ) {
292 return TRUE;
293 }
294
295 return FALSE;
296 }
297
298 /**
299 Connect the USB short form device path.
300
301 @param DevicePath USB short form device path
302
303 @retval EFI_SUCCESS Successfully connected the USB device
304 @retval EFI_NOT_FOUND Cannot connect the USB device
305 @retval EFI_INVALID_PARAMETER The device path is invalid.
306 **/
307 EFI_STATUS
ConnectUsbShortFormDevicePath(IN EFI_DEVICE_PATH_PROTOCOL * DevicePath)308 ConnectUsbShortFormDevicePath (
309 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
310 )
311 {
312 EFI_STATUS Status;
313 EFI_HANDLE *Handles;
314 UINTN HandleCount;
315 UINTN Index;
316 EFI_PCI_IO_PROTOCOL *PciIo;
317 UINT8 Class[3];
318 BOOLEAN AtLeastOneConnected;
319
320 //
321 // Check the passed in parameters
322 //
323 if (DevicePath == NULL) {
324 return EFI_INVALID_PARAMETER;
325 }
326
327 if (!IsUsbShortForm (DevicePath)) {
328 return EFI_INVALID_PARAMETER;
329 }
330
331 //
332 // Find the usb host controller firstly, then connect with the remaining device path
333 //
334 AtLeastOneConnected = FALSE;
335 Status = gBS->LocateHandleBuffer (
336 ByProtocol,
337 &gEfiPciIoProtocolGuid,
338 NULL,
339 &HandleCount,
340 &Handles
341 );
342 for (Index = 0; Index < HandleCount; Index++) {
343 Status = gBS->HandleProtocol (
344 Handles[Index],
345 &gEfiPciIoProtocolGuid,
346 (VOID **) &PciIo
347 );
348 if (!EFI_ERROR (Status)) {
349 //
350 // Check whether the Pci device is the wanted usb host controller
351 //
352 Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 3, &Class);
353 if (!EFI_ERROR (Status) &&
354 ((PCI_CLASS_SERIAL == Class[2]) && (PCI_CLASS_SERIAL_USB == Class[1]))
355 ) {
356 Status = gBS->ConnectController (
357 Handles[Index],
358 NULL,
359 DevicePath,
360 FALSE
361 );
362 if (!EFI_ERROR(Status)) {
363 AtLeastOneConnected = TRUE;
364 }
365 }
366 }
367 }
368
369 return AtLeastOneConnected ? EFI_SUCCESS : EFI_NOT_FOUND;
370 }
371
372 /**
373 Update the ConIn/ConOut variable with ISA Serial device path,if its not already exists in ConIn/ConOut
374 **/
375 VOID
EnumIsaSerial(VOID)376 EnumIsaSerial (
377 VOID
378 )
379 {
380 DEBUG ((DEBUG_INFO, "[EnumIsaSerial]\n"));
381 EfiBootManagerUpdateConsoleVariable (ConIn, (EFI_DEVICE_PATH_PROTOCOL *) &gIsaSerialDevicePath, NULL);
382 EfiBootManagerUpdateConsoleVariable (ConOut, (EFI_DEVICE_PATH_PROTOCOL *) &gIsaSerialDevicePath, NULL);
383
384 //
385 // Append ISA Serial DevicePath to "ConInDev" and "ConOutDev"
386 //
387 EfiBootManagerUpdateConsoleVariable (ConInDev, (EFI_DEVICE_PATH_PROTOCOL *) &gIsaSerialDevicePath, NULL);
388 EfiBootManagerUpdateConsoleVariable (ConOutDev, (EFI_DEVICE_PATH_PROTOCOL *) &gIsaSerialDevicePath, NULL);
389 }
390
391 /**
392 Update the ConIn variable with USB Keyboard device path,if its not already exists in ConIn
393 **/
394 VOID
EnumUsbKeyboard(VOID)395 EnumUsbKeyboard (
396 VOID
397 )
398 {
399 DEBUG ((DEBUG_INFO, "[EnumUsbKeyboard]\n"));
400 EfiBootManagerUpdateConsoleVariable (ConIn, (EFI_DEVICE_PATH_PROTOCOL *) &gUsbClassKeyboardDevicePath, NULL);
401
402 //
403 // Append Usb Keyboard short form DevicePath into "ConInDev"
404 //
405 EfiBootManagerUpdateConsoleVariable (ConInDev, (EFI_DEVICE_PATH_PROTOCOL *) &gUsbClassKeyboardDevicePath, NULL);
406 }
407
408 BOOLEAN
IsVgaHandle(IN EFI_HANDLE Handle)409 IsVgaHandle (
410 IN EFI_HANDLE Handle
411 )
412 {
413 EFI_PCI_IO_PROTOCOL *PciIo;
414 PCI_TYPE00 Pci;
415 EFI_STATUS Status;
416
417 Status = gBS->HandleProtocol (
418 Handle,
419 &gEfiPciIoProtocolGuid,
420 (VOID **)&PciIo
421 );
422 if (!EFI_ERROR (Status)) {
423 Status = PciIo->Pci.Read (
424 PciIo,
425 EfiPciIoWidthUint32,
426 0,
427 sizeof (Pci) / sizeof (UINT32),
428 &Pci
429 );
430 if (!EFI_ERROR (Status)) {
431 if (IS_PCI_VGA (&Pci) || IS_PCI_OLD_VGA (&Pci)) {
432 return TRUE;
433 }
434 }
435 }
436 return FALSE;
437 }
438
439 EFI_HANDLE
IsVideoController(IN EFI_DEVICE_PATH_PROTOCOL * DevicePath)440 IsVideoController (
441 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
442 )
443 {
444 EFI_DEVICE_PATH_PROTOCOL *DupDevicePath;
445 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
446 EFI_STATUS Status;
447 EFI_HANDLE DeviceHandle;
448
449 DupDevicePath = DuplicateDevicePath (DevicePath);
450 ASSERT (DupDevicePath != NULL);
451 if (DupDevicePath == NULL) {
452 return NULL;
453 }
454
455 TempDevicePath = DupDevicePath;
456 Status = gBS->LocateDevicePath (
457 &gEfiDevicePathProtocolGuid,
458 &TempDevicePath,
459 &DeviceHandle
460 );
461 FreePool (DupDevicePath);
462 if (EFI_ERROR (Status)) {
463 return NULL;
464 }
465
466 if (IsVgaHandle (DeviceHandle)) {
467 return DeviceHandle;
468 } else {
469 return NULL;
470 }
471 }
472
473 BOOLEAN
IsGopDevicePath(IN EFI_DEVICE_PATH_PROTOCOL * DevicePath)474 IsGopDevicePath (
475 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
476 )
477 {
478 while (!IsDevicePathEndType (DevicePath)) {
479 if (DevicePathType (DevicePath) == ACPI_DEVICE_PATH &&
480 DevicePathSubType (DevicePath) == ACPI_ADR_DP) {
481 return TRUE;
482 }
483 DevicePath = NextDevicePathNode (DevicePath);
484 }
485 return FALSE;
486 }
487
488 /**
489 Remove all GOP device path instance from DevicePath and add the Gop to the DevicePath.
490 **/
491 EFI_DEVICE_PATH_PROTOCOL *
UpdateGopDevicePath(EFI_DEVICE_PATH_PROTOCOL * DevicePath,EFI_DEVICE_PATH_PROTOCOL * Gop)492 UpdateGopDevicePath (
493 EFI_DEVICE_PATH_PROTOCOL *DevicePath,
494 EFI_DEVICE_PATH_PROTOCOL *Gop
495 )
496 {
497 UINTN Size;
498 UINTN GopSize;
499 EFI_DEVICE_PATH_PROTOCOL *Temp;
500 EFI_DEVICE_PATH_PROTOCOL *Return;
501 EFI_DEVICE_PATH_PROTOCOL *Instance;
502 BOOLEAN Exist;
503
504 Exist = FALSE;
505 Return = NULL;
506 GopSize = GetDevicePathSize (Gop);
507 do {
508 Instance = GetNextDevicePathInstance (&DevicePath, &Size);
509 if (Instance == NULL) {
510 break;
511 }
512 if (!IsGopDevicePath (Instance) ||
513 (Size == GopSize && CompareMem (Instance, Gop, GopSize) == 0)
514 ) {
515 if (Size == GopSize && CompareMem (Instance, Gop, GopSize) == 0) {
516 Exist = TRUE;
517 }
518 Temp = Return;
519 Return = AppendDevicePathInstance (Return, Instance);
520 if (Temp != NULL) {
521 FreePool (Temp);
522 }
523 }
524 FreePool (Instance);
525 } while (DevicePath != NULL);
526
527 if (!Exist) {
528 Temp = Return;
529 Return = AppendDevicePathInstance (Return, Gop);
530 if (Temp != NULL) {
531 FreePool (Temp);
532 }
533 }
534 return Return;
535 }
536
537 /**
538 Get Graphics Controller Handle.
539
540 @retval GraphicsController Successfully located
541 @retval NULL Failed to locate
542 **/
543 EFI_HANDLE
544 EFIAPI
GetGraphicsController(IN BOOLEAN NeedTrustedConsole)545 GetGraphicsController (
546 IN BOOLEAN NeedTrustedConsole
547 )
548 {
549 EFI_STATUS Status;
550 UINTN Index;
551 EFI_HANDLE *PciHandles;
552 UINTN PciHandlesSize;
553 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
554
555 Status = gBS->LocateHandleBuffer (
556 ByProtocol,
557 &gEfiPciIoProtocolGuid,
558 NULL,
559 &PciHandlesSize,
560 &PciHandles
561 );
562 if (EFI_ERROR (Status)) {
563 return NULL;
564 }
565
566 for (Index = 0; Index < PciHandlesSize; Index++) {
567 Status = gBS->HandleProtocol (
568 PciHandles[Index],
569 &gEfiDevicePathProtocolGuid,
570 (VOID **) &DevicePath
571 );
572 if (EFI_ERROR(Status)) {
573 continue;
574 }
575 if (!IsVgaHandle (PciHandles[Index])) {
576 continue;
577 }
578 if ((NeedTrustedConsole && IsTrustedConsole (ConOut, DevicePath)) ||
579 ((!NeedTrustedConsole) && (!IsTrustedConsole (ConOut, DevicePath)))) {
580 return PciHandles[Index];
581 }
582 }
583
584 return NULL;
585 }
586
587 VOID
UpdateGraphicConOut(IN BOOLEAN NeedTrustedConsole)588 UpdateGraphicConOut (
589 IN BOOLEAN NeedTrustedConsole
590 )
591 {
592 EFI_HANDLE GraphicsControllerHandle;
593 EFI_DEVICE_PATH_PROTOCOL *GopDevicePath;
594 EFI_DEVICE_PATH_PROTOCOL *ConOutDevicePath;
595 EFI_DEVICE_PATH_PROTOCOL *UpdatedConOutDevicePath;
596
597 //
598 // Update ConOut variable
599 //
600 GraphicsControllerHandle = GetGraphicsController (NeedTrustedConsole);
601 if (GraphicsControllerHandle != NULL) {
602 //
603 // Connect the GOP driver
604 //
605 gBS->ConnectController (GraphicsControllerHandle, NULL, NULL, TRUE);
606
607 //
608 // Get the GOP device path
609 // NOTE: We may get a device path that contains Controller node in it.
610 //
611 GopDevicePath = EfiBootManagerGetGopDevicePath (GraphicsControllerHandle);
612 if (GopDevicePath != NULL) {
613 GetEfiGlobalVariable2 (L"ConOut", (VOID **)&ConOutDevicePath, NULL);
614 UpdatedConOutDevicePath = UpdateGopDevicePath (ConOutDevicePath, GopDevicePath);
615 if (ConOutDevicePath != NULL) {
616 FreePool (ConOutDevicePath);
617 }
618 FreePool (GopDevicePath);
619 gRT->SetVariable (
620 L"ConOut",
621 &gEfiGlobalVariableGuid,
622 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
623 GetDevicePathSize (UpdatedConOutDevicePath),
624 UpdatedConOutDevicePath
625 );
626 }
627 }
628 }
629
630 VOID
AddConsoleVariable(IN CONSOLE_TYPE ConsoleType,IN EFI_DEVICE_PATH * ConsoleDevicePath)631 AddConsoleVariable (
632 IN CONSOLE_TYPE ConsoleType,
633 IN EFI_DEVICE_PATH *ConsoleDevicePath
634 )
635 {
636 EFI_DEVICE_PATH *TempDevicePath;
637 EFI_DEVICE_PATH *Instance;
638 UINTN Size;
639 EFI_HANDLE GraphicsControllerHandle;
640 EFI_DEVICE_PATH *GopDevicePath;
641
642 TempDevicePath = ConsoleDevicePath;
643 do {
644 Instance = GetNextDevicePathInstance (&TempDevicePath, &Size);
645 if (Instance == NULL) {
646 break;
647 }
648
649 switch (ConsoleType) {
650 case ConIn:
651 if (IsUsbShortForm (Instance)) {
652 //
653 // Append Usb Keyboard short form DevicePath into "ConInDev"
654 //
655 EfiBootManagerUpdateConsoleVariable (ConInDev, Instance, NULL);
656 }
657 EfiBootManagerUpdateConsoleVariable (ConsoleType, Instance, NULL);
658 break;
659 case ConOut:
660 GraphicsControllerHandle = IsVideoController (Instance);
661 if (GraphicsControllerHandle == NULL) {
662 EfiBootManagerUpdateConsoleVariable (ConsoleType, Instance, NULL);
663 } else {
664 //
665 // Connect the GOP driver
666 //
667 gBS->ConnectController (GraphicsControllerHandle, NULL, NULL, TRUE);
668 //
669 // Get the GOP device path
670 // NOTE: We may get a device path that contains Controller node in it.
671 //
672 GopDevicePath = EfiBootManagerGetGopDevicePath (GraphicsControllerHandle);
673 if (GopDevicePath != NULL) {
674 EfiBootManagerUpdateConsoleVariable (ConsoleType, GopDevicePath, NULL);
675 }
676 }
677 break;
678 default:
679 ASSERT(FALSE);
680 break;
681 }
682
683 FreePool (Instance);
684 } while (TempDevicePath != NULL);
685 }
686
687 /**
688 The function connects the trusted consoles.
689 **/
690 VOID
ConnectTrustedConsole(VOID)691 ConnectTrustedConsole (
692 VOID
693 )
694 {
695 EFI_DEVICE_PATH_PROTOCOL *Consoles;
696 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
697 EFI_DEVICE_PATH_PROTOCOL *Instance;
698 EFI_DEVICE_PATH_PROTOCOL *Next;
699 UINTN Size;
700 UINTN Index;
701 EFI_HANDLE Handle;
702 EFI_STATUS Status;
703 CHAR16 *ConsoleVar[] = {L"ConIn", L"ConOut"};
704 VOID *TrustedConsoleDevicepath;
705
706 TrustedConsoleDevicepath = PcdGetPtr (PcdTrustedConsoleInputDevicePath);
707 DumpDevicePath (L"TrustedConsoleIn", TrustedConsoleDevicepath);
708 TrustedConsoleDevicepath = PcdGetPtr (PcdTrustedConsoleOutputDevicePath);
709 DumpDevicePath (L"TrustedConsoleOut", TrustedConsoleDevicepath);
710
711 for (Index = 0; Index < sizeof (ConsoleVar) / sizeof (ConsoleVar[0]); Index++) {
712
713 GetEfiGlobalVariable2 (ConsoleVar[Index], (VOID **)&Consoles, NULL);
714
715 TempDevicePath = Consoles;
716 do {
717 Instance = GetNextDevicePathInstance (&TempDevicePath, &Size);
718 if (Instance == NULL) {
719 break;
720 }
721 if (IsTrustedConsole (Index, Instance)) {
722 if (IsUsbShortForm (Instance)) {
723 ConnectUsbShortFormDevicePath (Instance);
724 } else {
725 for (Next = Instance; !IsDevicePathEnd (Next); Next = NextDevicePathNode (Next)) {
726 if (DevicePathType (Next) == ACPI_DEVICE_PATH && DevicePathSubType (Next) == ACPI_ADR_DP) {
727 break;
728 } else if (DevicePathType (Next) == HARDWARE_DEVICE_PATH &&
729 DevicePathSubType (Next) == HW_CONTROLLER_DP &&
730 DevicePathType (NextDevicePathNode (Next)) == ACPI_DEVICE_PATH &&
731 DevicePathSubType (NextDevicePathNode (Next)) == ACPI_ADR_DP
732 ) {
733 break;
734 }
735 }
736 if (!IsDevicePathEnd (Next)) {
737 SetDevicePathEndNode (Next);
738 Status = EfiBootManagerConnectDevicePath (Instance, &Handle);
739 if (!EFI_ERROR (Status)) {
740 gBS->ConnectController (Handle, NULL, NULL, TRUE);
741 }
742 } else {
743 EfiBootManagerConnectDevicePath (Instance, NULL);
744 }
745 }
746 }
747 FreePool (Instance);
748 } while (TempDevicePath != NULL);
749
750 if (Consoles != NULL) {
751 FreePool (Consoles);
752 }
753 }
754 }
755
756 /**
757 The function connects the trusted Storages.
758 **/
759 VOID
ConnectTrustedStorage(VOID)760 ConnectTrustedStorage (
761 VOID
762 )
763 {
764 VOID *TrustedStorageDevicepath;
765 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
766 EFI_DEVICE_PATH_PROTOCOL *Instance;
767 UINTN Size;
768 EFI_DEVICE_PATH_PROTOCOL *TempStorageDevicePath;
769 EFI_STATUS Status;
770 EFI_HANDLE DeviceHandle;
771
772 TrustedStorageDevicepath = PcdGetPtr (PcdTrustedStorageDevicePath);
773 DumpDevicePath (L"TrustedStorage", TrustedStorageDevicepath);
774
775 TempDevicePath = TrustedStorageDevicepath;
776 do {
777 Instance = GetNextDevicePathInstance (&TempDevicePath, &Size);
778 if (Instance == NULL) {
779 break;
780 }
781
782 EfiBootManagerConnectDevicePath (Instance, NULL);
783
784 TempStorageDevicePath = Instance;
785
786 Status = gBS->LocateDevicePath (
787 &gEfiDevicePathProtocolGuid,
788 &TempStorageDevicePath,
789 &DeviceHandle
790 );
791 if (!EFI_ERROR (Status)) {
792 gBS->ConnectController (DeviceHandle, NULL, NULL, FALSE);
793 }
794
795 FreePool (Instance);
796 } while (TempDevicePath != NULL);
797 }
798
799 /**
800 The function connects the trusted consoles and then call the PP processing library interface.
801 **/
802 VOID
ProcessTcgPp(VOID)803 ProcessTcgPp (
804 VOID
805 )
806 {
807 gPPRequireUIConfirm |= Tcg2PhysicalPresenceLibNeedUserConfirm();
808
809 if (gPPRequireUIConfirm) {
810 ConnectTrustedConsole ();
811 }
812
813 Tcg2PhysicalPresenceLibProcessRequest (NULL);
814 }
815
816 /**
817 The function connects the trusted storage to perform TPerReset.
818 **/
819 VOID
ProcessTcgMor(VOID)820 ProcessTcgMor (
821 VOID
822 )
823 {
824 if (IsMorBitSet ()) {
825 ConnectTrustedConsole();
826 ConnectTrustedStorage();
827 }
828 }
829
830 /**
831 Check if current BootCurrent variable is internal shell boot option.
832
833 @retval TRUE BootCurrent is internal shell.
834 @retval FALSE BootCurrent is not internal shell.
835 **/
836 BOOLEAN
BootCurrentIsInternalShell(VOID)837 BootCurrentIsInternalShell (
838 VOID
839 )
840 {
841 UINTN VarSize;
842 UINT16 BootCurrent;
843 CHAR16 BootOptionName[16];
844 UINT8 *BootOption;
845 UINT8 *Ptr;
846 BOOLEAN Result;
847 EFI_STATUS Status;
848 EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
849 EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode;
850 EFI_GUID *GuidPoint;
851
852 BootOption = NULL;
853 Result = FALSE;
854
855 //
856 // Get BootCurrent variable
857 //
858 VarSize = sizeof (UINT16);
859 Status = gRT->GetVariable (
860 L"BootCurrent",
861 &gEfiGlobalVariableGuid,
862 NULL,
863 &VarSize,
864 &BootCurrent
865 );
866 if (EFI_ERROR (Status)) {
867 return FALSE;
868 }
869
870 //
871 // Create boot option Bootxxxx from BootCurrent
872 //
873 UnicodeSPrint (BootOptionName, sizeof(BootOptionName), L"Boot%04X", BootCurrent);
874
875 GetEfiGlobalVariable2 (BootOptionName, (VOID **) &BootOption, &VarSize);
876 if (BootOption == NULL || VarSize == 0) {
877 return FALSE;
878 }
879
880 Ptr = BootOption;
881 Ptr += sizeof (UINT32);
882 Ptr += sizeof (UINT16);
883 Ptr += StrSize ((CHAR16 *) Ptr);
884 TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
885 LastDeviceNode = TempDevicePath;
886 while (!IsDevicePathEnd (TempDevicePath)) {
887 LastDeviceNode = TempDevicePath;
888 TempDevicePath = NextDevicePathNode (TempDevicePath);
889 }
890 GuidPoint = EfiGetNameGuidFromFwVolDevicePathNode (
891 (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode
892 );
893 if ((GuidPoint != NULL) &&
894 ((CompareGuid (GuidPoint, &gUefiShellFileGuid)))
895 ) {
896 //
897 // if this option is internal shell, return TRUE
898 //
899 Result = TRUE;
900 }
901
902 if (BootOption != NULL) {
903 FreePool (BootOption);
904 BootOption = NULL;
905 }
906
907 return Result;
908 }
909
910 /**
911 This function will change video resolution and text mode
912 for internl shell when internal shell is launched.
913
914 @param None.
915
916 @retval EFI_SUCCESS Mode is changed successfully.
917 @retval Others Mode failed to changed.
918 **/
919 EFI_STATUS
920 EFIAPI
ChangeModeForInternalShell(VOID)921 ChangeModeForInternalShell (
922 VOID
923 )
924 {
925 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
926 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
927 UINTN SizeOfInfo;
928 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
929 UINT32 MaxGopMode;
930 UINT32 MaxTextMode;
931 UINT32 ModeNumber;
932 UINTN HandleCount;
933 EFI_HANDLE *HandleBuffer;
934 EFI_STATUS Status;
935 UINTN Index;
936 UINTN CurrentColumn;
937 UINTN CurrentRow;
938
939 Status = gBS->HandleProtocol (
940 gST->ConsoleOutHandle,
941 &gEfiGraphicsOutputProtocolGuid,
942 (VOID**)&GraphicsOutput
943 );
944 if (EFI_ERROR (Status)) {
945 GraphicsOutput = NULL;
946 }
947
948 Status = gBS->HandleProtocol (
949 gST->ConsoleOutHandle,
950 &gEfiSimpleTextOutProtocolGuid,
951 (VOID**)&SimpleTextOut
952 );
953 if (EFI_ERROR (Status)) {
954 SimpleTextOut = NULL;
955 }
956
957 if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) {
958 return EFI_UNSUPPORTED;
959 }
960
961 MaxGopMode = GraphicsOutput->Mode->MaxMode;
962 MaxTextMode = SimpleTextOut->Mode->MaxMode;
963
964 //
965 // 1. If current video resolution is same with new video resolution,
966 // video resolution need not be changed.
967 // 1.1. If current text mode is same with new text mode, text mode need not be change.
968 // 1.2. If current text mode is different with new text mode, text mode need be change to new text mode.
969 // 2. If current video resolution is different with new video resolution, we need restart whole console drivers.
970 //
971 for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) {
972 Status = GraphicsOutput->QueryMode (
973 GraphicsOutput,
974 ModeNumber,
975 &SizeOfInfo,
976 &Info
977 );
978 if (!EFI_ERROR (Status)) {
979 if ((Info->HorizontalResolution == mShellHorizontalResolution) &&
980 (Info->VerticalResolution == mShellVerticalResolution)) {
981 if ((GraphicsOutput->Mode->Info->HorizontalResolution == mShellHorizontalResolution) &&
982 (GraphicsOutput->Mode->Info->VerticalResolution == mShellVerticalResolution)) {
983 //
984 // If current video resolution is same with new resolution,
985 // then check if current text mode is same with new text mode.
986 //
987 Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow);
988 ASSERT_EFI_ERROR (Status);
989 if (CurrentColumn == mShellModeColumn && CurrentRow == mShellModeRow) {
990 //
991 // Current text mode is same with new text mode, text mode need not be change.
992 //
993 FreePool (Info);
994 return EFI_SUCCESS;
995 } else {
996 //
997 // Current text mode is different with new text mode, text mode need be change to new text mode.
998 //
999 for (Index = 0; Index < MaxTextMode; Index++) {
1000 Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow);
1001 if (!EFI_ERROR(Status)) {
1002 if ((CurrentColumn == mShellModeColumn) && (CurrentRow == mShellModeRow)) {
1003 //
1004 // New text mode is supported, set it.
1005 //
1006 Status = SimpleTextOut->SetMode (SimpleTextOut, Index);
1007 ASSERT_EFI_ERROR (Status);
1008 //
1009 // Update text mode PCD.
1010 //
1011 Status = PcdSet32S (PcdConOutColumn, mShellModeColumn);
1012 ASSERT_EFI_ERROR (Status);
1013
1014 Status = PcdSet32S (PcdConOutRow, mShellModeRow);
1015 ASSERT_EFI_ERROR (Status);
1016
1017 FreePool (Info);
1018 return EFI_SUCCESS;
1019 }
1020 }
1021 }
1022 if (Index == MaxTextMode) {
1023 //
1024 // If new text mode is not supported, return error.
1025 //
1026 FreePool (Info);
1027 return EFI_UNSUPPORTED;
1028 }
1029 }
1030 } else {
1031 FreePool (Info);
1032 //
1033 // If current video resolution is not same with the new one, set new video resolution.
1034 // In this case, the driver which produces simple text out need be restarted.
1035 //
1036 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);
1037 if (!EFI_ERROR (Status)) {
1038 //
1039 // Set PCD to restart GraphicsConsole and Consplitter to change video resolution
1040 // and produce new text mode based on new resolution.
1041 //
1042 Status = PcdSet32S (PcdVideoHorizontalResolution, mShellHorizontalResolution);
1043 ASSERT_EFI_ERROR (Status);
1044
1045 Status = PcdSet32S (PcdVideoVerticalResolution, mShellVerticalResolution);
1046 ASSERT_EFI_ERROR (Status);
1047
1048 Status = PcdSet32S (PcdConOutColumn, mShellModeColumn);
1049 ASSERT_EFI_ERROR (Status);
1050
1051 Status = PcdSet32S (PcdConOutRow, mShellModeRow);
1052 ASSERT_EFI_ERROR (Status);
1053
1054 Status = gBS->LocateHandleBuffer (
1055 ByProtocol,
1056 &gEfiSimpleTextOutProtocolGuid,
1057 NULL,
1058 &HandleCount,
1059 &HandleBuffer
1060 );
1061 if (!EFI_ERROR (Status)) {
1062 for (Index = 0; Index < HandleCount; Index++) {
1063 gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
1064 }
1065 for (Index = 0; Index < HandleCount; Index++) {
1066 gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
1067 }
1068 if (HandleBuffer != NULL) {
1069 FreePool (HandleBuffer);
1070 }
1071 break;
1072 }
1073 }
1074 }
1075 }
1076 FreePool (Info);
1077 }
1078 }
1079
1080 if (ModeNumber == MaxGopMode) {
1081 //
1082 // If the new resolution is not supported, return error.
1083 //
1084 return EFI_UNSUPPORTED;
1085 }
1086
1087 return EFI_SUCCESS;
1088 }
1089
1090 /**
1091 ReadyToBoot callback to set video and text mode for internal shell boot.
1092 That will not connect USB controller while CSM and FastBoot are disabled, we need to connect them
1093 before booting to Shell for showing USB devices in Shell.
1094
1095 When FastBoot is enabled and Windows Console is the chosen Console behavior, input devices will not be connected
1096 by default. Hence, when booting to EFI shell, connecting input consoles are required.
1097
1098 @param Event Pointer to this event
1099 @param Context Event hanlder private data
1100
1101 @retval None.
1102 **/
1103 VOID
1104 EFIAPI
OnReadyToBootCallBack(IN EFI_EVENT Event,IN VOID * Context)1105 OnReadyToBootCallBack (
1106 IN EFI_EVENT Event,
1107 IN VOID *Context
1108 )
1109 {
1110 DEBUG ((DEBUG_INFO, "OnReadyToBootCallBack\n"));
1111
1112 if (BootCurrentIsInternalShell ()) {
1113
1114 ChangeModeForInternalShell ();
1115 EfiBootManagerConnectAllDefaultConsoles();
1116 gDS->Dispatch ();
1117 }
1118 }
1119
1120 /**
1121 Platform Bds init. Incude the platform firmware vendor, revision
1122 and so crc check.
1123 **/
1124 VOID
1125 EFIAPI
PlatformBootManagerBeforeConsole(VOID)1126 PlatformBootManagerBeforeConsole (
1127 VOID
1128 )
1129 {
1130 EFI_STATUS Status;
1131 EFI_DEVICE_PATH_PROTOCOL *VarConOut;
1132 EFI_DEVICE_PATH_PROTOCOL *VarConIn;
1133 EFI_EVENT Event;
1134
1135 DEBUG ((DEBUG_INFO, "PlatformBootManagerBeforeConsole\n"));
1136
1137 Status = EFI_SUCCESS;
1138
1139 //
1140 // Get user defined text mode for internal shell only once.
1141 //
1142 mShellHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
1143 mShellVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
1144 mShellModeColumn = PcdGet32 (PcdSetupConOutColumn);
1145 mShellModeRow = PcdGet32 (PcdSetupConOutRow);
1146
1147 //
1148 // Create event to set proper video resolution and text mode for internal shell.
1149 //
1150 Status = EfiCreateEventReadyToBootEx (
1151 TPL_CALLBACK,
1152 OnReadyToBootCallBack,
1153 NULL,
1154 &Event
1155 );
1156 ASSERT_EFI_ERROR (Status);
1157
1158 //
1159 // Connect Root Bridge to make PCI BAR resource allocated and all PciIo created
1160 //
1161 ConnectRootBridge (FALSE);
1162
1163 //
1164 // Fill ConIn/ConOut in Full Configuration boot mode
1165 //
1166 gBootMode = GetBootModeHob();
1167 DEBUG ((DEBUG_INFO, "PlatformBootManagerBeforeConsole: BootMode = %x\n", gBootMode));
1168
1169 if (gBootMode == BOOT_WITH_FULL_CONFIGURATION ||
1170 gBootMode == BOOT_WITH_DEFAULT_SETTINGS ||
1171 gBootMode == BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS ||
1172 gBootMode == BOOT_IN_RECOVERY_MODE) {
1173
1174 GetEfiGlobalVariable2 (L"ConOut", (VOID **)&VarConOut, NULL); if (VarConOut != NULL) { FreePool (VarConOut); }
1175 GetEfiGlobalVariable2 (L"ConIn", (VOID **)&VarConIn, NULL); if (VarConIn != NULL) { FreePool (VarConIn); }
1176
1177 //
1178 // Only fill ConIn/ConOut when ConIn/ConOut is empty because we may drop to Full Configuration boot mode in non-first boot
1179 //
1180 if (VarConOut == NULL || VarConIn == NULL) {
1181 if (PcdGetSize (PcdTrustedConsoleOutputDevicePath) >= sizeof(EFI_DEVICE_PATH_PROTOCOL)) {
1182 AddConsoleVariable (ConOut, PcdGetPtr (PcdTrustedConsoleOutputDevicePath));
1183 }
1184 if (PcdGetSize (PcdTrustedConsoleInputDevicePath) >= sizeof(EFI_DEVICE_PATH_PROTOCOL)) {
1185 AddConsoleVariable (ConIn, PcdGetPtr (PcdTrustedConsoleInputDevicePath));
1186 }
1187 }
1188 }
1189
1190 EnumIsaSerial ();
1191
1192 EnumUsbKeyboard ();
1193 //
1194 // For trusted console it must be handled here.
1195 //
1196 UpdateGraphicConOut (TRUE);
1197
1198 if (gBootMode == BOOT_ON_FLASH_UPDATE) {
1199 //
1200 // Logo show
1201 //
1202 BootLogoEnableLogo ();
1203
1204 DEBUG((DEBUG_INFO, "ProcessCapsules Before EndOfDxe......\n"));
1205 ProcessCapsules ();
1206 DEBUG((DEBUG_INFO, "ProcessCapsules Done\n"));
1207 }
1208
1209 //
1210 // Dynamically register hot key: F2/F7/Enter
1211 //
1212 RegisterDefaultBootOption ();
1213 RegisterStaticHotkey ();
1214
1215 PERF_START_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7010);
1216 if (PcdGetBool (PcdTpm2Enable)) {
1217 ProcessTcgPp ();
1218 ProcessTcgMor ();
1219 }
1220 PERF_END_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7011);
1221
1222 //
1223 // We should make all UEFI memory and GCD information populated before ExitPmAuth.
1224 // SMM may consume these information.
1225 //
1226 MemoryTest((EXTENDMEM_COVERAGE_LEVEL) PcdGet32 (PcdPlatformMemoryCheckLevel));
1227
1228 PERF_START_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7020);
1229 ExitPmAuth ();
1230 PERF_END_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7021);
1231
1232 //
1233 // Dispatch the deferred 3rd party images.
1234 //
1235 EfiBootManagerDispatchDeferredImages ();
1236
1237 //
1238 // For non-trusted console it must be handled here.
1239 //
1240 UpdateGraphicConOut (FALSE);
1241
1242 if (gBootMode == BOOT_ON_FLASH_UPDATE) {
1243 //
1244 // Logo show
1245 //
1246 BootLogoEnableLogo ();
1247
1248 DEBUG((DEBUG_INFO, "ProcessCapsules After ConnectAll......\n"));
1249 ProcessCapsules();
1250 DEBUG((DEBUG_INFO, "ProcessCapsules Done\n"));
1251 }
1252 }
1253
1254
1255 /**
1256 Connect with predeined platform connect sequence,
1257 the OEM/IBV can customize with their own connect sequence.
1258
1259 @param[in] BootMode Boot mode of this boot.
1260 **/
1261 VOID
ConnectSequence(IN EFI_BOOT_MODE BootMode)1262 ConnectSequence (
1263 IN EFI_BOOT_MODE BootMode
1264 )
1265 {
1266 switch (BootMode) {
1267 case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
1268 case BOOT_WITH_MINIMAL_CONFIGURATION:
1269 case BOOT_ON_S4_RESUME:
1270 break;
1271 case BOOT_WITH_FULL_CONFIGURATION:
1272 case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
1273 case BOOT_WITH_DEFAULT_SETTINGS:
1274 default:
1275 EfiBootManagerConnectAll ();
1276 break;
1277 }
1278 }
1279
1280 /**
1281 The function is to consider the boot order which is not in our expectation.
1282 In the case that we need to re-sort the boot option.
1283
1284 @retval TRUE Need to sort Boot Option.
1285 @retval FALSE Don't need to sort Boot Option.
1286 **/
1287 BOOLEAN
IsNeedSortBootOption(VOID)1288 IsNeedSortBootOption (
1289 VOID
1290 )
1291 {
1292 EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
1293 UINTN BootOptionCount;
1294
1295 BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
1296
1297 //
1298 // If setup is the first priority in boot option, we need to sort boot option.
1299 //
1300 if ((BootOptionCount > 1) &&
1301 (((StrnCmp (BootOptions->Description, L"Enter Setup", StrLen (L"Enter Setup"))) == 0) ||
1302 ((StrnCmp (BootOptions->Description, L"Boot Device List", StrLen (L"Boot Device List"))) == 0))) {
1303 return TRUE;
1304 }
1305
1306 return FALSE;
1307 }
1308
1309 /**
1310 The function will excute with as the platform policy, current policy
1311 is driven by boot mode. IBV/OEM can customize this code for their specific
1312 policy action.
1313
1314 @param DriverOptionList - The header of the driver option link list
1315 @param BootOptionList - The header of the boot option link list
1316 @param ProcessCapsules - A pointer to ProcessCapsules()
1317 @param BaseMemoryTest - A pointer to BaseMemoryTest()
1318 **/
1319 VOID
1320 EFIAPI
PlatformBootManagerAfterConsole(VOID)1321 PlatformBootManagerAfterConsole (
1322 VOID
1323 )
1324 {
1325 EFI_STATUS Status;
1326 EFI_BOOT_MODE LocalBootMode;
1327
1328 DEBUG ((DEBUG_INFO, "PlatformBootManagerAfterConsole\n"));
1329
1330 //
1331 // Get current Boot Mode
1332 //
1333 LocalBootMode = gBootMode;
1334 DEBUG ((DEBUG_INFO, "PlatformBootManagerAfterConsole: BootMode = %x\n", gBootMode));
1335
1336 //
1337 // Logo show
1338 //
1339 BootLogoEnableLogo ();
1340
1341 //
1342 // Go the different platform policy with different boot mode
1343 // Notes: this part code can be change with the table policy
1344 //
1345 switch (LocalBootMode) {
1346
1347
1348 case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
1349 case BOOT_WITH_MINIMAL_CONFIGURATION:
1350 case BOOT_ON_S4_RESUME:
1351 //
1352 // Perform some platform specific connect sequence
1353 //
1354 PERF_START_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7050);
1355 ConnectSequence (LocalBootMode);
1356 PERF_END_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7051);
1357
1358 break;
1359
1360 case BOOT_WITH_FULL_CONFIGURATION:
1361 case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
1362 case BOOT_WITH_DEFAULT_SETTINGS:
1363 default:
1364 //
1365 // Perform some platform specific connect sequence
1366 //
1367 ConnectSequence (LocalBootMode);
1368
1369 //
1370 // Only in Full Configuration boot mode we do the enumeration of boot device
1371 //
1372 //
1373 // Dispatch all but Storage Oprom explicitly, because we assume Int13Thunk driver is there.
1374 //
1375 EfiBootManagerRefreshAllBootOption ();
1376
1377 //
1378 // PXE boot option may appear after boot option enumeration
1379 //
1380
1381 break;
1382 }
1383
1384 //
1385 // Use a DynamicHii type pcd to save the boot status, which is used to
1386 // control configuration mode, such as FULL/MINIMAL/NO_CHANGES configuration.
1387 //
1388 DEBUG ((DEBUG_INFO, "PcdBootState = %d\n", PcdGetBool(PcdBootState)));
1389 if (PcdGetBool(PcdBootState)) {
1390 Status = PcdSetBoolS(PcdBootState, FALSE);
1391 if (EFI_ERROR (Status)) {
1392 DEBUG ((DEBUG_ERROR, "Set PcdBootState to FALSE failed.\n"));
1393 }
1394 DEBUG ((DEBUG_INFO, "PcdBootState = %d\n", PcdGetBool(PcdBootState)));
1395 }
1396
1397 Print (L"Press F7 for BootMenu!\n");
1398
1399 EfiBootManagerRefreshAllBootOption ();
1400 if (IsNeedSortBootOption()) {
1401 EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot, CompareBootOption);
1402 }
1403 }
1404
1405 /**
1406 The function is called when no boot option could be launched,
1407 including platform recovery options and options pointing to applications
1408 built into firmware volumes.
1409
1410 If this function returns, BDS attempts to enter an infinite loop.
1411 **/
1412 VOID
1413 EFIAPI
PlatformBootManagerUnableToBoot(VOID)1414 PlatformBootManagerUnableToBoot (
1415 VOID
1416 )
1417 {
1418 EFI_STATUS Status;
1419 EFI_BOOT_MANAGER_LOAD_OPTION BootDeviceList;
1420 CHAR16 OptionName[sizeof ("Boot####")];
1421
1422 if (mBootMenuOptionNumber == LoadOptionNumberUnassigned) {
1423 return;
1424 }
1425 UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", mBootMenuOptionNumber);
1426 Status = EfiBootManagerVariableToLoadOption (OptionName, &BootDeviceList);
1427 if (EFI_ERROR (Status)) {
1428 return;
1429 }
1430 for (;;) {
1431 EfiBootManagerBoot (&BootDeviceList);
1432 }
1433 }
1434