X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=OvmfPkg%2FLibrary%2FPlatformBootManagerLib%2FBdsPlatform.c;h=862fa6ebb4e5f67f3693e1b4bc281546b77cd8df;hp=1988b3e04c3034f7f78971f9565fddac563728b0;hb=a34a886962561f6d8550b2a1bb193798ca456431;hpb=a7566234e92c91ba43e0f016b7d14fb08b871161
diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
index 1988b3e04c..862fa6ebb4 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
+++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
@@ -2,19 +2,20 @@
Platform BDS customizations.
Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
+ This program and the accompanying materials are licensed and made available
+ under the terms and conditions of the BSD License which accompanies this
+ distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
+ WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "BdsPlatform.h"
+#include
#include
-#include
+#include
//
@@ -36,11 +37,6 @@ CONST UINT8 PciHostIrqs[] = {
0x0a, 0x0a, 0x0b, 0x0b
};
-//
-// Array Size macro
-//
-#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0]))
-
//
// Type definitions
//
@@ -88,6 +84,233 @@ InstallDevicePathCallback (
VOID
);
+VOID
+PlatformRegisterFvBootOption (
+ EFI_GUID *FileGuid,
+ CHAR16 *Description,
+ UINT32 Attributes
+ )
+{
+ EFI_STATUS Status;
+ INTN OptionIndex;
+ EFI_BOOT_MANAGER_LOAD_OPTION NewOption;
+ EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
+ UINTN BootOptionCount;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ Status = gBS->HandleProtocol (
+ gImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **) &LoadedImage
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
+ DevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle);
+ ASSERT (DevicePath != NULL);
+ DevicePath = AppendDevicePathNode (
+ DevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
+ );
+ ASSERT (DevicePath != NULL);
+
+ Status = EfiBootManagerInitializeLoadOption (
+ &NewOption,
+ LoadOptionNumberUnassigned,
+ LoadOptionTypeBoot,
+ Attributes,
+ Description,
+ DevicePath,
+ NULL,
+ 0
+ );
+ ASSERT_EFI_ERROR (Status);
+ FreePool (DevicePath);
+
+ BootOptions = EfiBootManagerGetLoadOptions (
+ &BootOptionCount, LoadOptionTypeBoot
+ );
+
+ OptionIndex = EfiBootManagerFindLoadOption (
+ &NewOption, BootOptions, BootOptionCount
+ );
+
+ if (OptionIndex == -1) {
+ Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);
+ ASSERT_EFI_ERROR (Status);
+ }
+ EfiBootManagerFreeLoadOption (&NewOption);
+ EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+}
+
+/**
+ Remove all MemoryMapped(...)/FvFile(...) and Fv(...)/FvFile(...) boot options
+ whose device paths do not resolve exactly to an FvFile in the system.
+
+ This removes any boot options that point to binaries built into the firmware
+ and have become stale due to any of the following:
+ - DXEFV's base address or size changed (historical),
+ - DXEFV's FvNameGuid changed,
+ - the FILE_GUID of the pointed-to binary changed,
+ - the referenced binary is no longer built into the firmware.
+
+ EfiBootManagerFindLoadOption() used in PlatformRegisterFvBootOption() only
+ avoids exact duplicates.
+**/
+VOID
+RemoveStaleFvFileOptions (
+ VOID
+ )
+{
+ EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;
+ UINTN BootOptionCount;
+ UINTN Index;
+
+ BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount,
+ LoadOptionTypeBoot);
+
+ for (Index = 0; Index < BootOptionCount; ++Index) {
+ EFI_DEVICE_PATH_PROTOCOL *Node1, *Node2, *SearchNode;
+ EFI_STATUS Status;
+ EFI_HANDLE FvHandle;
+
+ //
+ // If the device path starts with neither MemoryMapped(...) nor Fv(...),
+ // then keep the boot option.
+ //
+ Node1 = BootOptions[Index].FilePath;
+ if (!(DevicePathType (Node1) == HARDWARE_DEVICE_PATH &&
+ DevicePathSubType (Node1) == HW_MEMMAP_DP) &&
+ !(DevicePathType (Node1) == MEDIA_DEVICE_PATH &&
+ DevicePathSubType (Node1) == MEDIA_PIWG_FW_VOL_DP)) {
+ continue;
+ }
+
+ //
+ // If the second device path node is not FvFile(...), then keep the boot
+ // option.
+ //
+ Node2 = NextDevicePathNode (Node1);
+ if (DevicePathType (Node2) != MEDIA_DEVICE_PATH ||
+ DevicePathSubType (Node2) != MEDIA_PIWG_FW_FILE_DP) {
+ continue;
+ }
+
+ //
+ // Locate the Firmware Volume2 protocol instance that is denoted by the
+ // boot option. If this lookup fails (i.e., the boot option references a
+ // firmware volume that doesn't exist), then we'll proceed to delete the
+ // boot option.
+ //
+ SearchNode = Node1;
+ Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid,
+ &SearchNode, &FvHandle);
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // The firmware volume was found; now let's see if it contains the FvFile
+ // identified by GUID.
+ //
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFileNode;
+ UINTN BufferSize;
+ EFI_FV_FILETYPE FoundType;
+ EFI_FV_FILE_ATTRIBUTES FileAttributes;
+ UINT32 AuthenticationStatus;
+
+ Status = gBS->HandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID **)&FvProtocol);
+ ASSERT_EFI_ERROR (Status);
+
+ FvFileNode = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)Node2;
+ //
+ // Buffer==NULL means we request metadata only: BufferSize, FoundType,
+ // FileAttributes.
+ //
+ Status = FvProtocol->ReadFile (
+ FvProtocol,
+ &FvFileNode->FvFileName, // NameGuid
+ NULL, // Buffer
+ &BufferSize,
+ &FoundType,
+ &FileAttributes,
+ &AuthenticationStatus
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // The FvFile was found. Keep the boot option.
+ //
+ continue;
+ }
+ }
+
+ //
+ // Delete the boot option.
+ //
+ Status = EfiBootManagerDeleteLoadOptionVariable (
+ BootOptions[Index].OptionNumber, LoadOptionTypeBoot);
+ DEBUG_CODE (
+ CHAR16 *DevicePathString;
+
+ DevicePathString = ConvertDevicePathToText(BootOptions[Index].FilePath,
+ FALSE, FALSE);
+ DEBUG ((
+ EFI_ERROR (Status) ? EFI_D_WARN : EFI_D_VERBOSE,
+ "%a: removing stale Boot#%04x %s: %r\n",
+ __FUNCTION__,
+ (UINT32)BootOptions[Index].OptionNumber,
+ DevicePathString == NULL ? L"" : DevicePathString,
+ Status
+ ));
+ if (DevicePathString != NULL) {
+ FreePool (DevicePathString);
+ }
+ );
+ }
+
+ EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+}
+
+VOID
+PlatformRegisterOptionsAndKeys (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_INPUT_KEY Enter;
+ EFI_INPUT_KEY F2;
+ EFI_INPUT_KEY Esc;
+ EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
+
+ //
+ // Register ENTER as CONTINUE key
+ //
+ Enter.ScanCode = SCAN_NULL;
+ Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
+ Status = EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Map F2 to Boot Manager Menu
+ //
+ F2.ScanCode = SCAN_F2;
+ F2.UnicodeChar = CHAR_NULL;
+ Esc.ScanCode = SCAN_ESC;
+ Esc.UnicodeChar = CHAR_NULL;
+ Status = EfiBootManagerGetBootManagerMenu (&BootOption);
+ ASSERT_EFI_ERROR (Status);
+ Status = EfiBootManagerAddKeyOptionVariable (
+ NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL
+ );
+ ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
+ Status = EfiBootManagerAddKeyOptionVariable (
+ NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL
+ );
+ ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
+}
+
EFI_STATUS
EFIAPI
ConnectRootBridge (
@@ -105,28 +328,28 @@ SaveS3BootScript (
//
// BDS Platform Functions
//
+/**
+ Do the platform init, can be customized by OEM/IBV
+
+ Possible things that can be done in PlatformBootManagerBeforeConsole:
+
+ > Update console variable: 1. include hot-plug devices;
+ > 2. Clear ConIn and add SOL for AMT
+ > Register new Driver#### or Boot####
+ > Register new Key####: e.g.: F12
+ > Signal ReadyToLock event
+ > Authentication action: 1. connect Auth devices;
+ > 2. Identify auto logon user.
+**/
VOID
EFIAPI
PlatformBootManagerBeforeConsole (
VOID
)
-/*++
-
-Routine Description:
-
- Platform Bds init. Incude the platform firmware vendor, revision
- and so crc check.
-
-Arguments:
-
-Returns:
-
- None.
-
---*/
{
- EFI_HANDLE Handle;
- EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ EFI_STATUS Status;
+ RETURN_STATUS PcdStatus;
DEBUG ((EFI_D_INFO, "PlatformBootManagerBeforeConsole\n"));
InstallDevicePathCallback ();
@@ -164,6 +387,19 @@ Returns:
&gEfiDxeSmmReadyToLockProtocolGuid, EFI_NATIVE_INTERFACE,
NULL);
ASSERT_EFI_ERROR (Status);
+
+ //
+ // Dispatch deferred images after EndOfDxe event and ReadyToLock
+ // installation.
+ //
+ EfiBootManagerDispatchDeferredImages ();
+
+ PlatformInitializeConsole (gPlatformConsole);
+ PcdStatus = PcdSet16S (PcdPlatformBootTimeOut,
+ GetFrontPageTimeoutFromQemu ());
+ ASSERT_RETURN_ERROR (PcdStatus);
+
+ PlatformRegisterOptionsAndKeys ();
}
@@ -192,28 +428,21 @@ ConnectRootBridge (
}
+/**
+ Add IsaKeyboard to ConIn; add IsaSerial to ConOut, ConIn, ErrOut.
+
+ @param[in] DeviceHandle Handle of the LPC Bridge device.
+
+ @retval EFI_SUCCESS Console devices on the LPC bridge have been added to
+ ConOut, ConIn, and ErrOut.
+
+ @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing
+ from DeviceHandle.
+**/
EFI_STATUS
PrepareLpcBridgeDevicePath (
IN EFI_HANDLE DeviceHandle
)
-/*++
-
-Routine Description:
-
- Add IsaKeyboard to ConIn,
- add IsaSerial to ConOut, ConIn, ErrOut.
- LPC Bridge: 06 01 00
-
-Arguments:
-
- DeviceHandle - Handle of PCIIO protocol.
-
-Returns:
-
- EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut.
- EFI_STATUS - No LPC bridge is added.
-
---*/
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
@@ -234,9 +463,10 @@ Returns:
//
// Register Keyboard
//
- DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);
- BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
//
// Register COM1
@@ -244,14 +474,17 @@ Returns:
DevicePath = TempDevicePath;
gPnp16550ComPortDeviceNode.UID = 0;
- DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);
- DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
- DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
//
// Print Device Path
//
- DevPathStr = DevicePathToStr(DevicePath);
+ DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
if (DevPathStr != NULL) {
DEBUG((
EFI_D_INFO,
@@ -263,9 +496,9 @@ Returns:
FreePool(DevPathStr);
}
- BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);
- BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);
- BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
//
// Register COM2
@@ -273,14 +506,17 @@ Returns:
DevicePath = TempDevicePath;
gPnp16550ComPortDeviceNode.UID = 1;
- DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);
- DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
- DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
//
// Print Device Path
//
- DevPathStr = DevicePathToStr(DevicePath);
+ DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
if (DevPathStr != NULL) {
DEBUG((
EFI_D_INFO,
@@ -292,9 +528,9 @@ Returns:
FreePool(DevPathStr);
}
- BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);
- BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);
- BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
return EFI_SUCCESS;
}
@@ -333,7 +569,7 @@ GetGopDevicePath (
}
//
- // Try to connect this handle, so that GOP dirver could start on this
+ // Try to connect this handle, so that GOP driver could start on this
// device and create child handles with GraphicsOutput Protocol installed
// on them, then we get device paths of these child handles and select
// them as possible console device.
@@ -352,7 +588,8 @@ GetGopDevicePath (
// Add all the child handles as possible Console Device
//
for (Index = 0; Index < GopHandleCount; Index++) {
- Status = gBS->HandleProtocol (GopHandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath);
+ Status = gBS->HandleProtocol (GopHandleBuffer[Index],
+ &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath);
if (EFI_ERROR (Status)) {
continue;
}
@@ -365,17 +602,17 @@ GetGopDevicePath (
// In current implementation, we only enable one of the child handles
// as console device, i.e. sotre one of the child handle's device
// path to variable "ConOut"
- // In futhure, we could select all child handles to be console device
+ // In future, we could select all child handles to be console device
//
*GopDevicePath = TempDevicePath;
//
- // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()
- // Add the integrity GOP device path.
+ // Delete the PCI device's path that added by
+ // GetPlugInPciVgaDevicePath(). Add the integrity GOP device path.
//
- BdsLibUpdateConsoleVariable (VarConsoleOutDev, NULL, PciDevicePath);
- BdsLibUpdateConsoleVariable (VarConsoleOutDev, TempDevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ConOutDev, NULL, PciDevicePath);
+ EfiBootManagerUpdateConsoleVariable (ConOutDev, TempDevicePath, NULL);
}
}
gBS->FreePool (GopHandleBuffer);
@@ -384,27 +621,20 @@ GetGopDevicePath (
return EFI_SUCCESS;
}
-EFI_STATUS
-PreparePciVgaDevicePath (
- IN EFI_HANDLE DeviceHandle
- )
-/*++
-
-Routine Description:
-
- Add PCI VGA to ConOut.
- PCI VGA: 03 00 00
-
-Arguments:
-
- DeviceHandle - Handle of PCIIO protocol.
+/**
+ Add PCI display to ConOut.
-Returns:
+ @param[in] DeviceHandle Handle of the PCI display device.
- EFI_SUCCESS - PCI VGA is added to ConOut.
- EFI_STATUS - No PCI VGA device is added.
+ @retval EFI_SUCCESS The PCI display device has been added to ConOut.
---*/
+ @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing
+ from DeviceHandle.
+**/
+EFI_STATUS
+PreparePciDisplayDevicePath (
+ IN EFI_HANDLE DeviceHandle
+ )
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
@@ -424,32 +654,26 @@ Returns:
GetGopDevicePath (DevicePath, &GopDevicePath);
DevicePath = GopDevicePath;
- BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
return EFI_SUCCESS;
}
-EFI_STATUS
-PreparePciSerialDevicePath (
- IN EFI_HANDLE DeviceHandle
- )
-/*++
-
-Routine Description:
-
+/**
Add PCI Serial to ConOut, ConIn, ErrOut.
- PCI Serial: 07 00 02
-
-Arguments:
-
- DeviceHandle - Handle of PCIIO protocol.
-Returns:
+ @param[in] DeviceHandle Handle of the PCI serial device.
- EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.
- EFI_STATUS - No PCI Serial device is added.
+ @retval EFI_SUCCESS The PCI serial device has been added to ConOut, ConIn,
+ ErrOut.
---*/
+ @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing
+ from DeviceHandle.
+**/
+EFI_STATUS
+PreparePciSerialDevicePath (
+ IN EFI_HANDLE DeviceHandle
+ )
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
@@ -464,12 +688,14 @@ Returns:
return Status;
}
- DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
- DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
- BdsLibUpdateConsoleVariable (VarConsoleOut, DevicePath, NULL);
- BdsLibUpdateConsoleVariable (VarConsoleInp, DevicePath, NULL);
- BdsLibUpdateConsoleVariable (VarErrorOut, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
return EFI_SUCCESS;
}
@@ -581,7 +807,8 @@ VisitAllPciInstances (
@param[in] PciIo - PCI IO protocol instance
@param[in] Pci - PCI Header register block
- @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
+ @retval EFI_SUCCESS - PCI Device check and Console variable update
+ successfully.
@retval EFI_STATUS - PCI Device check or Console variable update fail.
**/
@@ -635,14 +862,14 @@ DetectAndPreparePlatformPciDevicePath (
}
//
- // Here we decide which VGA device to enable in PCI bus
+ // Here we decide which display device to enable in PCI bus
//
- if (IS_PCI_VGA (Pci)) {
+ if (IS_PCI_DISPLAY (Pci)) {
//
// Add them to ConOut.
//
- DEBUG ((EFI_D_INFO, "Found PCI VGA device\n"));
- PreparePciVgaDevicePath (Handle);
+ DEBUG ((EFI_D_INFO, "Found PCI display device\n"));
+ PreparePciDisplayDevicePath (Handle);
return EFI_SUCCESS;
}
@@ -655,7 +882,8 @@ DetectAndPreparePlatformPciDevicePath (
@param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.
- @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
+ @retval EFI_SUCCESS - PCI Device check and Console variable update
+ successfully.
@retval EFI_STATUS - PCI Device check or Console variable update fail.
**/
@@ -669,61 +897,39 @@ DetectAndPreparePlatformPciDevicePaths (
}
-EFI_STATUS
-PlatformBdsConnectConsole (
- IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
- )
-/*++
-
-Routine Description:
-
- Connect the predefined platform default console device. Always try to find
- and enable the vga device if have.
-
-Arguments:
-
- PlatformConsole - Predfined platform default console device array.
-
-Returns:
-
- EFI_SUCCESS - Success connect at least one ConIn and ConOut
- device, there must have one ConOut device is
- active vga device.
+/**
+ Connect the predefined platform default console device.
- EFI_STATUS - Return the status of
- BdsLibConnectAllDefaultConsoles ()
+ Always try to find and enable PCI display devices.
---*/
+ @param[in] PlatformConsole Predefined platform default console device array.
+**/
+VOID
+PlatformInitializeConsole (
+ IN PLATFORM_CONSOLE_CONNECT_ENTRY *PlatformConsole
+ )
{
- EFI_STATUS Status;
UINTN Index;
EFI_DEVICE_PATH_PROTOCOL *VarConout;
EFI_DEVICE_PATH_PROTOCOL *VarConin;
- UINTN DevicePathSize;
//
// Connect RootBridge
//
- VarConout = BdsLibGetVariableAndSize (
- VarConsoleOut,
- &gEfiGlobalVariableGuid,
- &DevicePathSize
- );
- VarConin = BdsLibGetVariableAndSize (
- VarConsoleInp,
- &gEfiGlobalVariableGuid,
- &DevicePathSize
- );
+ GetEfiGlobalVariable2 (EFI_CON_OUT_VARIABLE_NAME, (VOID **) &VarConout,
+ NULL);
+ GetEfiGlobalVariable2 (EFI_CON_IN_VARIABLE_NAME, (VOID **) &VarConin, NULL);
if (VarConout == NULL || VarConin == NULL) {
//
- // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
+ // Do platform specific PCI Device check and add them to ConOut, ConIn,
+ // ErrOut
//
DetectAndPreparePlatformPciDevicePaths (FALSE);
//
// Have chance to connect the platform default console,
- // the platform default console is the minimue device group
+ // the platform default console is the minimum device group
// the platform should support
//
for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) {
@@ -731,13 +937,16 @@ Returns:
// Update the console variable with the connect type
//
if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
- BdsLibUpdateConsoleVariable (VarConsoleInp, PlatformConsole[Index].DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ConIn,
+ PlatformConsole[Index].DevicePath, NULL);
}
if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
- BdsLibUpdateConsoleVariable (VarConsoleOut, PlatformConsole[Index].DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ConOut,
+ PlatformConsole[Index].DevicePath, NULL);
}
if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
- BdsLibUpdateConsoleVariable (VarErrorOut, PlatformConsole[Index].DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ErrOut,
+ PlatformConsole[Index].DevicePath, NULL);
}
}
} else {
@@ -746,16 +955,6 @@ Returns:
//
DetectAndPreparePlatformPciDevicePaths (TRUE);
}
-
- //
- // Connect the all the default console with current cosole variable
- //
- Status = BdsLibConnectAllDefaultConsoles ();
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- return EFI_SUCCESS;
}
@@ -964,6 +1163,37 @@ PciAcpiInitialization (
IoOr16 ((PciRead32 (Pmba) & ~BIT0) + 4, BIT0);
}
+/**
+ This function detects if OVMF is running on Xen.
+
+**/
+STATIC
+BOOLEAN
+XenDetected (
+ VOID
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ STATIC INTN FoundHob = -1;
+
+ if (FoundHob == 0) {
+ return FALSE;
+ } else if (FoundHob == 1) {
+ return TRUE;
+ }
+
+ //
+ // See if a XenInfo HOB is available
+ //
+ GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid);
+ if (GuidHob == NULL) {
+ FoundHob = 0;
+ return FALSE;
+ }
+
+ FoundHob = 1;
+ return TRUE;
+}
EFI_STATUS
EFIAPI
@@ -977,7 +1207,11 @@ ConnectRecursivelyIfPciMassStorage (
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
CHAR16 *DevPathStr;
- if (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE)) {
+ //
+ // Recognize PCI Mass Storage, and Xen PCI devices
+ //
+ if (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE) ||
+ (XenDetected() && IS_CLASS2 (PciHeader, 0xFF, 0x80))) {
DevicePath = NULL;
Status = gBS->HandleProtocol (
Handle,
@@ -991,11 +1225,15 @@ ConnectRecursivelyIfPciMassStorage (
//
// Print Device Path
//
- DevPathStr = DevicePathToStr (DevicePath);
+ DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
if (DevPathStr != NULL) {
DEBUG((
EFI_D_INFO,
- "Found Mass Storage device: %s\n",
+ "Found %s device: %s\n",
+ (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE) ?
+ L"Mass Storage" :
+ L"Xen"
+ ),
DevPathStr
));
FreePool(DevPathStr);
@@ -1016,8 +1254,8 @@ ConnectRecursivelyIfPciMassStorage (
This notification function is invoked when the
EMU Variable FVB has been changed.
- @param Event The event that occured
- @param Context For EFI compatiblity. Not used.
+ @param Event The event that occurred
+ @param Context For EFI compatibility. Not used.
**/
VOID
@@ -1042,6 +1280,7 @@ VisitingFileSystemInstance (
{
EFI_STATUS Status;
STATIC BOOLEAN ConnectedToFileSystem = FALSE;
+ RETURN_STATUS PcdStatus;
if (ConnectedToFileSystem) {
return EFI_ALREADY_STARTED;
@@ -1061,7 +1300,9 @@ VisitingFileSystemInstance (
NULL,
&mEmuVariableEventReg
);
- PcdSet64 (PcdEmuVariableEvent, (UINT64)(UINTN) mEmuVariableEvent);
+ PcdStatus = PcdSet64S (PcdEmuVariableEvent,
+ (UINT64)(UINTN) mEmuVariableEvent);
+ ASSERT_RETURN_ERROR (PcdStatus);
return EFI_SUCCESS;
}
@@ -1080,29 +1321,18 @@ PlatformBdsRestoreNvVarsFromHardDisk (
}
+/**
+ Connect with predefined platform connect sequence.
+ The OEM/IBV can customize with their own connect sequence.
+**/
VOID
PlatformBdsConnectSequence (
VOID
)
-/*++
-
-Routine Description:
-
- Connect with predeined platform connect sequence,
- the OEM/IBV can customize with their own connect sequence.
-
-Arguments:
-
- None.
-
-Returns:
-
- None.
-
---*/
{
- UINTN Index;
+ UINTN Index;
+ RETURN_STATUS Status;
DEBUG ((EFI_D_INFO, "PlatformBdsConnectSequence\n"));
@@ -1117,104 +1347,20 @@ Returns:
//
// Build the platform boot option
//
- BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);
+ EfiBootManagerConnectDevicePath (gPlatformConnectSequence[Index], NULL);
Index++;
}
- //
- // Just use the simple policy to connect all devices
- //
- BdsLibConnectAll ();
-
- PciAcpiInitialization ();
-
- //
- // Clear the logo after all devices are connected.
- //
- gST->ConOut->ClearScreen (gST->ConOut);
-}
-
-VOID
-PlatformBdsGetDriverOption (
- IN OUT LIST_ENTRY *BdsDriverLists
- )
-/*++
-
-Routine Description:
-
- Load the predefined driver option, OEM/IBV can customize this
- to load their own drivers
-
-Arguments:
-
- BdsDriverLists - The header of the driver option link list.
-
-Returns:
-
- None.
-
---*/
-{
- DEBUG ((EFI_D_INFO, "PlatformBdsGetDriverOption\n"));
- return;
-}
-
-VOID
-PlatformBdsDiagnostics (
- IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,
- IN BOOLEAN QuietBoot,
- IN BASEM_MEMORY_TEST BaseMemoryTest
- )
-/*++
-
-Routine Description:
-
- Perform the platform diagnostic, such like test memory. OEM/IBV also
- can customize this fuction to support specific platform diagnostic.
-
-Arguments:
-
- MemoryTestLevel - The memory test intensive level
-
- QuietBoot - Indicate if need to enable the quiet boot
-
- BaseMemoryTest - A pointer to BaseMemoryTest()
-
-Returns:
-
- None.
-
---*/
-{
- EFI_STATUS Status;
-
- DEBUG ((EFI_D_INFO, "PlatformBdsDiagnostics\n"));
-
- //
- // Here we can decide if we need to show
- // the diagnostics screen
- // Notes: this quiet boot code should be remove
- // from the graphic lib
- //
- if (QuietBoot) {
- EnableQuietBoot (PcdGetPtr(PcdLogoFile));
+ Status = ConnectDevicesFromQemu ();
+ if (RETURN_ERROR (Status)) {
//
- // Perform system diagnostic
+ // Just use the simple policy to connect all devices
//
- Status = BaseMemoryTest (MemoryTestLevel);
- if (EFI_ERROR (Status)) {
- DisableQuietBoot ();
- }
-
- return ;
+ DEBUG ((DEBUG_INFO, "EfiBootManagerConnectAll\n"));
+ EfiBootManagerConnectAll ();
}
- //
- // Perform system diagnostic
- //
- Status = BaseMemoryTest (MemoryTestLevel);
}
-
/**
Save the S3 boot script.
@@ -1247,22 +1393,25 @@ SaveS3BootScript (
}
+/**
+ Do the platform specific action after the console is ready
+
+ Possible things that can be done in PlatformBootManagerAfterConsole:
+
+ > Console post action:
+ > Dynamically switch output mode from 100x31 to 80x25 for certain senarino
+ > Signal console ready platform customized event
+ > Run diagnostics like memory testing
+ > Connect certain devices
+ > Dispatch aditional option roms
+ > Special boot: e.g.: USB boot, enter UI
+**/
VOID
EFIAPI
PlatformBootManagerAfterConsole (
VOID
)
-/*++
-
-Routine Description:
-
- The function will excute with as the platform policy, current policy
- is driven by boot mode. IBV/OEM can customize this code for their specific
- policy action.
-
---*/
{
- EFI_STATUS Status;
EFI_BOOT_MODE BootMode;
DEBUG ((EFI_D_INFO, "PlatformBootManagerAfterConsole\n"));
@@ -1278,187 +1427,57 @@ Routine Description:
PlatformBdsRestoreNvVarsFromHardDisk ();
}
- //
- // Load the driver option as the driver option list
- //
- PlatformBdsGetDriverOption (DriverOptionList);
-
//
// Get current Boot Mode
//
- Status = BdsLibGetBootMode (&BootMode);
- DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode));
+ BootMode = GetBootModeHob ();
+ DEBUG ((DEBUG_INFO, "Boot Mode:%x\n", BootMode));
//
// Go the different platform policy with different boot mode
// Notes: this part code can be change with the table policy
//
ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);
- //
- // Connect platform console
- //
- Status = PlatformBdsConnectConsole (gPlatformConsole);
- if (EFI_ERROR (Status)) {
- //
- // Here OEM/IBV can customize with defined action
- //
- PlatformBdsNoConsoleAction ();
- }
//
- // Memory test and Logo show
+ // Logo show
//
- PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);
+ BootLogoEnableLogo ();
//
- // Perform some platform specific connect sequence
+ // Set PCI Interrupt Line registers and ACPI SCI_EN
//
- PlatformBdsConnectSequence ();
+ PciAcpiInitialization ();
//
// Process QEMU's -kernel command line option
//
TryRunningQemuKernel ();
- DEBUG ((EFI_D_INFO, "BdsLibConnectAll\n"));
- BdsLibConnectAll ();
- BdsLibEnumerateAllBootOption (BootOptionList);
-
- SetBootOrderFromQemu (BootOptionList);
- //
- // The BootOrder variable may have changed, reload the in-memory list with
- // it.
//
- BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
-
- PlatformBdsEnterFrontPage (GetFrontPageTimeoutFromQemu(), TRUE);
-}
-
-VOID
-EFIAPI
-PlatformBdsBootSuccess (
- IN BDS_COMMON_OPTION *Option
- )
-/*++
-
-Routine Description:
-
- Hook point after a boot attempt succeeds. We don't expect a boot option to
- return, so the EFI 1.0 specification defines that you will default to an
- interactive mode and stop processing the BootOrder list in this case. This
- is alos a platform implementation and can be customized by IBV/OEM.
-
-Arguments:
-
- Option - Pointer to Boot Option that succeeded to boot.
-
-Returns:
-
- None.
-
---*/
-{
- CHAR16 *TmpStr;
-
- DEBUG ((EFI_D_INFO, "PlatformBdsBootSuccess\n"));
- //
- // If Boot returned with EFI_SUCCESS and there is not in the boot device
- // select loop then we need to pop up a UI and wait for user input.
+ // Perform some platform specific connect sequence
//
- TmpStr = Option->StatusString;
- if (TmpStr != NULL) {
- BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);
- FreePool (TmpStr);
- }
-}
-
-VOID
-EFIAPI
-PlatformBdsBootFail (
- IN BDS_COMMON_OPTION *Option,
- IN EFI_STATUS Status,
- IN CHAR16 *ExitData,
- IN UINTN ExitDataSize
- )
-/*++
-
-Routine Description:
-
- Hook point after a boot attempt fails.
-
-Arguments:
-
- Option - Pointer to Boot Option that failed to boot.
-
- Status - Status returned from failed boot.
-
- ExitData - Exit data returned from failed boot.
-
- ExitDataSize - Exit data size returned from failed boot.
-
-Returns:
-
- None.
-
---*/
-{
- CHAR16 *TmpStr;
+ PlatformBdsConnectSequence ();
- DEBUG ((EFI_D_INFO, "PlatformBdsBootFail\n"));
+ EfiBootManagerRefreshAllBootOption ();
//
- // If Boot returned with failed status then we need to pop up a UI and wait
- // for user input.
+ // Register UEFI Shell
//
- TmpStr = Option->StatusString;
- if (TmpStr != NULL) {
- BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);
- FreePool (TmpStr);
- }
-}
-
-EFI_STATUS
-PlatformBdsNoConsoleAction (
- VOID
- )
-/*++
-
-Routine Description:
-
- This function is remained for IBV/OEM to do some platform action,
- if there no console device can be connected.
-
-Arguments:
-
- None.
-
-Returns:
-
- EFI_SUCCESS - Direct return success now.
+ PlatformRegisterFvBootOption (
+ PcdGetPtr (PcdShellFile), L"EFI Internal Shell", LOAD_OPTION_ACTIVE
+ );
---*/
-{
- DEBUG ((EFI_D_INFO, "PlatformBdsNoConsoleAction\n"));
- return EFI_SUCCESS;
+ RemoveStaleFvFileOptions ();
+ SetBootOrderFromQemu ();
}
-VOID
-EFIAPI
-PlatformBdsLockNonUpdatableFlash (
- VOID
- )
-{
- DEBUG ((EFI_D_INFO, "PlatformBdsLockNonUpdatableFlash\n"));
- return;
-}
-
-
/**
This notification function is invoked when an instance of the
EFI_DEVICE_PATH_PROTOCOL is produced.
- @param Event The event that occured
- @param Context For EFI compatiblity. Not used.
+ @param Event The event that occurred
+ @param Context For EFI compatibility. Not used.
**/
VOID
@@ -1504,7 +1523,8 @@ NotifyDevPath (
//
// Get the DevicePath protocol on that handle
//
- Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevPathNode);
+ Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid,
+ (VOID **)&DevPathNode);
ASSERT_EFI_ERROR (Status);
while (!IsDevicePathEnd (DevPathNode)) {
@@ -1554,7 +1574,8 @@ InstallDevicePathCallback (
}
/**
- This function is called each second during the boot manager waits the timeout.
+ This function is called each second during the boot manager waits the
+ timeout.
@param TimeoutRemain The remaining timeout.
**/
@@ -1564,25 +1585,22 @@ PlatformBootManagerWaitCallback (
UINT16 TimeoutRemain
)
{
-}
-
-/**
- Lock the ConsoleIn device in system table. All key
- presses will be ignored until the Password is typed in. The only way to
- disable the password is to type it in to a ConIn device.
-
- @param Password Password used to lock ConIn device.
-
- @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
- @retval EFI_UNSUPPORTED Password not found
-
-**/
-EFI_STATUS
-EFIAPI
-LockKeyboards (
- IN CHAR16 *Password
- )
-{
- return EFI_UNSUPPORTED;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White;
+ UINT16 Timeout;
+
+ Timeout = PcdGet16 (PcdPlatformBootTimeOut);
+
+ Black.Raw = 0x00000000;
+ White.Raw = 0x00FFFFFF;
+
+ BootLogoUpdateProgress (
+ White.Pixel,
+ Black.Pixel,
+ L"Start boot option",
+ White.Pixel,
+ (Timeout - TimeoutRemain) * 100 / Timeout,
+ 0
+ );
}