OvmfPkg/PlatformBootManagerLib: Connect the Xen drivers before loading NvVars

When OVMF tried to load the file-based NvVars, it checked all the PCI
instances and connected the drivers to the mass storage device. However,
Xen registered its PCI device with a special class id (0xFF80), so
ConnectRecursivelyIfPciMassStorage() couldn't recognize it and skipped the
driver connecting for Xen PCI devices. In the end, the Xen block device
wasn't initialized until EfiBootManagerConnectAll() was called, and it's
already too late to load NvVars.

This commit connects the Xen drivers in ConnectRecursivelyIfPciMassStorage()
so that Xen can use the file-based NvVars.

v3:
* Introduce XenDetected() to cache the result of Xen detection instead
  of relying on PcdPciDisableBusEnumeration.

v2:
* Cosmetic changes

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Gary Lin <glin@suse.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
This commit is contained in:
Gary Lin 2016-06-01 18:26:20 +08:00 committed by Jordan Justen
parent 05bf4747dd
commit da2369d21d
2 changed files with 40 additions and 2 deletions

View File

@ -13,6 +13,7 @@
**/
#include "BdsPlatform.h"
#include <Guid/XenInfo.h>
#include <Guid/RootBridgesConnectedEventGroup.h>
@ -1037,6 +1038,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
@ -1050,7 +1082,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,
@ -1068,7 +1104,8 @@ ConnectRecursivelyIfPciMassStorage (
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);

View File

@ -74,5 +74,6 @@
gEfiLoadedImageProtocolGuid # PROTOCOL SOMETIMES_PRODUCED
[Guids]
gEfiXenInfoGuid
gEfiEndOfDxeEventGroupGuid
gRootBridgesConnectedEventGroupGuid