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 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 (
84 PciRomLoadEfiDriversFromRomImage (
85 IN EFI_PHYSICAL_ADDRESS Rom
,
90 // BDS Platform Functions
101 Platform Bds init. Incude the platform firmware vendor, revision
112 DEBUG ((EFI_D_INFO
, "PlatformBdsInit\n"));
113 InstallDevicePathCallback ();
134 EFI_SUCCESS - Connect RootBridge successfully.
135 EFI_STATUS - Connect RootBridge fail.
140 EFI_HANDLE RootHandle
;
143 // Make all the PCI_IO protocols on PCI Seg 0 show up
145 BdsLibConnectDevicePath (gPlatformRootBridges
[0]);
147 Status
= gBS
->LocateDevicePath (
148 &gEfiDevicePathProtocolGuid
,
149 &gPlatformRootBridges
[0],
152 if (EFI_ERROR (Status
)) {
156 Status
= gBS
->ConnectController (RootHandle
, NULL
, NULL
, FALSE
);
157 if (EFI_ERROR (Status
)) {
166 PrepareLpcBridgeDevicePath (
167 IN EFI_HANDLE DeviceHandle
173 Add IsaKeyboard to ConIn,
174 add IsaSerial to ConOut, ConIn, ErrOut.
179 DeviceHandle - Handle of PCIIO protocol.
183 EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut.
184 EFI_STATUS - No LPC bridge is added.
189 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
190 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
194 Status
= gBS
->HandleProtocol (
196 &gEfiDevicePathProtocolGuid
,
199 if (EFI_ERROR (Status
)) {
202 TempDevicePath
= DevicePath
;
207 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnpPs2KeyboardDeviceNode
);
209 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
214 DevicePath
= TempDevicePath
;
215 gPnp16550ComPortDeviceNode
.UID
= 0;
217 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnp16550ComPortDeviceNode
);
218 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
219 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
224 DevPathStr
= DevicePathToStr(DevicePath
);
227 "BdsPlatform.c+%d: COM%d DevPath: %s\n",
229 gPnp16550ComPortDeviceNode
.UID
+ 1,
232 FreePool(DevPathStr
);
234 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
235 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
236 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
241 DevicePath
= TempDevicePath
;
242 gPnp16550ComPortDeviceNode
.UID
= 1;
244 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnp16550ComPortDeviceNode
);
245 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
246 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
251 DevPathStr
= DevicePathToStr(DevicePath
);
254 "BdsPlatform.c+%d: COM%d DevPath: %s\n",
256 gPnp16550ComPortDeviceNode
.UID
+ 1,
259 FreePool(DevPathStr
);
261 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
262 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
263 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
270 IN EFI_DEVICE_PATH_PROTOCOL
*PciDevicePath
,
271 OUT EFI_DEVICE_PATH_PROTOCOL
**GopDevicePath
276 EFI_HANDLE PciDeviceHandle
;
277 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
278 EFI_DEVICE_PATH_PROTOCOL
*TempPciDevicePath
;
279 UINTN GopHandleCount
;
280 EFI_HANDLE
*GopHandleBuffer
;
282 if (PciDevicePath
== NULL
|| GopDevicePath
== NULL
) {
283 return EFI_INVALID_PARAMETER
;
287 // Initialize the GopDevicePath to be PciDevicePath
289 *GopDevicePath
= PciDevicePath
;
290 TempPciDevicePath
= PciDevicePath
;
292 Status
= gBS
->LocateDevicePath (
293 &gEfiDevicePathProtocolGuid
,
297 if (EFI_ERROR (Status
)) {
302 // Try to connect this handle, so that GOP dirver could start on this
303 // device and create child handles with GraphicsOutput Protocol installed
304 // on them, then we get device paths of these child handles and select
305 // them as possible console device.
307 gBS
->ConnectController (PciDeviceHandle
, NULL
, NULL
, FALSE
);
309 Status
= gBS
->LocateHandleBuffer (
311 &gEfiGraphicsOutputProtocolGuid
,
316 if (!EFI_ERROR (Status
)) {
318 // Add all the child handles as possible Console Device
320 for (Index
= 0; Index
< GopHandleCount
; Index
++) {
321 Status
= gBS
->HandleProtocol (GopHandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*)&TempDevicePath
);
322 if (EFI_ERROR (Status
)) {
328 GetDevicePathSize (PciDevicePath
) - END_DEVICE_PATH_LENGTH
331 // In current implementation, we only enable one of the child handles
332 // as console device, i.e. sotre one of the child handle's device
333 // path to variable "ConOut"
334 // In futhure, we could select all child handles to be console device
337 *GopDevicePath
= TempDevicePath
;
340 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()
341 // Add the integrity GOP device path.
343 BdsLibUpdateConsoleVariable (VarConsoleOutDev
, NULL
, PciDevicePath
);
344 BdsLibUpdateConsoleVariable (VarConsoleOutDev
, TempDevicePath
, NULL
);
347 gBS
->FreePool (GopHandleBuffer
);
354 PreparePciVgaDevicePath (
355 IN EFI_HANDLE DeviceHandle
361 Add PCI VGA to ConOut.
366 DeviceHandle - Handle of PCIIO protocol.
370 EFI_SUCCESS - PCI VGA is added to ConOut.
371 EFI_STATUS - No PCI VGA device is added.
376 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
377 EFI_DEVICE_PATH_PROTOCOL
*GopDevicePath
;
380 Status
= gBS
->HandleProtocol (
382 &gEfiDevicePathProtocolGuid
,
385 if (EFI_ERROR (Status
)) {
389 GetGopDevicePath (DevicePath
, &GopDevicePath
);
390 DevicePath
= GopDevicePath
;
392 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
398 PreparePciSerialDevicePath (
399 IN EFI_HANDLE DeviceHandle
405 Add PCI Serial to ConOut, ConIn, ErrOut.
410 DeviceHandle - Handle of PCIIO protocol.
414 EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.
415 EFI_STATUS - No PCI Serial device is added.
420 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
423 Status
= gBS
->HandleProtocol (
425 &gEfiDevicePathProtocolGuid
,
428 if (EFI_ERROR (Status
)) {
432 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
433 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
435 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
436 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
437 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
443 VisitAllInstancesOfProtocol (
445 IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction
,
451 EFI_HANDLE
*HandleBuffer
;
456 // Start to check all the PciIo to find all possible device
460 Status
= gBS
->LocateHandleBuffer (
467 if (EFI_ERROR (Status
)) {
471 for (Index
= 0; Index
< HandleCount
; Index
++) {
472 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], Id
, &Instance
);
473 if (EFI_ERROR (Status
)) {
477 Status
= (*CallBackFunction
) (
484 gBS
->FreePool (HandleBuffer
);
492 VisitingAPciInstance (
493 IN EFI_HANDLE Handle
,
499 EFI_PCI_IO_PROTOCOL
*PciIo
;
502 PciIo
= (EFI_PCI_IO_PROTOCOL
*) Instance
;
505 // Check for all PCI device
507 Status
= PciIo
->Pci
.Read (
511 sizeof (Pci
) / sizeof (UINT32
),
514 if (EFI_ERROR (Status
)) {
518 return (*(VISIT_PCI_INSTANCE_CALLBACK
)(UINTN
) Context
) (
529 VisitAllPciInstances (
530 IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
533 return VisitAllInstancesOfProtocol (
534 &gEfiPciIoProtocolGuid
,
535 VisitingAPciInstance
,
536 (VOID
*)(UINTN
) CallBackFunction
542 Do platform specific PCI Device check and add them to
543 ConOut, ConIn, ErrOut.
545 @param[in] Handle - Handle of PCI device instance
546 @param[in] PciIo - PCI IO protocol instance
547 @param[in] Pci - PCI Header register block
549 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
550 @retval EFI_STATUS - PCI Device check or Console variable update fail.
554 DetectAndPreparePlatformPciDevicePath (
555 IN EFI_HANDLE Handle
,
556 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
562 Status
= PciIo
->Attributes (
564 EfiPciIoAttributeOperationEnable
,
565 EFI_PCI_DEVICE_ENABLE
,
568 ASSERT_EFI_ERROR (Status
);
570 if (!mDetectVgaOnly
) {
572 // Here we decide whether it is LPC Bridge
574 if ((IS_PCI_LPC (Pci
)) ||
575 ((IS_PCI_ISA_PDECODE (Pci
)) &&
576 (Pci
->Hdr
.VendorId
== 0x8086) &&
577 (Pci
->Hdr
.DeviceId
== 0x7000)
581 // Add IsaKeyboard to ConIn,
582 // add IsaSerial to ConOut, ConIn, ErrOut
584 DEBUG ((EFI_D_INFO
, "Found LPC Bridge device\n"));
585 PrepareLpcBridgeDevicePath (Handle
);
589 // Here we decide which Serial device to enable in PCI bus
591 if (IS_PCI_16550SERIAL (Pci
)) {
593 // Add them to ConOut, ConIn, ErrOut.
595 DEBUG ((EFI_D_INFO
, "Found PCI 16550 SERIAL device\n"));
596 PreparePciSerialDevicePath (Handle
);
602 // Here we decide which VGA device to enable in PCI bus
604 if (IS_PCI_VGA (Pci
)) {
606 // Add them to ConOut.
608 DEBUG ((EFI_D_INFO
, "Found PCI VGA device\n"));
609 PreparePciVgaDevicePath (Handle
);
618 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
620 @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.
622 @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
623 @retval EFI_STATUS - PCI Device check or Console variable update fail.
627 DetectAndPreparePlatformPciDevicePaths (
628 BOOLEAN DetectVgaOnly
631 mDetectVgaOnly
= DetectVgaOnly
;
632 return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath
);
637 PlatformBdsConnectConsole (
638 IN BDS_CONSOLE_CONNECT_ENTRY
*PlatformConsole
644 Connect the predefined platform default console device. Always try to find
645 and enable the vga device if have.
649 PlatformConsole - Predfined platform default console device array.
653 EFI_SUCCESS - Success connect at least one ConIn and ConOut
654 device, there must have one ConOut device is
657 EFI_STATUS - Return the status of
658 BdsLibConnectAllDefaultConsoles ()
664 EFI_DEVICE_PATH_PROTOCOL
*VarConout
;
665 EFI_DEVICE_PATH_PROTOCOL
*VarConin
;
666 UINTN DevicePathSize
;
669 // Connect RootBridge
671 VarConout
= BdsLibGetVariableAndSize (
673 &gEfiGlobalVariableGuid
,
676 VarConin
= BdsLibGetVariableAndSize (
678 &gEfiGlobalVariableGuid
,
682 if (VarConout
== NULL
|| VarConin
== NULL
) {
684 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
686 DetectAndPreparePlatformPciDevicePaths (FALSE
);
689 // Have chance to connect the platform default console,
690 // the platform default console is the minimue device group
691 // the platform should support
693 for (Index
= 0; PlatformConsole
[Index
].DevicePath
!= NULL
; ++Index
) {
695 // Update the console variable with the connect type
697 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
698 BdsLibUpdateConsoleVariable (VarConsoleInp
, PlatformConsole
[Index
].DevicePath
, NULL
);
700 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
701 BdsLibUpdateConsoleVariable (VarConsoleOut
, PlatformConsole
[Index
].DevicePath
, NULL
);
703 if ((PlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
704 BdsLibUpdateConsoleVariable (VarErrorOut
, PlatformConsole
[Index
].DevicePath
, NULL
);
709 // Only detect VGA device and add them to ConOut
711 DetectAndPreparePlatformPciDevicePaths (TRUE
);
715 // Connect the all the default console with current cosole variable
717 Status
= BdsLibConnectAllDefaultConsoles ();
718 if (EFI_ERROR (Status
)) {
731 // Bus 0, Device 0, Function 0 - Host to PCI Bridge
733 PciWrite8 (PCI_LIB_ADDRESS (0, 0, 0, 0x3c), 0x00);
736 // Bus 0, Device 1, Function 0 - PCI to ISA Bridge
738 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x3c), 0x00);
739 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b);
740 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x09);
741 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0b);
742 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x09);
745 // Bus 0, Device 1, Function 1 - IDE Controller
747 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x3c), 0x00);
748 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x0d), 0x40);
751 // Bus 0, Device 1, Function 3 - Power Managment Controller
753 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3c), 0x0b);
754 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3d), 0x01);
757 // Bus 0, Device 2, Function 0 - Video Controller
759 PciWrite8 (PCI_LIB_ADDRESS (0, 2, 0, 0x3c), 0x00);
762 // Bus 0, Device 3, Function 0 - Network Controller
764 PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3c), 0x0b);
765 PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3d), 0x01);
768 // Bus 0, Device 4, Function 0 - RAM Memory
770 PciWrite8 (PCI_LIB_ADDRESS (0, 4, 0, 0x3c), 0x09);
771 PciWrite8 (PCI_LIB_ADDRESS (0, 4, 0, 0x3d), 0x01);
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 ();
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
;
1451 PCI_DATA_STRUCTURE
*Pcir
;
1455 // The virtual machines sometimes load the video rom image
1456 // directly at the legacy video BIOS location of C000:0000,
1457 // and do not implement the PCI expansion ROM feature.
1459 Pcir
= (PCI_DATA_STRUCTURE
*) (UINTN
) 0xc0000;
1460 RomSize
= Pcir
->ImageLength
* 512;
1461 PciRomLoadEfiDriversFromRomImage (0xc0000, RomSize
);
1467 PciRomLoadEfiDriversFromRomImage (
1468 IN EFI_PHYSICAL_ADDRESS Rom
,
1473 EFI_PCI_EXPANSION_ROM_HEADER
*EfiRomHeader
;
1474 PCI_DATA_STRUCTURE
*Pcir
;
1479 EFI_HANDLE ImageHandle
;
1481 EFI_STATUS retStatus
;
1482 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
1484 UINT32 DestinationSize
;
1488 VOID
*DecompressedImageBuffer
;
1490 EFI_DECOMPRESS_PROTOCOL
*Decompress
;
1492 FileName
= L
"PciRomInMemory";
1494 //FileName = L"PciRom Addr=0000000000000000";
1495 //HexToString (&FileName[12], Rom, 16);
1498 retStatus
= EFI_NOT_FOUND
;
1499 RomOffset
= (UINTN
) Rom
;
1503 EfiRomHeader
= (EFI_PCI_EXPANSION_ROM_HEADER
*) (UINTN
) RomOffset
;
1505 if (EfiRomHeader
->Signature
!= 0xaa55) {
1509 Pcir
= (PCI_DATA_STRUCTURE
*) (UINTN
) (RomOffset
+ EfiRomHeader
->PcirOffset
);
1510 ImageSize
= Pcir
->ImageLength
* 512;
1512 if ((Pcir
->CodeType
== PCI_CODE_TYPE_EFI_IMAGE
) &&
1513 (EfiRomHeader
->EfiSignature
== EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE
) ) {
1515 if ((EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
) ||
1516 (EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
) ) {
1518 ImageOffset
= EfiRomHeader
->EfiImageHeaderOffset
;
1519 ImageSize
= EfiRomHeader
->InitializationSize
* 512;
1521 ImageBuffer
= (VOID
*) (UINTN
) (RomOffset
+ ImageOffset
);
1522 ImageLength
= ImageSize
- ImageOffset
;
1523 DecompressedImageBuffer
= NULL
;
1526 // decompress here if needed
1529 if (EfiRomHeader
->CompressionType
> EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
1533 if (EfiRomHeader
->CompressionType
== EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
1534 Status
= gBS
->LocateProtocol (&gEfiDecompressProtocolGuid
, NULL
, (VOID
**) &Decompress
);
1535 if (EFI_ERROR (Status
)) {
1539 Status
= Decompress
->GetInfo (
1546 if (!EFI_ERROR (Status
)) {
1547 DecompressedImageBuffer
= NULL
;
1548 DecompressedImageBuffer
= AllocatePool (DestinationSize
);
1549 if (DecompressedImageBuffer
!= NULL
) {
1550 Scratch
= AllocatePool (ScratchSize
);
1551 if (Scratch
!= NULL
) {
1552 Status
= Decompress
->Decompress (
1556 DecompressedImageBuffer
,
1561 if (!EFI_ERROR (Status
)) {
1562 ImageBuffer
= DecompressedImageBuffer
;
1563 ImageLength
= DestinationSize
;
1567 gBS
->FreePool (Scratch
);
1577 // load image and start image
1580 FilePath
= FileDevicePath (NULL
, FileName
);
1582 Status
= gBS
->LoadImage (
1590 if (!EFI_ERROR (Status
)) {
1591 Status
= gBS
->StartImage (ImageHandle
, NULL
, NULL
);
1592 if (!EFI_ERROR (Status
)) {
1596 if (FilePath
!= NULL
) {
1597 gBS
->FreePool (FilePath
);
1601 if (DecompressedImageBuffer
!= NULL
) {
1602 gBS
->FreePool (DecompressedImageBuffer
);
1608 RomOffset
= RomOffset
+ ImageSize
;
1610 } while (((Pcir
->Indicator
& 0x80) == 0x00) && ((RomOffset
- (UINTN
) Rom
) < RomSize
));