2 Platform BDS customizations.
4 Copyright (c) 2004 - 2009, Intel Corporation. <BR>
5 All rights reserved. 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 BOOLEAN mDetectVgaOnly
;
33 (EFIAPI
*PROTOCOL_INSTANCE_CALLBACK
)(
40 @param[in] Handle - Handle of PCI device instance
41 @param[in] PciIo - PCI IO protocol instance
42 @param[in] Pci - PCI Header register block
46 (EFIAPI
*VISIT_PCI_INSTANCE_CALLBACK
)(
48 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
54 // Function prototypes
58 VisitAllInstancesOfProtocol (
60 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction
,
65 VisitAllPciInstancesOfProtocol (
66 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
70 InstallDevicePathCallback (
82 PciRomLoadEfiDriversFromRomImage (
83 IN EFI_PHYSICAL_ADDRESS Rom
,
88 // BDS Platform Functions
99 Platform Bds init. Incude the platform firmware vendor, revision
110 DEBUG ((EFI_D_INFO
, "PlatformBdsInit\n"));
111 InstallDevicePathCallback ();
132 EFI_SUCCESS - Connect RootBridge successfully.
133 EFI_STATUS - Connect RootBridge fail.
138 EFI_HANDLE RootHandle
;
141 // Make all the PCI_IO protocols on PCI Seg 0 show up
143 BdsLibConnectDevicePath (gPlatformRootBridges
[0]);
145 Status
= gBS
->LocateDevicePath (
146 &gEfiDevicePathProtocolGuid
,
147 &gPlatformRootBridges
[0],
150 if (EFI_ERROR (Status
)) {
154 Status
= gBS
->ConnectController (RootHandle
, NULL
, NULL
, FALSE
);
155 if (EFI_ERROR (Status
)) {
164 PrepareLpcBridgeDevicePath (
165 IN EFI_HANDLE DeviceHandle
171 Add IsaKeyboard to ConIn,
172 add IsaSerial to ConOut, ConIn, ErrOut.
177 DeviceHandle - Handle of PCIIO protocol.
181 EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut.
182 EFI_STATUS - No LPC bridge is added.
187 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
188 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
192 Status
= gBS
->HandleProtocol (
194 &gEfiDevicePathProtocolGuid
,
197 if (EFI_ERROR (Status
)) {
200 TempDevicePath
= DevicePath
;
205 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnpPs2KeyboardDeviceNode
);
207 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
212 DevicePath
= TempDevicePath
;
213 gPnp16550ComPortDeviceNode
.UID
= 0;
215 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnp16550ComPortDeviceNode
);
216 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
217 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
222 DevPathStr
= DevicePathToStr(DevicePath
);
225 "BdsPlatform.c+%d: COM%d DevPath: %s\n",
227 gPnp16550ComPortDeviceNode
.UID
+ 1,
230 FreePool(DevPathStr
);
232 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
233 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
234 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
239 DevicePath
= TempDevicePath
;
240 gPnp16550ComPortDeviceNode
.UID
= 1;
242 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnp16550ComPortDeviceNode
);
243 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
244 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
249 DevPathStr
= DevicePathToStr(DevicePath
);
252 "BdsPlatform.c+%d: COM%d DevPath: %s\n",
254 gPnp16550ComPortDeviceNode
.UID
+ 1,
257 FreePool(DevPathStr
);
259 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
260 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
261 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
268 IN EFI_DEVICE_PATH_PROTOCOL
*PciDevicePath
,
269 OUT EFI_DEVICE_PATH_PROTOCOL
**GopDevicePath
274 EFI_HANDLE PciDeviceHandle
;
275 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
276 EFI_DEVICE_PATH_PROTOCOL
*TempPciDevicePath
;
277 UINTN GopHandleCount
;
278 EFI_HANDLE
*GopHandleBuffer
;
280 if (PciDevicePath
== NULL
|| GopDevicePath
== NULL
) {
281 return EFI_INVALID_PARAMETER
;
285 // Initialize the GopDevicePath to be PciDevicePath
287 *GopDevicePath
= PciDevicePath
;
288 TempPciDevicePath
= PciDevicePath
;
290 Status
= gBS
->LocateDevicePath (
291 &gEfiDevicePathProtocolGuid
,
295 if (EFI_ERROR (Status
)) {
300 // Try to connect this handle, so that GOP dirver could start on this
301 // device and create child handles with GraphicsOutput Protocol installed
302 // on them, then we get device paths of these child handles and select
303 // them as possible console device.
305 gBS
->ConnectController (PciDeviceHandle
, NULL
, NULL
, FALSE
);
307 Status
= gBS
->LocateHandleBuffer (
309 &gEfiGraphicsOutputProtocolGuid
,
314 if (!EFI_ERROR (Status
)) {
316 // Add all the child handles as possible Console Device
318 for (Index
= 0; Index
< GopHandleCount
; Index
++) {
319 Status
= gBS
->HandleProtocol (GopHandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*)&TempDevicePath
);
320 if (EFI_ERROR (Status
)) {
326 GetDevicePathSize (PciDevicePath
) - END_DEVICE_PATH_LENGTH
329 // In current implementation, we only enable one of the child handles
330 // as console device, i.e. sotre one of the child handle's device
331 // path to variable "ConOut"
332 // In futhure, we could select all child handles to be console device
335 *GopDevicePath
= TempDevicePath
;
338 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()
339 // Add the integrity GOP device path.
341 BdsLibUpdateConsoleVariable (VarConsoleOutDev
, NULL
, PciDevicePath
);
342 BdsLibUpdateConsoleVariable (VarConsoleOutDev
, TempDevicePath
, NULL
);
345 gBS
->FreePool (GopHandleBuffer
);
352 PreparePciVgaDevicePath (
353 IN EFI_HANDLE DeviceHandle
359 Add PCI VGA to ConOut.
364 DeviceHandle - Handle of PCIIO protocol.
368 EFI_SUCCESS - PCI VGA is added to ConOut.
369 EFI_STATUS - No PCI VGA device is added.
374 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
375 EFI_DEVICE_PATH_PROTOCOL
*GopDevicePath
;
378 Status
= gBS
->HandleProtocol (
380 &gEfiDevicePathProtocolGuid
,
383 if (EFI_ERROR (Status
)) {
387 GetGopDevicePath (DevicePath
, &GopDevicePath
);
388 DevicePath
= GopDevicePath
;
390 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
396 PreparePciSerialDevicePath (
397 IN EFI_HANDLE DeviceHandle
403 Add PCI Serial to ConOut, ConIn, ErrOut.
408 DeviceHandle - Handle of PCIIO protocol.
412 EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.
413 EFI_STATUS - No PCI Serial device is added.
418 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
421 Status
= gBS
->HandleProtocol (
423 &gEfiDevicePathProtocolGuid
,
426 if (EFI_ERROR (Status
)) {
430 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
431 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
433 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
434 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
435 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
441 VisitAllInstancesOfProtocol (
443 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction
,
449 EFI_HANDLE
*HandleBuffer
;
454 // Start to check all the PciIo to find all possible device
458 Status
= gBS
->LocateHandleBuffer (
465 if (EFI_ERROR (Status
)) {
469 for (Index
= 0; Index
< HandleCount
; Index
++) {
470 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], Id
, &Instance
);
471 if (EFI_ERROR (Status
)) {
475 Status
= (*CallBackFunction
) (
482 gBS
->FreePool (HandleBuffer
);
490 VisitingAPciInstance (
491 IN EFI_HANDLE Handle
,
497 EFI_PCI_IO_PROTOCOL
*PciIo
;
500 PciIo
= (EFI_PCI_IO_PROTOCOL
*) Instance
;
503 // Check for all PCI device
505 Status
= PciIo
->Pci
.Read (
509 sizeof (Pci
) / sizeof (UINT32
),
512 if (EFI_ERROR (Status
)) {
516 return (*(VISIT_PCI_INSTANCE_CALLBACK
)(UINTN
) Context
) (
527 VisitAllPciInstances (
528 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
531 return VisitAllInstancesOfProtocol (
532 &gEfiPciIoProtocolGuid
,
533 VisitingAPciInstance
,
534 (VOID
*)(UINTN
) CallBackFunction
540 Do platform specific PCI Device check and add them to
541 ConOut, ConIn, ErrOut.
543 @param[in] Handle - Handle of PCI device instance
544 @param[in] PciIo - PCI IO protocol instance
545 @param[in] Pci - PCI Header register block
547 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
548 @retval EFI_STATUS - PCI Device check or Console variable update fail.
552 DetectAndPreparePlatformPciDevicePath (
553 IN EFI_HANDLE Handle
,
554 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
560 Status
= PciIo
->Attributes (
562 EfiPciIoAttributeOperationEnable
,
563 EFI_PCI_DEVICE_ENABLE
,
566 ASSERT_EFI_ERROR (Status
);
568 if (!mDetectVgaOnly
) {
570 // Here we decide whether it is LPC Bridge
572 if ((IS_PCI_LPC (Pci
)) ||
573 ((IS_PCI_ISA_PDECODE (Pci
)) &&
574 (Pci
->Hdr
.VendorId
== 0x8086) &&
575 (Pci
->Hdr
.DeviceId
== 0x7000)
579 // Add IsaKeyboard to ConIn,
580 // add IsaSerial to ConOut, ConIn, ErrOut
582 DEBUG ((EFI_D_INFO
, "Found LPC Bridge device\n"));
583 PrepareLpcBridgeDevicePath (Handle
);
587 // Here we decide which Serial device to enable in PCI bus
589 if (IS_PCI_16550SERIAL (Pci
)) {
591 // Add them to ConOut, ConIn, ErrOut.
593 DEBUG ((EFI_D_INFO
, "Found PCI 16550 SERIAL device\n"));
594 PreparePciSerialDevicePath (Handle
);
600 // Here we decide which VGA device to enable in PCI bus
602 if (IS_PCI_VGA (Pci
)) {
604 // Add them to ConOut.
606 DEBUG ((EFI_D_INFO
, "Found PCI VGA device\n"));
607 PreparePciVgaDevicePath (Handle
);
616 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
618 @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.
620 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
621 @retval EFI_STATUS - PCI Device check or Console variable update fail.
625 DetectAndPreparePlatformPciDevicePaths (
626 BOOLEAN DetectVgaOnly
629 mDetectVgaOnly
= DetectVgaOnly
;
630 return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath
);
635 PlatformBdsConnectConsole (
636 IN BDS_CONSOLE_CONNECT_ENTRY
*PlatformConsole
642 Connect the predefined platform default console device. Always try to find
643 and enable the vga device if have.
647 PlatformConsole - Predfined platform default console device array.
651 EFI_SUCCESS - Success connect at least one ConIn and ConOut
652 device, there must have one ConOut device is
655 EFI_STATUS - Return the status of
656 BdsLibConnectAllDefaultConsoles ()
662 EFI_DEVICE_PATH_PROTOCOL
*VarConout
;
663 EFI_DEVICE_PATH_PROTOCOL
*VarConin
;
664 UINTN DevicePathSize
;
667 // Connect RootBridge
669 VarConout
= BdsLibGetVariableAndSize (
671 &gEfiGlobalVariableGuid
,
674 VarConin
= BdsLibGetVariableAndSize (
676 &gEfiGlobalVariableGuid
,
680 if (VarConout
== NULL
|| VarConin
== NULL
) {
682 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
684 DetectAndPreparePlatformPciDevicePaths (FALSE
);
687 // Have chance to connect the platform default console,
688 // the platform default console is the minimue device group
689 // the platform should support
691 for (Index
= 0; PlatformConsole
[Index
].DevicePath
!= NULL
; ++Index
) {
693 // Update the console variable with the connect type
695 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
696 BdsLibUpdateConsoleVariable (VarConsoleInp
, PlatformConsole
[Index
].DevicePath
, NULL
);
698 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
699 BdsLibUpdateConsoleVariable (VarConsoleOut
, PlatformConsole
[Index
].DevicePath
, NULL
);
701 if ((PlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
702 BdsLibUpdateConsoleVariable (VarErrorOut
, PlatformConsole
[Index
].DevicePath
, NULL
);
707 // Only detect VGA device and add them to ConOut
709 DetectAndPreparePlatformPciDevicePaths (TRUE
);
713 // Connect the all the default console with current cosole variable
715 Status
= BdsLibConnectAllDefaultConsoles ();
716 if (EFI_ERROR (Status
)) {
729 // Bus 0, Device 0, Function 0 - Host to PCI Bridge
731 PciWrite8 (PCI_LIB_ADDRESS (0, 0, 0, 0x3c), 0x00);
734 // Bus 0, Device 1, Function 0 - PCI to ISA Bridge
736 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x3c), 0x00);
737 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b);
738 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x09);
739 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0b);
740 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x09);
743 // Bus 0, Device 1, Function 1 - IDE Controller
745 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x3c), 0x00);
746 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x0d), 0x40);
749 // Bus 0, Device 1, Function 3 - Power Managment Controller
751 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3c), 0x0b);
752 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3d), 0x01);
755 // Bus 0, Device 2, Function 0 - Video Controller
757 PciWrite8 (PCI_LIB_ADDRESS (0, 2, 0, 0x3c), 0x00);
760 // Bus 0, Device 3, Function 0 - Network Controller
762 PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3c), 0x0b);
763 PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3d), 0x01);
766 // Bus 0, Device 4, Function 0 - RAM Memory
768 PciWrite8 (PCI_LIB_ADDRESS (0, 4, 0, 0x3c), 0x09);
769 PciWrite8 (PCI_LIB_ADDRESS (0, 4, 0, 0x3d), 0x01);
775 ConnectRecursivelyIfPciMassStorage (
776 IN EFI_HANDLE Handle
,
777 IN EFI_PCI_IO_PROTOCOL
*Instance
,
778 IN PCI_TYPE00
*PciHeader
782 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
785 if (IS_CLASS1 (PciHeader
, PCI_CLASS_MASS_STORAGE
)) {
787 Status
= gBS
->HandleProtocol (
789 &gEfiDevicePathProtocolGuid
,
792 if (EFI_ERROR (Status
)) {
799 DevPathStr
= DevicePathToStr (DevicePath
);
802 "Found Mass Storage device: %s\n",
805 FreePool(DevPathStr
);
807 Status
= gBS
->ConnectController (Handle
, NULL
, NULL
, TRUE
);
808 if (EFI_ERROR (Status
)) {
820 VisitingFileSystemInstance (
821 IN EFI_HANDLE Handle
,
827 STATIC BOOLEAN ConnectedToFileSystem
= FALSE
;
829 if (ConnectedToFileSystem
) {
830 return EFI_ALREADY_STARTED
;
833 Status
= ConnectNvVarsToFileSystem (Handle
);
834 if (EFI_ERROR (Status
)) {
838 ConnectedToFileSystem
= TRUE
;
844 PlatformBdsRestoreNvVarsFromHardDisk (
847 VisitAllPciInstances (ConnectRecursivelyIfPciMassStorage
);
848 VisitAllInstancesOfProtocol (
849 &gEfiSimpleFileSystemProtocolGuid
,
850 VisitingFileSystemInstance
,
858 PlatformBdsConnectSequence (
865 Connect with predeined platform connect sequence,
866 the OEM/IBV can customize with their own connect sequence.
880 DEBUG ((EFI_D_INFO
, "PlatformBdsConnectSequence\n"));
885 // Here we can get the customized platform connect sequence
886 // Notes: we can connect with new variable which record the
887 // last time boots connect device path sequence
889 while (gPlatformConnectSequence
[Index
] != NULL
) {
891 // Build the platform boot option
893 BdsLibConnectDevicePath (gPlatformConnectSequence
[Index
]);
898 // Just use the simple policy to connect all devices
902 PciInitialization ();
905 // Clear the logo after all devices are connected.
907 gST
->ConOut
->ClearScreen (gST
->ConOut
);
911 PlatformBdsGetDriverOption (
912 IN OUT LIST_ENTRY
*BdsDriverLists
918 Load the predefined driver option, OEM/IBV can customize this
919 to load their own drivers
923 BdsDriverLists - The header of the driver option link list.
931 DEBUG ((EFI_D_INFO
, "PlatformBdsGetDriverOption\n"));
936 PlatformBdsDiagnostics (
937 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel
,
938 IN BOOLEAN QuietBoot
,
939 IN BASEM_MEMORY_TEST BaseMemoryTest
945 Perform the platform diagnostic, such like test memory. OEM/IBV also
946 can customize this fuction to support specific platform diagnostic.
950 MemoryTestLevel - The memory test intensive level
952 QuietBoot - Indicate if need to enable the quiet boot
954 BaseMemoryTest - A pointer to BaseMemoryTest()
964 DEBUG ((EFI_D_INFO
, "PlatformBdsDiagnostics\n"));
967 // Here we can decide if we need to show
968 // the diagnostics screen
969 // Notes: this quiet boot code should be remove
970 // from the graphic lib
973 EnableQuietBoot (PcdGetPtr(PcdLogoFile
));
975 // Perform system diagnostic
977 Status
= BaseMemoryTest (MemoryTestLevel
);
978 if (EFI_ERROR (Status
)) {
985 // Perform system diagnostic
987 Status
= BaseMemoryTest (MemoryTestLevel
);
993 PlatformBdsPolicyBehavior (
994 IN OUT LIST_ENTRY
*DriverOptionList
,
995 IN OUT LIST_ENTRY
*BootOptionList
,
996 IN PROCESS_CAPSULES ProcessCapsules
,
997 IN BASEM_MEMORY_TEST BaseMemoryTest
1001 Routine Description:
1003 The function will excute with as the platform policy, current policy
1004 is driven by boot mode. IBV/OEM can customize this code for their specific
1009 DriverOptionList - The header of the driver option link list
1011 BootOptionList - The header of the boot option link list
1013 ProcessCapsules - A pointer to ProcessCapsules()
1015 BaseMemoryTest - A pointer to BaseMemoryTest()
1025 EFI_EVENT UserInputDurationTime
;
1027 BDS_COMMON_OPTION
*BootOption
;
1031 EFI_BOOT_MODE BootMode
;
1033 DEBUG ((EFI_D_INFO
, "PlatformBdsPolicyBehavior\n"));
1035 ConnectRootBridge ();
1038 // Try to restore variables from the hard disk early so
1039 // they can be used for the other BDS connect operations.
1041 PlatformBdsRestoreNvVarsFromHardDisk ();
1044 // Init the time out value
1046 Timeout
= PcdGet16 (PcdPlatformBootTimeOut
);
1049 // Load the driver option as the driver option list
1051 PlatformBdsGetDriverOption (DriverOptionList
);
1054 // Get current Boot Mode
1056 Status
= BdsLibGetBootMode (&BootMode
);
1057 DEBUG ((EFI_D_ERROR
, "Boot Mode:%x\n", BootMode
));
1060 // Go the different platform policy with different boot mode
1061 // Notes: this part code can be change with the table policy
1063 ASSERT (BootMode
== BOOT_WITH_FULL_CONFIGURATION
);
1065 // Connect platform console
1067 Status
= PlatformBdsConnectConsole (gPlatformConsole
);
1068 if (EFI_ERROR (Status
)) {
1070 // Here OEM/IBV can customize with defined action
1072 PlatformBdsNoConsoleAction ();
1075 // Create a 300ms duration event to ensure user has enough input time to enter Setup
1077 Status
= gBS
->CreateEvent (
1082 &UserInputDurationTime
1084 ASSERT (Status
== EFI_SUCCESS
);
1085 Status
= gBS
->SetTimer (UserInputDurationTime
, TimerRelative
, 3000000);
1086 ASSERT (Status
== EFI_SUCCESS
);
1088 // Memory test and Logo show
1090 PlatformBdsDiagnostics (IGNORE
, TRUE
, BaseMemoryTest
);
1093 // Perform some platform specific connect sequence
1095 PlatformBdsConnectSequence ();
1098 // Give one chance to enter the setup if we
1099 // have the time out
1102 //PlatformBdsEnterFrontPage (Timeout, FALSE);
1105 DEBUG ((EFI_D_INFO
, "BdsLibConnectAll\n"));
1106 BdsLibConnectAll ();
1107 BdsLibEnumerateAllBootOption (BootOptionList
);
1110 // Please uncomment above ConnectAll and EnumerateAll code and remove following first boot
1111 // checking code in real production tip.
1113 // In BOOT_WITH_FULL_CONFIGURATION boot mode, should always connect every device
1114 // and do enumerate all the default boot options. But in development system board, the boot mode
1115 // cannot be BOOT_ASSUMING_NO_CONFIGURATION_CHANGES because the machine box
1116 // is always open. So the following code only do the ConnectAll and EnumerateAll at first boot.
1118 Status
= BdsLibBuildOptionFromVar (BootOptionList
, L
"BootOrder");
1119 if (EFI_ERROR(Status
)) {
1121 // If cannot find "BootOrder" variable, it may be first boot.
1122 // Try to connect all devices and enumerate all boot options here.
1124 BdsLibConnectAll ();
1125 BdsLibEnumerateAllBootOption (BootOptionList
);
1129 // To give the User a chance to enter Setup here, if user set TimeOut is 0.
1130 // BDS should still give user a chance to enter Setup
1132 // Connect first boot option, and then check user input before exit
1134 for (Link
= BootOptionList
->ForwardLink
; Link
!= BootOptionList
;Link
= Link
->ForwardLink
) {
1135 BootOption
= CR (Link
, BDS_COMMON_OPTION
, Link
, BDS_LOAD_OPTION_SIGNATURE
);
1136 if (!IS_LOAD_OPTION_TYPE (BootOption
->Attribute
, LOAD_OPTION_ACTIVE
)) {
1138 // skip the header of the link list, becuase it has no boot option
1143 // Make sure the boot option device path connected, but ignore the BBS device path
1145 if (DevicePathType (BootOption
->DevicePath
) != BBS_DEVICE_PATH
) {
1146 BdsLibConnectDevicePath (BootOption
->DevicePath
);
1153 // Check whether the user input after the duration time has expired
1155 OldTpl
= EfiGetCurrentTpl();
1156 gBS
->RestoreTPL (TPL_APPLICATION
);
1157 gBS
->WaitForEvent (1, &UserInputDurationTime
, &Index
);
1158 gBS
->CloseEvent (UserInputDurationTime
);
1159 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
1160 gBS
->RaiseTPL (OldTpl
);
1162 if (!EFI_ERROR (Status
)) {
1164 // Enter Setup if user input
1167 PlatformBdsEnterFrontPage (Timeout
, FALSE
);
1175 PlatformBdsBootSuccess (
1176 IN BDS_COMMON_OPTION
*Option
1180 Routine Description:
1182 Hook point after a boot attempt succeeds. We don't expect a boot option to
1183 return, so the EFI 1.0 specification defines that you will default to an
1184 interactive mode and stop processing the BootOrder list in this case. This
1185 is alos a platform implementation and can be customized by IBV/OEM.
1189 Option - Pointer to Boot Option that succeeded to boot.
1199 DEBUG ((EFI_D_INFO
, "PlatformBdsBootSuccess\n"));
1201 // If Boot returned with EFI_SUCCESS and there is not in the boot device
1202 // select loop then we need to pop up a UI and wait for user input.
1204 TmpStr
= Option
->StatusString
;
1205 if (TmpStr
!= NULL
) {
1206 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
1213 PlatformBdsBootFail (
1214 IN BDS_COMMON_OPTION
*Option
,
1215 IN EFI_STATUS Status
,
1216 IN CHAR16
*ExitData
,
1217 IN UINTN ExitDataSize
1221 Routine Description:
1223 Hook point after a boot attempt fails.
1227 Option - Pointer to Boot Option that failed to boot.
1229 Status - Status returned from failed boot.
1231 ExitData - Exit data returned from failed boot.
1233 ExitDataSize - Exit data size returned from failed boot.
1243 DEBUG ((EFI_D_INFO
, "PlatformBdsBootFail\n"));
1246 // If Boot returned with failed status then we need to pop up a UI and wait
1249 TmpStr
= Option
->StatusString
;
1250 if (TmpStr
!= NULL
) {
1251 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
1257 PlatformBdsNoConsoleAction (
1262 Routine Description:
1264 This function is remained for IBV/OEM to do some platform action,
1265 if there no console device can be connected.
1273 EFI_SUCCESS - Direct return success now.
1277 DEBUG ((EFI_D_INFO
, "PlatformBdsNoConsoleAction\n"));
1283 PlatformBdsLockNonUpdatableFlash (
1287 DEBUG ((EFI_D_INFO
, "PlatformBdsLockNonUpdatableFlash\n"));
1293 This notification function is invoked when an instance of the
1294 EFI_DEVICE_PATH_PROTOCOL is produced.
1296 @param Event The event that occured
1297 @param Context For EFI compatiblity. Not used.
1310 EFI_DEVICE_PATH_PROTOCOL
*DevPathNode
;
1311 ATAPI_DEVICE_PATH
*Atapi
;
1314 // Examine all new handles
1318 // Get the next handle
1320 BufferSize
= sizeof (Handle
);
1321 Status
= gBS
->LocateHandle (
1324 mEfiDevPathNotifyReg
,
1330 // If not found, we're done
1332 if (EFI_NOT_FOUND
== Status
) {
1336 if (EFI_ERROR (Status
)) {
1341 // Get the DevicePath protocol on that handle
1343 Status
= gBS
->HandleProtocol (Handle
, &gEfiDevicePathProtocolGuid
, (VOID
**)&DevPathNode
);
1344 ASSERT_EFI_ERROR (Status
);
1346 while (!IsDevicePathEnd (DevPathNode
)) {
1348 // Find the handler to dump this device path node
1351 (DevicePathType(DevPathNode
) == MESSAGING_DEVICE_PATH
) &&
1352 (DevicePathSubType(DevPathNode
) == MSG_ATAPI_DP
)
1354 Atapi
= (ATAPI_DEVICE_PATH
*) DevPathNode
;
1360 (Atapi
->PrimarySecondary
== 1) ? 0x42: 0x40
1367 // Next device path node
1369 DevPathNode
= NextDevicePathNode (DevPathNode
);
1378 InstallDevicePathCallback (
1382 DEBUG ((EFI_D_INFO
, "Registered NotifyDevPath Event\n"));
1383 mEfiDevPathEvent
= EfiCreateProtocolNotifyEvent (
1384 &gEfiDevicePathProtocolGuid
,
1388 &mEfiDevPathNotifyReg
1393 Lock the ConsoleIn device in system table. All key
1394 presses will be ignored until the Password is typed in. The only way to
1395 disable the password is to type it in to a ConIn device.
1397 @param Password Password used to lock ConIn device.
1399 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
1400 @retval EFI_UNSUPPORTED Password not found
1409 return EFI_UNSUPPORTED
;
1419 PCI_DATA_STRUCTURE
*Pcir
;
1423 // The virtual machines sometimes load the video rom image
1424 // directly at the legacy video BIOS location of C000:0000,
1425 // and do not implement the PCI expansion ROM feature.
1427 Pcir
= (PCI_DATA_STRUCTURE
*) (UINTN
) 0xc0000;
1428 RomSize
= Pcir
->ImageLength
* 512;
1429 PciRomLoadEfiDriversFromRomImage (0xc0000, RomSize
);
1435 PciRomLoadEfiDriversFromRomImage (
1436 IN EFI_PHYSICAL_ADDRESS Rom
,
1441 EFI_PCI_EXPANSION_ROM_HEADER
*EfiRomHeader
;
1442 PCI_DATA_STRUCTURE
*Pcir
;
1447 EFI_HANDLE ImageHandle
;
1449 EFI_STATUS retStatus
;
1450 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
1452 UINT32 DestinationSize
;
1456 VOID
*DecompressedImageBuffer
;
1458 EFI_DECOMPRESS_PROTOCOL
*Decompress
;
1460 FileName
= L
"PciRomInMemory";
1462 //FileName = L"PciRom Addr=0000000000000000";
1463 //HexToString (&FileName[12], Rom, 16);
1466 retStatus
= EFI_NOT_FOUND
;
1467 RomOffset
= (UINTN
) Rom
;
1471 EfiRomHeader
= (EFI_PCI_EXPANSION_ROM_HEADER
*) (UINTN
) RomOffset
;
1473 if (EfiRomHeader
->Signature
!= 0xaa55) {
1477 Pcir
= (PCI_DATA_STRUCTURE
*) (UINTN
) (RomOffset
+ EfiRomHeader
->PcirOffset
);
1478 ImageSize
= Pcir
->ImageLength
* 512;
1480 if ((Pcir
->CodeType
== PCI_CODE_TYPE_EFI_IMAGE
) &&
1481 (EfiRomHeader
->EfiSignature
== EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE
) ) {
1483 if ((EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
) ||
1484 (EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
) ) {
1486 ImageOffset
= EfiRomHeader
->EfiImageHeaderOffset
;
1487 ImageSize
= EfiRomHeader
->InitializationSize
* 512;
1489 ImageBuffer
= (VOID
*) (UINTN
) (RomOffset
+ ImageOffset
);
1490 ImageLength
= ImageSize
- ImageOffset
;
1491 DecompressedImageBuffer
= NULL
;
1494 // decompress here if needed
1497 if (EfiRomHeader
->CompressionType
> EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
1501 if (EfiRomHeader
->CompressionType
== EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
1502 Status
= gBS
->LocateProtocol (&gEfiDecompressProtocolGuid
, NULL
, (VOID
**) &Decompress
);
1503 if (EFI_ERROR (Status
)) {
1507 Status
= Decompress
->GetInfo (
1514 if (!EFI_ERROR (Status
)) {
1515 DecompressedImageBuffer
= NULL
;
1516 DecompressedImageBuffer
= AllocatePool (DestinationSize
);
1517 if (DecompressedImageBuffer
!= NULL
) {
1518 Scratch
= AllocatePool (ScratchSize
);
1519 if (Scratch
!= NULL
) {
1520 Status
= Decompress
->Decompress (
1524 DecompressedImageBuffer
,
1529 if (!EFI_ERROR (Status
)) {
1530 ImageBuffer
= DecompressedImageBuffer
;
1531 ImageLength
= DestinationSize
;
1535 gBS
->FreePool (Scratch
);
1545 // load image and start image
1548 FilePath
= FileDevicePath (NULL
, FileName
);
1550 Status
= gBS
->LoadImage (
1558 if (!EFI_ERROR (Status
)) {
1559 Status
= gBS
->StartImage (ImageHandle
, NULL
, NULL
);
1560 if (!EFI_ERROR (Status
)) {
1564 if (FilePath
!= NULL
) {
1565 gBS
->FreePool (FilePath
);
1569 if (DecompressedImageBuffer
!= NULL
) {
1570 gBS
->FreePool (DecompressedImageBuffer
);
1576 RomOffset
= RomOffset
+ ImageSize
;
1578 } while (((Pcir
->Indicator
& 0x80) == 0x00) && ((RomOffset
- (UINTN
) Rom
) < RomSize
));