2 Platform BDS customizations.
4 Copyright (c) 2004 - 2012, 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
);
214 "BdsPlatform.c+%d: COM%d DevPath: %s\n",
216 gPnp16550ComPortDeviceNode
.UID
+ 1,
219 FreePool(DevPathStr
);
221 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
222 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
223 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
228 DevicePath
= TempDevicePath
;
229 gPnp16550ComPortDeviceNode
.UID
= 1;
231 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnp16550ComPortDeviceNode
);
232 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
233 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
238 DevPathStr
= DevicePathToStr(DevicePath
);
241 "BdsPlatform.c+%d: COM%d DevPath: %s\n",
243 gPnp16550ComPortDeviceNode
.UID
+ 1,
246 FreePool(DevPathStr
);
248 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
249 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
250 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
257 IN EFI_DEVICE_PATH_PROTOCOL
*PciDevicePath
,
258 OUT EFI_DEVICE_PATH_PROTOCOL
**GopDevicePath
263 EFI_HANDLE PciDeviceHandle
;
264 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
265 EFI_DEVICE_PATH_PROTOCOL
*TempPciDevicePath
;
266 UINTN GopHandleCount
;
267 EFI_HANDLE
*GopHandleBuffer
;
269 if (PciDevicePath
== NULL
|| GopDevicePath
== NULL
) {
270 return EFI_INVALID_PARAMETER
;
274 // Initialize the GopDevicePath to be PciDevicePath
276 *GopDevicePath
= PciDevicePath
;
277 TempPciDevicePath
= PciDevicePath
;
279 Status
= gBS
->LocateDevicePath (
280 &gEfiDevicePathProtocolGuid
,
284 if (EFI_ERROR (Status
)) {
289 // Try to connect this handle, so that GOP dirver could start on this
290 // device and create child handles with GraphicsOutput Protocol installed
291 // on them, then we get device paths of these child handles and select
292 // them as possible console device.
294 gBS
->ConnectController (PciDeviceHandle
, NULL
, NULL
, FALSE
);
296 Status
= gBS
->LocateHandleBuffer (
298 &gEfiGraphicsOutputProtocolGuid
,
303 if (!EFI_ERROR (Status
)) {
305 // Add all the child handles as possible Console Device
307 for (Index
= 0; Index
< GopHandleCount
; Index
++) {
308 Status
= gBS
->HandleProtocol (GopHandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*)&TempDevicePath
);
309 if (EFI_ERROR (Status
)) {
315 GetDevicePathSize (PciDevicePath
) - END_DEVICE_PATH_LENGTH
318 // In current implementation, we only enable one of the child handles
319 // as console device, i.e. sotre one of the child handle's device
320 // path to variable "ConOut"
321 // In futhure, we could select all child handles to be console device
324 *GopDevicePath
= TempDevicePath
;
327 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()
328 // Add the integrity GOP device path.
330 BdsLibUpdateConsoleVariable (VarConsoleOutDev
, NULL
, PciDevicePath
);
331 BdsLibUpdateConsoleVariable (VarConsoleOutDev
, TempDevicePath
, NULL
);
334 gBS
->FreePool (GopHandleBuffer
);
341 PreparePciVgaDevicePath (
342 IN EFI_HANDLE DeviceHandle
348 Add PCI VGA to ConOut.
353 DeviceHandle - Handle of PCIIO protocol.
357 EFI_SUCCESS - PCI VGA is added to ConOut.
358 EFI_STATUS - No PCI VGA device is added.
363 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
364 EFI_DEVICE_PATH_PROTOCOL
*GopDevicePath
;
367 Status
= gBS
->HandleProtocol (
369 &gEfiDevicePathProtocolGuid
,
372 if (EFI_ERROR (Status
)) {
376 GetGopDevicePath (DevicePath
, &GopDevicePath
);
377 DevicePath
= GopDevicePath
;
379 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
385 PreparePciSerialDevicePath (
386 IN EFI_HANDLE DeviceHandle
392 Add PCI Serial to ConOut, ConIn, ErrOut.
397 DeviceHandle - Handle of PCIIO protocol.
401 EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.
402 EFI_STATUS - No PCI Serial device is added.
407 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
410 Status
= gBS
->HandleProtocol (
412 &gEfiDevicePathProtocolGuid
,
415 if (EFI_ERROR (Status
)) {
419 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
420 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
422 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
423 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
424 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
430 VisitAllInstancesOfProtocol (
432 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction
,
438 EFI_HANDLE
*HandleBuffer
;
443 // Start to check all the PciIo to find all possible device
447 Status
= gBS
->LocateHandleBuffer (
454 if (EFI_ERROR (Status
)) {
458 for (Index
= 0; Index
< HandleCount
; Index
++) {
459 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], Id
, &Instance
);
460 if (EFI_ERROR (Status
)) {
464 Status
= (*CallBackFunction
) (
471 gBS
->FreePool (HandleBuffer
);
479 VisitingAPciInstance (
480 IN EFI_HANDLE Handle
,
486 EFI_PCI_IO_PROTOCOL
*PciIo
;
489 PciIo
= (EFI_PCI_IO_PROTOCOL
*) Instance
;
492 // Check for all PCI device
494 Status
= PciIo
->Pci
.Read (
498 sizeof (Pci
) / sizeof (UINT32
),
501 if (EFI_ERROR (Status
)) {
505 return (*(VISIT_PCI_INSTANCE_CALLBACK
)(UINTN
) Context
) (
516 VisitAllPciInstances (
517 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
520 return VisitAllInstancesOfProtocol (
521 &gEfiPciIoProtocolGuid
,
522 VisitingAPciInstance
,
523 (VOID
*)(UINTN
) CallBackFunction
529 Do platform specific PCI Device check and add them to
530 ConOut, ConIn, ErrOut.
532 @param[in] Handle - Handle of PCI device instance
533 @param[in] PciIo - PCI IO protocol instance
534 @param[in] Pci - PCI Header register block
536 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
537 @retval EFI_STATUS - PCI Device check or Console variable update fail.
542 DetectAndPreparePlatformPciDevicePath (
543 IN EFI_HANDLE Handle
,
544 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
550 Status
= PciIo
->Attributes (
552 EfiPciIoAttributeOperationEnable
,
553 EFI_PCI_DEVICE_ENABLE
,
556 ASSERT_EFI_ERROR (Status
);
558 if (!mDetectVgaOnly
) {
560 // Here we decide whether it is LPC Bridge
562 if ((IS_PCI_LPC (Pci
)) ||
563 ((IS_PCI_ISA_PDECODE (Pci
)) &&
564 (Pci
->Hdr
.VendorId
== 0x8086) &&
565 (Pci
->Hdr
.DeviceId
== 0x7000)
569 // Add IsaKeyboard to ConIn,
570 // add IsaSerial to ConOut, ConIn, ErrOut
572 DEBUG ((EFI_D_INFO
, "Found LPC Bridge device\n"));
573 PrepareLpcBridgeDevicePath (Handle
);
577 // Here we decide which Serial device to enable in PCI bus
579 if (IS_PCI_16550SERIAL (Pci
)) {
581 // Add them to ConOut, ConIn, ErrOut.
583 DEBUG ((EFI_D_INFO
, "Found PCI 16550 SERIAL device\n"));
584 PreparePciSerialDevicePath (Handle
);
590 // Here we decide which VGA device to enable in PCI bus
592 if (IS_PCI_VGA (Pci
)) {
594 // Add them to ConOut.
596 DEBUG ((EFI_D_INFO
, "Found PCI VGA device\n"));
597 PreparePciVgaDevicePath (Handle
);
606 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
608 @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.
610 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
611 @retval EFI_STATUS - PCI Device check or Console variable update fail.
615 DetectAndPreparePlatformPciDevicePaths (
616 BOOLEAN DetectVgaOnly
619 mDetectVgaOnly
= DetectVgaOnly
;
620 return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath
);
625 PlatformBdsConnectConsole (
626 IN BDS_CONSOLE_CONNECT_ENTRY
*PlatformConsole
632 Connect the predefined platform default console device. Always try to find
633 and enable the vga device if have.
637 PlatformConsole - Predfined platform default console device array.
641 EFI_SUCCESS - Success connect at least one ConIn and ConOut
642 device, there must have one ConOut device is
645 EFI_STATUS - Return the status of
646 BdsLibConnectAllDefaultConsoles ()
652 EFI_DEVICE_PATH_PROTOCOL
*VarConout
;
653 EFI_DEVICE_PATH_PROTOCOL
*VarConin
;
654 UINTN DevicePathSize
;
657 // Connect RootBridge
659 VarConout
= BdsLibGetVariableAndSize (
661 &gEfiGlobalVariableGuid
,
664 VarConin
= BdsLibGetVariableAndSize (
666 &gEfiGlobalVariableGuid
,
670 if (VarConout
== NULL
|| VarConin
== NULL
) {
672 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
674 DetectAndPreparePlatformPciDevicePaths (FALSE
);
677 // Have chance to connect the platform default console,
678 // the platform default console is the minimue device group
679 // the platform should support
681 for (Index
= 0; PlatformConsole
[Index
].DevicePath
!= NULL
; ++Index
) {
683 // Update the console variable with the connect type
685 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
686 BdsLibUpdateConsoleVariable (VarConsoleInp
, PlatformConsole
[Index
].DevicePath
, NULL
);
688 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
689 BdsLibUpdateConsoleVariable (VarConsoleOut
, PlatformConsole
[Index
].DevicePath
, NULL
);
691 if ((PlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
692 BdsLibUpdateConsoleVariable (VarErrorOut
, PlatformConsole
[Index
].DevicePath
, NULL
);
697 // Only detect VGA device and add them to ConOut
699 DetectAndPreparePlatformPciDevicePaths (TRUE
);
703 // Connect the all the default console with current cosole variable
705 Status
= BdsLibConnectAllDefaultConsoles ();
706 if (EFI_ERROR (Status
)) {
719 // Bus 0, Device 0, Function 0 - Host to PCI Bridge
721 PciWrite8 (PCI_LIB_ADDRESS (0, 0, 0, 0x3c), 0x00);
724 // Bus 0, Device 1, Function 0 - PCI to ISA Bridge
726 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x3c), 0x00);
727 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // LNKA routing target
728 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // LNKB routing target
729 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // LNKC routing target
730 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // LNKD routing target
733 // Bus 0, Device 1, Function 1 - IDE Controller
735 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x3c), 0x00);
736 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x0d), 0x40);
739 // Bus 0, Device 1, Function 3 - Power Managment Controller
741 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3c), 0x09);
742 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3d), 0x01); // INTA
745 // Bus 0, Device 2, Function 0 - Video Controller
747 PciWrite8 (PCI_LIB_ADDRESS (0, 2, 0, 0x3c), 0x00);
750 // Bus 0, Device 3, Function 0 - Network Controller
752 PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3c), 0x0a);
753 PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3d), 0x01); // INTA (-> LNKC)
756 // Bus 0, Device 5, Function 0 - RAM Memory
758 PciWrite8 (PCI_LIB_ADDRESS (0, 5, 0, 0x3c), 0x0b);
759 PciWrite8 (PCI_LIB_ADDRESS (0, 5, 0, 0x3d), 0x01); // INTA (-> LNKA)
769 // Set ACPI SCI_EN bit in PMCNTRL
771 IoOr16 ((PciRead32 (PCI_LIB_ADDRESS (0, 1, 3, 0x40)) & ~BIT0
) + 4, BIT0
);
777 ConnectRecursivelyIfPciMassStorage (
778 IN EFI_HANDLE Handle
,
779 IN EFI_PCI_IO_PROTOCOL
*Instance
,
780 IN PCI_TYPE00
*PciHeader
784 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
787 if (IS_CLASS1 (PciHeader
, PCI_CLASS_MASS_STORAGE
)) {
789 Status
= gBS
->HandleProtocol (
791 &gEfiDevicePathProtocolGuid
,
794 if (EFI_ERROR (Status
)) {
801 DevPathStr
= DevicePathToStr (DevicePath
);
804 "Found Mass Storage device: %s\n",
807 FreePool(DevPathStr
);
809 Status
= gBS
->ConnectController (Handle
, NULL
, NULL
, TRUE
);
810 if (EFI_ERROR (Status
)) {
821 This notification function is invoked when the
822 EMU Variable FVB has been changed.
824 @param Event The event that occured
825 @param Context For EFI compatiblity. Not used.
830 EmuVariablesUpdatedCallback (
835 DEBUG ((EFI_D_INFO
, "EmuVariablesUpdatedCallback\n"));
836 UpdateNvVarsOnFileSystem ();
842 VisitingFileSystemInstance (
843 IN EFI_HANDLE Handle
,
849 STATIC BOOLEAN ConnectedToFileSystem
= FALSE
;
851 if (ConnectedToFileSystem
) {
852 return EFI_ALREADY_STARTED
;
855 Status
= ConnectNvVarsToFileSystem (Handle
);
856 if (EFI_ERROR (Status
)) {
860 ConnectedToFileSystem
= TRUE
;
862 EfiCreateProtocolNotifyEvent (
863 &gEfiDevicePathProtocolGuid
,
865 EmuVariablesUpdatedCallback
,
867 &mEmuVariableEventReg
869 PcdSet64 (PcdEmuVariableEvent
, (UINT64
)(UINTN
) mEmuVariableEvent
);
876 PlatformBdsRestoreNvVarsFromHardDisk (
879 VisitAllPciInstances (ConnectRecursivelyIfPciMassStorage
);
880 VisitAllInstancesOfProtocol (
881 &gEfiSimpleFileSystemProtocolGuid
,
882 VisitingFileSystemInstance
,
890 PlatformBdsConnectSequence (
897 Connect with predeined platform connect sequence,
898 the OEM/IBV can customize with their own connect sequence.
912 DEBUG ((EFI_D_INFO
, "PlatformBdsConnectSequence\n"));
917 // Here we can get the customized platform connect sequence
918 // Notes: we can connect with new variable which record the
919 // last time boots connect device path sequence
921 while (gPlatformConnectSequence
[Index
] != NULL
) {
923 // Build the platform boot option
925 BdsLibConnectDevicePath (gPlatformConnectSequence
[Index
]);
930 // Just use the simple policy to connect all devices
934 PciInitialization ();
935 AcpiInitialization ();
938 // Clear the logo after all devices are connected.
940 gST
->ConOut
->ClearScreen (gST
->ConOut
);
944 PlatformBdsGetDriverOption (
945 IN OUT LIST_ENTRY
*BdsDriverLists
951 Load the predefined driver option, OEM/IBV can customize this
952 to load their own drivers
956 BdsDriverLists - The header of the driver option link list.
964 DEBUG ((EFI_D_INFO
, "PlatformBdsGetDriverOption\n"));
969 PlatformBdsDiagnostics (
970 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel
,
971 IN BOOLEAN QuietBoot
,
972 IN BASEM_MEMORY_TEST BaseMemoryTest
978 Perform the platform diagnostic, such like test memory. OEM/IBV also
979 can customize this fuction to support specific platform diagnostic.
983 MemoryTestLevel - The memory test intensive level
985 QuietBoot - Indicate if need to enable the quiet boot
987 BaseMemoryTest - A pointer to BaseMemoryTest()
997 DEBUG ((EFI_D_INFO
, "PlatformBdsDiagnostics\n"));
1000 // Here we can decide if we need to show
1001 // the diagnostics screen
1002 // Notes: this quiet boot code should be remove
1003 // from the graphic lib
1006 EnableQuietBoot (PcdGetPtr(PcdLogoFile
));
1008 // Perform system diagnostic
1010 Status
= BaseMemoryTest (MemoryTestLevel
);
1011 if (EFI_ERROR (Status
)) {
1012 DisableQuietBoot ();
1018 // Perform system diagnostic
1020 Status
= BaseMemoryTest (MemoryTestLevel
);
1026 PlatformBdsPolicyBehavior (
1027 IN OUT LIST_ENTRY
*DriverOptionList
,
1028 IN OUT LIST_ENTRY
*BootOptionList
,
1029 IN PROCESS_CAPSULES ProcessCapsules
,
1030 IN BASEM_MEMORY_TEST BaseMemoryTest
1034 Routine Description:
1036 The function will excute with as the platform policy, current policy
1037 is driven by boot mode. IBV/OEM can customize this code for their specific
1042 DriverOptionList - The header of the driver option link list
1044 BootOptionList - The header of the boot option link list
1046 ProcessCapsules - A pointer to ProcessCapsules()
1048 BaseMemoryTest - A pointer to BaseMemoryTest()
1058 EFI_EVENT UserInputDurationTime
;
1060 BDS_COMMON_OPTION
*BootOption
;
1064 EFI_BOOT_MODE BootMode
;
1066 DEBUG ((EFI_D_INFO
, "PlatformBdsPolicyBehavior\n"));
1068 ConnectRootBridge ();
1071 // Try to restore variables from the hard disk early so
1072 // they can be used for the other BDS connect operations.
1074 PlatformBdsRestoreNvVarsFromHardDisk ();
1077 // Init the time out value
1079 Timeout
= PcdGet16 (PcdPlatformBootTimeOut
);
1082 // Load the driver option as the driver option list
1084 PlatformBdsGetDriverOption (DriverOptionList
);
1087 // Get current Boot Mode
1089 Status
= BdsLibGetBootMode (&BootMode
);
1090 DEBUG ((EFI_D_ERROR
, "Boot Mode:%x\n", BootMode
));
1093 // Go the different platform policy with different boot mode
1094 // Notes: this part code can be change with the table policy
1096 ASSERT (BootMode
== BOOT_WITH_FULL_CONFIGURATION
);
1098 // Connect platform console
1100 Status
= PlatformBdsConnectConsole (gPlatformConsole
);
1101 if (EFI_ERROR (Status
)) {
1103 // Here OEM/IBV can customize with defined action
1105 PlatformBdsNoConsoleAction ();
1108 // Create a 300ms duration event to ensure user has enough input time to enter Setup
1110 Status
= gBS
->CreateEvent (
1115 &UserInputDurationTime
1117 ASSERT (Status
== EFI_SUCCESS
);
1118 Status
= gBS
->SetTimer (UserInputDurationTime
, TimerRelative
, 3000000);
1119 ASSERT (Status
== EFI_SUCCESS
);
1121 // Memory test and Logo show
1123 PlatformBdsDiagnostics (IGNORE
, TRUE
, BaseMemoryTest
);
1126 // Perform some platform specific connect sequence
1128 PlatformBdsConnectSequence ();
1131 // Give one chance to enter the setup if we
1132 // have the time out
1135 //PlatformBdsEnterFrontPage (Timeout, FALSE);
1138 DEBUG ((EFI_D_INFO
, "BdsLibConnectAll\n"));
1139 BdsLibConnectAll ();
1140 BdsLibEnumerateAllBootOption (BootOptionList
);
1142 SetBootOrderFromQemu (BootOptionList
);
1145 // Please uncomment above ConnectAll and EnumerateAll code and remove following first boot
1146 // checking code in real production tip.
1148 // In BOOT_WITH_FULL_CONFIGURATION boot mode, should always connect every device
1149 // and do enumerate all the default boot options. But in development system board, the boot mode
1150 // cannot be BOOT_ASSUMING_NO_CONFIGURATION_CHANGES because the machine box
1151 // is always open. So the following code only do the ConnectAll and EnumerateAll at first boot.
1153 Status
= BdsLibBuildOptionFromVar (BootOptionList
, L
"BootOrder");
1154 if (EFI_ERROR(Status
)) {
1156 // If cannot find "BootOrder" variable, it may be first boot.
1157 // Try to connect all devices and enumerate all boot options here.
1159 BdsLibConnectAll ();
1160 BdsLibEnumerateAllBootOption (BootOptionList
);
1164 // To give the User a chance to enter Setup here, if user set TimeOut is 0.
1165 // BDS should still give user a chance to enter Setup
1167 // Connect first boot option, and then check user input before exit
1169 for (Link
= BootOptionList
->ForwardLink
; Link
!= BootOptionList
;Link
= Link
->ForwardLink
) {
1170 BootOption
= CR (Link
, BDS_COMMON_OPTION
, Link
, BDS_LOAD_OPTION_SIGNATURE
);
1171 if (!IS_LOAD_OPTION_TYPE (BootOption
->Attribute
, LOAD_OPTION_ACTIVE
)) {
1173 // skip the header of the link list, becuase it has no boot option
1178 // Make sure the boot option device path connected, but ignore the BBS device path
1180 if (DevicePathType (BootOption
->DevicePath
) != BBS_DEVICE_PATH
) {
1181 BdsLibConnectDevicePath (BootOption
->DevicePath
);
1188 // Check whether the user input after the duration time has expired
1190 OldTpl
= EfiGetCurrentTpl();
1191 gBS
->RestoreTPL (TPL_APPLICATION
);
1192 gBS
->WaitForEvent (1, &UserInputDurationTime
, &Index
);
1193 gBS
->CloseEvent (UserInputDurationTime
);
1194 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
1195 gBS
->RaiseTPL (OldTpl
);
1197 if (!EFI_ERROR (Status
)) {
1199 // Enter Setup if user input
1202 PlatformBdsEnterFrontPage (Timeout
, FALSE
);
1210 PlatformBdsBootSuccess (
1211 IN BDS_COMMON_OPTION
*Option
1215 Routine Description:
1217 Hook point after a boot attempt succeeds. We don't expect a boot option to
1218 return, so the EFI 1.0 specification defines that you will default to an
1219 interactive mode and stop processing the BootOrder list in this case. This
1220 is alos a platform implementation and can be customized by IBV/OEM.
1224 Option - Pointer to Boot Option that succeeded to boot.
1234 DEBUG ((EFI_D_INFO
, "PlatformBdsBootSuccess\n"));
1236 // If Boot returned with EFI_SUCCESS and there is not in the boot device
1237 // select loop then we need to pop up a UI and wait for user input.
1239 TmpStr
= Option
->StatusString
;
1240 if (TmpStr
!= NULL
) {
1241 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
1248 PlatformBdsBootFail (
1249 IN BDS_COMMON_OPTION
*Option
,
1250 IN EFI_STATUS Status
,
1251 IN CHAR16
*ExitData
,
1252 IN UINTN ExitDataSize
1256 Routine Description:
1258 Hook point after a boot attempt fails.
1262 Option - Pointer to Boot Option that failed to boot.
1264 Status - Status returned from failed boot.
1266 ExitData - Exit data returned from failed boot.
1268 ExitDataSize - Exit data size returned from failed boot.
1278 DEBUG ((EFI_D_INFO
, "PlatformBdsBootFail\n"));
1281 // If Boot returned with failed status then we need to pop up a UI and wait
1284 TmpStr
= Option
->StatusString
;
1285 if (TmpStr
!= NULL
) {
1286 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
1292 PlatformBdsNoConsoleAction (
1297 Routine Description:
1299 This function is remained for IBV/OEM to do some platform action,
1300 if there no console device can be connected.
1308 EFI_SUCCESS - Direct return success now.
1312 DEBUG ((EFI_D_INFO
, "PlatformBdsNoConsoleAction\n"));
1318 PlatformBdsLockNonUpdatableFlash (
1322 DEBUG ((EFI_D_INFO
, "PlatformBdsLockNonUpdatableFlash\n"));
1328 This notification function is invoked when an instance of the
1329 EFI_DEVICE_PATH_PROTOCOL is produced.
1331 @param Event The event that occured
1332 @param Context For EFI compatiblity. Not used.
1345 EFI_DEVICE_PATH_PROTOCOL
*DevPathNode
;
1346 ATAPI_DEVICE_PATH
*Atapi
;
1349 // Examine all new handles
1353 // Get the next handle
1355 BufferSize
= sizeof (Handle
);
1356 Status
= gBS
->LocateHandle (
1359 mEfiDevPathNotifyReg
,
1365 // If not found, we're done
1367 if (EFI_NOT_FOUND
== Status
) {
1371 if (EFI_ERROR (Status
)) {
1376 // Get the DevicePath protocol on that handle
1378 Status
= gBS
->HandleProtocol (Handle
, &gEfiDevicePathProtocolGuid
, (VOID
**)&DevPathNode
);
1379 ASSERT_EFI_ERROR (Status
);
1381 while (!IsDevicePathEnd (DevPathNode
)) {
1383 // Find the handler to dump this device path node
1386 (DevicePathType(DevPathNode
) == MESSAGING_DEVICE_PATH
) &&
1387 (DevicePathSubType(DevPathNode
) == MSG_ATAPI_DP
)
1389 Atapi
= (ATAPI_DEVICE_PATH
*) DevPathNode
;
1395 (Atapi
->PrimarySecondary
== 1) ? 0x42: 0x40
1402 // Next device path node
1404 DevPathNode
= NextDevicePathNode (DevPathNode
);
1413 InstallDevicePathCallback (
1417 DEBUG ((EFI_D_INFO
, "Registered NotifyDevPath Event\n"));
1418 mEfiDevPathEvent
= EfiCreateProtocolNotifyEvent (
1419 &gEfiDevicePathProtocolGuid
,
1423 &mEfiDevPathNotifyReg
1428 Lock the ConsoleIn device in system table. All key
1429 presses will be ignored until the Password is typed in. The only way to
1430 disable the password is to type it in to a ConIn device.
1432 @param Password Password used to lock ConIn device.
1434 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
1435 @retval EFI_UNSUPPORTED Password not found
1444 return EFI_UNSUPPORTED
;