2 Platform BDS customizations.
4 Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "BdsPlatform.h"
16 #include "QemuBootOrder.h"
23 VOID
*mEfiDevPathNotifyReg
;
24 EFI_EVENT mEfiDevPathEvent
;
25 VOID
*mEmuVariableEventReg
;
26 EFI_EVENT mEmuVariableEvent
;
27 BOOLEAN mDetectVgaOnly
;
36 (EFIAPI
*PROTOCOL_INSTANCE_CALLBACK
)(
43 @param[in] Handle - Handle of PCI device instance
44 @param[in] PciIo - PCI IO protocol instance
45 @param[in] Pci - PCI Header register block
49 (EFIAPI
*VISIT_PCI_INSTANCE_CALLBACK
)(
51 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
57 // Function prototypes
61 VisitAllInstancesOfProtocol (
63 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction
,
68 VisitAllPciInstancesOfProtocol (
69 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
73 InstallDevicePathCallback (
78 // BDS Platform Functions
89 Platform Bds init. Incude the platform firmware vendor, revision
100 DEBUG ((EFI_D_INFO
, "PlatformBdsInit\n"));
101 InstallDevicePathCallback ();
121 EFI_SUCCESS - Connect RootBridge successfully.
122 EFI_STATUS - Connect RootBridge fail.
127 EFI_HANDLE RootHandle
;
130 // Make all the PCI_IO protocols on PCI Seg 0 show up
132 BdsLibConnectDevicePath (gPlatformRootBridges
[0]);
134 Status
= gBS
->LocateDevicePath (
135 &gEfiDevicePathProtocolGuid
,
136 &gPlatformRootBridges
[0],
139 if (EFI_ERROR (Status
)) {
143 Status
= gBS
->ConnectController (RootHandle
, NULL
, NULL
, FALSE
);
144 if (EFI_ERROR (Status
)) {
153 PrepareLpcBridgeDevicePath (
154 IN EFI_HANDLE DeviceHandle
160 Add IsaKeyboard to ConIn,
161 add IsaSerial to ConOut, ConIn, ErrOut.
166 DeviceHandle - Handle of PCIIO protocol.
170 EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut.
171 EFI_STATUS - No LPC bridge is added.
176 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
177 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
181 Status
= gBS
->HandleProtocol (
183 &gEfiDevicePathProtocolGuid
,
186 if (EFI_ERROR (Status
)) {
189 TempDevicePath
= DevicePath
;
194 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnpPs2KeyboardDeviceNode
);
196 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
201 DevicePath
= TempDevicePath
;
202 gPnp16550ComPortDeviceNode
.UID
= 0;
204 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnp16550ComPortDeviceNode
);
205 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
206 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
211 DevPathStr
= DevicePathToStr(DevicePath
);
212 if (DevPathStr
!= NULL
) {
215 "BdsPlatform.c+%d: COM%d DevPath: %s\n",
217 gPnp16550ComPortDeviceNode
.UID
+ 1,
220 FreePool(DevPathStr
);
223 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
224 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
225 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
230 DevicePath
= TempDevicePath
;
231 gPnp16550ComPortDeviceNode
.UID
= 1;
233 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnp16550ComPortDeviceNode
);
234 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
235 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
240 DevPathStr
= DevicePathToStr(DevicePath
);
241 if (DevPathStr
!= NULL
) {
244 "BdsPlatform.c+%d: COM%d DevPath: %s\n",
246 gPnp16550ComPortDeviceNode
.UID
+ 1,
249 FreePool(DevPathStr
);
252 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
253 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
254 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
261 IN EFI_DEVICE_PATH_PROTOCOL
*PciDevicePath
,
262 OUT EFI_DEVICE_PATH_PROTOCOL
**GopDevicePath
267 EFI_HANDLE PciDeviceHandle
;
268 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
269 EFI_DEVICE_PATH_PROTOCOL
*TempPciDevicePath
;
270 UINTN GopHandleCount
;
271 EFI_HANDLE
*GopHandleBuffer
;
273 if (PciDevicePath
== NULL
|| GopDevicePath
== NULL
) {
274 return EFI_INVALID_PARAMETER
;
278 // Initialize the GopDevicePath to be PciDevicePath
280 *GopDevicePath
= PciDevicePath
;
281 TempPciDevicePath
= PciDevicePath
;
283 Status
= gBS
->LocateDevicePath (
284 &gEfiDevicePathProtocolGuid
,
288 if (EFI_ERROR (Status
)) {
293 // Try to connect this handle, so that GOP dirver could start on this
294 // device and create child handles with GraphicsOutput Protocol installed
295 // on them, then we get device paths of these child handles and select
296 // them as possible console device.
298 gBS
->ConnectController (PciDeviceHandle
, NULL
, NULL
, FALSE
);
300 Status
= gBS
->LocateHandleBuffer (
302 &gEfiGraphicsOutputProtocolGuid
,
307 if (!EFI_ERROR (Status
)) {
309 // Add all the child handles as possible Console Device
311 for (Index
= 0; Index
< GopHandleCount
; Index
++) {
312 Status
= gBS
->HandleProtocol (GopHandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*)&TempDevicePath
);
313 if (EFI_ERROR (Status
)) {
319 GetDevicePathSize (PciDevicePath
) - END_DEVICE_PATH_LENGTH
322 // In current implementation, we only enable one of the child handles
323 // as console device, i.e. sotre one of the child handle's device
324 // path to variable "ConOut"
325 // In futhure, we could select all child handles to be console device
328 *GopDevicePath
= TempDevicePath
;
331 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()
332 // Add the integrity GOP device path.
334 BdsLibUpdateConsoleVariable (VarConsoleOutDev
, NULL
, PciDevicePath
);
335 BdsLibUpdateConsoleVariable (VarConsoleOutDev
, TempDevicePath
, NULL
);
338 gBS
->FreePool (GopHandleBuffer
);
345 PreparePciVgaDevicePath (
346 IN EFI_HANDLE DeviceHandle
352 Add PCI VGA to ConOut.
357 DeviceHandle - Handle of PCIIO protocol.
361 EFI_SUCCESS - PCI VGA is added to ConOut.
362 EFI_STATUS - No PCI VGA device is added.
367 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
368 EFI_DEVICE_PATH_PROTOCOL
*GopDevicePath
;
371 Status
= gBS
->HandleProtocol (
373 &gEfiDevicePathProtocolGuid
,
376 if (EFI_ERROR (Status
)) {
380 GetGopDevicePath (DevicePath
, &GopDevicePath
);
381 DevicePath
= GopDevicePath
;
383 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
389 PreparePciSerialDevicePath (
390 IN EFI_HANDLE DeviceHandle
396 Add PCI Serial to ConOut, ConIn, ErrOut.
401 DeviceHandle - Handle of PCIIO protocol.
405 EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.
406 EFI_STATUS - No PCI Serial device is added.
411 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
414 Status
= gBS
->HandleProtocol (
416 &gEfiDevicePathProtocolGuid
,
419 if (EFI_ERROR (Status
)) {
423 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
424 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
426 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
427 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
428 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
434 VisitAllInstancesOfProtocol (
436 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction
,
442 EFI_HANDLE
*HandleBuffer
;
447 // Start to check all the PciIo to find all possible device
451 Status
= gBS
->LocateHandleBuffer (
458 if (EFI_ERROR (Status
)) {
462 for (Index
= 0; Index
< HandleCount
; Index
++) {
463 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], Id
, &Instance
);
464 if (EFI_ERROR (Status
)) {
468 Status
= (*CallBackFunction
) (
475 gBS
->FreePool (HandleBuffer
);
483 VisitingAPciInstance (
484 IN EFI_HANDLE Handle
,
490 EFI_PCI_IO_PROTOCOL
*PciIo
;
493 PciIo
= (EFI_PCI_IO_PROTOCOL
*) Instance
;
496 // Check for all PCI device
498 Status
= PciIo
->Pci
.Read (
502 sizeof (Pci
) / sizeof (UINT32
),
505 if (EFI_ERROR (Status
)) {
509 return (*(VISIT_PCI_INSTANCE_CALLBACK
)(UINTN
) Context
) (
520 VisitAllPciInstances (
521 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
524 return VisitAllInstancesOfProtocol (
525 &gEfiPciIoProtocolGuid
,
526 VisitingAPciInstance
,
527 (VOID
*)(UINTN
) CallBackFunction
533 Do platform specific PCI Device check and add them to
534 ConOut, ConIn, ErrOut.
536 @param[in] Handle - Handle of PCI device instance
537 @param[in] PciIo - PCI IO protocol instance
538 @param[in] Pci - PCI Header register block
540 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
541 @retval EFI_STATUS - PCI Device check or Console variable update fail.
546 DetectAndPreparePlatformPciDevicePath (
547 IN EFI_HANDLE Handle
,
548 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
554 Status
= PciIo
->Attributes (
556 EfiPciIoAttributeOperationEnable
,
557 EFI_PCI_DEVICE_ENABLE
,
560 ASSERT_EFI_ERROR (Status
);
562 if (!mDetectVgaOnly
) {
564 // Here we decide whether it is LPC Bridge
566 if ((IS_PCI_LPC (Pci
)) ||
567 ((IS_PCI_ISA_PDECODE (Pci
)) &&
568 (Pci
->Hdr
.VendorId
== 0x8086) &&
569 (Pci
->Hdr
.DeviceId
== 0x7000)
573 // Add IsaKeyboard to ConIn,
574 // add IsaSerial to ConOut, ConIn, ErrOut
576 DEBUG ((EFI_D_INFO
, "Found LPC Bridge device\n"));
577 PrepareLpcBridgeDevicePath (Handle
);
581 // Here we decide which Serial device to enable in PCI bus
583 if (IS_PCI_16550SERIAL (Pci
)) {
585 // Add them to ConOut, ConIn, ErrOut.
587 DEBUG ((EFI_D_INFO
, "Found PCI 16550 SERIAL device\n"));
588 PreparePciSerialDevicePath (Handle
);
594 // Here we decide which VGA device to enable in PCI bus
596 if (IS_PCI_VGA (Pci
)) {
598 // Add them to ConOut.
600 DEBUG ((EFI_D_INFO
, "Found PCI VGA device\n"));
601 PreparePciVgaDevicePath (Handle
);
610 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
612 @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.
614 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
615 @retval EFI_STATUS - PCI Device check or Console variable update fail.
619 DetectAndPreparePlatformPciDevicePaths (
620 BOOLEAN DetectVgaOnly
623 mDetectVgaOnly
= DetectVgaOnly
;
624 return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath
);
629 PlatformBdsConnectConsole (
630 IN BDS_CONSOLE_CONNECT_ENTRY
*PlatformConsole
636 Connect the predefined platform default console device. Always try to find
637 and enable the vga device if have.
641 PlatformConsole - Predfined platform default console device array.
645 EFI_SUCCESS - Success connect at least one ConIn and ConOut
646 device, there must have one ConOut device is
649 EFI_STATUS - Return the status of
650 BdsLibConnectAllDefaultConsoles ()
656 EFI_DEVICE_PATH_PROTOCOL
*VarConout
;
657 EFI_DEVICE_PATH_PROTOCOL
*VarConin
;
658 UINTN DevicePathSize
;
661 // Connect RootBridge
663 VarConout
= BdsLibGetVariableAndSize (
665 &gEfiGlobalVariableGuid
,
668 VarConin
= BdsLibGetVariableAndSize (
670 &gEfiGlobalVariableGuid
,
674 if (VarConout
== NULL
|| VarConin
== NULL
) {
676 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
678 DetectAndPreparePlatformPciDevicePaths (FALSE
);
681 // Have chance to connect the platform default console,
682 // the platform default console is the minimue device group
683 // the platform should support
685 for (Index
= 0; PlatformConsole
[Index
].DevicePath
!= NULL
; ++Index
) {
687 // Update the console variable with the connect type
689 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
690 BdsLibUpdateConsoleVariable (VarConsoleInp
, PlatformConsole
[Index
].DevicePath
, NULL
);
692 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
693 BdsLibUpdateConsoleVariable (VarConsoleOut
, PlatformConsole
[Index
].DevicePath
, NULL
);
695 if ((PlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
696 BdsLibUpdateConsoleVariable (VarErrorOut
, PlatformConsole
[Index
].DevicePath
, NULL
);
701 // Only detect VGA device and add them to ConOut
703 DetectAndPreparePlatformPciDevicePaths (TRUE
);
707 // Connect the all the default console with current cosole variable
709 Status
= BdsLibConnectAllDefaultConsoles ();
710 if (EFI_ERROR (Status
)) {
723 // Bus 0, Device 0, Function 0 - Host to PCI Bridge
725 PciWrite8 (PCI_LIB_ADDRESS (0, 0, 0, 0x3c), 0x00);
728 // Bus 0, Device 1, Function 0 - PCI to ISA Bridge
730 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x3c), 0x00);
731 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // LNKA routing target
732 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // LNKB routing target
733 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // LNKC routing target
734 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // LNKD routing target
737 // Bus 0, Device 1, Function 1 - IDE Controller
739 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x3c), 0x00);
740 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x0d), 0x40);
743 // Bus 0, Device 1, Function 3 - Power Managment Controller
745 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3c), 0x09);
746 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3d), 0x01); // INTA
749 // Bus 0, Device 2, Function 0 - Video Controller
751 PciWrite8 (PCI_LIB_ADDRESS (0, 2, 0, 0x3c), 0x00);
754 // Bus 0, Device 3, Function 0 - Network Controller
756 PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3c), 0x0a);
757 PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3d), 0x01); // INTA (-> LNKC)
760 // Bus 0, Device 5, Function 0 - RAM Memory
762 PciWrite8 (PCI_LIB_ADDRESS (0, 5, 0, 0x3c), 0x0b);
763 PciWrite8 (PCI_LIB_ADDRESS (0, 5, 0, 0x3d), 0x01); // INTA (-> LNKA)
773 // Set ACPI SCI_EN bit in PMCNTRL
775 IoOr16 ((PciRead32 (PCI_LIB_ADDRESS (0, 1, 3, 0x40)) & ~BIT0
) + 4, BIT0
);
781 ConnectRecursivelyIfPciMassStorage (
782 IN EFI_HANDLE Handle
,
783 IN EFI_PCI_IO_PROTOCOL
*Instance
,
784 IN PCI_TYPE00
*PciHeader
788 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
791 if (IS_CLASS1 (PciHeader
, PCI_CLASS_MASS_STORAGE
)) {
793 Status
= gBS
->HandleProtocol (
795 &gEfiDevicePathProtocolGuid
,
798 if (EFI_ERROR (Status
)) {
805 DevPathStr
= DevicePathToStr (DevicePath
);
806 if (DevPathStr
!= NULL
) {
809 "Found Mass Storage device: %s\n",
812 FreePool(DevPathStr
);
815 Status
= gBS
->ConnectController (Handle
, NULL
, NULL
, TRUE
);
816 if (EFI_ERROR (Status
)) {
827 This notification function is invoked when the
828 EMU Variable FVB has been changed.
830 @param Event The event that occured
831 @param Context For EFI compatiblity. Not used.
836 EmuVariablesUpdatedCallback (
841 DEBUG ((EFI_D_INFO
, "EmuVariablesUpdatedCallback\n"));
842 UpdateNvVarsOnFileSystem ();
848 VisitingFileSystemInstance (
849 IN EFI_HANDLE Handle
,
855 STATIC BOOLEAN ConnectedToFileSystem
= FALSE
;
857 if (ConnectedToFileSystem
) {
858 return EFI_ALREADY_STARTED
;
861 Status
= ConnectNvVarsToFileSystem (Handle
);
862 if (EFI_ERROR (Status
)) {
866 ConnectedToFileSystem
= TRUE
;
868 EfiCreateProtocolNotifyEvent (
869 &gEfiDevicePathProtocolGuid
,
871 EmuVariablesUpdatedCallback
,
873 &mEmuVariableEventReg
875 PcdSet64 (PcdEmuVariableEvent
, (UINT64
)(UINTN
) mEmuVariableEvent
);
882 PlatformBdsRestoreNvVarsFromHardDisk (
885 VisitAllPciInstances (ConnectRecursivelyIfPciMassStorage
);
886 VisitAllInstancesOfProtocol (
887 &gEfiSimpleFileSystemProtocolGuid
,
888 VisitingFileSystemInstance
,
896 PlatformBdsConnectSequence (
903 Connect with predeined platform connect sequence,
904 the OEM/IBV can customize with their own connect sequence.
918 DEBUG ((EFI_D_INFO
, "PlatformBdsConnectSequence\n"));
923 // Here we can get the customized platform connect sequence
924 // Notes: we can connect with new variable which record the
925 // last time boots connect device path sequence
927 while (gPlatformConnectSequence
[Index
] != NULL
) {
929 // Build the platform boot option
931 BdsLibConnectDevicePath (gPlatformConnectSequence
[Index
]);
936 // Just use the simple policy to connect all devices
940 PciInitialization ();
941 AcpiInitialization ();
944 // Clear the logo after all devices are connected.
946 gST
->ConOut
->ClearScreen (gST
->ConOut
);
950 PlatformBdsGetDriverOption (
951 IN OUT LIST_ENTRY
*BdsDriverLists
957 Load the predefined driver option, OEM/IBV can customize this
958 to load their own drivers
962 BdsDriverLists - The header of the driver option link list.
970 DEBUG ((EFI_D_INFO
, "PlatformBdsGetDriverOption\n"));
975 PlatformBdsDiagnostics (
976 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel
,
977 IN BOOLEAN QuietBoot
,
978 IN BASEM_MEMORY_TEST BaseMemoryTest
984 Perform the platform diagnostic, such like test memory. OEM/IBV also
985 can customize this fuction to support specific platform diagnostic.
989 MemoryTestLevel - The memory test intensive level
991 QuietBoot - Indicate if need to enable the quiet boot
993 BaseMemoryTest - A pointer to BaseMemoryTest()
1003 DEBUG ((EFI_D_INFO
, "PlatformBdsDiagnostics\n"));
1006 // Here we can decide if we need to show
1007 // the diagnostics screen
1008 // Notes: this quiet boot code should be remove
1009 // from the graphic lib
1012 EnableQuietBoot (PcdGetPtr(PcdLogoFile
));
1014 // Perform system diagnostic
1016 Status
= BaseMemoryTest (MemoryTestLevel
);
1017 if (EFI_ERROR (Status
)) {
1018 DisableQuietBoot ();
1024 // Perform system diagnostic
1026 Status
= BaseMemoryTest (MemoryTestLevel
);
1032 PlatformBdsPolicyBehavior (
1033 IN OUT LIST_ENTRY
*DriverOptionList
,
1034 IN OUT LIST_ENTRY
*BootOptionList
,
1035 IN PROCESS_CAPSULES ProcessCapsules
,
1036 IN BASEM_MEMORY_TEST BaseMemoryTest
1040 Routine Description:
1042 The function will excute with as the platform policy, current policy
1043 is driven by boot mode. IBV/OEM can customize this code for their specific
1048 DriverOptionList - The header of the driver option link list
1050 BootOptionList - The header of the boot option link list
1052 ProcessCapsules - A pointer to ProcessCapsules()
1054 BaseMemoryTest - A pointer to BaseMemoryTest()
1064 EFI_EVENT UserInputDurationTime
;
1066 BDS_COMMON_OPTION
*BootOption
;
1070 EFI_BOOT_MODE BootMode
;
1072 DEBUG ((EFI_D_INFO
, "PlatformBdsPolicyBehavior\n"));
1074 ConnectRootBridge ();
1076 if (PcdGetBool (PcdOvmfFlashVariablesEnable
)) {
1077 DEBUG ((EFI_D_INFO
, "PlatformBdsPolicyBehavior: not restoring NvVars "
1078 "from disk since flash variables appear to be supported.\n"));
1081 // Try to restore variables from the hard disk early so
1082 // they can be used for the other BDS connect operations.
1084 PlatformBdsRestoreNvVarsFromHardDisk ();
1088 // Init the time out value
1090 Timeout
= PcdGet16 (PcdPlatformBootTimeOut
);
1093 // Load the driver option as the driver option list
1095 PlatformBdsGetDriverOption (DriverOptionList
);
1098 // Get current Boot Mode
1100 Status
= BdsLibGetBootMode (&BootMode
);
1101 DEBUG ((EFI_D_ERROR
, "Boot Mode:%x\n", BootMode
));
1104 // Go the different platform policy with different boot mode
1105 // Notes: this part code can be change with the table policy
1107 ASSERT (BootMode
== BOOT_WITH_FULL_CONFIGURATION
);
1109 // Connect platform console
1111 Status
= PlatformBdsConnectConsole (gPlatformConsole
);
1112 if (EFI_ERROR (Status
)) {
1114 // Here OEM/IBV can customize with defined action
1116 PlatformBdsNoConsoleAction ();
1119 // Create a 300ms duration event to ensure user has enough input time to enter Setup
1121 Status
= gBS
->CreateEvent (
1126 &UserInputDurationTime
1128 ASSERT (Status
== EFI_SUCCESS
);
1129 Status
= gBS
->SetTimer (UserInputDurationTime
, TimerRelative
, 3000000);
1130 ASSERT (Status
== EFI_SUCCESS
);
1132 // Memory test and Logo show
1134 PlatformBdsDiagnostics (IGNORE
, TRUE
, BaseMemoryTest
);
1137 // Perform some platform specific connect sequence
1139 PlatformBdsConnectSequence ();
1142 // Process QEMU's -kernel command line option
1144 TryRunningQemuKernel ();
1147 // Give one chance to enter the setup if we
1148 // have the time out
1151 //PlatformBdsEnterFrontPage (Timeout, FALSE);
1154 DEBUG ((EFI_D_INFO
, "BdsLibConnectAll\n"));
1155 BdsLibConnectAll ();
1156 BdsLibEnumerateAllBootOption (BootOptionList
);
1158 SetBootOrderFromQemu (BootOptionList
);
1161 // Please uncomment above ConnectAll and EnumerateAll code and remove following first boot
1162 // checking code in real production tip.
1164 // In BOOT_WITH_FULL_CONFIGURATION boot mode, should always connect every device
1165 // and do enumerate all the default boot options. But in development system board, the boot mode
1166 // cannot be BOOT_ASSUMING_NO_CONFIGURATION_CHANGES because the machine box
1167 // is always open. So the following code only do the ConnectAll and EnumerateAll at first boot.
1169 Status
= BdsLibBuildOptionFromVar (BootOptionList
, L
"BootOrder");
1170 if (EFI_ERROR(Status
)) {
1172 // If cannot find "BootOrder" variable, it may be first boot.
1173 // Try to connect all devices and enumerate all boot options here.
1175 BdsLibConnectAll ();
1176 BdsLibEnumerateAllBootOption (BootOptionList
);
1180 // To give the User a chance to enter Setup here, if user set TimeOut is 0.
1181 // BDS should still give user a chance to enter Setup
1183 // Connect first boot option, and then check user input before exit
1185 for (Link
= BootOptionList
->ForwardLink
; Link
!= BootOptionList
;Link
= Link
->ForwardLink
) {
1186 BootOption
= CR (Link
, BDS_COMMON_OPTION
, Link
, BDS_LOAD_OPTION_SIGNATURE
);
1187 if (!IS_LOAD_OPTION_TYPE (BootOption
->Attribute
, LOAD_OPTION_ACTIVE
)) {
1189 // skip the header of the link list, becuase it has no boot option
1194 // Make sure the boot option device path connected, but ignore the BBS device path
1196 if (DevicePathType (BootOption
->DevicePath
) != BBS_DEVICE_PATH
) {
1197 BdsLibConnectDevicePath (BootOption
->DevicePath
);
1204 // Check whether the user input after the duration time has expired
1206 OldTpl
= EfiGetCurrentTpl();
1207 gBS
->RestoreTPL (TPL_APPLICATION
);
1208 gBS
->WaitForEvent (1, &UserInputDurationTime
, &Index
);
1209 gBS
->CloseEvent (UserInputDurationTime
);
1210 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
1211 gBS
->RaiseTPL (OldTpl
);
1213 if (!EFI_ERROR (Status
)) {
1215 // Enter Setup if user input
1218 PlatformBdsEnterFrontPage (Timeout
, FALSE
);
1226 PlatformBdsBootSuccess (
1227 IN BDS_COMMON_OPTION
*Option
1231 Routine Description:
1233 Hook point after a boot attempt succeeds. We don't expect a boot option to
1234 return, so the EFI 1.0 specification defines that you will default to an
1235 interactive mode and stop processing the BootOrder list in this case. This
1236 is alos a platform implementation and can be customized by IBV/OEM.
1240 Option - Pointer to Boot Option that succeeded to boot.
1250 DEBUG ((EFI_D_INFO
, "PlatformBdsBootSuccess\n"));
1252 // If Boot returned with EFI_SUCCESS and there is not in the boot device
1253 // select loop then we need to pop up a UI and wait for user input.
1255 TmpStr
= Option
->StatusString
;
1256 if (TmpStr
!= NULL
) {
1257 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
1264 PlatformBdsBootFail (
1265 IN BDS_COMMON_OPTION
*Option
,
1266 IN EFI_STATUS Status
,
1267 IN CHAR16
*ExitData
,
1268 IN UINTN ExitDataSize
1272 Routine Description:
1274 Hook point after a boot attempt fails.
1278 Option - Pointer to Boot Option that failed to boot.
1280 Status - Status returned from failed boot.
1282 ExitData - Exit data returned from failed boot.
1284 ExitDataSize - Exit data size returned from failed boot.
1294 DEBUG ((EFI_D_INFO
, "PlatformBdsBootFail\n"));
1297 // If Boot returned with failed status then we need to pop up a UI and wait
1300 TmpStr
= Option
->StatusString
;
1301 if (TmpStr
!= NULL
) {
1302 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
1308 PlatformBdsNoConsoleAction (
1313 Routine Description:
1315 This function is remained for IBV/OEM to do some platform action,
1316 if there no console device can be connected.
1324 EFI_SUCCESS - Direct return success now.
1328 DEBUG ((EFI_D_INFO
, "PlatformBdsNoConsoleAction\n"));
1334 PlatformBdsLockNonUpdatableFlash (
1338 DEBUG ((EFI_D_INFO
, "PlatformBdsLockNonUpdatableFlash\n"));
1344 This notification function is invoked when an instance of the
1345 EFI_DEVICE_PATH_PROTOCOL is produced.
1347 @param Event The event that occured
1348 @param Context For EFI compatiblity. Not used.
1361 EFI_DEVICE_PATH_PROTOCOL
*DevPathNode
;
1362 ATAPI_DEVICE_PATH
*Atapi
;
1365 // Examine all new handles
1369 // Get the next handle
1371 BufferSize
= sizeof (Handle
);
1372 Status
= gBS
->LocateHandle (
1375 mEfiDevPathNotifyReg
,
1381 // If not found, we're done
1383 if (EFI_NOT_FOUND
== Status
) {
1387 if (EFI_ERROR (Status
)) {
1392 // Get the DevicePath protocol on that handle
1394 Status
= gBS
->HandleProtocol (Handle
, &gEfiDevicePathProtocolGuid
, (VOID
**)&DevPathNode
);
1395 ASSERT_EFI_ERROR (Status
);
1397 while (!IsDevicePathEnd (DevPathNode
)) {
1399 // Find the handler to dump this device path node
1402 (DevicePathType(DevPathNode
) == MESSAGING_DEVICE_PATH
) &&
1403 (DevicePathSubType(DevPathNode
) == MSG_ATAPI_DP
)
1405 Atapi
= (ATAPI_DEVICE_PATH
*) DevPathNode
;
1411 (Atapi
->PrimarySecondary
== 1) ? 0x42: 0x40
1418 // Next device path node
1420 DevPathNode
= NextDevicePathNode (DevPathNode
);
1429 InstallDevicePathCallback (
1433 DEBUG ((EFI_D_INFO
, "Registered NotifyDevPath Event\n"));
1434 mEfiDevPathEvent
= EfiCreateProtocolNotifyEvent (
1435 &gEfiDevicePathProtocolGuid
,
1439 &mEfiDevPathNotifyReg
1444 Lock the ConsoleIn device in system table. All key
1445 presses will be ignored until the Password is typed in. The only way to
1446 disable the password is to type it in to a ConIn device.
1448 @param Password Password used to lock ConIn device.
1450 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
1451 @retval EFI_UNSUPPORTED Password not found
1460 return EFI_UNSUPPORTED
;