2 Platform BDS customizations.
4 Copyright (c) 2004 - 2008, 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
;
27 // Function prototypes
31 InstallDevicePathCallback (
43 PciRomLoadEfiDriversFromRomImage (
44 IN EFI_PHYSICAL_ADDRESS Rom
,
49 // BDS Platform Functions
60 Platform Bds init. Incude the platform firmware vendor, revision
71 DEBUG ((EFI_D_INFO
, "PlatformBdsInit\n"));
72 InstallDevicePathCallback ();
93 EFI_SUCCESS - Connect RootBridge successfully.
94 EFI_STATUS - Connect RootBridge fail.
99 EFI_HANDLE RootHandle
;
102 // Make all the PCI_IO protocols on PCI Seg 0 show up
104 BdsLibConnectDevicePath (gPlatformRootBridges
[0]);
106 Status
= gBS
->LocateDevicePath (
107 &gEfiDevicePathProtocolGuid
,
108 &gPlatformRootBridges
[0],
111 if (EFI_ERROR (Status
)) {
115 Status
= gBS
->ConnectController (RootHandle
, NULL
, NULL
, FALSE
);
116 if (EFI_ERROR (Status
)) {
125 PrepareLpcBridgeDevicePath (
126 IN EFI_HANDLE DeviceHandle
132 Add IsaKeyboard to ConIn,
133 add IsaSerial to ConOut, ConIn, ErrOut.
138 DeviceHandle - Handle of PCIIO protocol.
142 EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut.
143 EFI_STATUS - No LPC bridge is added.
148 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
149 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
153 Status
= gBS
->HandleProtocol (
155 &gEfiDevicePathProtocolGuid
,
158 if (EFI_ERROR (Status
)) {
161 TempDevicePath
= DevicePath
;
166 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnpPs2KeyboardDeviceNode
);
168 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
173 DevicePath
= TempDevicePath
;
174 gPnp16550ComPortDeviceNode
.UID
= 0;
176 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gPnp16550ComPortDeviceNode
);
177 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
178 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
183 DevPathStr
= DevicePathToStr(DevicePath
);
186 "BdsPlatform.c+%d: COM%d DevPath: %s\n",
188 gPnp16550ComPortDeviceNode
.UID
+ 1,
191 FreePool(DevPathStr
);
193 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
194 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
195 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
200 DevicePath
= TempDevicePath
;
201 gPnp16550ComPortDeviceNode
.UID
= 1;
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
);
229 IN EFI_DEVICE_PATH_PROTOCOL
*PciDevicePath
,
230 OUT EFI_DEVICE_PATH_PROTOCOL
**GopDevicePath
235 EFI_HANDLE PciDeviceHandle
;
236 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
237 EFI_DEVICE_PATH_PROTOCOL
*TempPciDevicePath
;
238 UINTN GopHandleCount
;
239 EFI_HANDLE
*GopHandleBuffer
;
241 if (PciDevicePath
== NULL
|| GopDevicePath
== NULL
) {
242 return EFI_INVALID_PARAMETER
;
246 // Initialize the GopDevicePath to be PciDevicePath
248 *GopDevicePath
= PciDevicePath
;
249 TempPciDevicePath
= PciDevicePath
;
251 Status
= gBS
->LocateDevicePath (
252 &gEfiDevicePathProtocolGuid
,
256 if (EFI_ERROR (Status
)) {
261 // Try to connect this handle, so that GOP dirver could start on this
262 // device and create child handles with GraphicsOutput Protocol installed
263 // on them, then we get device paths of these child handles and select
264 // them as possible console device.
266 gBS
->ConnectController (PciDeviceHandle
, NULL
, NULL
, FALSE
);
268 Status
= gBS
->LocateHandleBuffer (
270 &gEfiGraphicsOutputProtocolGuid
,
275 if (!EFI_ERROR (Status
)) {
277 // Add all the child handles as possible Console Device
279 for (Index
= 0; Index
< GopHandleCount
; Index
++) {
280 Status
= gBS
->HandleProtocol (GopHandleBuffer
[Index
], &gEfiDevicePathProtocolGuid
, (VOID
*)&TempDevicePath
);
281 if (EFI_ERROR (Status
)) {
287 GetDevicePathSize (PciDevicePath
) - END_DEVICE_PATH_LENGTH
290 // In current implementation, we only enable one of the child handles
291 // as console device, i.e. sotre one of the child handle's device
292 // path to variable "ConOut"
293 // In futhure, we could select all child handles to be console device
296 *GopDevicePath
= TempDevicePath
;
299 // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()
300 // Add the integrity GOP device path.
302 BdsLibUpdateConsoleVariable (VarConsoleOutDev
, NULL
, PciDevicePath
);
303 BdsLibUpdateConsoleVariable (VarConsoleOutDev
, TempDevicePath
, NULL
);
306 gBS
->FreePool (GopHandleBuffer
);
313 PreparePciVgaDevicePath (
314 IN EFI_HANDLE DeviceHandle
320 Add PCI VGA to ConOut.
325 DeviceHandle - Handle of PCIIO protocol.
329 EFI_SUCCESS - PCI VGA is added to ConOut.
330 EFI_STATUS - No PCI VGA device is added.
335 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
336 EFI_DEVICE_PATH_PROTOCOL
*GopDevicePath
;
339 Status
= gBS
->HandleProtocol (
341 &gEfiDevicePathProtocolGuid
,
344 if (EFI_ERROR (Status
)) {
348 GetGopDevicePath (DevicePath
, &GopDevicePath
);
349 DevicePath
= GopDevicePath
;
351 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
357 PreparePciSerialDevicePath (
358 IN EFI_HANDLE DeviceHandle
364 Add PCI Serial to ConOut, ConIn, ErrOut.
369 DeviceHandle - Handle of PCIIO protocol.
373 EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.
374 EFI_STATUS - No PCI Serial device is added.
379 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
382 Status
= gBS
->HandleProtocol (
384 &gEfiDevicePathProtocolGuid
,
387 if (EFI_ERROR (Status
)) {
391 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gUartDeviceNode
);
392 DevicePath
= AppendDevicePathNode (DevicePath
, (EFI_DEVICE_PATH_PROTOCOL
*)&gTerminalTypeDeviceNode
);
394 BdsLibUpdateConsoleVariable (VarConsoleOut
, DevicePath
, NULL
);
395 BdsLibUpdateConsoleVariable (VarConsoleInp
, DevicePath
, NULL
);
396 BdsLibUpdateConsoleVariable (VarErrorOut
, DevicePath
, NULL
);
402 DetectAndPreparePlatformPciDevicePath (
403 BOOLEAN DetectVgaOnly
409 Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
413 DetectVgaOnly - Only detect VGA device if it's TRUE.
417 EFI_SUCCESS - PCI Device check and Console variable update successfully.
418 EFI_STATUS - PCI Device check or Console variable update fail.
424 EFI_HANDLE
*HandleBuffer
;
426 EFI_PCI_IO_PROTOCOL
*PciIo
;
430 // Start to check all the PciIo to find all possible device
434 Status
= gBS
->LocateHandleBuffer (
436 &gEfiPciIoProtocolGuid
,
441 if (EFI_ERROR (Status
)) {
445 for (Index
= 0; Index
< HandleCount
; Index
++) {
446 Status
= gBS
->HandleProtocol (HandleBuffer
[Index
], &gEfiPciIoProtocolGuid
, (VOID
*)&PciIo
);
447 if (EFI_ERROR (Status
)) {
452 // Check for all PCI device
454 Status
= PciIo
->Pci
.Read (
458 sizeof (Pci
) / sizeof (UINT32
),
461 if (EFI_ERROR (Status
)) {
465 if (!DetectVgaOnly
) {
467 // Here we decide whether it is LPC Bridge
469 if ((IS_PCI_LPC (&Pci
)) ||
470 ((IS_PCI_ISA_PDECODE (&Pci
)) &&
471 (Pci
.Hdr
.VendorId
== 0x8086) &&
472 (Pci
.Hdr
.DeviceId
== 0x7000)
475 Status
= PciIo
->Attributes (
477 EfiPciIoAttributeOperationEnable
,
478 EFI_PCI_DEVICE_ENABLE
,
482 // Add IsaKeyboard to ConIn,
483 // add IsaSerial to ConOut, ConIn, ErrOut
485 DEBUG ((EFI_D_INFO
, "Find the LPC Bridge device\n"));
486 PrepareLpcBridgeDevicePath (HandleBuffer
[Index
]);
490 // Here we decide which Serial device to enable in PCI bus
492 if (IS_PCI_16550SERIAL (&Pci
)) {
494 // Add them to ConOut, ConIn, ErrOut.
496 DEBUG ((EFI_D_INFO
, "Find the 16550 SERIAL device\n"));
497 PreparePciSerialDevicePath (HandleBuffer
[Index
]);
502 if ((Pci
.Hdr
.VendorId
== 0x8086) &&
503 (Pci
.Hdr
.DeviceId
== 0x7010)
505 Status
= PciIo
->Attributes (
507 EfiPciIoAttributeOperationEnable
,
508 EFI_PCI_DEVICE_ENABLE
,
514 // Here we decide which VGA device to enable in PCI bus
516 if (IS_PCI_VGA (&Pci
)) {
518 // Add them to ConOut.
520 DEBUG ((EFI_D_INFO
, "Find the VGA device\n"));
521 PreparePciVgaDevicePath (HandleBuffer
[Index
]);
526 gBS
->FreePool (HandleBuffer
);
533 PlatformBdsConnectConsole (
534 IN BDS_CONSOLE_CONNECT_ENTRY
*PlatformConsole
540 Connect the predefined platform default console device. Always try to find
541 and enable the vga device if have.
545 PlatformConsole - Predfined platform default console device array.
549 EFI_SUCCESS - Success connect at least one ConIn and ConOut
550 device, there must have one ConOut device is
553 EFI_STATUS - Return the status of
554 BdsLibConnectAllDefaultConsoles ()
560 EFI_DEVICE_PATH_PROTOCOL
*VarConout
;
561 EFI_DEVICE_PATH_PROTOCOL
*VarConin
;
562 UINTN DevicePathSize
;
565 // Connect RootBridge
567 ConnectRootBridge ();
569 VarConout
= BdsLibGetVariableAndSize (
571 &gEfiGlobalVariableGuid
,
574 VarConin
= BdsLibGetVariableAndSize (
576 &gEfiGlobalVariableGuid
,
580 if (VarConout
== NULL
|| VarConin
== NULL
) {
582 // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
584 DetectAndPreparePlatformPciDevicePath (FALSE
);
587 // Have chance to connect the platform default console,
588 // the platform default console is the minimue device group
589 // the platform should support
591 for (Index
= 0; PlatformConsole
[Index
].DevicePath
!= NULL
; ++Index
) {
593 // Update the console variable with the connect type
595 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_IN
) == CONSOLE_IN
) {
596 BdsLibUpdateConsoleVariable (VarConsoleInp
, PlatformConsole
[Index
].DevicePath
, NULL
);
598 if ((PlatformConsole
[Index
].ConnectType
& CONSOLE_OUT
) == CONSOLE_OUT
) {
599 BdsLibUpdateConsoleVariable (VarConsoleOut
, PlatformConsole
[Index
].DevicePath
, NULL
);
601 if ((PlatformConsole
[Index
].ConnectType
& STD_ERROR
) == STD_ERROR
) {
602 BdsLibUpdateConsoleVariable (VarErrorOut
, PlatformConsole
[Index
].DevicePath
, NULL
);
607 // Only detect VGA device and add them to ConOut
609 DetectAndPreparePlatformPciDevicePath (TRUE
);
613 // Connect the all the default console with current cosole variable
615 Status
= BdsLibConnectAllDefaultConsoles ();
616 if (EFI_ERROR (Status
)) {
629 // Bus 0, Device 0, Function 0 - Host to PCI Bridge
631 PciWrite8 (PCI_LIB_ADDRESS (0, 0, 0, 0x3c), 0x00);
634 // Bus 0, Device 1, Function 0 - PCI to ISA Bridge
636 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x3c), 0x00);
637 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b);
638 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x09);
639 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0b);
640 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x09);
643 // Bus 0, Device 1, Function 1 - IDE Controller
645 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x3c), 0x00);
646 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 1, 0x0d), 0x40);
649 // Bus 0, Device 1, Function 3 - Power Managment Controller
651 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3c), 0x0b);
652 PciWrite8 (PCI_LIB_ADDRESS (0, 1, 3, 0x3d), 0x01);
655 // Bus 0, Device 2, Function 0 - Video Controller
657 PciWrite8 (PCI_LIB_ADDRESS (0, 2, 0, 0x3c), 0x00);
660 // Bus 0, Device 3, Function 0 - Network Controller
662 PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3c), 0x0b);
663 PciWrite8 (PCI_LIB_ADDRESS (0, 3, 0, 0x3d), 0x01);
666 // Bus 0, Device 4, Function 0 - RAM Memory
668 PciWrite8 (PCI_LIB_ADDRESS (0, 4, 0, 0x3c), 0x09);
669 PciWrite8 (PCI_LIB_ADDRESS (0, 4, 0, 0x3d), 0x01);
674 PlatformBdsConnectSequence (
681 Connect with predeined platform connect sequence,
682 the OEM/IBV can customize with their own connect sequence.
696 DEBUG ((EFI_D_INFO
, "PlatformBdsConnectSequence\n"));
701 // Here we can get the customized platform connect sequence
702 // Notes: we can connect with new variable which record the
703 // last time boots connect device path sequence
705 while (gPlatformConnectSequence
[Index
] != NULL
) {
707 // Build the platform boot option
709 BdsLibConnectDevicePath (gPlatformConnectSequence
[Index
]);
714 // Just use the simple policy to connect all devices
718 PciInitialization ();
721 // Clear the logo after all devices are connected.
723 gST
->ConOut
->ClearScreen (gST
->ConOut
);
727 PlatformBdsGetDriverOption (
728 IN OUT LIST_ENTRY
*BdsDriverLists
734 Load the predefined driver option, OEM/IBV can customize this
735 to load their own drivers
739 BdsDriverLists - The header of the driver option link list.
747 DEBUG ((EFI_D_INFO
, "PlatformBdsGetDriverOption\n"));
752 PlatformBdsDiagnostics (
753 IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel
,
754 IN BOOLEAN QuietBoot
,
755 IN BASEM_MEMORY_TEST BaseMemoryTest
761 Perform the platform diagnostic, such like test memory. OEM/IBV also
762 can customize this fuction to support specific platform diagnostic.
766 MemoryTestLevel - The memory test intensive level
768 QuietBoot - Indicate if need to enable the quiet boot
770 BaseMemoryTest - A pointer to BaseMemoryTest()
780 DEBUG ((EFI_D_INFO
, "PlatformBdsDiagnostics\n"));
783 // Here we can decide if we need to show
784 // the diagnostics screen
785 // Notes: this quiet boot code should be remove
786 // from the graphic lib
789 EnableQuietBoot (PcdGetPtr(PcdLogoFile
));
791 // Perform system diagnostic
793 Status
= BaseMemoryTest (MemoryTestLevel
);
794 if (EFI_ERROR (Status
)) {
801 // Perform system diagnostic
803 Status
= BaseMemoryTest (MemoryTestLevel
);
809 PlatformBdsPolicyBehavior (
810 IN OUT LIST_ENTRY
*DriverOptionList
,
811 IN OUT LIST_ENTRY
*BootOptionList
,
812 IN PROCESS_CAPSULES ProcessCapsules
,
813 IN BASEM_MEMORY_TEST BaseMemoryTest
819 The function will excute with as the platform policy, current policy
820 is driven by boot mode. IBV/OEM can customize this code for their specific
825 DriverOptionList - The header of the driver option link list
827 BootOptionList - The header of the boot option link list
829 ProcessCapsules - A pointer to ProcessCapsules()
831 BaseMemoryTest - A pointer to BaseMemoryTest()
841 EFI_EVENT UserInputDurationTime
;
843 BDS_COMMON_OPTION
*BootOption
;
847 EFI_BOOT_MODE BootMode
;
849 DEBUG ((EFI_D_INFO
, "PlatformBdsPolicyBehavior\n"));
852 // Init the time out value
854 Timeout
= PcdGet16 (PcdPlatformBootTimeOut
);
857 // Load the driver option as the driver option list
859 PlatformBdsGetDriverOption (DriverOptionList
);
862 // Get current Boot Mode
864 Status
= BdsLibGetBootMode (&BootMode
);
865 DEBUG ((EFI_D_ERROR
, "Boot Mode:%x\n", BootMode
));
868 // Go the different platform policy with different boot mode
869 // Notes: this part code can be change with the table policy
871 ASSERT (BootMode
== BOOT_WITH_FULL_CONFIGURATION
);
873 // Connect platform console
875 Status
= PlatformBdsConnectConsole (gPlatformConsole
);
876 if (EFI_ERROR (Status
)) {
878 // Here OEM/IBV can customize with defined action
880 PlatformBdsNoConsoleAction ();
883 // Create a 300ms duration event to ensure user has enough input time to enter Setup
885 Status
= gBS
->CreateEvent (
890 &UserInputDurationTime
892 ASSERT (Status
== EFI_SUCCESS
);
893 Status
= gBS
->SetTimer (UserInputDurationTime
, TimerRelative
, 3000000);
894 ASSERT (Status
== EFI_SUCCESS
);
896 // Memory test and Logo show
898 PlatformBdsDiagnostics (IGNORE
, TRUE
, BaseMemoryTest
);
901 // Perform some platform specific connect sequence
903 PlatformBdsConnectSequence ();
906 // Give one chance to enter the setup if we
910 //PlatformBdsEnterFrontPage (Timeout, FALSE);
913 DEBUG ((EFI_D_INFO
, "BdsLibConnectAll\n"));
915 BdsLibEnumerateAllBootOption (BootOptionList
);
918 // Please uncomment above ConnectAll and EnumerateAll code and remove following first boot
919 // checking code in real production tip.
921 // In BOOT_WITH_FULL_CONFIGURATION boot mode, should always connect every device
922 // and do enumerate all the default boot options. But in development system board, the boot mode
923 // cannot be BOOT_ASSUMING_NO_CONFIGURATION_CHANGES because the machine box
924 // is always open. So the following code only do the ConnectAll and EnumerateAll at first boot.
926 Status
= BdsLibBuildOptionFromVar (BootOptionList
, L
"BootOrder");
927 if (EFI_ERROR(Status
)) {
929 // If cannot find "BootOrder" variable, it may be first boot.
930 // Try to connect all devices and enumerate all boot options here.
933 BdsLibEnumerateAllBootOption (BootOptionList
);
937 // To give the User a chance to enter Setup here, if user set TimeOut is 0.
938 // BDS should still give user a chance to enter Setup
940 // Connect first boot option, and then check user input before exit
942 for (Link
= BootOptionList
->ForwardLink
; Link
!= BootOptionList
;Link
= Link
->ForwardLink
) {
943 BootOption
= CR (Link
, BDS_COMMON_OPTION
, Link
, BDS_LOAD_OPTION_SIGNATURE
);
944 if (!IS_LOAD_OPTION_TYPE (BootOption
->Attribute
, LOAD_OPTION_ACTIVE
)) {
946 // skip the header of the link list, becuase it has no boot option
951 // Make sure the boot option device path connected, but ignore the BBS device path
953 if (DevicePathType (BootOption
->DevicePath
) != BBS_DEVICE_PATH
) {
954 BdsLibConnectDevicePath (BootOption
->DevicePath
);
961 // Check whether the user input after the duration time has expired
963 OldTpl
= EfiGetCurrentTpl();
964 gBS
->RestoreTPL (TPL_APPLICATION
);
965 gBS
->WaitForEvent (1, &UserInputDurationTime
, &Index
);
966 gBS
->CloseEvent (UserInputDurationTime
);
967 Status
= gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
968 gBS
->RaiseTPL (OldTpl
);
970 if (!EFI_ERROR (Status
)) {
972 // Enter Setup if user input
975 PlatformBdsEnterFrontPage (Timeout
, FALSE
);
983 PlatformBdsBootSuccess (
984 IN BDS_COMMON_OPTION
*Option
990 Hook point after a boot attempt succeeds. We don't expect a boot option to
991 return, so the EFI 1.0 specification defines that you will default to an
992 interactive mode and stop processing the BootOrder list in this case. This
993 is alos a platform implementation and can be customized by IBV/OEM.
997 Option - Pointer to Boot Option that succeeded to boot.
1007 DEBUG ((EFI_D_INFO
, "PlatformBdsBootSuccess\n"));
1009 // If Boot returned with EFI_SUCCESS and there is not in the boot device
1010 // select loop then we need to pop up a UI and wait for user input.
1012 TmpStr
= Option
->StatusString
;
1013 if (TmpStr
!= NULL
) {
1014 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
1021 PlatformBdsBootFail (
1022 IN BDS_COMMON_OPTION
*Option
,
1023 IN EFI_STATUS Status
,
1024 IN CHAR16
*ExitData
,
1025 IN UINTN ExitDataSize
1029 Routine Description:
1031 Hook point after a boot attempt fails.
1035 Option - Pointer to Boot Option that failed to boot.
1037 Status - Status returned from failed boot.
1039 ExitData - Exit data returned from failed boot.
1041 ExitDataSize - Exit data size returned from failed boot.
1051 DEBUG ((EFI_D_INFO
, "PlatformBdsBootFail\n"));
1054 // If Boot returned with failed status then we need to pop up a UI and wait
1057 TmpStr
= Option
->StatusString
;
1058 if (TmpStr
!= NULL
) {
1059 BdsLibOutputStrings (gST
->ConOut
, TmpStr
, Option
->Description
, L
"\n\r", NULL
);
1065 PlatformBdsNoConsoleAction (
1070 Routine Description:
1072 This function is remained for IBV/OEM to do some platform action,
1073 if there no console device can be connected.
1081 EFI_SUCCESS - Direct return success now.
1085 DEBUG ((EFI_D_INFO
, "PlatformBdsNoConsoleAction\n"));
1091 PlatformBdsLockNonUpdatableFlash (
1095 DEBUG ((EFI_D_INFO
, "PlatformBdsLockNonUpdatableFlash\n"));
1101 This notification function is invoked when an instance of the
1102 EFI_DEVICE_PATH_PROTOCOL is produced.
1104 @param Event The event that occured
1105 @param Context For EFI compatiblity. Not used.
1118 EFI_DEVICE_PATH_PROTOCOL
*DevPathNode
;
1119 ATAPI_DEVICE_PATH
*Atapi
;
1122 // Examine all new handles
1126 // Get the next handle
1128 BufferSize
= sizeof (Handle
);
1129 Status
= gBS
->LocateHandle (
1132 mEfiDevPathNotifyReg
,
1138 // If not found, we're done
1140 if (EFI_NOT_FOUND
== Status
) {
1144 if (EFI_ERROR (Status
)) {
1149 // Get the DevicePath protocol on that handle
1151 Status
= gBS
->HandleProtocol (Handle
, &gEfiDevicePathProtocolGuid
, (VOID
**)&DevPathNode
);
1152 ASSERT_EFI_ERROR (Status
);
1154 while (!IsDevicePathEnd (DevPathNode
)) {
1156 // Find the handler to dump this device path node
1159 (DevicePathType(DevPathNode
) == MESSAGING_DEVICE_PATH
) &&
1160 (DevicePathSubType(DevPathNode
) == MSG_ATAPI_DP
)
1162 Atapi
= (ATAPI_DEVICE_PATH
*) DevPathNode
;
1168 (Atapi
->PrimarySecondary
== 1) ? 0x42: 0x40
1175 // Next device path node
1177 DevPathNode
= NextDevicePathNode (DevPathNode
);
1186 InstallDevicePathCallback (
1190 DEBUG ((EFI_D_INFO
, "Registered NotifyDevPath Event\n"));
1191 mEfiDevPathEvent
= EfiCreateProtocolNotifyEvent (
1192 &gEfiDevicePathProtocolGuid
,
1196 &mEfiDevPathNotifyReg
1201 Lock the ConsoleIn device in system table. All key
1202 presses will be ignored until the Password is typed in. The only way to
1203 disable the password is to type it in to a ConIn device.
1205 @param Password Password used to lock ConIn device.
1207 @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
1208 @retval EFI_UNSUPPORTED Password not found
1217 return EFI_UNSUPPORTED
;
1227 PCI_DATA_STRUCTURE
*Pcir
;
1231 // The virtual machines sometimes load the video rom image
1232 // directly at the legacy video BIOS location of C000:0000,
1233 // and do not implement the PCI expansion ROM feature.
1235 Pcir
= (PCI_DATA_STRUCTURE
*) (UINTN
) 0xc0000;
1236 RomSize
= Pcir
->ImageLength
* 512;
1237 PciRomLoadEfiDriversFromRomImage (0xc0000, RomSize
);
1243 PciRomLoadEfiDriversFromRomImage (
1244 IN EFI_PHYSICAL_ADDRESS Rom
,
1249 EFI_PCI_EXPANSION_ROM_HEADER
*EfiRomHeader
;
1250 PCI_DATA_STRUCTURE
*Pcir
;
1255 EFI_HANDLE ImageHandle
;
1257 EFI_STATUS retStatus
;
1258 EFI_DEVICE_PATH_PROTOCOL
*FilePath
;
1260 UINT32 DestinationSize
;
1264 VOID
*DecompressedImageBuffer
;
1266 EFI_DECOMPRESS_PROTOCOL
*Decompress
;
1268 FileName
= L
"PciRomInMemory";
1270 //FileName = L"PciRom Addr=0000000000000000";
1271 //HexToString (&FileName[12], Rom, 16);
1274 retStatus
= EFI_NOT_FOUND
;
1275 RomOffset
= (UINTN
) Rom
;
1279 EfiRomHeader
= (EFI_PCI_EXPANSION_ROM_HEADER
*) (UINTN
) RomOffset
;
1281 if (EfiRomHeader
->Signature
!= 0xaa55) {
1285 Pcir
= (PCI_DATA_STRUCTURE
*) (UINTN
) (RomOffset
+ EfiRomHeader
->PcirOffset
);
1286 ImageSize
= Pcir
->ImageLength
* 512;
1288 if ((Pcir
->CodeType
== PCI_CODE_TYPE_EFI_IMAGE
) &&
1289 (EfiRomHeader
->EfiSignature
== EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE
) ) {
1291 if ((EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
) ||
1292 (EfiRomHeader
->EfiSubsystem
== EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER
) ) {
1294 ImageOffset
= EfiRomHeader
->EfiImageHeaderOffset
;
1295 ImageSize
= EfiRomHeader
->InitializationSize
* 512;
1297 ImageBuffer
= (VOID
*) (UINTN
) (RomOffset
+ ImageOffset
);
1298 ImageLength
= ImageSize
- ImageOffset
;
1299 DecompressedImageBuffer
= NULL
;
1302 // decompress here if needed
1305 if (EfiRomHeader
->CompressionType
> EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
1309 if (EfiRomHeader
->CompressionType
== EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED
) {
1310 Status
= gBS
->LocateProtocol (&gEfiDecompressProtocolGuid
, NULL
, (VOID
**) &Decompress
);
1311 if (EFI_ERROR (Status
)) {
1315 Status
= Decompress
->GetInfo (
1322 if (!EFI_ERROR (Status
)) {
1323 DecompressedImageBuffer
= NULL
;
1324 DecompressedImageBuffer
= AllocatePool (DestinationSize
);
1325 if (DecompressedImageBuffer
!= NULL
) {
1326 Scratch
= AllocatePool (ScratchSize
);
1327 if (Scratch
!= NULL
) {
1328 Status
= Decompress
->Decompress (
1332 DecompressedImageBuffer
,
1337 if (!EFI_ERROR (Status
)) {
1338 ImageBuffer
= DecompressedImageBuffer
;
1339 ImageLength
= DestinationSize
;
1343 gBS
->FreePool (Scratch
);
1353 // load image and start image
1356 FilePath
= FileDevicePath (NULL
, FileName
);
1358 Status
= gBS
->LoadImage (
1366 if (!EFI_ERROR (Status
)) {
1367 Status
= gBS
->StartImage (ImageHandle
, NULL
, NULL
);
1368 if (!EFI_ERROR (Status
)) {
1372 if (FilePath
!= NULL
) {
1373 gBS
->FreePool (FilePath
);
1377 if (DecompressedImageBuffer
!= NULL
) {
1378 gBS
->FreePool (DecompressedImageBuffer
);
1384 RomOffset
= RomOffset
+ ImageSize
;
1386 } while (((Pcir
->Indicator
& 0x80) == 0x00) && ((RomOffset
- (UINTN
) Rom
) < RomSize
));