/** @file\r
Platform BDS customizations.\r
\r
- Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "BdsPlatform.h"\r
-#include <Guid/XenInfo.h>\r
#include <Guid/RootBridgesConnectedEventGroup.h>\r
+#include <Guid/SerialPortLibVendor.h>\r
#include <Protocol/FirmwareVolume2.h>\r
+#include <Library/PlatformBmPrintScLib.h>\r
+#include <Library/Tcg2PhysicalPresenceLib.h>\r
+#include <Library/XenPlatformLib.h>\r
\r
\r
//\r
EFI_EVENT mEfiDevPathEvent;\r
VOID *mEmuVariableEventReg;\r
EFI_EVENT mEmuVariableEvent;\r
-BOOLEAN mDetectVgaOnly;\r
UINT16 mHostBridgeDevId;\r
\r
//\r
// (for configuring PCI Interrupt Line register)\r
//\r
CONST UINT8 PciHostIrqs[] = {\r
- 0x0a, 0x0a, 0x0b, 0x0b\r
+ 0x0a, // LNKA, LNKE\r
+ 0x0a, // LNKB, LNKF\r
+ 0x0b, // LNKC, LNKG\r
+ 0x0b // LNKD, LNKH\r
};\r
\r
-//\r
-// Array Size macro\r
-//\r
-#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0]))\r
-\r
//\r
// Type definitions\r
//\r
DevicePathString = ConvertDevicePathToText(BootOptions[Index].FilePath,\r
FALSE, FALSE);\r
DEBUG ((\r
- EFI_ERROR (Status) ? EFI_D_WARN : EFI_D_VERBOSE,\r
+ EFI_ERROR (Status) ? DEBUG_WARN : DEBUG_VERBOSE,\r
"%a: removing stale Boot#%04x %s: %r\n",\r
__FUNCTION__,\r
(UINT32)BootOptions[Index].OptionNumber,\r
IN VOID *Context\r
);\r
\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+ConnectVirtioPciRng (\r
+ IN EFI_HANDLE Handle,\r
+ IN VOID *Instance,\r
+ IN VOID *Context\r
+ );\r
+\r
STATIC\r
VOID\r
SaveS3BootScript (\r
//\r
// BDS Platform Functions\r
//\r
+/**\r
+ Do the platform init, can be customized by OEM/IBV\r
+\r
+ Possible things that can be done in PlatformBootManagerBeforeConsole:\r
+\r
+ > Update console variable: 1. include hot-plug devices;\r
+ > 2. Clear ConIn and add SOL for AMT\r
+ > Register new Driver#### or Boot####\r
+ > Register new Key####: e.g.: F12\r
+ > Signal ReadyToLock event\r
+ > Authentication action: 1. connect Auth devices;\r
+ > 2. Identify auto logon user.\r
+**/\r
VOID\r
EFIAPI\r
PlatformBootManagerBeforeConsole (\r
VOID\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Platform Bds init. Include the platform firmware vendor, revision\r
- and so crc check.\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
- None.\r
-\r
---*/\r
{\r
- EFI_HANDLE Handle;\r
- EFI_STATUS Status;\r
+ EFI_HANDLE Handle;\r
+ EFI_STATUS Status;\r
+ UINT16 FrontPageTimeout;\r
+ RETURN_STATUS PcdStatus;\r
\r
- DEBUG ((EFI_D_INFO, "PlatformBootManagerBeforeConsole\n"));\r
+ DEBUG ((DEBUG_INFO, "PlatformBootManagerBeforeConsole\n"));\r
InstallDevicePathCallback ();\r
\r
VisitAllInstancesOfProtocol (&gEfiPciRootBridgeIoProtocolGuid,\r
//\r
EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);\r
\r
- if (QemuFwCfgS3Enabled ()) {\r
+ if (PcdGetBool (PcdAcpiS3Enable)) {\r
//\r
// Save the boot script too. Note that this will require us to emit the\r
// DxeSmmReadyToLock event just below, which in turn locks down SMM.\r
SaveS3BootScript ();\r
}\r
\r
+ // We need to connect all trusted consoles for TCG PP. Here we treat all\r
+ // consoles in OVMF to be trusted consoles.\r
+ PlatformInitializeConsole (\r
+ XenDetected() ? gXenPlatformConsole : gPlatformConsole);\r
+\r
+ //\r
+ // Process TPM PPI request; this may require keyboard input\r
+ //\r
+ Tcg2PhysicalPresenceLibProcessRequest (NULL);\r
+\r
//\r
// Prevent further changes to LockBoxes or SMRAM.\r
+ // Any TPM 2 Physical Presence Interface opcode must be handled before.\r
//\r
Handle = NULL;\r
Status = gBS->InstallProtocolInterface (&Handle,\r
NULL);\r
ASSERT_EFI_ERROR (Status);\r
\r
- PlatformInitializeConsole (gPlatformConsole);\r
- PcdSet16 (PcdPlatformBootTimeOut, GetFrontPageTimeoutFromQemu ());\r
+ //\r
+ // Dispatch deferred images after EndOfDxe event and ReadyToLock\r
+ // installation.\r
+ //\r
+ EfiBootManagerDispatchDeferredImages ();\r
+\r
+ FrontPageTimeout = GetFrontPageTimeoutFromQemu ();\r
+ PcdStatus = PcdSet16S (PcdPlatformBootTimeOut, FrontPageTimeout);\r
+ ASSERT_RETURN_ERROR (PcdStatus);\r
+ //\r
+ // Reflect the PCD in the standard Timeout variable.\r
+ //\r
+ Status = gRT->SetVariable (\r
+ EFI_TIME_OUT_VARIABLE_NAME,\r
+ &gEfiGlobalVariableGuid,\r
+ (EFI_VARIABLE_NON_VOLATILE |\r
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |\r
+ EFI_VARIABLE_RUNTIME_ACCESS),\r
+ sizeof FrontPageTimeout,\r
+ &FrontPageTimeout\r
+ );\r
+ DEBUG ((\r
+ EFI_ERROR (Status) ? DEBUG_ERROR : DEBUG_VERBOSE,\r
+ "%a: SetVariable(%s, %u): %r\n",\r
+ __FUNCTION__,\r
+ EFI_TIME_OUT_VARIABLE_NAME,\r
+ FrontPageTimeout,\r
+ Status\r
+ ));\r
\r
PlatformRegisterOptionsAndKeys ();\r
+\r
+ //\r
+ // Install both VIRTIO_DEVICE_PROTOCOL and (dependent) EFI_RNG_PROTOCOL\r
+ // instances on Virtio PCI RNG devices.\r
+ //\r
+ VisitAllInstancesOfProtocol (&gEfiPciIoProtocolGuid, ConnectVirtioPciRng,\r
+ NULL);\r
}\r
\r
\r
}\r
\r
\r
+STATIC\r
EFI_STATUS\r
-PrepareLpcBridgeDevicePath (\r
- IN EFI_HANDLE DeviceHandle\r
+EFIAPI\r
+ConnectVirtioPciRng (\r
+ IN EFI_HANDLE Handle,\r
+ IN VOID *Instance,\r
+ IN VOID *Context\r
)\r
-/*++\r
+{\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_STATUS Status;\r
+ UINT16 VendorId;\r
+ UINT16 DeviceId;\r
+ UINT8 RevisionId;\r
+ BOOLEAN Virtio10;\r
+ UINT16 SubsystemId;\r
\r
-Routine Description:\r
+ PciIo = Instance;\r
\r
- Add IsaKeyboard to ConIn,\r
- add IsaSerial to ConOut, ConIn, ErrOut.\r
- LPC Bridge: 06 01 00\r
+ //\r
+ // Read and check VendorId.\r
+ //\r
+ Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_VENDOR_ID_OFFSET,\r
+ 1, &VendorId);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Error;\r
+ }\r
+ if (VendorId != VIRTIO_VENDOR_ID) {\r
+ return EFI_SUCCESS;\r
+ }\r
\r
-Arguments:\r
+ //\r
+ // Read DeviceId and RevisionId.\r
+ //\r
+ Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_DEVICE_ID_OFFSET,\r
+ 1, &DeviceId);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Error;\r
+ }\r
+ Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, PCI_REVISION_ID_OFFSET,\r
+ 1, &RevisionId);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Error;\r
+ }\r
\r
- DeviceHandle - Handle of PCIIO protocol.\r
+ //\r
+ // From DeviceId and RevisionId, determine whether the device is a\r
+ // modern-only Virtio 1.0 device. In case of Virtio 1.0, DeviceId can\r
+ // immediately be restricted to VIRTIO_SUBSYSTEM_ENTROPY_SOURCE, and\r
+ // SubsystemId will only play a sanity-check role. Otherwise, DeviceId can\r
+ // only be sanity-checked, and SubsystemId will decide.\r
+ //\r
+ if (DeviceId == 0x1040 + VIRTIO_SUBSYSTEM_ENTROPY_SOURCE &&\r
+ RevisionId >= 0x01) {\r
+ Virtio10 = TRUE;\r
+ } else if (DeviceId >= 0x1000 && DeviceId <= 0x103F && RevisionId == 0x00) {\r
+ Virtio10 = FALSE;\r
+ } else {\r
+ return EFI_SUCCESS;\r
+ }\r
\r
-Returns:\r
+ //\r
+ // Read and check SubsystemId as dictated by Virtio10.\r
+ //\r
+ Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16,\r
+ PCI_SUBSYSTEM_ID_OFFSET, 1, &SubsystemId);\r
+ if (EFI_ERROR (Status)) {\r
+ goto Error;\r
+ }\r
+ if ((Virtio10 && SubsystemId >= 0x40) ||\r
+ (!Virtio10 && SubsystemId == VIRTIO_SUBSYSTEM_ENTROPY_SOURCE)) {\r
+ Status = gBS->ConnectController (\r
+ Handle, // ControllerHandle\r
+ NULL, // DriverImageHandle -- connect all drivers\r
+ NULL, // RemainingDevicePath -- produce all child handles\r
+ FALSE // Recursive -- don't follow child handles\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto Error;\r
+ }\r
+ }\r
+ return EFI_SUCCESS;\r
+\r
+Error:\r
+ DEBUG ((DEBUG_ERROR, "%a: %r\n", __FUNCTION__, Status));\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Add IsaKeyboard to ConIn; add IsaSerial to ConOut, ConIn, ErrOut.\r
\r
- EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut.\r
- EFI_STATUS - No LPC bridge is added.\r
+ @param[in] DeviceHandle Handle of the LPC Bridge device.\r
\r
---*/\r
+ @retval EFI_SUCCESS Console devices on the LPC bridge have been added to\r
+ ConOut, ConIn, and ErrOut.\r
+\r
+ @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing\r
+ from DeviceHandle.\r
+**/\r
+EFI_STATUS\r
+PrepareLpcBridgeDevicePath (\r
+ IN EFI_HANDLE DeviceHandle\r
+ )\r
{\r
EFI_STATUS Status;\r
EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
//\r
// Register Keyboard\r
//\r
- DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);\r
+ DevicePath = AppendDevicePathNode (DevicePath,\r
+ (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);\r
\r
EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);\r
\r
DevicePath = TempDevicePath;\r
gPnp16550ComPortDeviceNode.UID = 0;\r
\r
- DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);\r
- DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
- DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
+ DevicePath = AppendDevicePathNode (DevicePath,\r
+ (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);\r
+ DevicePath = AppendDevicePathNode (DevicePath,\r
+ (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
+ DevicePath = AppendDevicePathNode (DevicePath,\r
+ (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
\r
//\r
// Print Device Path\r
DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);\r
if (DevPathStr != NULL) {\r
DEBUG((\r
- EFI_D_INFO,\r
+ DEBUG_INFO,\r
"BdsPlatform.c+%d: COM%d DevPath: %s\n",\r
- __LINE__,\r
+ DEBUG_LINE_NUMBER,\r
gPnp16550ComPortDeviceNode.UID + 1,\r
DevPathStr\r
));\r
DevicePath = TempDevicePath;\r
gPnp16550ComPortDeviceNode.UID = 1;\r
\r
- DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);\r
- DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
- DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
+ DevicePath = AppendDevicePathNode (DevicePath,\r
+ (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode);\r
+ DevicePath = AppendDevicePathNode (DevicePath,\r
+ (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
+ DevicePath = AppendDevicePathNode (DevicePath,\r
+ (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
\r
//\r
// Print Device Path\r
DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);\r
if (DevPathStr != NULL) {\r
DEBUG((\r
- EFI_D_INFO,\r
+ DEBUG_INFO,\r
"BdsPlatform.c+%d: COM%d DevPath: %s\n",\r
- __LINE__,\r
+ DEBUG_LINE_NUMBER,\r
gPnp16550ComPortDeviceNode.UID + 1,\r
DevPathStr\r
));\r
return EFI_SUCCESS;\r
}\r
\r
+typedef struct {\r
+ VENDOR_DEVICE_PATH Guid;\r
+ EFI_DEVICE_PATH_PROTOCOL End;\r
+} SERIAL_DEVICE_PATH;\r
+\r
+SERIAL_DEVICE_PATH serialDevicePath = {\r
+ {\r
+ { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0} },\r
+ EDKII_SERIAL_PORT_LIB_VENDOR_GUID\r
+ },\r
+ { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } }\r
+};\r
+\r
+VOID\r
+PrepareMicrovmDevicePath (\r
+ VOID\r
+ )\r
+{\r
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
+ UINT16 HostBridgeDevId;\r
+\r
+ HostBridgeDevId = PcdGet16 (PcdOvmfHostBridgePciDevId);\r
+ if (HostBridgeDevId != MICROVM_PSEUDO_DEVICE_ID) {\r
+ return;\r
+ }\r
+\r
+ DevicePath = (EFI_DEVICE_PATH_PROTOCOL*)&serialDevicePath;\r
+ DevicePath = AppendDevicePathNode (DevicePath,\r
+ (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
+ DevicePath = AppendDevicePathNode (DevicePath,\r
+ (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
+\r
+ EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);\r
+ EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);\r
+ EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);\r
+}\r
+\r
EFI_STATUS\r
GetGopDevicePath (\r
IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,\r
// Add all the child handles as possible Console Device\r
//\r
for (Index = 0; Index < GopHandleCount; Index++) {\r
- Status = gBS->HandleProtocol (GopHandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath);\r
+ Status = gBS->HandleProtocol (GopHandleBuffer[Index],\r
+ &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath);\r
if (EFI_ERROR (Status)) {\r
continue;\r
}\r
*GopDevicePath = TempDevicePath;\r
\r
//\r
- // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath()\r
- // Add the integrity GOP device path.\r
+ // Delete the PCI device's path that added by\r
+ // GetPlugInPciVgaDevicePath(). Add the integrity GOP device path.\r
//\r
EfiBootManagerUpdateConsoleVariable (ConOutDev, NULL, PciDevicePath);\r
EfiBootManagerUpdateConsoleVariable (ConOutDev, TempDevicePath, NULL);\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Add PCI display to ConOut.\r
+\r
+ @param[in] DeviceHandle Handle of the PCI display device.\r
+\r
+ @retval EFI_SUCCESS The PCI display device has been added to ConOut.\r
+\r
+ @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing\r
+ from DeviceHandle.\r
+**/\r
EFI_STATUS\r
PreparePciDisplayDevicePath (\r
IN EFI_HANDLE DeviceHandle\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Add PCI VGA to ConOut.\r
- PCI VGA: 03 00 00\r
-\r
-Arguments:\r
-\r
- DeviceHandle - Handle of PCIIO protocol.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - PCI VGA is added to ConOut.\r
- EFI_STATUS - No PCI VGA device is added.\r
-\r
---*/\r
{\r
EFI_STATUS Status;\r
EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
return EFI_SUCCESS;\r
}\r
\r
-EFI_STATUS\r
-PreparePciSerialDevicePath (\r
- IN EFI_HANDLE DeviceHandle\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
+/**\r
Add PCI Serial to ConOut, ConIn, ErrOut.\r
- PCI Serial: 07 00 02\r
-\r
-Arguments:\r
\r
- DeviceHandle - Handle of PCIIO protocol.\r
+ @param[in] DeviceHandle Handle of the PCI serial device.\r
\r
-Returns:\r
+ @retval EFI_SUCCESS The PCI serial device has been added to ConOut, ConIn,\r
+ ErrOut.\r
\r
- EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut.\r
- EFI_STATUS - No PCI Serial device is added.\r
-\r
---*/\r
+ @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing\r
+ from DeviceHandle.\r
+**/\r
+EFI_STATUS\r
+PreparePciSerialDevicePath (\r
+ IN EFI_HANDLE DeviceHandle\r
+ )\r
{\r
EFI_STATUS Status;\r
EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
return Status;\r
}\r
\r
- DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
- DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
+ DevicePath = AppendDevicePathNode (DevicePath,\r
+ (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode);\r
+ DevicePath = AppendDevicePathNode (DevicePath,\r
+ (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);\r
\r
EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);\r
EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);\r
@param[in] PciIo - PCI IO protocol instance\r
@param[in] Pci - PCI Header register block\r
\r
- @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
+ @retval EFI_SUCCESS - PCI Device check and Console variable update\r
+ successfully.\r
@retval EFI_STATUS - PCI Device check or Console variable update fail.\r
\r
**/\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
- if (!mDetectVgaOnly) {\r
+ //\r
+ // Here we decide whether it is LPC Bridge\r
+ //\r
+ if ((IS_PCI_LPC (Pci)) ||\r
+ ((IS_PCI_ISA_PDECODE (Pci)) &&\r
+ (Pci->Hdr.VendorId == 0x8086) &&\r
+ (Pci->Hdr.DeviceId == 0x7000)\r
+ )\r
+ ) {\r
//\r
- // Here we decide whether it is LPC Bridge\r
+ // Add IsaKeyboard to ConIn,\r
+ // add IsaSerial to ConOut, ConIn, ErrOut\r
//\r
- if ((IS_PCI_LPC (Pci)) ||\r
- ((IS_PCI_ISA_PDECODE (Pci)) &&\r
- (Pci->Hdr.VendorId == 0x8086) &&\r
- (Pci->Hdr.DeviceId == 0x7000)\r
- )\r
- ) {\r
- //\r
- // Add IsaKeyboard to ConIn,\r
- // add IsaSerial to ConOut, ConIn, ErrOut\r
- //\r
- DEBUG ((EFI_D_INFO, "Found LPC Bridge device\n"));\r
- PrepareLpcBridgeDevicePath (Handle);\r
- return EFI_SUCCESS;\r
- }\r
+ DEBUG ((DEBUG_INFO, "Found LPC Bridge device\n"));\r
+ PrepareLpcBridgeDevicePath (Handle);\r
+ return EFI_SUCCESS;\r
+ }\r
+ //\r
+ // Here we decide which Serial device to enable in PCI bus\r
+ //\r
+ if (IS_PCI_16550SERIAL (Pci)) {\r
//\r
- // Here we decide which Serial device to enable in PCI bus\r
+ // Add them to ConOut, ConIn, ErrOut.\r
//\r
- if (IS_PCI_16550SERIAL (Pci)) {\r
- //\r
- // Add them to ConOut, ConIn, ErrOut.\r
- //\r
- DEBUG ((EFI_D_INFO, "Found PCI 16550 SERIAL device\n"));\r
- PreparePciSerialDevicePath (Handle);\r
- return EFI_SUCCESS;\r
- }\r
+ DEBUG ((DEBUG_INFO, "Found PCI 16550 SERIAL device\n"));\r
+ PreparePciSerialDevicePath (Handle);\r
+ return EFI_SUCCESS;\r
}\r
\r
//\r
//\r
// Add them to ConOut.\r
//\r
- DEBUG ((EFI_D_INFO, "Found PCI display device\n"));\r
+ DEBUG ((DEBUG_INFO, "Found PCI display device\n"));\r
PreparePciDisplayDevicePath (Handle);\r
return EFI_SUCCESS;\r
}\r
\r
\r
/**\r
- Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
+ Connect the predefined platform default console device.\r
\r
- @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE.\r
-\r
- @retval EFI_SUCCESS - PCI Device check and Console variable update successfully.\r
- @retval EFI_STATUS - PCI Device check or Console variable update fail.\r
+ Always try to find and enable PCI display devices.\r
\r
+ @param[in] PlatformConsole Predefined platform default console device array.\r
**/\r
-EFI_STATUS\r
-DetectAndPreparePlatformPciDevicePaths (\r
- BOOLEAN DetectVgaOnly\r
- )\r
-{\r
- mDetectVgaOnly = DetectVgaOnly;\r
- return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath);\r
-}\r
-\r
-\r
VOID\r
PlatformInitializeConsole (\r
IN PLATFORM_CONSOLE_CONNECT_ENTRY *PlatformConsole\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Connect the predefined platform default console device. Always try to find\r
- and enable the vga device if have.\r
-\r
-Arguments:\r
-\r
- PlatformConsole - Predefined platform default console device array.\r
---*/\r
{\r
UINTN Index;\r
- EFI_DEVICE_PATH_PROTOCOL *VarConout;\r
- EFI_DEVICE_PATH_PROTOCOL *VarConin;\r
\r
//\r
- // Connect RootBridge\r
+ // Do platform specific PCI Device check and add them to ConOut, ConIn,\r
+ // ErrOut\r
//\r
- GetEfiGlobalVariable2 (EFI_CON_OUT_VARIABLE_NAME, (VOID **) &VarConout, NULL);\r
- GetEfiGlobalVariable2 (EFI_CON_IN_VARIABLE_NAME, (VOID **) &VarConin, NULL);\r
+ VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath);\r
\r
- if (VarConout == NULL || VarConin == NULL) {\r
- //\r
- // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut\r
- //\r
- DetectAndPreparePlatformPciDevicePaths (FALSE);\r
+ PrepareMicrovmDevicePath ();\r
\r
+ //\r
+ // Have chance to connect the platform default console,\r
+ // the platform default console is the minimum device group\r
+ // the platform should support\r
+ //\r
+ for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) {\r
//\r
- // Have chance to connect the platform default console,\r
- // the platform default console is the minimum device group\r
- // the platform should support\r
+ // Update the console variable with the connect type\r
//\r
- for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) {\r
- //\r
- // Update the console variable with the connect type\r
- //\r
- if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {\r
- EfiBootManagerUpdateConsoleVariable (ConIn, PlatformConsole[Index].DevicePath, NULL);\r
- }\r
- if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {\r
- EfiBootManagerUpdateConsoleVariable (ConOut, PlatformConsole[Index].DevicePath, NULL);\r
- }\r
- if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {\r
- EfiBootManagerUpdateConsoleVariable (ErrOut, PlatformConsole[Index].DevicePath, NULL);\r
- }\r
+ if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {\r
+ EfiBootManagerUpdateConsoleVariable (ConIn,\r
+ PlatformConsole[Index].DevicePath, NULL);\r
+ }\r
+ if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {\r
+ EfiBootManagerUpdateConsoleVariable (ConOut,\r
+ PlatformConsole[Index].DevicePath, NULL);\r
+ }\r
+ if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {\r
+ EfiBootManagerUpdateConsoleVariable (ErrOut,\r
+ PlatformConsole[Index].DevicePath, NULL);\r
}\r
- } else {\r
- //\r
- // Only detect VGA device and add them to ConOut\r
- //\r
- DetectAndPreparePlatformPciDevicePaths (TRUE);\r
}\r
}\r
\r
}\r
if (RootBusNumber == 0 && RootSlot == 0) {\r
DEBUG((\r
- EFI_D_ERROR,\r
+ DEBUG_ERROR,\r
"%a: PCI host bridge (00:00.0) should have no interrupts!\n",\r
__FUNCTION__\r
));\r
Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);\r
ASSERT_EFI_ERROR (Status);\r
\r
- DEBUG ((EFI_D_VERBOSE, "%a: [%02x:%02x.%x] %s -> 0x%02x\n", __FUNCTION__,\r
+ DEBUG ((DEBUG_VERBOSE, "%a: [%02x:%02x.%x] %s -> 0x%02x\n", __FUNCTION__,\r
(UINT32)Bus, (UINT32)Device, (UINT32)Function, DevPathString,\r
IrqLine));\r
\r
//\r
// 00:01.0 ISA Bridge (PIIX4) LNK routing targets\r
//\r
- PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), 0x0b); // A\r
- PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), 0x0b); // B\r
- PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), 0x0a); // C\r
- PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), 0x0a); // D\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x60), PciHostIrqs[0]); // A\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x61), PciHostIrqs[1]); // B\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x62), PciHostIrqs[2]); // C\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 1, 0, 0x63), PciHostIrqs[3]); // D\r
break;\r
case INTEL_Q35_MCH_DEVICE_ID:\r
Pmba = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);\r
//\r
// 00:1f.0 LPC Bridge (Q35) LNK routing targets\r
//\r
- PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x60), 0x0a); // A\r
- PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x61), 0x0a); // B\r
- PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x62), 0x0b); // C\r
- PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x63), 0x0b); // D\r
- PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x68), 0x0a); // E\r
- PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x69), 0x0a); // F\r
- PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6a), 0x0b); // G\r
- PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), 0x0b); // H\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x60), PciHostIrqs[0]); // A\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x61), PciHostIrqs[1]); // B\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x62), PciHostIrqs[2]); // C\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x63), PciHostIrqs[3]); // D\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x68), PciHostIrqs[0]); // E\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x69), PciHostIrqs[1]); // F\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6a), PciHostIrqs[2]); // G\r
+ PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), PciHostIrqs[3]); // H\r
break;\r
+ case MICROVM_PSEUDO_DEVICE_ID:\r
+ return;\r
default:\r
- DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",\r
+ if (XenDetected ()) {\r
+ //\r
+ // There is no PCI bus in this case.\r
+ //\r
+ return;\r
+ }\r
+ DEBUG ((DEBUG_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",\r
__FUNCTION__, mHostBridgeDevId));\r
ASSERT (FALSE);\r
return;\r
IoOr16 ((PciRead32 (Pmba) & ~BIT0) + 4, BIT0);\r
}\r
\r
-/**\r
- This function detects if OVMF is running on Xen.\r
-\r
-**/\r
-STATIC\r
-BOOLEAN\r
-XenDetected (\r
- VOID\r
- )\r
-{\r
- EFI_HOB_GUID_TYPE *GuidHob;\r
- STATIC INTN FoundHob = -1;\r
-\r
- if (FoundHob == 0) {\r
- return FALSE;\r
- } else if (FoundHob == 1) {\r
- return TRUE;\r
- }\r
-\r
- //\r
- // See if a XenInfo HOB is available\r
- //\r
- GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid);\r
- if (GuidHob == NULL) {\r
- FoundHob = 0;\r
- return FALSE;\r
- }\r
-\r
- FoundHob = 1;\r
- return TRUE;\r
-}\r
-\r
EFI_STATUS\r
EFIAPI\r
ConnectRecursivelyIfPciMassStorage (\r
DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);\r
if (DevPathStr != NULL) {\r
DEBUG((\r
- EFI_D_INFO,\r
+ DEBUG_INFO,\r
"Found %s device: %s\n",\r
- IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE) ? L"Mass Storage" : L"Xen",\r
+ (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE) ?\r
+ L"Mass Storage" :\r
+ L"Xen"\r
+ ),\r
DevPathStr\r
));\r
FreePool(DevPathStr);\r
IN VOID *Context\r
)\r
{\r
- DEBUG ((EFI_D_INFO, "EmuVariablesUpdatedCallback\n"));\r
+ DEBUG ((DEBUG_INFO, "EmuVariablesUpdatedCallback\n"));\r
UpdateNvVarsOnFileSystem ();\r
}\r
\r
{\r
EFI_STATUS Status;\r
STATIC BOOLEAN ConnectedToFileSystem = FALSE;\r
+ RETURN_STATUS PcdStatus;\r
\r
if (ConnectedToFileSystem) {\r
return EFI_ALREADY_STARTED;\r
NULL,\r
&mEmuVariableEventReg\r
);\r
- PcdSet64 (PcdEmuVariableEvent, (UINT64)(UINTN) mEmuVariableEvent);\r
+ PcdStatus = PcdSet64S (PcdEmuVariableEvent,\r
+ (UINT64)(UINTN) mEmuVariableEvent);\r
+ ASSERT_RETURN_ERROR (PcdStatus);\r
\r
return EFI_SUCCESS;\r
}\r
\r
}\r
\r
+/**\r
+ Connect with predefined platform connect sequence.\r
+\r
+ The OEM/IBV can customize with their own connect sequence.\r
+**/\r
VOID\r
PlatformBdsConnectSequence (\r
VOID\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Connect with predefined platform connect sequence,\r
- the OEM/IBV can customize with their own connect sequence.\r
-\r
-Arguments:\r
-\r
- None.\r
-\r
-Returns:\r
-\r
- None.\r
-\r
---*/\r
{\r
- UINTN Index;\r
+ UINTN Index;\r
+ RETURN_STATUS Status;\r
\r
- DEBUG ((EFI_D_INFO, "PlatformBdsConnectSequence\n"));\r
+ DEBUG ((DEBUG_INFO, "PlatformBdsConnectSequence\n"));\r
\r
Index = 0;\r
\r
Index++;\r
}\r
\r
- //\r
- // Just use the simple policy to connect all devices\r
- //\r
- DEBUG ((EFI_D_INFO, "EfiBootManagerConnectAll\n"));\r
- EfiBootManagerConnectAll ();\r
-\r
- PciAcpiInitialization ();\r
+ Status = ConnectDevicesFromQemu ();\r
+ if (RETURN_ERROR (Status)) {\r
+ //\r
+ // Just use the simple policy to connect all devices\r
+ //\r
+ DEBUG ((DEBUG_INFO, "EfiBootManagerConnectAll\n"));\r
+ EfiBootManagerConnectAll ();\r
+ }\r
}\r
\r
/**\r
}\r
\r
\r
+/**\r
+ Do the platform specific action after the console is ready\r
+\r
+ Possible things that can be done in PlatformBootManagerAfterConsole:\r
+\r
+ > Console post action:\r
+ > Dynamically switch output mode from 100x31 to 80x25 for certain senarino\r
+ > Signal console ready platform customized event\r
+ > Run diagnostics like memory testing\r
+ > Connect certain devices\r
+ > Dispatch aditional option roms\r
+ > Special boot: e.g.: USB boot, enter UI\r
+**/\r
VOID\r
EFIAPI\r
PlatformBootManagerAfterConsole (\r
VOID\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- The function will execute with as the platform policy, current policy\r
- is driven by boot mode. IBV/OEM can customize this code for their specific\r
- policy action.\r
-\r
---*/\r
{\r
EFI_BOOT_MODE BootMode;\r
\r
- DEBUG ((EFI_D_INFO, "PlatformBootManagerAfterConsole\n"));\r
+ DEBUG ((DEBUG_INFO, "PlatformBootManagerAfterConsole\n"));\r
\r
if (PcdGetBool (PcdOvmfFlashVariablesEnable)) {\r
- DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior: not restoring NvVars "\r
+ DEBUG ((DEBUG_INFO, "PlatformBdsPolicyBehavior: not restoring NvVars "\r
"from disk since flash variables appear to be supported.\n"));\r
} else {\r
//\r
// Get current Boot Mode\r
//\r
BootMode = GetBootModeHob ();\r
- DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode));\r
+ DEBUG ((DEBUG_INFO, "Boot Mode:%x\n", BootMode));\r
\r
//\r
// Go the different platform policy with different boot mode\r
BootLogoEnableLogo ();\r
\r
//\r
- // Perform some platform specific connect sequence\r
+ // Set PCI Interrupt Line registers and ACPI SCI_EN\r
//\r
- PlatformBdsConnectSequence ();\r
+ PciAcpiInitialization ();\r
\r
//\r
// Process QEMU's -kernel command line option\r
//\r
TryRunningQemuKernel ();\r
\r
+ //\r
+ // Perform some platform specific connect sequence\r
+ //\r
+ PlatformBdsConnectSequence ();\r
+\r
EfiBootManagerRefreshAllBootOption ();\r
\r
//\r
// Register UEFI Shell\r
//\r
PlatformRegisterFvBootOption (\r
- PcdGetPtr (PcdShellFile), L"EFI Internal Shell", LOAD_OPTION_ACTIVE\r
+ &gUefiShellFileGuid, L"EFI Internal Shell", LOAD_OPTION_ACTIVE\r
);\r
\r
RemoveStaleFvFileOptions ();\r
SetBootOrderFromQemu ();\r
+\r
+ PlatformBmPrintScRegisterHandler ();\r
}\r
\r
/**\r
//\r
// Get the DevicePath protocol on that handle\r
//\r
- Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevPathNode);\r
+ Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid,\r
+ (VOID **)&DevPathNode);\r
ASSERT_EFI_ERROR (Status);\r
\r
while (!IsDevicePathEnd (DevPathNode)) {\r
VOID\r
)\r
{\r
- DEBUG ((EFI_D_INFO, "Registered NotifyDevPath Event\n"));\r
+ DEBUG ((DEBUG_INFO, "Registered NotifyDevPath Event\n"));\r
mEfiDevPathEvent = EfiCreateProtocolNotifyEvent (\r
&gEfiDevicePathProtocolGuid,\r
TPL_CALLBACK,\r
}\r
\r
/**\r
- This function is called each second during the boot manager waits the timeout.\r
+ This function is called each second during the boot manager waits the\r
+ timeout.\r
\r
@param TimeoutRemain The remaining timeout.\r
**/\r
{\r
EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black;\r
EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White;\r
- UINT16 Timeout;\r
+ UINT16 TimeoutInitial;\r
\r
- Timeout = PcdGet16 (PcdPlatformBootTimeOut);\r
+ TimeoutInitial = PcdGet16 (PcdPlatformBootTimeOut);\r
+\r
+ //\r
+ // If PcdPlatformBootTimeOut is set to zero, then we consider\r
+ // that no progress update should be enacted (since we'd only\r
+ // ever display a one-shot progress of either 0% or 100%).\r
+ //\r
+ if (TimeoutInitial == 0) {\r
+ return;\r
+ }\r
\r
Black.Raw = 0x00000000;\r
White.Raw = 0x00FFFFFF;\r
Black.Pixel,\r
L"Start boot option",\r
White.Pixel,\r
- (Timeout - TimeoutRemain) * 100 / Timeout,\r
+ (TimeoutInitial - TimeoutRemain) * 100 / TimeoutInitial,\r
0\r
);\r
}\r
\r
+/**\r
+ The function is called when no boot option could be launched,\r
+ including platform recovery options and options pointing to applications\r
+ built into firmware volumes.\r
+\r
+ If this function returns, BDS attempts to enter an infinite loop.\r
+**/\r
+VOID\r
+EFIAPI\r
+PlatformBootManagerUnableToBoot (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_INPUT_KEY Key;\r
+ EFI_BOOT_MANAGER_LOAD_OPTION BootManagerMenu;\r
+ UINTN Index;\r
+\r
+ //\r
+ // BootManagerMenu doesn't contain the correct information when return status\r
+ // is EFI_NOT_FOUND.\r
+ //\r
+ Status = EfiBootManagerGetBootManagerMenu (&BootManagerMenu);\r
+ if (EFI_ERROR (Status)) {\r
+ return;\r
+ }\r
+ //\r
+ // Normally BdsDxe does not print anything to the system console, but this is\r
+ // a last resort -- the end-user will likely not see any DEBUG messages\r
+ // logged in this situation.\r
+ //\r
+ // AsciiPrint() will NULL-check gST->ConOut internally. We check gST->ConIn\r
+ // here to see if it makes sense to request and wait for a keypress.\r
+ //\r
+ if (gST->ConIn != NULL) {\r
+ AsciiPrint (\r
+ "%a: No bootable option or device was found.\n"\r
+ "%a: Press any key to enter the Boot Manager Menu.\n",\r
+ gEfiCallerBaseName,\r
+ gEfiCallerBaseName\r
+ );\r
+ Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Index);\r
+ ASSERT_EFI_ERROR (Status);\r
+ ASSERT (Index == 0);\r
+\r
+ //\r
+ // Drain any queued keys.\r
+ //\r
+ while (!EFI_ERROR (gST->ConIn->ReadKeyStroke (gST->ConIn, &Key))) {\r
+ //\r
+ // just throw away Key\r
+ //\r
+ }\r
+ }\r
+\r
+ for (;;) {\r
+ EfiBootManagerBoot (&BootManagerMenu);\r
+ }\r
+}\r