X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=OvmfPkg%2FLibrary%2FPlatformBootManagerLib%2FBdsPlatform.c;h=1408d94f7dae74fcef6b74f34e8f4f414026baee;hb=8e875037bf96c95b9f9c4adce8d453c7936309f0;hp=7ef4d3de16295fe466f7f43750fe4cd3f68a8a42;hpb=7f89929f7fb2f4d75c30fd6838daad61dc996eb5;p=mirror_edk2.git
diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
index 7ef4d3de16..1408d94f7d 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
+++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
@@ -1,20 +1,18 @@
/** @file
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
- 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.
+ Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "BdsPlatform.h"
#include
-#include
+#include
+#include
+#include
+#include
+#include
//
@@ -25,7 +23,6 @@ VOID *mEfiDevPathNotifyReg;
EFI_EVENT mEfiDevPathEvent;
VOID *mEmuVariableEventReg;
EFI_EVENT mEmuVariableEvent;
-BOOLEAN mDetectVgaOnly;
UINT16 mHostBridgeDevId;
//
@@ -33,14 +30,12 @@ UINT16 mHostBridgeDevId;
// (for configuring PCI Interrupt Line register)
//
CONST UINT8 PciHostIrqs[] = {
- 0x0a, 0x0a, 0x0b, 0x0b
+ 0x0a, // LNKA, LNKE
+ 0x0a, // LNKB, LNKF
+ 0x0b, // LNKC, LNKG
+ 0x0b // LNKD, LNKH
};
-//
-// Array Size macro
-//
-#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0]))
-
//
// Type definitions
//
@@ -149,6 +144,134 @@ PlatformRegisterFvBootOption (
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_BEGIN ();
+ CHAR16 *DevicePathString;
+
+ DevicePathString = ConvertDevicePathToText(BootOptions[Index].FilePath,
+ FALSE, FALSE);
+ DEBUG ((
+ EFI_ERROR (Status) ? DEBUG_WARN : DEBUG_VERBOSE,
+ "%a: removing stale Boot#%04x %s: %r\n",
+ __FUNCTION__,
+ (UINT32)BootOptions[Index].OptionNumber,
+ DevicePathString == NULL ? L"" : DevicePathString,
+ Status
+ ));
+ if (DevicePathString != NULL) {
+ FreePool (DevicePathString);
+ }
+ DEBUG_CODE_END ();
+ }
+
+ EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+}
+
VOID
PlatformRegisterOptionsAndKeys (
VOID
@@ -185,12 +308,6 @@ PlatformRegisterOptionsAndKeys (
NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL
);
ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
- //
- // Register UEFI Shell
- //
- PlatformRegisterFvBootOption (
- PcdGetPtr (PcdShellFile), L"EFI Internal Shell", LOAD_OPTION_ACTIVE
- );
}
EFI_STATUS
@@ -201,6 +318,15 @@ ConnectRootBridge (
IN VOID *Context
);
+STATIC
+EFI_STATUS
+EFIAPI
+ConnectVirtioPciRng (
+ IN EFI_HANDLE Handle,
+ IN VOID *Instance,
+ IN VOID *Context
+ );
+
STATIC
VOID
SaveS3BootScript (
@@ -210,30 +336,31 @@ 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;
+ UINT16 FrontPageTimeout;
+ RETURN_STATUS PcdStatus;
- DEBUG ((EFI_D_INFO, "PlatformBootManagerBeforeConsole\n"));
+ DEBUG ((DEBUG_INFO, "PlatformBootManagerBeforeConsole\n"));
InstallDevicePathCallback ();
VisitAllInstancesOfProtocol (&gEfiPciRootBridgeIoProtocolGuid,
@@ -253,7 +380,7 @@ Returns:
//
EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
- if (QemuFwCfgS3Enabled ()) {
+ if (PcdGetBool (PcdAcpiS3Enable)) {
//
// Save the boot script too. Note that this will require us to emit the
// DxeSmmReadyToLock event just below, which in turn locks down SMM.
@@ -261,8 +388,19 @@ Returns:
SaveS3BootScript ();
}
+ // We need to connect all trusted consoles for TCG PP. Here we treat all
+ // consoles in OVMF to be trusted consoles.
+ PlatformInitializeConsole (
+ XenDetected() ? gXenPlatformConsole : gPlatformConsole);
+
+ //
+ // Process TPM PPI request; this may require keyboard input
+ //
+ Tcg2PhysicalPresenceLibProcessRequest (NULL);
+
//
// Prevent further changes to LockBoxes or SMRAM.
+ // Any TPM 2 Physical Presence Interface opcode must be handled before.
//
Handle = NULL;
Status = gBS->InstallProtocolInterface (&Handle,
@@ -270,10 +408,44 @@ Returns:
NULL);
ASSERT_EFI_ERROR (Status);
- PlatformInitializeConsole (gPlatformConsole);
- PcdSet16 (PcdPlatformBootTimeOut, GetFrontPageTimeoutFromQemu ());
+ //
+ // Dispatch deferred images after EndOfDxe event and ReadyToLock
+ // installation.
+ //
+ EfiBootManagerDispatchDeferredImages ();
+
+ FrontPageTimeout = GetFrontPageTimeoutFromQemu ();
+ PcdStatus = PcdSet16S (PcdPlatformBootTimeOut, FrontPageTimeout);
+ ASSERT_RETURN_ERROR (PcdStatus);
+ //
+ // Reflect the PCD in the standard Timeout variable.
+ //
+ Status = gRT->SetVariable (
+ EFI_TIME_OUT_VARIABLE_NAME,
+ &gEfiGlobalVariableGuid,
+ (EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS),
+ sizeof FrontPageTimeout,
+ &FrontPageTimeout
+ );
+ DEBUG ((
+ EFI_ERROR (Status) ? DEBUG_ERROR : DEBUG_VERBOSE,
+ "%a: SetVariable(%s, %u): %r\n",
+ __FUNCTION__,
+ EFI_TIME_OUT_VARIABLE_NAME,
+ FrontPageTimeout,
+ Status
+ ));
PlatformRegisterOptionsAndKeys ();
+
+ //
+ // Install both VIRTIO_DEVICE_PROTOCOL and (dependent) EFI_RNG_PROTOCOL
+ // instances on Virtio PCI RNG devices.
+ //
+ VisitAllInstancesOfProtocol (&gEfiPciIoProtocolGuid, ConnectVirtioPciRng,
+ NULL);
}
@@ -302,28 +474,110 @@ ConnectRootBridge (
}
+STATIC
EFI_STATUS
-PrepareLpcBridgeDevicePath (
- IN EFI_HANDLE DeviceHandle
+EFIAPI
+ConnectVirtioPciRng (
+ IN EFI_HANDLE Handle,
+ IN VOID *Instance,
+ IN VOID *Context
)
-/*++
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_STATUS Status;
+ UINT16 VendorId;
+ UINT16 DeviceId;
+ UINT8 RevisionId;
+ BOOLEAN Virtio10;
+ UINT16 SubsystemId;
-Routine Description:
+ PciIo = Instance;
- Add IsaKeyboard to ConIn,
- add IsaSerial to ConOut, ConIn, ErrOut.
- LPC Bridge: 06 01 00
+ //
+ // Read and check VendorId.
+ //
+ Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_VENDOR_ID_OFFSET,
+ 1, &VendorId);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ if (VendorId != VIRTIO_VENDOR_ID) {
+ return EFI_SUCCESS;
+ }
-Arguments:
+ //
+ // Read DeviceId and RevisionId.
+ //
+ Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_DEVICE_ID_OFFSET,
+ 1, &DeviceId);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, PCI_REVISION_ID_OFFSET,
+ 1, &RevisionId);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
- DeviceHandle - Handle of PCIIO protocol.
+ //
+ // From DeviceId and RevisionId, determine whether the device is a
+ // modern-only Virtio 1.0 device. In case of Virtio 1.0, DeviceId can
+ // immediately be restricted to VIRTIO_SUBSYSTEM_ENTROPY_SOURCE, and
+ // SubsystemId will only play a sanity-check role. Otherwise, DeviceId can
+ // only be sanity-checked, and SubsystemId will decide.
+ //
+ if (DeviceId == 0x1040 + VIRTIO_SUBSYSTEM_ENTROPY_SOURCE &&
+ RevisionId >= 0x01) {
+ Virtio10 = TRUE;
+ } else if (DeviceId >= 0x1000 && DeviceId <= 0x103F && RevisionId == 0x00) {
+ Virtio10 = FALSE;
+ } else {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Read and check SubsystemId as dictated by Virtio10.
+ //
+ Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16,
+ PCI_SUBSYSTEM_ID_OFFSET, 1, &SubsystemId);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ if ((Virtio10 && SubsystemId >= 0x40) ||
+ (!Virtio10 && SubsystemId == VIRTIO_SUBSYSTEM_ENTROPY_SOURCE)) {
+ Status = gBS->ConnectController (
+ Handle, // ControllerHandle
+ NULL, // DriverImageHandle -- connect all drivers
+ NULL, // RemainingDevicePath -- produce all child handles
+ FALSE // Recursive -- don't follow child handles
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ }
+ return EFI_SUCCESS;
+
+Error:
+ DEBUG ((DEBUG_ERROR, "%a: %r\n", __FUNCTION__, Status));
+ return Status;
+}
-Returns:
- EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut.
- EFI_STATUS - No LPC bridge is added.
+/**
+ 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
+ )
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
@@ -344,7 +598,8 @@ Returns:
//
// Register Keyboard
//
- DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);
EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
@@ -354,9 +609,12 @@ 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
@@ -364,9 +622,9 @@ Returns:
DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
if (DevPathStr != NULL) {
DEBUG((
- EFI_D_INFO,
+ DEBUG_INFO,
"BdsPlatform.c+%d: COM%d DevPath: %s\n",
- __LINE__,
+ DEBUG_LINE_NUMBER,
gPnp16550ComPortDeviceNode.UID + 1,
DevPathStr
));
@@ -383,9 +641,12 @@ 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
@@ -393,9 +654,9 @@ Returns:
DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
if (DevPathStr != NULL) {
DEBUG((
- EFI_D_INFO,
+ DEBUG_INFO,
"BdsPlatform.c+%d: COM%d DevPath: %s\n",
- __LINE__,
+ DEBUG_LINE_NUMBER,
gPnp16550ComPortDeviceNode.UID + 1,
DevPathStr
));
@@ -409,6 +670,43 @@ Returns:
return EFI_SUCCESS;
}
+typedef struct {
+ VENDOR_DEVICE_PATH Guid;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} SERIAL_DEVICE_PATH;
+
+SERIAL_DEVICE_PATH serialDevicePath = {
+ {
+ { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0} },
+ EDKII_SERIAL_PORT_LIB_VENDOR_GUID
+ },
+ { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } }
+};
+
+VOID
+PrepareMicrovmDevicePath (
+ VOID
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ UINT16 HostBridgeDevId;
+
+ HostBridgeDevId = PcdGet16 (PcdOvmfHostBridgePciDevId);
+ if (HostBridgeDevId != MICROVM_PSEUDO_DEVICE_ID) {
+ return;
+ }
+
+ DevicePath = (EFI_DEVICE_PATH_PROTOCOL*)&serialDevicePath;
+ DevicePath = AppendDevicePathNode (DevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);
+ DevicePath = AppendDevicePathNode (DevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
+
+ EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
+ EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
+}
+
EFI_STATUS
GetGopDevicePath (
IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,
@@ -443,7 +741,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.
@@ -462,7 +760,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;
}
@@ -475,14 +774,14 @@ 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.
//
EfiBootManagerUpdateConsoleVariable (ConOutDev, NULL, PciDevicePath);
EfiBootManagerUpdateConsoleVariable (ConOutDev, TempDevicePath, NULL);
@@ -494,27 +793,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;
@@ -539,27 +831,21 @@ Returns:
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.
+ @param[in] DeviceHandle Handle of the PCI serial device.
-Returns:
+ @retval EFI_SUCCESS The PCI serial device has been added to ConOut, ConIn,
+ ErrOut.
- EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.
- EFI_STATUS - No PCI Serial device is added.
-
---*/
+ @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;
@@ -574,8 +860,10 @@ 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);
EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
@@ -691,7 +979,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.
**/
@@ -713,46 +1002,44 @@ DetectAndPreparePlatformPciDevicePath (
);
ASSERT_EFI_ERROR (Status);
- if (!mDetectVgaOnly) {
+ //
+ // Here we decide whether it is LPC Bridge
+ //
+ if ((IS_PCI_LPC (Pci)) ||
+ ((IS_PCI_ISA_PDECODE (Pci)) &&
+ (Pci->Hdr.VendorId == 0x8086) &&
+ (Pci->Hdr.DeviceId == 0x7000)
+ )
+ ) {
//
- // Here we decide whether it is LPC Bridge
+ // Add IsaKeyboard to ConIn,
+ // add IsaSerial to ConOut, ConIn, ErrOut
//
- if ((IS_PCI_LPC (Pci)) ||
- ((IS_PCI_ISA_PDECODE (Pci)) &&
- (Pci->Hdr.VendorId == 0x8086) &&
- (Pci->Hdr.DeviceId == 0x7000)
- )
- ) {
- //
- // Add IsaKeyboard to ConIn,
- // add IsaSerial to ConOut, ConIn, ErrOut
- //
- DEBUG ((EFI_D_INFO, "Found LPC Bridge device\n"));
- PrepareLpcBridgeDevicePath (Handle);
- return EFI_SUCCESS;
- }
+ DEBUG ((DEBUG_INFO, "Found LPC Bridge device\n"));
+ PrepareLpcBridgeDevicePath (Handle);
+ return EFI_SUCCESS;
+ }
+ //
+ // Here we decide which Serial device to enable in PCI bus
+ //
+ if (IS_PCI_16550SERIAL (Pci)) {
//
- // Here we decide which Serial device to enable in PCI bus
+ // Add them to ConOut, ConIn, ErrOut.
//
- if (IS_PCI_16550SERIAL (Pci)) {
- //
- // Add them to ConOut, ConIn, ErrOut.
- //
- DEBUG ((EFI_D_INFO, "Found PCI 16550 SERIAL device\n"));
- PreparePciSerialDevicePath (Handle);
- return EFI_SUCCESS;
- }
+ DEBUG ((DEBUG_INFO, "Found PCI 16550 SERIAL device\n"));
+ PreparePciSerialDevicePath (Handle);
+ return EFI_SUCCESS;
}
//
- // 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 ((DEBUG_INFO, "Found PCI display device\n"));
+ PreparePciDisplayDevicePath (Handle);
return EFI_SUCCESS;
}
@@ -761,80 +1048,48 @@ DetectAndPreparePlatformPciDevicePath (
/**
- Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
-
- @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.
+ Connect the predefined platform default console device.
- @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.
- @retval EFI_STATUS - PCI Device check or Console variable update fail.
+ Always try to find and enable PCI display devices.
+ @param[in] PlatformConsole Predefined platform default console device array.
**/
-EFI_STATUS
-DetectAndPreparePlatformPciDevicePaths (
- BOOLEAN DetectVgaOnly
- )
-{
- mDetectVgaOnly = DetectVgaOnly;
- return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath);
-}
-
-
VOID
PlatformInitializeConsole (
IN PLATFORM_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.
---*/
{
UINTN Index;
- EFI_DEVICE_PATH_PROTOCOL *VarConout;
- EFI_DEVICE_PATH_PROTOCOL *VarConin;
//
- // Connect RootBridge
+ // Do platform specific PCI Device check and add them to ConOut, ConIn,
+ // ErrOut
//
- GetEfiGlobalVariable2 (EFI_CON_OUT_VARIABLE_NAME, (VOID **) &VarConout, NULL);
- GetEfiGlobalVariable2 (EFI_CON_IN_VARIABLE_NAME, (VOID **) &VarConin, NULL);
+ VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath);
- if (VarConout == NULL || VarConin == NULL) {
- //
- // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
- //
- DetectAndPreparePlatformPciDevicePaths (FALSE);
+ PrepareMicrovmDevicePath ();
+ //
+ // Have chance to connect the platform default console,
+ // the platform default console is the minimum device group
+ // the platform should support
+ //
+ for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) {
//
- // Have chance to connect the platform default console,
- // the platform default console is the minimue device group
- // the platform should support
+ // Update the console variable with the connect type
//
- for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) {
- //
- // Update the console variable with the connect type
- //
- if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
- EfiBootManagerUpdateConsoleVariable (ConIn, PlatformConsole[Index].DevicePath, NULL);
- }
- if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
- EfiBootManagerUpdateConsoleVariable (ConOut, PlatformConsole[Index].DevicePath, NULL);
- }
- if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
- EfiBootManagerUpdateConsoleVariable (ErrOut, PlatformConsole[Index].DevicePath, NULL);
- }
+ if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
+ EfiBootManagerUpdateConsoleVariable (ConIn,
+ PlatformConsole[Index].DevicePath, NULL);
+ }
+ if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
+ EfiBootManagerUpdateConsoleVariable (ConOut,
+ PlatformConsole[Index].DevicePath, NULL);
+ }
+ if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
+ EfiBootManagerUpdateConsoleVariable (ErrOut,
+ PlatformConsole[Index].DevicePath, NULL);
}
- } else {
- //
- // Only detect VGA device and add them to ConOut
- //
- DetectAndPreparePlatformPciDevicePaths (TRUE);
}
}
@@ -914,7 +1169,7 @@ SetPciIntLine (
}
if (RootBusNumber == 0 && RootSlot == 0) {
DEBUG((
- EFI_D_ERROR,
+ DEBUG_ERROR,
"%a: PCI host bridge (00:00.0) should have no interrupts!\n",
__FUNCTION__
));
@@ -965,7 +1220,7 @@ SetPciIntLine (
Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
ASSERT_EFI_ERROR (Status);
- DEBUG ((EFI_D_VERBOSE, "%a: [%02x:%02x.%x] %s -> 0x%02x\n", __FUNCTION__,
+ DEBUG ((DEBUG_VERBOSE, "%a: [%02x:%02x.%x] %s -> 0x%02x\n", __FUNCTION__,
(UINT32)Bus, (UINT32)Device, (UINT32)Function, DevPathString,
IrqLine));
@@ -1007,27 +1262,35 @@ PciAcpiInitialization (
//
// 00:01.0 ISA Bridge (PIIX4) LNK routing targets
//
- PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // A
- PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // B
- PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // C
- PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // D
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), PciHostIrqs[0]); // A
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), PciHostIrqs[1]); // B
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), PciHostIrqs[2]); // C
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), PciHostIrqs[3]); // D
break;
case INTEL_Q35_MCH_DEVICE_ID:
Pmba = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);
//
// 00:1f.0 LPC Bridge (Q35) LNK routing targets
//
- PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x60), 0x0a); // A
- PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x61), 0x0a); // B
- PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x62), 0x0b); // C
- PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x63), 0x0b); // D
- PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x68), 0x0a); // E
- PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x69), 0x0a); // F
- PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6a), 0x0b); // G
- PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), 0x0b); // H
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x60), PciHostIrqs[0]); // A
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x61), PciHostIrqs[1]); // B
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x62), PciHostIrqs[2]); // C
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x63), PciHostIrqs[3]); // D
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x68), PciHostIrqs[0]); // E
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x69), PciHostIrqs[1]); // F
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6a), PciHostIrqs[2]); // G
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), PciHostIrqs[3]); // H
break;
+ case MICROVM_PSEUDO_DEVICE_ID:
+ return;
default:
- DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
+ if (XenDetected ()) {
+ //
+ // There is no PCI bus in this case.
+ //
+ return;
+ }
+ DEBUG ((DEBUG_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
__FUNCTION__, mHostBridgeDevId));
ASSERT (FALSE);
return;
@@ -1044,7 +1307,6 @@ PciAcpiInitialization (
IoOr16 ((PciRead32 (Pmba) & ~BIT0) + 4, BIT0);
}
-
EFI_STATUS
EFIAPI
ConnectRecursivelyIfPciMassStorage (
@@ -1057,7 +1319,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,
@@ -1074,8 +1340,12 @@ ConnectRecursivelyIfPciMassStorage (
DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
if (DevPathStr != NULL) {
DEBUG((
- EFI_D_INFO,
- "Found Mass Storage device: %s\n",
+ DEBUG_INFO,
+ "Found %s device: %s\n",
+ (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE) ?
+ L"Mass Storage" :
+ L"Xen"
+ ),
DevPathStr
));
FreePool(DevPathStr);
@@ -1096,8 +1366,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
@@ -1107,7 +1377,7 @@ EmuVariablesUpdatedCallback (
IN VOID *Context
)
{
- DEBUG ((EFI_D_INFO, "EmuVariablesUpdatedCallback\n"));
+ DEBUG ((DEBUG_INFO, "EmuVariablesUpdatedCallback\n"));
UpdateNvVarsOnFileSystem ();
}
@@ -1122,6 +1392,7 @@ VisitingFileSystemInstance (
{
EFI_STATUS Status;
STATIC BOOLEAN ConnectedToFileSystem = FALSE;
+ RETURN_STATUS PcdStatus;
if (ConnectedToFileSystem) {
return EFI_ALREADY_STARTED;
@@ -1141,7 +1412,9 @@ VisitingFileSystemInstance (
NULL,
&mEmuVariableEventReg
);
- PcdSet64 (PcdEmuVariableEvent, (UINT64)(UINTN) mEmuVariableEvent);
+ PcdStatus = PcdSet64S (PcdEmuVariableEvent,
+ (UINT64)(UINTN) mEmuVariableEvent);
+ ASSERT_RETURN_ERROR (PcdStatus);
return EFI_SUCCESS;
}
@@ -1160,31 +1433,20 @@ 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"));
+ DEBUG ((DEBUG_INFO, "PlatformBdsConnectSequence\n"));
Index = 0;
@@ -1197,104 +1459,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.
@@ -1327,28 +1505,31 @@ 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"));
+ DEBUG ((DEBUG_INFO, "PlatformBootManagerAfterConsole\n"));
if (PcdGetBool (PcdOvmfFlashVariablesEnable)) {
- DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior: not restoring NvVars "
+ DEBUG ((DEBUG_INFO, "PlatformBdsPolicyBehavior: not restoring NvVars "
"from disk since flash variables appear to be supported.\n"));
} else {
//
@@ -1358,16 +1539,11 @@ 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
@@ -1376,38 +1552,46 @@ Routine Description:
ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);
//
- // 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);
+ //
+ // Perform some platform specific connect sequence
+ //
+ PlatformBdsConnectSequence ();
+
+ EfiBootManagerRefreshAllBootOption ();
- SetBootOrderFromQemu (BootOptionList);
//
- // The BootOrder variable may have changed, reload the in-memory list with
- // it.
+ // Register UEFI Shell
//
- BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
+ PlatformRegisterFvBootOption (
+ &gUefiShellFileGuid, L"EFI Internal Shell", LOAD_OPTION_ACTIVE
+ );
+
+ RemoveStaleFvFileOptions ();
+ SetBootOrderFromQemu ();
+
+ PlatformBmPrintScRegisterHandler ();
}
/**
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
@@ -1453,7 +1637,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)) {
@@ -1492,7 +1677,7 @@ InstallDevicePathCallback (
VOID
)
{
- DEBUG ((EFI_D_INFO, "Registered NotifyDevPath Event\n"));
+ DEBUG ((DEBUG_INFO, "Registered NotifyDevPath Event\n"));
mEfiDevPathEvent = EfiCreateProtocolNotifyEvent (
&gEfiDevicePathProtocolGuid,
TPL_CALLBACK,
@@ -1503,7 +1688,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.
**/
@@ -1513,5 +1699,90 @@ PlatformBootManagerWaitCallback (
UINT16 TimeoutRemain
)
{
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White;
+ UINT16 TimeoutInitial;
+
+ TimeoutInitial = PcdGet16 (PcdPlatformBootTimeOut);
+
+ //
+ // If PcdPlatformBootTimeOut is set to zero, then we consider
+ // that no progress update should be enacted (since we'd only
+ // ever display a one-shot progress of either 0% or 100%).
+ //
+ if (TimeoutInitial == 0) {
+ return;
+ }
+
+ Black.Raw = 0x00000000;
+ White.Raw = 0x00FFFFFF;
+
+ BootLogoUpdateProgress (
+ White.Pixel,
+ Black.Pixel,
+ L"Start boot option",
+ White.Pixel,
+ (TimeoutInitial - TimeoutRemain) * 100 / TimeoutInitial,
+ 0
+ );
}
+/**
+ The function is called when no boot option could be launched,
+ including platform recovery options and options pointing to applications
+ built into firmware volumes.
+
+ If this function returns, BDS attempts to enter an infinite loop.
+**/
+VOID
+EFIAPI
+PlatformBootManagerUnableToBoot (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_INPUT_KEY Key;
+ EFI_BOOT_MANAGER_LOAD_OPTION BootManagerMenu;
+ UINTN Index;
+
+ //
+ // BootManagerMenu doesn't contain the correct information when return status
+ // is EFI_NOT_FOUND.
+ //
+ Status = EfiBootManagerGetBootManagerMenu (&BootManagerMenu);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+ //
+ // Normally BdsDxe does not print anything to the system console, but this is
+ // a last resort -- the end-user will likely not see any DEBUG messages
+ // logged in this situation.
+ //
+ // AsciiPrint() will NULL-check gST->ConOut internally. We check gST->ConIn
+ // here to see if it makes sense to request and wait for a keypress.
+ //
+ if (gST->ConIn != NULL) {
+ AsciiPrint (
+ "%a: No bootable option or device was found.\n"
+ "%a: Press any key to enter the Boot Manager Menu.\n",
+ gEfiCallerBaseName,
+ gEfiCallerBaseName
+ );
+ Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Index);
+ ASSERT_EFI_ERROR (Status);
+ ASSERT (Index == 0);
+
+ //
+ // Drain any queued keys.
+ //
+ while (!EFI_ERROR (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key))) {
+ //
+ // just throw away Key
+ //
+ }
+ }
+
+ for (;;) {
+ EfiBootManagerBoot (&BootManagerMenu);
+ }
+}