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"
22 VOID
*mEfiDevPathNotifyReg
;
23 EFI_EVENT mEfiDevPathEvent
;
24 VOID
*mEmuVariableEventReg
;
25 EFI_EVENT mEmuVariableEvent
;
26 BOOLEAN mDetectVgaOnly
;
35 (EFIAPI
*PROTOCOL_INSTANCE_CALLBACK
)(
42 @param[in] Handle - Handle of PCI device instance
43 @param[in] PciIo - PCI IO protocol instance
44 @param[in] Pci - PCI Header register block
48 (EFIAPI
*VISIT_PCI_INSTANCE_CALLBACK
)(
50 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
56 // Function prototypes
60 VisitAllInstancesOfProtocol (
62 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction
,
67 VisitAllPciInstancesOfProtocol (
68 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
72 InstallDevicePathCallback (
77 // BDS Platform Functions
88 Platform Bds init. Incude the platform firmware vendor, revision
99 DEBUG ((EFI_D_INFO
, "PlatformBdsInit\n"));
100 InstallDevicePathCallback ();
120 EFI_SUCCESS - Connect RootBridge successfully.
121 EFI_STATUS - Connect RootBridge fail.
126 EFI_HANDLE RootHandle
;
129 // Make all the PCI_IO protocols on PCI Seg 0 show up
131 BdsLibConnectDevicePath (gPlatformRootBridges
[0]);
133 Status
= gBS
->LocateDevicePath (
134 &gEfiDevicePathProtocolGuid
,
135 &gPlatformRootBridges
[0],
138 if (EFI_ERROR (Status
)) {
142 Status
= gBS
->ConnectController (RootHandle
, NULL
, NULL
, FALSE
);
143 if (EFI_ERROR (Status
)) {
152 PrepareLpcBridgeDevicePath (
153 IN EFI_HANDLE DeviceHandle
159 Add IsaKeyboard to ConIn,
160 add IsaSerial to ConOut, ConIn, ErrOut.
165 DeviceHandle - Handle of PCIIO protocol.
169 EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut.
170 EFI_STATUS - No LPC bridge is added.
175 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
176 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
180 Status
= gBS
->HandleProtocol (
182 &gEfiDevicePathProtocolGuid
,
185 if (EFI_ERROR (Status
)) {
188 TempDevicePath
= DevicePath
;
193 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnpPs2KeyboardDeviceNode
);
195 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
200 DevicePath
= TempDevicePath
;
201 gPnp16550ComPortDeviceNode
.UID
= 0;
203 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnp16550ComPortDeviceNode
);
204 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
205 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
210 DevPathStr
= DevicePathToStr(DevicePath
);
213 "BdsPlatform.c+%d: COM%d DevPath: %s\n",
215 gPnp16550ComPortDeviceNode
.UID
+ 1,
218 FreePool(DevPathStr
);
220 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
221 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
222 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
227 DevicePath
= TempDevicePath
;
228 gPnp16550ComPortDeviceNode
.UID
= 1;
230 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnp16550ComPortDeviceNode
);
231 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
232 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
237 DevPathStr
= DevicePathToStr(DevicePath
);
240 "BdsPlatform.c+%d: COM%d DevPath: %s\n",
242 gPnp16550ComPortDeviceNode
.UID
+ 1,
245 FreePool(DevPathStr
);
247 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
248 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
249 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
256 IN EFI_DEVICE_PATH_PROTOCOL
*PciDevicePath
,
257 OUT EFI_DEVICE_PATH_PROTOCOL
**GopDevicePath
262 EFI_HANDLE PciDeviceHandle
;
263 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
264 EFI_DEVICE_PATH_PROTOCOL
*TempPciDevicePath
;
265 UINTN GopHandleCount
;
266 EFI_HANDLE
*GopHandleBuffer
;
268 if (PciDevicePath
== NULL
|| GopDevicePath
== NULL
) {
269 return EFI_INVALID_PARAMETER
;
273 // Initialize the GopDevicePath to be PciDevicePath
275 *GopDevicePath
= PciDevicePath
;
276 TempPciDevicePath
= PciDevicePath
;
278 Status
= gBS
->LocateDevicePath (
279 &gEfiDevicePathProtocolGuid
,
283 if (EFI_ERROR (Status
)) {
288 // Try to connect this handle, so that GOP dirver could start on this
289 // device and create child handles with GraphicsOutput Protocol installed
290 // on them, then we get device paths of these child handles and select
291 // them as possible console device.
293 gBS
->ConnectController (PciDeviceHandle
, NULL
, NULL
, FALSE
);
295 Status
= gBS
->LocateHandleBuffer (
297 &gEfiGraphicsOutputProtocolGuid
,
302 if (!EFI_ERROR (Status
)) {
304 // Add all the child handles as possible Console Device
306 for (Index
= 0; Index
< GopHandleCount
; Index
++) {
307 Status
= gBS
->HandleProtocol (GopHandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*)&TempDevicePath
);
308 if (EFI_ERROR (Status
)) {
314 GetDevicePathSize (PciDevicePath
) - END_DEVICE_PATH_LENGTH
317 // In current implementation, we only enable one of the child handles
318 // as console device, i.e. sotre one of the child handle's device
319 // path to variable "ConOut"
320 // In futhure, we could select all child handles to be console device
323 *GopDevicePath
= TempDevicePath
;
326 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()
327 // Add the integrity GOP device path.
329 BdsLibUpdateConsoleVariable (VarConsoleOutDev
, NULL
, PciDevicePath
);
330 BdsLibUpdateConsoleVariable (VarConsoleOutDev
, TempDevicePath
, NULL
);
333 gBS
->FreePool (GopHandleBuffer
);
340 PreparePciVgaDevicePath (
341 IN EFI_HANDLE DeviceHandle
347 Add PCI VGA to ConOut.
352 DeviceHandle - Handle of PCIIO protocol.
356 EFI_SUCCESS - PCI VGA is added to ConOut.
357 EFI_STATUS - No PCI VGA device is added.
362 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
363 EFI_DEVICE_PATH_PROTOCOL
*GopDevicePath
;
366 Status
= gBS
->HandleProtocol (
368 &gEfiDevicePathProtocolGuid
,
371 if (EFI_ERROR (Status
)) {
375 GetGopDevicePath (DevicePath
, &GopDevicePath
);
376 DevicePath
= GopDevicePath
;
378 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
384 PreparePciSerialDevicePath (
385 IN EFI_HANDLE DeviceHandle
391 Add PCI Serial to ConOut, ConIn, ErrOut.
396 DeviceHandle - Handle of PCIIO protocol.
400 EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.
401 EFI_STATUS - No PCI Serial device is added.
406 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
409 Status
= gBS
->HandleProtocol (
411 &gEfiDevicePathProtocolGuid
,
414 if (EFI_ERROR (Status
)) {
418 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
419 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
421 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
422 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
423 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
429 VisitAllInstancesOfProtocol (
431 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction
,
437 EFI_HANDLE
*HandleBuffer
;
442 // Start to check all the PciIo to find all possible device
446 Status
= gBS
->LocateHandleBuffer (
453 if (EFI_ERROR (Status
)) {
457 for (Index
= 0; Index
< HandleCount
; Index
++) {
458 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], Id
, &Instance
);
459 if (EFI_ERROR (Status
)) {
463 Status
= (*CallBackFunction
) (
470 gBS
->FreePool (HandleBuffer
);
478 VisitingAPciInstance (
479 IN EFI_HANDLE Handle
,
485 EFI_PCI_IO_PROTOCOL
*PciIo
;
488 PciIo
= (EFI_PCI_IO_PROTOCOL
*) Instance
;
491 // Check for all PCI device
493 Status
= PciIo
->Pci
.Read (
497 sizeof (Pci
) / sizeof (UINT32
),
500 if (EFI_ERROR (Status
)) {
504 return (*(VISIT_PCI_INSTANCE_CALLBACK
)(UINTN
) Context
) (
515 VisitAllPciInstances (
516 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
519 return VisitAllInstancesOfProtocol (
520 &gEfiPciIoProtocolGuid
,
521 VisitingAPciInstance
,
522 (VOID
*)(UINTN
) CallBackFunction
528 Do platform specific PCI Device check and add them to
529 ConOut, ConIn, ErrOut.
531 @param[in] Handle - Handle of PCI device instance
532 @param[in] PciIo - PCI IO protocol instance
533 @param[in] Pci - PCI Header register block
535 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
536 @retval EFI_STATUS - PCI Device check or Console variable update fail.
541 DetectAndPreparePlatformPciDevicePath (
542 IN EFI_HANDLE Handle
,
543 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
549 Status
= PciIo
->Attributes (
551 EfiPciIoAttributeOperationEnable
,
552 EFI_PCI_DEVICE_ENABLE
,
555 ASSERT_EFI_ERROR (Status
);
557 if (!mDetectVgaOnly
) {
559 // Here we decide whether it is LPC Bridge
561 if ((IS_PCI_LPC (Pci
)) ||
562 ((IS_PCI_ISA_PDECODE (Pci
)) &&
563 (Pci
->Hdr
.VendorId
== 0x8086) &&
564 (Pci
->Hdr
.DeviceId
== 0x7000)
568 // Add IsaKeyboard to ConIn,
569 // add IsaSerial to ConOut, ConIn, ErrOut
571 DEBUG ((EFI_D_INFO
, "Found LPC Bridge device\n"));
572 PrepareLpcBridgeDevicePath (Handle
);
576 // Here we decide which Serial device to enable in PCI bus
578 if (IS_PCI_16550SERIAL (Pci
)) {
580 // Add them to ConOut, ConIn, ErrOut.
582 DEBUG ((EFI_D_INFO
, "Found PCI 16550 SERIAL device\n"));
583 PreparePciSerialDevicePath (Handle
);
589 // Here we decide which VGA device to enable in PCI bus
591 if (IS_PCI_VGA (Pci
)) {
593 // Add them to ConOut.
595 DEBUG ((EFI_D_INFO
, "Found PCI VGA device\n"));
596 PreparePciVgaDevicePath (Handle
);
605 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
607 @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.
609 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
610 @retval EFI_STATUS - PCI Device check or Console variable update fail.
614 DetectAndPreparePlatformPciDevicePaths (
615 BOOLEAN DetectVgaOnly
618 mDetectVgaOnly
= DetectVgaOnly
;
619 return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath
);
624 PlatformBdsConnectConsole (
625 IN BDS_CONSOLE_CONNECT_ENTRY
*PlatformConsole
631 Connect the predefined platform default console device. Always try to find
632 and enable the vga device if have.
636 PlatformConsole - Predfined platform default console device array.
640 EFI_SUCCESS - Success connect at least one ConIn and ConOut
641 device, there must have one ConOut device is
644 EFI_STATUS - Return the status of
645 BdsLibConnectAllDefaultConsoles ()
651 EFI_DEVICE_PATH_PROTOCOL
*VarConout
;
652 EFI_DEVICE_PATH_PROTOCOL
*VarConin
;
653 UINTN DevicePathSize
;
656 // Connect RootBridge
658 VarConout
= BdsLibGetVariableAndSize (
660 &gEfiGlobalVariableGuid
,
663 VarConin
= BdsLibGetVariableAndSize (
665 &gEfiGlobalVariableGuid
,
669 if (VarConout
== NULL
|| VarConin
== NULL
) {
671 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
673 DetectAndPreparePlatformPciDevicePaths (FALSE
);
676 // Have chance to connect the platform default console,
677 // the platform default console is the minimue device group
678 // the platform should support
680 for (Index
= 0; PlatformConsole
[Index
].DevicePath
!= NULL
; ++Index
) {
682 // Update the console variable with the connect type
684 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
685 BdsLibUpdateConsoleVariable (VarConsoleInp
, PlatformConsole
[Index
].DevicePath
, NULL
);
687 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
688 BdsLibUpdateConsoleVariable (VarConsoleOut
, PlatformConsole
[Index
].DevicePath
, NULL
);
690 if ((PlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
691 BdsLibUpdateConsoleVariable (VarErrorOut
, PlatformConsole
[Index
].DevicePath
, NULL
);
696 // Only detect VGA device and add them to ConOut
698 DetectAndPreparePlatformPciDevicePaths (TRUE
);
702 // Connect the all the default console with current cosole variable
704 Status
= BdsLibConnectAllDefaultConsoles ();
705 if (EFI_ERROR (Status
)) {
718 // Bus 0, Device 0, Function 0 - Host to PCI Bridge
720 PciWrite8 (PCI_LIB_ADDRESS (0, 0, 0, 0x3c), 0x00);
723 // Bus 0, Device 1, Function 0 - PCI to ISA Bridge
725 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x3c), 0x00);
726 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // LNKA routing target
727 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // LNKB routing target
728 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // LNKC routing target
729 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // LNKD routing target
732 // Bus 0, Device 1, Function 1 - IDE Controller
734 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x3c), 0x00);
735 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x0d), 0x40);
738 // Bus 0, Device 1, Function 3 - Power Managment Controller
740 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3c), 0x09);
741 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3d), 0x01); // INTA
744 // Bus 0, Device 2, Function 0 - Video Controller
746 PciWrite8 (PCI_LIB_ADDRESS (0, 2, 0, 0x3c), 0x00);
749 // Bus 0, Device 3, Function 0 - Network Controller
751 PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3c), 0x0a);
752 PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3d), 0x01); // INTA (-> LNKC)
755 // Bus 0, Device 5, Function 0 - RAM Memory
757 PciWrite8 (PCI_LIB_ADDRESS (0, 5, 0, 0x3c), 0x0b);
758 PciWrite8 (PCI_LIB_ADDRESS (0, 5, 0, 0x3d), 0x01); // INTA (-> LNKA)
768 // Set ACPI SCI_EN bit in PMCNTRL
770 IoOr16 ((PciRead32 (PCI_LIB_ADDRESS (0, 1, 3, 0x40)) & ~BIT0
) + 4, BIT0
);
776 ConnectRecursivelyIfPciMassStorage (
777 IN EFI_HANDLE Handle
,
778 IN EFI_PCI_IO_PROTOCOL
*Instance
,
779 IN PCI_TYPE00
*PciHeader
783 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
786 if (IS_CLASS1 (PciHeader
, PCI_CLASS_MASS_STORAGE
)) {
788 Status
= gBS
->HandleProtocol (
790 &gEfiDevicePathProtocolGuid
,
793 if (EFI_ERROR (Status
)) {
800 DevPathStr
= DevicePathToStr (DevicePath
);
803 "Found Mass Storage device: %s\n",
806 FreePool(DevPathStr
);
808 Status
= gBS
->ConnectController (Handle
, NULL
, NULL
, TRUE
);
809 if (EFI_ERROR (Status
)) {
820 This notification function is invoked when the
821 EMU Variable FVB has been changed.
823 @param Event The event that occured
824 @param Context For EFI compatiblity. Not used.
829 EmuVariablesUpdatedCallback (
834 DEBUG ((EFI_D_INFO
, "EmuVariablesUpdatedCallback\n"));
835 UpdateNvVarsOnFileSystem ();
841 VisitingFileSystemInstance (
842 IN EFI_HANDLE Handle
,
848 STATIC BOOLEAN ConnectedToFileSystem
= FALSE
;
850 if (ConnectedToFileSystem
) {
851 return EFI_ALREADY_STARTED
;
854 Status
= ConnectNvVarsToFileSystem (Handle
);
855 if (EFI_ERROR (Status
)) {
859 ConnectedToFileSystem
= TRUE
;
861 EfiCreateProtocolNotifyEvent (
862 &gEfiDevicePathProtocolGuid
,
864 EmuVariablesUpdatedCallback
,
866 &mEmuVariableEventReg
868 PcdSet64 (PcdEmuVariableEvent
, (UINT64
)(UINTN
) mEmuVariableEvent
);
875 PlatformBdsRestoreNvVarsFromHardDisk (
878 VisitAllPciInstances (ConnectRecursivelyIfPciMassStorage
);
879 VisitAllInstancesOfProtocol (
880 &gEfiSimpleFileSystemProtocolGuid
,
881 VisitingFileSystemInstance
,
889 PlatformBdsConnectSequence (
896 Connect with predeined platform connect sequence,
897 the OEM/IBV can customize with their own connect sequence.
911 DEBUG ((EFI_D_INFO
, "PlatformBdsConnectSequence\n"));
916 // Here we can get the customized platform connect sequence
917 // Notes: we can connect with new variable which record the
918 // last time boots connect device path sequence
920 while (gPlatformConnectSequence
[Index
] != NULL
) {
922 // Build the platform boot option
924 BdsLibConnectDevicePath (gPlatformConnectSequence
[Index
]);
929 // Just use the simple policy to connect all devices
933 PciInitialization ();
934 AcpiInitialization ();
937 // Clear the logo after all devices are connected.
939 gST
->ConOut
->ClearScreen (gST
->ConOut
);
943 PlatformBdsGetDriverOption (
944 IN OUT LIST_ENTRY
*BdsDriverLists
950 Load the predefined driver option, OEM/IBV can customize this
951 to load their own drivers
955 BdsDriverLists - The header of the driver option link list.
963 DEBUG ((EFI_D_INFO
, "PlatformBdsGetDriverOption\n"));
968 PlatformBdsDiagnostics (
969 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel
,
970 IN BOOLEAN QuietBoot
,
971 IN BASEM_MEMORY_TEST BaseMemoryTest
977 Perform the platform diagnostic, such like test memory. OEM/IBV also
978 can customize this fuction to support specific platform diagnostic.
982 MemoryTestLevel - The memory test intensive level
984 QuietBoot - Indicate if need to enable the quiet boot
986 BaseMemoryTest - A pointer to BaseMemoryTest()
996 DEBUG ((EFI_D_INFO
, "PlatformBdsDiagnostics\n"));
999 // Here we can decide if we need to show
1000 // the diagnostics screen
1001 // Notes: this quiet boot code should be remove
1002 // from the graphic lib
1005 EnableQuietBoot (PcdGetPtr(PcdLogoFile
));
1007 // Perform system diagnostic
1009 Status
= BaseMemoryTest (MemoryTestLevel
);
1010 if (EFI_ERROR (Status
)) {
1011 DisableQuietBoot ();
1017 // Perform system diagnostic
1019 Status
= BaseMemoryTest (MemoryTestLevel
);
1025 PlatformBdsPolicyBehavior (
1026 IN OUT LIST_ENTRY
*DriverOptionList
,
1027 IN OUT LIST_ENTRY
*BootOptionList
,
1028 IN PROCESS_CAPSULES ProcessCapsules
,
1029 IN BASEM_MEMORY_TEST BaseMemoryTest
1033 Routine Description:
1035 The function will excute with as the platform policy, current policy
1036 is driven by boot mode. IBV/OEM can customize this code for their specific
1041 DriverOptionList - The header of the driver option link list
1043 BootOptionList - The header of the boot option link list
1045 ProcessCapsules - A pointer to ProcessCapsules()
1047 BaseMemoryTest - A pointer to BaseMemoryTest()
1057 EFI_EVENT UserInputDurationTime
;
1059 BDS_COMMON_OPTION
*BootOption
;
1063 EFI_BOOT_MODE BootMode
;
1065 DEBUG ((EFI_D_INFO
, "PlatformBdsPolicyBehavior\n"));
1067 ConnectRootBridge ();
1070 // Try to restore variables from the hard disk early so
1071 // they can be used for the other BDS connect operations.
1073 PlatformBdsRestoreNvVarsFromHardDisk ();
1076 // Init the time out value
1078 Timeout
= PcdGet16 (PcdPlatformBootTimeOut
);
1081 // Load the driver option as the driver option list
1083 PlatformBdsGetDriverOption (DriverOptionList
);
1086 // Get current Boot Mode
1088 Status
= BdsLibGetBootMode (&BootMode
);
1089 DEBUG ((EFI_D_ERROR
, "Boot Mode:%x\n", BootMode
));
1092 // Go the different platform policy with different boot mode
1093 // Notes: this part code can be change with the table policy
1095 ASSERT (BootMode
== BOOT_WITH_FULL_CONFIGURATION
);
1097 // Connect platform console
1099 Status
= PlatformBdsConnectConsole (gPlatformConsole
);
1100 if (EFI_ERROR (Status
)) {
1102 // Here OEM/IBV can customize with defined action
1104 PlatformBdsNoConsoleAction ();
1107 // Create a 300ms duration event to ensure user has enough input time to enter Setup
1109 Status
= gBS
->CreateEvent (
1114 &UserInputDurationTime
1116 ASSERT (Status
== EFI_SUCCESS
);
1117 Status
= gBS
->SetTimer (UserInputDurationTime
, TimerRelative
, 3000000);
1118 ASSERT (Status
== EFI_SUCCESS
);
1120 // Memory test and Logo show
1122 PlatformBdsDiagnostics (IGNORE
, TRUE
, BaseMemoryTest
);
1125 // Perform some platform specific connect sequence
1127 PlatformBdsConnectSequence ();
1130 // Give one chance to enter the setup if we
1131 // have the time out
1134 //PlatformBdsEnterFrontPage (Timeout, FALSE);
1137 DEBUG ((EFI_D_INFO
, "BdsLibConnectAll\n"));
1138 BdsLibConnectAll ();
1139 BdsLibEnumerateAllBootOption (BootOptionList
);
1142 // Please uncomment above ConnectAll and EnumerateAll code and remove following first boot
1143 // checking code in real production tip.
1145 // In BOOT_WITH_FULL_CONFIGURATION boot mode, should always connect every device
1146 // and do enumerate all the default boot options. But in development system board, the boot mode
1147 // cannot be BOOT_ASSUMING_NO_CONFIGURATION_CHANGES because the machine box
1148 // is always open. So the following code only do the ConnectAll and EnumerateAll at first boot.
1150 Status
= BdsLibBuildOptionFromVar (BootOptionList
, L
"BootOrder");
1151 if (EFI_ERROR(Status
)) {
1153 // If cannot find "BootOrder" variable, it may be first boot.
1154 // Try to connect all devices and enumerate all boot options here.
1156 BdsLibConnectAll ();
1157 BdsLibEnumerateAllBootOption (BootOptionList
);
1161 // To give the User a chance to enter Setup here, if user set TimeOut is 0.
1162 // BDS should still give user a chance to enter Setup
1164 // Connect first boot option, and then check user input before exit
1166 for (Link
= BootOptionList
->ForwardLink
; Link
!= BootOptionList
;Link
= Link
->ForwardLink
) {
1167 BootOption
= CR (Link
, BDS_COMMON_OPTION
, Link
, BDS_LOAD_OPTION_SIGNATURE
);
1168 if (!IS_LOAD_OPTION_TYPE (BootOption
->Attribute
, LOAD_OPTION_ACTIVE
)) {
1170 // skip the header of the link list, becuase it has no boot option
1175 // Make sure the boot option device path connected, but ignore the BBS device path
1177 if (DevicePathType (BootOption
->DevicePath
) != BBS_DEVICE_PATH
) {
1178 BdsLibConnectDevicePath (BootOption
->DevicePath
);
1185 // Check whether the user input after the duration time has expired
1187 OldTpl
= EfiGetCurrentTpl();
1188 gBS
->RestoreTPL (TPL_APPLICATION
);
1189 gBS
->WaitForEvent (1, &UserInputDurationTime
, &Index
);
1190 gBS
->CloseEvent (UserInputDurationTime
);
1191 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
1192 gBS
->RaiseTPL (OldTpl
);
1194 if (!EFI_ERROR (Status
)) {
1196 // Enter Setup if user input
1199 PlatformBdsEnterFrontPage (Timeout
, FALSE
);
1207 PlatformBdsBootSuccess (
1208 IN BDS_COMMON_OPTION
*Option
1212 Routine Description:
1214 Hook point after a boot attempt succeeds. We don't expect a boot option to
1215 return, so the EFI 1.0 specification defines that you will default to an
1216 interactive mode and stop processing the BootOrder list in this case. This
1217 is alos a platform implementation and can be customized by IBV/OEM.
1221 Option - Pointer to Boot Option that succeeded to boot.
1231 DEBUG ((EFI_D_INFO
, "PlatformBdsBootSuccess\n"));
1233 // If Boot returned with EFI_SUCCESS and there is not in the boot device
1234 // select loop then we need to pop up a UI and wait for user input.
1236 TmpStr
= Option
->StatusString
;
1237 if (TmpStr
!= NULL
) {
1238 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
1245 PlatformBdsBootFail (
1246 IN BDS_COMMON_OPTION
*Option
,
1247 IN EFI_STATUS Status
,
1248 IN CHAR16
*ExitData
,
1249 IN UINTN ExitDataSize
1253 Routine Description:
1255 Hook point after a boot attempt fails.
1259 Option - Pointer to Boot Option that failed to boot.
1261 Status - Status returned from failed boot.
1263 ExitData - Exit data returned from failed boot.
1265 ExitDataSize - Exit data size returned from failed boot.
1275 DEBUG ((EFI_D_INFO
, "PlatformBdsBootFail\n"));
1278 // If Boot returned with failed status then we need to pop up a UI and wait
1281 TmpStr
= Option
->StatusString
;
1282 if (TmpStr
!= NULL
) {
1283 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
1289 PlatformBdsNoConsoleAction (
1294 Routine Description:
1296 This function is remained for IBV/OEM to do some platform action,
1297 if there no console device can be connected.
1305 EFI_SUCCESS - Direct return success now.
1309 DEBUG ((EFI_D_INFO
, "PlatformBdsNoConsoleAction\n"));
1315 PlatformBdsLockNonUpdatableFlash (
1319 DEBUG ((EFI_D_INFO
, "PlatformBdsLockNonUpdatableFlash\n"));
1325 This notification function is invoked when an instance of the
1326 EFI_DEVICE_PATH_PROTOCOL is produced.
1328 @param Event The event that occured
1329 @param Context For EFI compatiblity. Not used.
1342 EFI_DEVICE_PATH_PROTOCOL
*DevPathNode
;
1343 ATAPI_DEVICE_PATH
*Atapi
;
1346 // Examine all new handles
1350 // Get the next handle
1352 BufferSize
= sizeof (Handle
);
1353 Status
= gBS
->LocateHandle (
1356 mEfiDevPathNotifyReg
,
1362 // If not found, we're done
1364 if (EFI_NOT_FOUND
== Status
) {
1368 if (EFI_ERROR (Status
)) {
1373 // Get the DevicePath protocol on that handle
1375 Status
= gBS
->HandleProtocol (Handle
, &gEfiDevicePathProtocolGuid
, (VOID
**)&DevPathNode
);
1376 ASSERT_EFI_ERROR (Status
);
1378 while (!IsDevicePathEnd (DevPathNode
)) {
1380 // Find the handler to dump this device path node
1383 (DevicePathType(DevPathNode
) == MESSAGING_DEVICE_PATH
) &&
1384 (DevicePathSubType(DevPathNode
) == MSG_ATAPI_DP
)
1386 Atapi
= (ATAPI_DEVICE_PATH
*) DevPathNode
;
1392 (Atapi
->PrimarySecondary
== 1) ? 0x42: 0x40
1399 // Next device path node
1401 DevPathNode
= NextDevicePathNode (DevPathNode
);
1410 InstallDevicePathCallback (
1414 DEBUG ((EFI_D_INFO
, "Registered NotifyDevPath Event\n"));
1415 mEfiDevPathEvent
= EfiCreateProtocolNotifyEvent (
1416 &gEfiDevicePathProtocolGuid
,
1420 &mEfiDevPathNotifyReg
1425 Lock the ConsoleIn device in system table. All key
1426 presses will be ignored until the Password is typed in. The only way to
1427 disable the password is to type it in to a ConIn device.
1429 @param Password Password used to lock ConIn device.
1431 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
1432 @retval EFI_UNSUPPORTED Password not found
1441 return EFI_UNSUPPORTED
;