]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg: fix DEC spec violation introduced by Bhyve addition
authorLaszlo Ersek <lersek@redhat.com>
Sat, 1 Aug 2020 15:50:24 +0000 (17:50 +0200)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Sat, 1 Aug 2020 20:38:55 +0000 (20:38 +0000)
Sean reports that having two DEC files under OvmfPkg violates the DEC
spec:

> An EDK II Package (directory) is a directory that contains an EDK II
> package declaration (DEC) file. Only one DEC file is permitted per
> directory. EDK II Packages cannot be nested within other EDK II
> Packages.

This issue originates from commit 656419f922c0 ("Add BhyvePkg, to support
the bhyve hypervisor", 2020-07-31).

Remedy the problem as follows. (Note that these steps are not split to
multiple patches in order to keep Bhyve buildable across the transition.)

(1) Delete "OvmfPkg/Bhyve/BhyvePkg.dec".

(2) Point the [Packages] sections of the Bhyve-specific AcpiPlatformDxe,
    BhyveRfbDxe, and BhyveFwCtlLib INF files to "OvmfPkg.dec".

(3) Migrate the artifacts that "BhyvePkg.dec" used to have on top of
    "OvmfPkg.dec" as follows:

(3a) Merge the copyright notices from Rebecca Cran and Pluribus Networks
     into "OvmfPkg.dec".

(3b) Merge the "BhyveFwCtlLib" class header definition into "OvmfPkg.dec".

(3c) Merge value 0x2F8 for the fixed PcdDebugIoPort into
     "BhyvePkgX64.dsc".

(4) Unnest the the Include/Library/ and Library/ subtrees from under
    OvmfPkg/Bhyve to the corresponding, preexistent subtrees in OvmfPkg.
    The goal is to keep the [Includes] section in the "OvmfPkg.dec" file
    unchanged, plus simplify references in "BhyvePkgX64.dsc". Non-library
    modules remain under "OvmfPkg/Bhyve/".

(4a) The BhyveFwCtlLib class header, and sole instance, are already
     uniquely named, so their movements need not involve file renames.

(4b) Rename the Bhyve-specific PlatformBootManagerLib instance to
     PlatformBootManagerLibBhyve, in additon to moving it, for
     distinguishing it from OvmfPkg's preexistent lib instance. Apply the
     name change to all three of the lib instance directory name, the INF
     file, and the BASE_NAME define in the INF file.

(4c) Update lib class resolutions in "BhyvePkgX64.dsc" accordingly.

(5) Replace the "ACPI table storage" FILE_GUID in
    "OvmfPkg/Bhyve/AcpiTables/AcpiTables.inf" with a new GUID, and
    open-code the "ACPI table storage" GUID in the "ACPITABLE" FDF rule
    instead, replacing $(NAMED_GUID). This step is necessary because CI
    requires unique FILE_GUIDs over all INF files, and OVMF's original
    "AcpiTables.inf" already uses the "ACPI table storage" GUID as
    FILE_GUID.

Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
Cc: Rebecca Cran <rebecca@bsdio.com>
Cc: Sean Brogan <spbrogan@outlook.com>
Fixes: 656419f922c047a3c48bd3f4ecea7d8e87d0b761
Reported-by: Sean Brogan <spbrogan@outlook.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20200801155024.16439-1-lersek@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Rebecca Cran <rebecca@bsdio.com>
21 files changed:
OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatformDxe.inf
OvmfPkg/Bhyve/AcpiTables/AcpiTables.inf
OvmfPkg/Bhyve/BhyvePkg.dec [deleted file]
OvmfPkg/Bhyve/BhyvePkgX64.dsc
OvmfPkg/Bhyve/BhyvePkgX64.fdf
OvmfPkg/Bhyve/BhyveRfbDxe/BhyveRfbDxe.inf
OvmfPkg/Bhyve/Include/Library/BhyveFwCtlLib.h [deleted file]
OvmfPkg/Bhyve/Library/BhyveFwCtlLib/BhyveFwCtlLib.c [deleted file]
OvmfPkg/Bhyve/Library/BhyveFwCtlLib/BhyveFwCtlLib.inf [deleted file]
OvmfPkg/Bhyve/Library/PlatformBootManagerLib/BdsPlatform.c [deleted file]
OvmfPkg/Bhyve/Library/PlatformBootManagerLib/BdsPlatform.h [deleted file]
OvmfPkg/Bhyve/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf [deleted file]
OvmfPkg/Bhyve/Library/PlatformBootManagerLib/PlatformData.c [deleted file]
OvmfPkg/Include/Library/BhyveFwCtlLib.h [new file with mode: 0644]
OvmfPkg/Library/BhyveFwCtlLib/BhyveFwCtlLib.c [new file with mode: 0644]
OvmfPkg/Library/BhyveFwCtlLib/BhyveFwCtlLib.inf [new file with mode: 0644]
OvmfPkg/Library/PlatformBootManagerLibBhyve/BdsPlatform.c [new file with mode: 0644]
OvmfPkg/Library/PlatformBootManagerLibBhyve/BdsPlatform.h [new file with mode: 0644]
OvmfPkg/Library/PlatformBootManagerLibBhyve/PlatformBootManagerLibBhyve.inf [new file with mode: 0644]
OvmfPkg/Library/PlatformBootManagerLibBhyve/PlatformData.c [new file with mode: 0644]
OvmfPkg/OvmfPkg.dec

index bf0f4877f01e13578866ceb7596e94d93e04d5a9..eec5a42f41e3da4de4788111349f7cff11215cd1 100644 (file)
@@ -31,7 +31,7 @@
 [Packages]\r
   MdePkg/MdePkg.dec\r
   MdeModulePkg/MdeModulePkg.dec\r
-  OvmfPkg/Bhyve/BhyvePkg.dec\r
+  OvmfPkg/OvmfPkg.dec\r
   UefiCpuPkg/UefiCpuPkg.dec\r
 \r
 [LibraryClasses]\r
index 18a9e2aa78b22137bde366af1e0c76f84f2d2cb3..3aab42419ca72163262062f8031e74bbecc3decb 100644 (file)
@@ -14,7 +14,7 @@
 [Defines]\r
   INF_VERSION                    = 0x00010005\r
   BASE_NAME                      = PlatformAcpiTables\r
-  FILE_GUID                      = 7E374E25-8E01-4FEE-87F2-390C23C606CD\r
+  FILE_GUID                      = B4BA6241-936C-4485-A483-9FA832C758CA\r
   MODULE_TYPE                    = USER_DEFINED\r
   VERSION_STRING                 = 1.0\r
 \r
diff --git a/OvmfPkg/Bhyve/BhyvePkg.dec b/OvmfPkg/Bhyve/BhyvePkg.dec
deleted file mode 100644 (file)
index 8884b62..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-#\r
-#  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
-#  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
-#  Copyright (c) 2014, Pluribus Networks, Inc.\r
-#\r
-#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-#\r
-##\r
-\r
-[Defines]\r
-  DEC_SPECIFICATION              = 0x00010005\r
-  PACKAGE_NAME                   = BhyvePkg\r
-  PACKAGE_GUID                   = 178345e1-6ac0-439d-a3df-9abf70dccd57\r
-  PACKAGE_VERSION                = 0.1\r
-\r
-[Includes]\r
-  Include\r
-  ../Include\r
-\r
-[LibraryClasses]\r
-  ##  @libraryclass  Save and restore variables using a file\r
-  #\r
-  NvVarsFileLib|Include/Library/NvVarsFileLib.h\r
-\r
-  ##  @libraryclass  Provides services to work with PCI capabilities in PCI\r
-  #                  config space.\r
-  PciCapLib|Include/Library/PciCapLib.h\r
-\r
-  ##  @libraryclass  Layered on top of PciCapLib, allows clients to plug an\r
-  #                  EFI_PCI_IO_PROTOCOL backend into PciCapLib, for config\r
-  #                  space access.\r
-  PciCapPciIoLib|Include/Library/PciCapPciIoLib.h\r
-\r
-  ##  @libraryclass  Layered on top of PciCapLib, allows clients to plug a\r
-  #                  PciSegmentLib backend into PciCapLib, for config space\r
-  #                  access.\r
-  PciCapPciSegmentLib|Include/Library/PciCapPciSegmentLib.h\r
-\r
-  ##  @libraryclass  Register a status code handler for printing the Boot\r
-  #                  Manager's LoadImage() and StartImage() preparations, and\r
-  #                  return codes, to the UEFI console.\r
-  PlatformBmPrintScLib|Include/Library/PlatformBmPrintScLib.h\r
-\r
-  ##  @libraryclass  Serialize (and deserialize) variables\r
-  #\r
-  SerializeVariablesLib|Include/Library/SerializeVariablesLib.h\r
-\r
-  ##  @libraryclass  Access bhyve's firmware control interface\r
-  #\r
-  BhyveFwCtlLib|Include/Library/BhyveFwCtlLib.h\r
-\r
-[Guids]\r
-  gUefiOvmfPkgTokenSpaceGuid          = {0x93bb96af, 0xb9f2, 0x4eb8, {0x94, 0x62, 0xe0, 0xba, 0x74, 0x56, 0x42, 0x36}}\r
-  gOvmfPlatformConfigGuid             = {0x7235c51c, 0x0c80, 0x4cab, {0x87, 0xac, 0x3b, 0x08, 0x4a, 0x63, 0x04, 0xb1}}\r
-  gVirtioMmioTransportGuid            = {0x837dca9e, 0xe874, 0x4d82, {0xb2, 0x9a, 0x23, 0xfe, 0x0e, 0x23, 0xd1, 0xe2}}\r
-  gRootBridgesConnectedEventGroupGuid = {0x24a2d66f, 0xeedd, 0x4086, {0x90, 0x42, 0xf2, 0x6e, 0x47, 0x97, 0xee, 0x69}}\r
-\r
-[Protocols]\r
-  gVirtioDeviceProtocolGuid           = {0xfa920010, 0x6785, 0x4941, {0xb6, 0xec, 0x49, 0x8c, 0x57, 0x9f, 0x16, 0x0a}}\r
-  gIoMmuAbsentProtocolGuid            = {0xf8775d50, 0x8abd, 0x4adf, {0x92, 0xac, 0x85, 0x3e, 0x51, 0xf6, 0xc8, 0xdc}}\r
-\r
-[PcdsFixedAtBuild]\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|0x0|UINT32|0\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize|0x0|UINT32|1\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|0x0|UINT32|0x15\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize|0x0|UINT32|0x16\r
-\r
-  ## This flag is used to control the destination port for PlatformDebugLibIoPort\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdDebugIoPort|0x2F8|UINT16|4\r
-\r
-  ## When VirtioScsiDxe is instantiated for a HBA, the numbers of targets and\r
-  #  LUNs are retrieved from the host during virtio-scsi setup.\r
-  #  MdeModulePkg/Bus/Scsi/ScsiBusDxe then scans all MaxTarget * MaxLun\r
-  #  possible devices. This can take extremely long, for example with\r
-  #  MaxTarget=255 and MaxLun=16383. The *inclusive* constants below limit\r
-  #  MaxTarget and MaxLun, independently, should the host report higher values,\r
-  #  so that scanning the number of devices given by their product is still\r
-  #  acceptably fast.\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdVirtioScsiMaxTargetLimit|31|UINT16|6\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdVirtioScsiMaxLunLimit|7|UINT32|7\r
-\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogBase|0x0|UINT32|0x8\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize|0x0|UINT32|0x9\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize|0x0|UINT32|0xa\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize|0|UINT32|0xb\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase|0x0|UINT32|0xc\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwSpareBase|0x0|UINT32|0xd\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwWorkingBase|0x0|UINT32|0xe\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress|0x0|UINT32|0xf\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase|0x0|UINT32|0x11\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize|0x0|UINT32|0x12\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|0x0|UINT32|0x13\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize|0x0|UINT32|0x14\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase|0x0|UINT32|0x18\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize|0x0|UINT32|0x19\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize|0x0|UINT32|0x1a\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecompressionScratchEnd|0x0|UINT32|0x1f\r
-\r
-  ## Pcd8259LegacyModeMask defines the default mask value for platform. This\r
-  #  value is determined.\r
-  #  1) If platform only support pure UEFI, value should be set to 0xFFFF or\r
-  #     0xFFFE; Because only clock interrupt is allowed in legacy mode in pure\r
-  #     UEFI platform.\r
-  #  2) If platform install CSM and use thunk module:\r
-  #     a) If thunk call provided by CSM binary requires some legacy interrupt\r
-  #        support, the corresponding bit should be opened as 0.\r
-  #        For example, if keyboard interfaces provided CSM binary use legacy\r
-  #        keyboard interrupt in 8259 bit 1, then the value should be set to\r
-  #        0xFFFC.\r
-  #     b) If all thunk call provied by CSM binary do not require legacy\r
-  #        interrupt support, value should be set to 0xFFFF or 0xFFFE.\r
-  #\r
-  #  The default value of legacy mode mask could be changed by\r
-  #  EFI_LEGACY_8259_PROTOCOL->SetMask(). But it is rarely need change it\r
-  #  except some special cases such as when initializing the CSM binary, it\r
-  #  should be set to 0xFFFF to mask all legacy interrupt. Please restore the\r
-  #  original legacy mask value if changing is made for these special case.\r
-  gUefiOvmfPkgTokenSpaceGuid.Pcd8259LegacyModeMask|0xFFFF|UINT16|0x3\r
-\r
-  ## Pcd8259LegacyModeEdgeLevel defines the default edge level for legacy\r
-  #  mode's interrrupt controller.\r
-  #  For the corresponding bits, 0 = Edge triggered and 1 = Level triggered.\r
-  gUefiOvmfPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel|0x0000|UINT16|0x5\r
-\r
-\r
-\r
-[PcdsDynamic, PcdsDynamicEx]\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent|0|UINT64|2\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable|FALSE|BOOLEAN|0x10\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId|0|UINT16|0x1b\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE|BOOLEAN|0x21\r
-\r
-  ## The IO port aperture shared by all PCI root bridges.\r
-  #\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase|0x0|UINT64|0x22\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoSize|0x0|UINT64|0x23\r
-\r
-  ## The 32-bit MMIO aperture shared by all PCI root bridges.\r
-  #\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Base|0x0|UINT64|0x24\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Size|0x0|UINT64|0x25\r
-\r
-  ## The 64-bit MMIO aperture shared by all PCI root bridges.\r
-  #\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Base|0x0|UINT64|0x26\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Size|0x0|UINT64|0x27\r
-\r
-  ## The following setting controls how many megabytes we configure as TSEG on\r
-  #  Q35, for SMRAM purposes. Permitted defaults are: 1, 2, 8. Other defaults\r
-  #  cause undefined behavior. During boot, the PCD is updated by PlatformPei\r
-  #  to reflect the extended TSEG size, if one is advertized by QEMU.\r
-  #\r
-  #  This PCD is only accessed if PcdSmmSmramRequire is TRUE (see below).\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes|8|UINT16|0x20\r
-\r
-[PcdsFeatureFlag]\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation|TRUE|BOOLEAN|0x1c\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderMmioTranslation|FALSE|BOOLEAN|0x1d\r
-\r
-  ## This feature flag enables SMM/SMRAM support. Note that it also requires\r
-  #  such support from the underlying QEMU instance; if that support is not\r
-  #  present, the firmware will reject continuing after a certain point.\r
-  #\r
-  #  The flag also acts as a general "security switch"; when TRUE, many\r
-  #  components will change behavior, with the goal of preventing a malicious\r
-  #  runtime OS from tampering with firmware structures (special memory ranges\r
-  #  used by OVMF, the varstore pflash chip, LockBox etc).\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire|FALSE|BOOLEAN|0x1e\r
-\r
-[Protocols]\r
-gEfiLegacyBiosProtocolGuid          = {0xdb9a1e3d, 0x45cb, 0x4abb, {0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d}}\r
index 8eba48d109a3e6b8578ad46d85127b34d9654556..99e214619be08a9aa780395c048ed9c1e0db9375 100644 (file)
   SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf\r
   QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLibNull.inf\r
   QemuFwCfgS3Lib|OvmfPkg/Library/QemuFwCfgS3Lib/BaseQemuFwCfgS3LibNull.inf\r
-  BhyveFwCtlLib|OvmfPkg/Bhyve/Library/BhyveFwCtlLib/BhyveFwCtlLib.inf\r
+  BhyveFwCtlLib|OvmfPkg/Library/BhyveFwCtlLib/BhyveFwCtlLib.inf\r
   VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf\r
   MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf\r
   LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf\r
 !else\r
   DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf\r
 !endif\r
-  PlatformBootManagerLib|OvmfPkg/Bhyve/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf\r
+  PlatformBootManagerLib|OvmfPkg/Library/PlatformBootManagerLibBhyve/PlatformBootManagerLibBhyve.inf\r
   PlatformBmPrintScLib|OvmfPkg/Library/PlatformBmPrintScLib/PlatformBmPrintScLib.inf\r
   CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf\r
   LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf\r
   gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand|FALSE\r
 \r
   gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor|L"BHYVE"\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdDebugIoPort|0x2F8\r
 \r
 ################################################################################\r
 #\r
index e2852aa5e12f990a665a74dcbaf14537923325ce..d40344d523e44b6026772efcfab4a6da90a928d0 100644 (file)
@@ -459,7 +459,7 @@ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
   }\r
 \r
 [Rule.Common.USER_DEFINED.ACPITABLE]\r
-  FILE FREEFORM = $(NAMED_GUID) {\r
+  FILE FREEFORM = 7E374E25-8E01-4FEE-87F2-390C23C606CD {\r
     RAW ACPI               |.acpi\r
     RAW ASL                |.aml\r
   }\r
index 8fd72cb78d46181a7b74938ef9790f21c5ae0865..5d6e41f0575af03813e35c95ab7cab9c1099fb37 100644 (file)
@@ -37,7 +37,7 @@
 \r
 [Packages]\r
   MdePkg/MdePkg.dec\r
-  OvmfPkg/Bhyve/BhyvePkg.dec\r
+  OvmfPkg/OvmfPkg.dec\r
   MdeModulePkg/MdeModulePkg.dec\r
 \r
 \r
diff --git a/OvmfPkg/Bhyve/Include/Library/BhyveFwCtlLib.h b/OvmfPkg/Bhyve/Include/Library/BhyveFwCtlLib.h
deleted file mode 100644 (file)
index 13028ec..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/** @file\r
-  bhyve firmware configuration access\r
-\r
-  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
-  Copyright (c) 2015 Nahanni Systems\r
-\r
-  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#ifndef __BHYVE_FW_CTL_LIB__\r
-#define __BHYVE_FW_CTL_LIB__\r
-\r
-/**\r
-  Sysctl-like interface to read host information via a dot-separated\r
-  ASCII OID.\r
-\r
-  The information is copied into the buffer specified by Item. The\r
-  size of the buffer is given by the location specified by Size\r
-  before the call, and that location gives the amount of data copied\r
-  after a successfull call, and after a call that returns a truncated\r
-  value with an error return of RETURN_BUFFER_TOO_SMALL.\r
-\r
-  The size of the available data can be determined by passing a NULL\r
-  argument for Item. The size will be returned in the location pointed\r
-  to by Size.\r
-\r
-  @param[]  Name    - ASCII OID name\r
-  @param[]  Data    - return buffer pointer\r
-  @param[]  Size    - pointer to length\r
-\r
-  @return    RETURN_SUCCESS          Valid data/len returned.\r
-          RETURN_UNSUPPORTED        f/w interface not present.\r
-          RETURN_NOT_FOUND      OID not found.\r
-        RETURN_BUFFER_TOO_SMALL      Return message truncated.\r
-        RETURN_INVALID_PARAMETER  Buffer too large\r
-        RETURN_PROTOCOL_ERROR     Unknown error from host\r
- **/\r
-RETURN_STATUS\r
-EFIAPI\r
-BhyveFwCtlGet (\r
-  IN   CONST CHAR8    *Name,\r
-  OUT  VOID        *Item,\r
-  IN OUT  UINTN        *Size\r
-  );\r
-\r
-#endif\r
diff --git a/OvmfPkg/Bhyve/Library/BhyveFwCtlLib/BhyveFwCtlLib.c b/OvmfPkg/Bhyve/Library/BhyveFwCtlLib/BhyveFwCtlLib.c
deleted file mode 100644 (file)
index 2c45ad7..0000000
+++ /dev/null
@@ -1,426 +0,0 @@
-/** @file\r
-\r
-  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
-  Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>\r
-  Copyright (C) 2013, Red Hat, Inc.\r
-  Copyright (c) 2015, Nahanni Systems.\r
-\r
-  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "Uefi.h"\r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/IoLib.h>\r
-#include <Library/BhyveFwCtlLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-\r
-#define FW_PORT        0x510\r
-#define FW_IPORT    0x511\r
-\r
-/* Transport protocol basic operations */\r
-#define OP_NULL        1\r
-#define OP_ECHO        2\r
-#define OP_GET        3\r
-#define OP_GET_LEN    4\r
-#define OP_SET        5\r
-\r
-/* Transport protocol error returns */\r
-#define T_ESUCCESS    0\r
-#define T_ENOENT    2\r
-#define T_E2BIG        7\r
-#define T_EMSGSIZE    40\r
-\r
-#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))\r
-\r
-STATIC CONST CHAR8 mBhyveSig[4] = { 'B', 'H', 'Y', 'V' };\r
-\r
-STATIC BOOLEAN mBhyveFwCtlSupported = FALSE;\r
-\r
-STATIC INTN mBhyveFwCtlTxid = 0xa5;\r
-\r
-/* XXX Maybe a better inbuilt version of this ? */\r
-struct BIoVec {\r
-  VOID        *Base;\r
-  UINTN        Len;\r
-};\r
-\r
-struct MsgRxHdr {\r
-  UINT32    Sz;\r
-  UINT32    Op;\r
-  UINT32    TxId;\r
-  UINT32    Err;\r
-};\r
-\r
-STATIC\r
-RETURN_STATUS\r
-EFIAPI\r
-BhyveFwCtl_CvtErr (\r
-   IN UINT32    errno\r
-   )\r
-{\r
-  RETURN_STATUS        Status;\r
-\r
-  switch (errno) {\r
-  case T_ESUCCESS:\r
-    Status = RETURN_SUCCESS;\r
-    break;\r
-  case T_ENOENT:\r
-    Status = RETURN_NOT_FOUND;\r
-    break;\r
-  case T_E2BIG:\r
-    Status = RETURN_INVALID_PARAMETER;\r
-    break;\r
-  case T_EMSGSIZE:\r
-    Status = RETURN_BUFFER_TOO_SMALL;\r
-    break;\r
-  default:\r
-    Status = RETURN_PROTOCOL_ERROR;\r
-    break;\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-STATIC\r
-UINTN\r
-EFIAPI\r
-BIov_WLen (\r
-   IN struct BIoVec b[]\r
-   )\r
-{\r
-  UINTN        i;\r
-  UINTN        tLen;\r
-\r
-  tLen = 0;\r
-\r
-  if (b != NULL) {\r
-    for (i = 0; b[i].Base != NULL; i++)\r
-      tLen += ROUNDUP (b[i].Len, sizeof(UINT32));\r
-  }\r
-\r
-  return tLen;\r
-}\r
-\r
-/**\r
-   Utility to send 1-3 bhyes of input as a 4-byte value\r
-   with trailing zeroes.\r
- **/\r
-STATIC\r
-UINT32\r
-BIov_Send_Rem (\r
-   IN UINT32        *Data,\r
-   IN UINTN        Len\r
-   )\r
-{\r
-  union {\r
-    UINT8    c[4];\r
-    UINT32    w;\r
-  } u;\r
-  UINT8        *cdata;\r
-  UINTN        i;\r
-\r
-  cdata = (UINT8 *)Data;\r
-  u.w = 0;\r
-\r
-  for (i = 0; i < Len; i++)\r
-    u.c[i] = *cdata++;\r
-\r
-  return u.w;\r
-}\r
-\r
-/**\r
-   Send a block of data out the i/o port as 4-byte quantities,\r
-   appending trailing zeroes on the last if required.\r
- **/\r
-STATIC\r
-VOID\r
-BIov_Send (\r
-  IN char    *Data,\r
-  IN UINTN    Len\r
-  )\r
-{\r
-  UINT32    *LData;\r
-\r
-  LData = (UINT32 *)Data;\r
-\r
-  while (Len > sizeof(UINT32)) {\r
-    IoWrite32 (FW_PORT, *LData++);\r
-    Len -= sizeof(UINT32);\r
-  }\r
-\r
-  if (Len > 0) {\r
-    IoWrite32 (FW_PORT, BIov_Send_Rem (LData, Len));\r
-  }\r
-}\r
-\r
-/**\r
-   Send data described by an array of iovecs out the i/o port.\r
- **/\r
-STATIC\r
-VOID\r
-BIov_SendAll (\r
-   IN  struct BIoVec b[]\r
-   )\r
-{\r
-  INTN        i;\r
-\r
-  if (b != NULL) {\r
-    for (i = 0; b[i].Base; i++) {\r
-      BIov_Send (b[i].Base, b[i].Len);\r
-    }\r
-  }\r
-}\r
-\r
-/**\r
-   Prepend the transport header to a block of data and send.\r
- **/\r
-STATIC\r
-VOID\r
-EFIAPI\r
-BhyveFwCtl_MsgSend(\r
-   IN  UINTN    OpCode,\r
-   IN  struct BIoVec Data[]\r
-   )\r
-{\r
-  struct BIoVec hIov[4];\r
-  UINT32        Hdr[3];\r
-  UINTN         i;\r
-\r
-  /* Set up header as an iovec */\r
-  for (i = 0; i < 3; i++) {\r
-    hIov[i].Base = &Hdr[i];\r
-    hIov[i].Len  = sizeof(Hdr[0]);\r
-  }\r
-  hIov[i].Base = NULL;\r
-  hIov[i].Len = 0;\r
-\r
-  /* Initialize header */\r
-  Hdr[0] = BIov_WLen (hIov) + BIov_WLen (Data);\r
-  Hdr[1] = OpCode;\r
-  Hdr[2] = mBhyveFwCtlTxid;\r
-\r
-  /* Send header and data */\r
-  BIov_SendAll (hIov);\r
-  BIov_SendAll (Data);\r
-}\r
-\r
-/**\r
-   Read a transport response and optional data from the i/o port.\r
- **/\r
-STATIC\r
-RETURN_STATUS\r
-EFIAPI\r
-BhyveFwCtl_MsgRecv(\r
-   OUT  struct MsgRxHdr    *Rhdr,\r
-   OUT  struct BIoVec    Data[]\r
-   )\r
-{\r
-  RETURN_STATUS        Status;\r
-  UINT32        *Dp;\r
-  UINT32        Rd;\r
-  UINTN         remLen;\r
-  INTN            oLen, xLen;\r
-\r
-  Rd = IoRead32 (FW_PORT);\r
-  if (Rd < sizeof(struct MsgRxHdr)) {\r
-    ;\r
-  }\r
-\r
-  /* Read in header and setup initial error */\r
-  Rhdr->Sz   = Rd;\r
-  Rhdr->Op   = IoRead32 (FW_PORT);\r
-  Rhdr->TxId = IoRead32 (FW_PORT);\r
-  Rhdr->Err  = IoRead32 (FW_PORT);\r
-\r
-  /* Convert transport errno into UEFI error status */\r
-  Status = BhyveFwCtl_CvtErr(Rhdr->Err);\r
-\r
-  remLen = Rd - sizeof(struct MsgRxHdr);\r
-  xLen = 0;\r
-\r
-  /*\r
-   * A few cases to handle:\r
-   *  - the user didn't supply a read buffer\r
-   *  - the buffer is too small for the response\r
-   *  - the response is zero-length\r
-   */\r
-  if (Data != NULL) {\r
-    Dp = (UINT32 *)Data[0].Base;\r
-    oLen = remLen;\r
-    if (remLen > Data[0].Len) {\r
-      Status = RETURN_BUFFER_TOO_SMALL;\r
-      xLen = remLen - Data[0].Len;\r
-      oLen = remLen = Data[0].Len;\r
-    }\r
-    while (remLen > 0) {\r
-      *Dp++ = IoRead32 (FW_PORT);\r
-      remLen -= sizeof(UINT32);\r
-    }\r
-    Data[0].Len = oLen;\r
-  } else {\r
-    /* No user data, but data returned - drop */\r
-    if (remLen > 0) {\r
-      Status = RETURN_BUFFER_TOO_SMALL;\r
-      xLen = remLen;\r
-    }\r
-  }\r
-\r
-  /* Drop additional data */\r
-  while (xLen > 0) {\r
-    (void) IoRead32 (FW_PORT);\r
-    xLen -= sizeof(UINT32);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-STATIC\r
-RETURN_STATUS\r
-EFIAPI\r
-BhyveFwCtl_Msg(\r
-   IN   UINTN    OpCode,\r
-   IN   struct BIoVec Sdata[],\r
-   OUT  struct BIoVec Rdata[]\r
-   )\r
-{\r
-  struct MsgRxHdr     Rh;\r
-  RETURN_STATUS        Status;\r
-\r
-  Status = RETURN_SUCCESS;\r
-\r
-  BhyveFwCtl_MsgSend (OpCode, Sdata);\r
-  Status = BhyveFwCtl_MsgRecv (&Rh, Rdata);\r
-\r
-  mBhyveFwCtlTxid++;\r
-\r
-  return Status;\r
-}\r
-\r
-STATIC\r
-RETURN_STATUS\r
-EFIAPI\r
-BhyveFwCtlGetLen (\r
-  IN   CONST CHAR8    *Name,\r
-  IN OUT  UINTN        *Size\r
-  )\r
-{\r
-  struct BIoVec        Req[2], Resp[2];\r
-  RETURN_STATUS        Status;\r
-\r
-  Req[0].Base = (VOID *)Name;\r
-  Req[0].Len  = AsciiStrLen (Name) + 1;\r
-  Req[1].Base = NULL;\r
-\r
-  Resp[0].Base = Size;\r
-  Resp[0].Len  = sizeof(UINTN);\r
-  Resp[1].Base = NULL;\r
-\r
-  Status = BhyveFwCtl_Msg (OP_GET_LEN, Req, Resp);\r
-\r
-  return Status;\r
-}\r
-\r
-#define FMAXSZ    1024\r
-STATIC struct {\r
-  UINT64    fSize;\r
-  UINT32    fData[FMAXSZ];\r
-} FwGetvalBuf;\r
-\r
-STATIC\r
-RETURN_STATUS\r
-EFIAPI\r
-BhyveFwCtlGetVal (\r
-  IN   CONST CHAR8    *Name,\r
-  OUT  VOID        *Item,\r
-  IN OUT  UINTN        *Size\r
-  )\r
-{\r
-  struct BIoVec        Req[2], Resp[2];\r
-  RETURN_STATUS        Status;\r
-\r
-  /* Make sure temp buffer is larger than passed-in size */\r
-  if (*Size > sizeof(FwGetvalBuf.fData))\r
-      return RETURN_INVALID_PARAMETER;\r
-\r
-  Req[0].Base = (VOID *)Name;\r
-  Req[0].Len  = AsciiStrLen(Name) + 1;\r
-  Req[1].Base = NULL;\r
-\r
-  Resp[0].Base = &FwGetvalBuf;\r
-  Resp[0].Len  = sizeof(UINT64) + *Size;\r
-  Resp[1].Base = NULL;\r
-\r
-  Status = BhyveFwCtl_Msg (OP_GET, Req, Resp);\r
-\r
-  /*\r
-   * Copy out data on success (or on a truncated message).\r
-   * XXX This step can be eliminted with Msg() supporting\r
-   *     multiple iovecs.\r
-   */\r
-  if ((Status == RETURN_SUCCESS) || (Status == RETURN_BUFFER_TOO_SMALL)) {\r
-    *Size = FwGetvalBuf.fSize;\r
-    CopyMem (Item, FwGetvalBuf.fData, *Size);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-   Front end to the internal GET_LEN and GET protocols\r
- **/\r
-RETURN_STATUS\r
-EFIAPI\r
-BhyveFwCtlGet (\r
-  IN   CONST CHAR8    *Name,\r
-  OUT  VOID        *Item,\r
-  IN OUT  UINTN        *Size\r
-  )\r
-{\r
-  RETURN_STATUS        Status;\r
-\r
-  if (mBhyveFwCtlSupported == FALSE)\r
-    return RETURN_UNSUPPORTED;\r
-\r
-  if (Item == NULL) {\r
-    Status = BhyveFwCtlGetLen (Name, Size);\r
-  } else {\r
-    Status = BhyveFwCtlGetVal (Name, Item, Size);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-   Library initialization. Probe the host to see if the f/w ctl\r
-   interface is supported.\r
- **/\r
-RETURN_STATUS\r
-EFIAPI\r
-BhyveFwCtlInitialize (\r
-          VOID\r
-         )\r
-{\r
-  UINTN        i;\r
-  UINT8        ch;\r
-\r
-  DEBUG ((DEBUG_INFO, "FwCtlInitialize\n"));\r
-\r
-  IoWrite16 (FW_PORT, 0x0000);\r
-  for (i = 0; i < 4; i++) {\r
-    ch = IoRead8 (FW_IPORT);\r
-    if (ch != mBhyveSig[i]) {\r
-      DEBUG ((DEBUG_INFO, "Host f/w sig mismatch %c/%c\n", ch, mBhyveSig[i]));\r
-      return RETURN_SUCCESS;\r
-    }\r
-  }\r
-\r
-  mBhyveFwCtlSupported = TRUE;\r
-\r
-  return RETURN_SUCCESS;\r
-}\r
diff --git a/OvmfPkg/Bhyve/Library/BhyveFwCtlLib/BhyveFwCtlLib.inf b/OvmfPkg/Bhyve/Library/BhyveFwCtlLib/BhyveFwCtlLib.inf
deleted file mode 100644 (file)
index e9819f4..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-## @file\r
-#\r
-#  Copyright (C) 2020, Rebecca Cran <rebecca@bsdio.com>\r
-#  Copyright (C) 2015 Nahanni Systems\r
-#  Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
-#\r
-#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-#\r
-##\r
-\r
-[Defines]\r
-  INF_VERSION                    = 0x00010005\r
-  BASE_NAME                      = BhyveFwCtlLib\r
-  FILE_GUID                      = fd982666-67f9-11e5-a42a-0025908602f6\r
-  MODULE_TYPE                    = BASE\r
-  VERSION_STRING                 = 1.0\r
-  LIBRARY_CLASS                  = BhyveFwCtlLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER\r
-\r
-  CONSTRUCTOR                    = BhyveFwCtlInitialize\r
-\r
-#\r
-# The following information is for reference only and not required by the build tools.\r
-#\r
-#  VALID_ARCHITECTURES           = X64\r
-#\r
-\r
-[Sources]\r
-  BhyveFwCtlLib.c\r
-\r
-[Packages]\r
-  MdePkg/MdePkg.dec\r
-  OvmfPkg/Bhyve/BhyvePkg.dec\r
-\r
-[LibraryClasses]\r
-  BaseLib\r
-  BaseMemoryLib\r
-  DebugLib\r
-  IoLib\r
-  MemoryAllocationLib\r
-  IntrinsicLib\r
-\r
diff --git a/OvmfPkg/Bhyve/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Bhyve/Library/PlatformBootManagerLib/BdsPlatform.c
deleted file mode 100644 (file)
index 3b94630..0000000
+++ /dev/null
@@ -1,1660 +0,0 @@
-/** @file\r
-  Platform BDS customizations.\r
-\r
-  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\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/RootBridgesConnectedEventGroup.h>\r
-#include <Protocol/FirmwareVolume2.h>\r
-#include <Library/PlatformBmPrintScLib.h>\r
-#include <Library/Tcg2PhysicalPresenceLib.h>\r
-\r
-#include <Protocol/BlockIo.h>\r
-\r
-//\r
-// Global data\r
-//\r
-\r
-VOID          *mEfiDevPathNotifyReg;\r
-EFI_EVENT     mEfiDevPathEvent;\r
-VOID          *mEmuVariableEventReg;\r
-EFI_EVENT     mEmuVariableEvent;\r
-UINT16        mHostBridgeDevId;\r
-\r
-//\r
-// Table of host IRQs matching PCI IRQs A-D\r
-// (for configuring PCI Interrupt Line register)\r
-//\r
-CONST UINT8 PciHostIrqs[] = {\r
-  0x0a, 0x0a, 0x0b, 0x0b\r
-};\r
-\r
-//\r
-// Type definitions\r
-//\r
-\r
-typedef\r
-EFI_STATUS\r
-(EFIAPI *PROTOCOL_INSTANCE_CALLBACK)(\r
-  IN EFI_HANDLE           Handle,\r
-  IN VOID                 *Instance,\r
-  IN VOID                 *Context\r
-  );\r
-\r
-/**\r
-  @param[in]  Handle - Handle of PCI device instance\r
-  @param[in]  PciIo - PCI IO protocol instance\r
-  @param[in]  Pci - PCI Header register block\r
-**/\r
-typedef\r
-EFI_STATUS\r
-(EFIAPI *VISIT_PCI_INSTANCE_CALLBACK)(\r
-  IN EFI_HANDLE           Handle,\r
-  IN EFI_PCI_IO_PROTOCOL  *PciIo,\r
-  IN PCI_TYPE00           *Pci\r
-  );\r
-\r
-\r
-//\r
-// Function prototypes\r
-//\r
-\r
-EFI_STATUS\r
-VisitAllInstancesOfProtocol (\r
-  IN EFI_GUID                    *Id,\r
-  IN PROTOCOL_INSTANCE_CALLBACK  CallBackFunction,\r
-  IN VOID                        *Context\r
-  );\r
-\r
-EFI_STATUS\r
-VisitAllPciInstancesOfProtocol (\r
-  IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction\r
-  );\r
-\r
-VOID\r
-InstallDevicePathCallback (\r
-  VOID\r
-  );\r
-\r
-VOID\r
-PlatformRegisterFvBootOption (\r
-  EFI_GUID                         *FileGuid,\r
-  CHAR16                           *Description,\r
-  UINT32                           Attributes\r
-  )\r
-{\r
-  EFI_STATUS                        Status;\r
-  INTN                              OptionIndex;\r
-  EFI_BOOT_MANAGER_LOAD_OPTION      NewOption;\r
-  EFI_BOOT_MANAGER_LOAD_OPTION      *BootOptions;\r
-  UINTN                             BootOptionCount;\r
-  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;\r
-  EFI_LOADED_IMAGE_PROTOCOL         *LoadedImage;\r
-  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;\r
-\r
-  Status = gBS->HandleProtocol (\r
-                  gImageHandle,\r
-                  &gEfiLoadedImageProtocolGuid,\r
-                  (VOID **) &LoadedImage\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);\r
-  DevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle);\r
-  ASSERT (DevicePath != NULL);\r
-  DevicePath = AppendDevicePathNode (\r
-                 DevicePath,\r
-                 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode\r
-                 );\r
-  ASSERT (DevicePath != NULL);\r
-\r
-  Status = EfiBootManagerInitializeLoadOption (\r
-             &NewOption,\r
-             LoadOptionNumberUnassigned,\r
-             LoadOptionTypeBoot,\r
-             Attributes,\r
-             Description,\r
-             DevicePath,\r
-             NULL,\r
-             0\r
-             );\r
-  ASSERT_EFI_ERROR (Status);\r
-  FreePool (DevicePath);\r
-\r
-  BootOptions = EfiBootManagerGetLoadOptions (\r
-                  &BootOptionCount, LoadOptionTypeBoot\r
-                  );\r
-\r
-  OptionIndex = EfiBootManagerFindLoadOption (\r
-                  &NewOption, BootOptions, BootOptionCount\r
-                  );\r
-\r
-  if (OptionIndex == -1) {\r
-    Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);\r
-    ASSERT_EFI_ERROR (Status);\r
-  }\r
-  EfiBootManagerFreeLoadOption (&NewOption);\r
-  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
-}\r
-\r
-/**\r
-  Remove all MemoryMapped(...)/FvFile(...) and Fv(...)/FvFile(...) boot options\r
-  whose device paths do not resolve exactly to an FvFile in the system.\r
-\r
-  This removes any boot options that point to binaries built into the firmware\r
-  and have become stale due to any of the following:\r
-  - DXEFV's base address or size changed (historical),\r
-  - DXEFV's FvNameGuid changed,\r
-  - the FILE_GUID of the pointed-to binary changed,\r
-  - the referenced binary is no longer built into the firmware.\r
-\r
-  EfiBootManagerFindLoadOption() used in PlatformRegisterFvBootOption() only\r
-  avoids exact duplicates.\r
-**/\r
-VOID\r
-RemoveStaleFvFileOptions (\r
-  VOID\r
-  )\r
-{\r
-  EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;\r
-  UINTN                        BootOptionCount;\r
-  UINTN                        Index;\r
-\r
-  BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount,\r
-                  LoadOptionTypeBoot);\r
-\r
-  for (Index = 0; Index < BootOptionCount; ++Index) {\r
-    EFI_DEVICE_PATH_PROTOCOL *Node1, *Node2, *SearchNode;\r
-    EFI_STATUS               Status;\r
-    EFI_HANDLE               FvHandle;\r
-\r
-    //\r
-    // If the device path starts with neither MemoryMapped(...) nor Fv(...),\r
-    // then keep the boot option.\r
-    //\r
-    Node1 = BootOptions[Index].FilePath;\r
-    if (!(DevicePathType (Node1) == HARDWARE_DEVICE_PATH &&\r
-          DevicePathSubType (Node1) == HW_MEMMAP_DP) &&\r
-        !(DevicePathType (Node1) == MEDIA_DEVICE_PATH &&\r
-          DevicePathSubType (Node1) == MEDIA_PIWG_FW_VOL_DP)) {\r
-      continue;\r
-    }\r
-\r
-    //\r
-    // If the second device path node is not FvFile(...), then keep the boot\r
-    // option.\r
-    //\r
-    Node2 = NextDevicePathNode (Node1);\r
-    if (DevicePathType (Node2) != MEDIA_DEVICE_PATH ||\r
-        DevicePathSubType (Node2) != MEDIA_PIWG_FW_FILE_DP) {\r
-      continue;\r
-    }\r
-\r
-    //\r
-    // Locate the Firmware Volume2 protocol instance that is denoted by the\r
-    // boot option. If this lookup fails (i.e., the boot option references a\r
-    // firmware volume that doesn't exist), then we'll proceed to delete the\r
-    // boot option.\r
-    //\r
-    SearchNode = Node1;\r
-    Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid,\r
-                    &SearchNode, &FvHandle);\r
-\r
-    if (!EFI_ERROR (Status)) {\r
-      //\r
-      // The firmware volume was found; now let's see if it contains the FvFile\r
-      // identified by GUID.\r
-      //\r
-      EFI_FIRMWARE_VOLUME2_PROTOCOL     *FvProtocol;\r
-      MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFileNode;\r
-      UINTN                             BufferSize;\r
-      EFI_FV_FILETYPE                   FoundType;\r
-      EFI_FV_FILE_ATTRIBUTES            FileAttributes;\r
-      UINT32                            AuthenticationStatus;\r
-\r
-      Status = gBS->HandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid,\r
-                      (VOID **)&FvProtocol);\r
-      ASSERT_EFI_ERROR (Status);\r
-\r
-      FvFileNode = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)Node2;\r
-      //\r
-      // Buffer==NULL means we request metadata only: BufferSize, FoundType,\r
-      // FileAttributes.\r
-      //\r
-      Status = FvProtocol->ReadFile (\r
-                             FvProtocol,\r
-                             &FvFileNode->FvFileName, // NameGuid\r
-                             NULL,                    // Buffer\r
-                             &BufferSize,\r
-                             &FoundType,\r
-                             &FileAttributes,\r
-                             &AuthenticationStatus\r
-                             );\r
-      if (!EFI_ERROR (Status)) {\r
-        //\r
-        // The FvFile was found. Keep the boot option.\r
-        //\r
-        continue;\r
-      }\r
-    }\r
-\r
-    //\r
-    // Delete the boot option.\r
-    //\r
-    Status = EfiBootManagerDeleteLoadOptionVariable (\r
-               BootOptions[Index].OptionNumber, LoadOptionTypeBoot);\r
-    DEBUG_CODE (\r
-      CHAR16 *DevicePathString;\r
-\r
-      DevicePathString = ConvertDevicePathToText(BootOptions[Index].FilePath,\r
-                           FALSE, FALSE);\r
-      DEBUG ((\r
-        EFI_ERROR (Status) ? EFI_D_WARN : DEBUG_VERBOSE,\r
-        "%a: removing stale Boot#%04x %s: %r\n",\r
-        __FUNCTION__,\r
-        (UINT32)BootOptions[Index].OptionNumber,\r
-        DevicePathString == NULL ? L"<unavailable>" : DevicePathString,\r
-        Status\r
-        ));\r
-      if (DevicePathString != NULL) {\r
-        FreePool (DevicePathString);\r
-      }\r
-      );\r
-  }\r
-\r
-  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
-}\r
-\r
-VOID\r
-PlatformRegisterOptionsAndKeys (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS                   Status;\r
-  EFI_INPUT_KEY                Enter;\r
-  EFI_INPUT_KEY                F2;\r
-  EFI_INPUT_KEY                Esc;\r
-  EFI_BOOT_MANAGER_LOAD_OPTION BootOption;\r
-\r
-  //\r
-  // Register ENTER as CONTINUE key\r
-  //\r
-  Enter.ScanCode    = SCAN_NULL;\r
-  Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;\r
-  Status = EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Map F2 to Boot Manager Menu\r
-  //\r
-  F2.ScanCode     = SCAN_F2;\r
-  F2.UnicodeChar  = CHAR_NULL;\r
-  Esc.ScanCode    = SCAN_ESC;\r
-  Esc.UnicodeChar = CHAR_NULL;\r
-  Status = EfiBootManagerGetBootManagerMenu (&BootOption);\r
-  ASSERT_EFI_ERROR (Status);\r
-  Status = EfiBootManagerAddKeyOptionVariable (\r
-             NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL\r
-             );\r
-  ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);\r
-  Status = EfiBootManagerAddKeyOptionVariable (\r
-             NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL\r
-             );\r
-  ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConnectRootBridge (\r
-  IN EFI_HANDLE  RootBridgeHandle,\r
-  IN VOID        *Instance,\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
-  VOID\r
-  );\r
-\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
-  EFI_HANDLE    Handle;\r
-  EFI_STATUS    Status;\r
-\r
-  DEBUG ((DEBUG_INFO, "PlatformBootManagerBeforeConsole\n"));\r
-  InstallDevicePathCallback ();\r
-\r
-  VisitAllInstancesOfProtocol (&gEfiPciRootBridgeIoProtocolGuid,\r
-    ConnectRootBridge, NULL);\r
-\r
-  //\r
-  // Signal the ACPI platform driver that it can download QEMU ACPI tables.\r
-  //\r
-  EfiEventGroupSignal (&gRootBridgesConnectedEventGroupGuid);\r
-\r
-  //\r
-  // We can't signal End-of-Dxe earlier than this. Namely, End-of-Dxe triggers\r
-  // the preparation of S3 system information. That logic has a hard dependency\r
-  // on the presence of the FACS ACPI table. Since our ACPI tables are only\r
-  // installed after PCI enumeration completes, we must not trigger the S3 save\r
-  // earlier, hence we can't signal End-of-Dxe earlier.\r
-  //\r
-  EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);\r
-\r
-  //\r
-  // Prevent further changes to LockBoxes or SMRAM.\r
-  //\r
-  Handle = NULL;\r
-  Status = gBS->InstallProtocolInterface (&Handle,\r
-                  &gEfiDxeSmmReadyToLockProtocolGuid, EFI_NATIVE_INTERFACE,\r
-                  NULL);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Dispatch deferred images after EndOfDxe event and ReadyToLock\r
-  // installation.\r
-  //\r
-  EfiBootManagerDispatchDeferredImages ();\r
-\r
-  PlatformInitializeConsole (gPlatformConsole);\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
-EFI_STATUS\r
-EFIAPI\r
-ConnectRootBridge (\r
-  IN EFI_HANDLE  RootBridgeHandle,\r
-  IN VOID        *Instance,\r
-  IN VOID        *Context\r
-  )\r
-{\r
-  EFI_STATUS Status;\r
-\r
-  //\r
-  // Make the PCI bus driver connect the root bridge, non-recursively. This\r
-  // will produce a number of child handles with PciIo on them.\r
-  //\r
-  Status = gBS->ConnectController (\r
-                  RootBridgeHandle, // ControllerHandle\r
-                  NULL,             // DriverImageHandle\r
-                  NULL,             // RemainingDevicePath -- produce all\r
-                                    //   children\r
-                  FALSE             // Recursive\r
-                  );\r
-  return Status;\r
-}\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
-  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
-  PciIo = Instance;\r
-\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
-  //\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
-  //\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
-  //\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
-  @param[in] DeviceHandle  Handle of the LPC Bridge device.\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
-  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;\r
-  CHAR16                    *DevPathStr;\r
-\r
-  DevicePath = NULL;\r
-  Status = gBS->HandleProtocol (\r
-                  DeviceHandle,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  (VOID*)&DevicePath\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  TempDevicePath = DevicePath;\r
-\r
-  //\r
-  // Register Keyboard\r
-  //\r
-  DevicePath = AppendDevicePathNode (DevicePath,\r
-                 (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);\r
-\r
-  EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);\r
-\r
-  //\r
-  // Register COM1\r
-  //\r
-  DevicePath = TempDevicePath;\r
-  gPnp16550ComPortDeviceNode.UID = 0;\r
-\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
-  //\r
-  DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);\r
-  if (DevPathStr != NULL) {\r
-    DEBUG((\r
-      DEBUG_INFO,\r
-      "BdsPlatform.c+%d: COM%d DevPath: %s\n",\r
-      __LINE__,\r
-      gPnp16550ComPortDeviceNode.UID + 1,\r
-      DevPathStr\r
-      ));\r
-    FreePool(DevPathStr);\r
-  }\r
-\r
-  EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);\r
-  EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);\r
-  EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);\r
-\r
-  // Don't register COM2 which can be used for DBG instead so keep it clean\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GetGopDevicePath (\r
-   IN  EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,\r
-   OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath\r
-   )\r
-{\r
-  UINTN                           Index;\r
-  EFI_STATUS                      Status;\r
-  EFI_HANDLE                      PciDeviceHandle;\r
-  EFI_DEVICE_PATH_PROTOCOL        *TempDevicePath;\r
-  EFI_DEVICE_PATH_PROTOCOL        *TempPciDevicePath;\r
-  UINTN                           GopHandleCount;\r
-  EFI_HANDLE                      *GopHandleBuffer;\r
-\r
-  if (PciDevicePath == NULL || GopDevicePath == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Initialize the GopDevicePath to be PciDevicePath\r
-  //\r
-  *GopDevicePath    = PciDevicePath;\r
-  TempPciDevicePath = PciDevicePath;\r
-\r
-  Status = gBS->LocateDevicePath (\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  &TempPciDevicePath,\r
-                  &PciDeviceHandle\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Try to connect this handle, so that GOP driver could start on this\r
-  // device and create child handles with GraphicsOutput Protocol installed\r
-  // on them, then we get device paths of these child handles and select\r
-  // them as possible console device.\r
-  //\r
-  gBS->ConnectController (PciDeviceHandle, NULL, NULL, FALSE);\r
-\r
-  Status = gBS->LocateHandleBuffer (\r
-                  ByProtocol,\r
-                  &gEfiGraphicsOutputProtocolGuid,\r
-                  NULL,\r
-                  &GopHandleCount,\r
-                  &GopHandleBuffer\r
-                  );\r
-  if (!EFI_ERROR (Status)) {\r
-    //\r
-    // Add all the child handles as possible Console Device\r
-    //\r
-    for (Index = 0; Index < GopHandleCount; Index++) {\r
-      Status = gBS->HandleProtocol (GopHandleBuffer[Index],\r
-                      &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath);\r
-      if (EFI_ERROR (Status)) {\r
-        continue;\r
-      }\r
-      if (CompareMem (\r
-            PciDevicePath,\r
-            TempDevicePath,\r
-            GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH\r
-            ) == 0) {\r
-        //\r
-        // In current implementation, we only enable one of the child handles\r
-        // as console device, i.e. sotre one of the child handle's device\r
-        // path to variable "ConOut"\r
-        // In future, we could select all child handles to be console device\r
-        //\r
-\r
-        *GopDevicePath = TempDevicePath;\r
-\r
-        //\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
-      }\r
-    }\r
-    gBS->FreePool (GopHandleBuffer);\r
-  }\r
-\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
-  EFI_STATUS                Status;\r
-  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
-  EFI_DEVICE_PATH_PROTOCOL  *GopDevicePath;\r
-\r
-  DevicePath    = NULL;\r
-  GopDevicePath = NULL;\r
-  Status = gBS->HandleProtocol (\r
-                  DeviceHandle,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  (VOID*)&DevicePath\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  GetGopDevicePath (DevicePath, &GopDevicePath);\r
-  DevicePath = GopDevicePath;\r
-\r
-  EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Add PCI Serial to ConOut, ConIn, ErrOut.\r
-\r
-  @param[in] DeviceHandle  Handle of the PCI serial device.\r
-\r
-  @retval EFI_SUCCESS  The PCI serial device has been added to ConOut, ConIn,\r
-                       ErrOut.\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
-\r
-  DevicePath = NULL;\r
-  Status = gBS->HandleProtocol (\r
-                  DeviceHandle,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  (VOID*)&DevicePath\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\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
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-VisitAllInstancesOfProtocol (\r
-  IN EFI_GUID                    *Id,\r
-  IN PROTOCOL_INSTANCE_CALLBACK  CallBackFunction,\r
-  IN VOID                        *Context\r
-  )\r
-{\r
-  EFI_STATUS                Status;\r
-  UINTN                     HandleCount;\r
-  EFI_HANDLE                *HandleBuffer;\r
-  UINTN                     Index;\r
-  VOID                      *Instance;\r
-\r
-  //\r
-  // Start to check all the PciIo to find all possible device\r
-  //\r
-  HandleCount = 0;\r
-  HandleBuffer = NULL;\r
-  Status = gBS->LocateHandleBuffer (\r
-                  ByProtocol,\r
-                  Id,\r
-                  NULL,\r
-                  &HandleCount,\r
-                  &HandleBuffer\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  for (Index = 0; Index < HandleCount; Index++) {\r
-    Status = gBS->HandleProtocol (HandleBuffer[Index], Id, &Instance);\r
-    if (EFI_ERROR (Status)) {\r
-      continue;\r
-    }\r
-\r
-    Status = (*CallBackFunction) (\r
-               HandleBuffer[Index],\r
-               Instance,\r
-               Context\r
-               );\r
-  }\r
-\r
-  gBS->FreePool (HandleBuffer);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-VisitingAPciInstance (\r
-  IN EFI_HANDLE  Handle,\r
-  IN VOID        *Instance,\r
-  IN VOID        *Context\r
-  )\r
-{\r
-  EFI_STATUS                Status;\r
-  EFI_PCI_IO_PROTOCOL       *PciIo;\r
-  PCI_TYPE00                Pci;\r
-\r
-  PciIo = (EFI_PCI_IO_PROTOCOL*) Instance;\r
-\r
-  //\r
-  // Check for all PCI device\r
-  //\r
-  Status = PciIo->Pci.Read (\r
-                    PciIo,\r
-                    EfiPciIoWidthUint32,\r
-                    0,\r
-                    sizeof (Pci) / sizeof (UINT32),\r
-                    &Pci\r
-                    );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  return (*(VISIT_PCI_INSTANCE_CALLBACK)(UINTN) Context) (\r
-           Handle,\r
-           PciIo,\r
-           &Pci\r
-           );\r
-\r
-}\r
-\r
-\r
-\r
-EFI_STATUS\r
-VisitAllPciInstances (\r
-  IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction\r
-  )\r
-{\r
-  return VisitAllInstancesOfProtocol (\r
-           &gEfiPciIoProtocolGuid,\r
-           VisitingAPciInstance,\r
-           (VOID*)(UINTN) CallBackFunction\r
-           );\r
-}\r
-\r
-\r
-/**\r
-  Do platform specific PCI Device check and add them to\r
-  ConOut, ConIn, ErrOut.\r
-\r
-  @param[in]  Handle - Handle of PCI device instance\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\r
-                        successfully.\r
-  @retval EFI_STATUS - PCI Device check or Console variable update fail.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DetectAndPreparePlatformPciDevicePath (\r
-  IN EFI_HANDLE           Handle,\r
-  IN EFI_PCI_IO_PROTOCOL  *PciIo,\r
-  IN PCI_TYPE00           *Pci\r
-  )\r
-{\r
-  EFI_STATUS                Status;\r
-\r
-  Status = PciIo->Attributes (\r
-    PciIo,\r
-    EfiPciIoAttributeOperationEnable,\r
-    EFI_PCI_DEVICE_ENABLE,\r
-    NULL\r
-    );\r
-  ASSERT_EFI_ERROR (Status);\r
-\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
-    // Add IsaKeyboard to ConIn,\r
-    // add IsaSerial to ConOut, ConIn, ErrOut\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
-    // Add them to ConOut, ConIn, ErrOut.\r
-    //\r
-    DEBUG ((DEBUG_INFO, "Found PCI 16550 SERIAL device\n"));\r
-    PreparePciSerialDevicePath (Handle);\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // Here we decide which display device to enable in PCI bus\r
-  //\r
-  if (IS_PCI_DISPLAY (Pci)) {\r
-    //\r
-    // Add them to ConOut.\r
-    //\r
-    DEBUG ((DEBUG_INFO, "Found PCI display device\n"));\r
-    PreparePciDisplayDevicePath (Handle);\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Connect the predefined platform default console device.\r
-\r
-  Always try to find and enable PCI display devices.\r
-\r
-  @param[in] PlatformConsole  Predefined platform default console device array.\r
-**/\r
-VOID\r
-PlatformInitializeConsole (\r
-  IN PLATFORM_CONSOLE_CONNECT_ENTRY   *PlatformConsole\r
-  )\r
-{\r
-  UINTN                              Index;\r
-\r
-  //\r
-  // Do platform specific PCI Device check and add them to ConOut, ConIn,\r
-  // ErrOut\r
-  //\r
-  VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath);\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
-    // Update the console variable with the connect type\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
-  }\r
-}\r
-\r
-\r
-/**\r
-  Configure PCI Interrupt Line register for applicable devices\r
-  Ported from SeaBIOS, src/fw/pciinit.c, *_pci_slot_get_irq()\r
-\r
-  @param[in]  Handle - Handle of PCI device instance\r
-  @param[in]  PciIo - PCI IO protocol instance\r
-  @param[in]  PciHdr - PCI Header register block\r
-\r
-  @retval EFI_SUCCESS - PCI Interrupt Line register configured successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SetPciIntLine (\r
-  IN EFI_HANDLE           Handle,\r
-  IN EFI_PCI_IO_PROTOCOL  *PciIo,\r
-  IN PCI_TYPE00           *PciHdr\r
-  )\r
-{\r
-  EFI_DEVICE_PATH_PROTOCOL  *DevPathNode;\r
-  EFI_DEVICE_PATH_PROTOCOL  *DevPath;\r
-  UINTN                     RootSlot;\r
-  UINTN                     Idx;\r
-  UINT8                     IrqLine;\r
-  EFI_STATUS                Status;\r
-  UINT32                    RootBusNumber;\r
-\r
-  Status = EFI_SUCCESS;\r
-\r
-  if (PciHdr->Device.InterruptPin != 0) {\r
-\r
-    DevPathNode = DevicePathFromHandle (Handle);\r
-    ASSERT (DevPathNode != NULL);\r
-    DevPath = DevPathNode;\r
-\r
-    RootBusNumber = 0;\r
-    if (DevicePathType (DevPathNode) == ACPI_DEVICE_PATH &&\r
-        DevicePathSubType (DevPathNode) == ACPI_DP &&\r
-        ((ACPI_HID_DEVICE_PATH *)DevPathNode)->HID == EISA_PNP_ID(0x0A03)) {\r
-      RootBusNumber = ((ACPI_HID_DEVICE_PATH *)DevPathNode)->UID;\r
-    }\r
-\r
-    //\r
-    // Compute index into PciHostIrqs[] table by walking\r
-    // the device path and adding up all device numbers\r
-    //\r
-    Status = EFI_NOT_FOUND;\r
-    RootSlot = 0;\r
-    Idx = PciHdr->Device.InterruptPin - 1;\r
-    while (!IsDevicePathEnd (DevPathNode)) {\r
-      if (DevicePathType (DevPathNode) == HARDWARE_DEVICE_PATH &&\r
-          DevicePathSubType (DevPathNode) == HW_PCI_DP) {\r
-\r
-        Idx += ((PCI_DEVICE_PATH *)DevPathNode)->Device;\r
-\r
-        //\r
-        // Unlike SeaBIOS, which starts climbing from the leaf device\r
-        // up toward the root, we traverse the device path starting at\r
-        // the root moving toward the leaf node.\r
-        // The slot number of the top-level parent bridge is needed for\r
-        // Q35 cases with more than 24 slots on the root bus.\r
-        //\r
-        if (Status != EFI_SUCCESS) {\r
-          Status = EFI_SUCCESS;\r
-          RootSlot = ((PCI_DEVICE_PATH *)DevPathNode)->Device;\r
-        }\r
-      }\r
-\r
-      DevPathNode = NextDevicePathNode (DevPathNode);\r
-    }\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-    if (RootBusNumber == 0 && RootSlot == 0) {\r
-      DEBUG((\r
-        DEBUG_ERROR,\r
-        "%a: PCI host bridge (00:00.0) should have no interrupts!\n",\r
-        __FUNCTION__\r
-        ));\r
-      ASSERT (FALSE);\r
-    }\r
-\r
-    //\r
-    // Final PciHostIrqs[] index calculation depends on the platform\r
-    // and should match SeaBIOS src/fw/pciinit.c *_pci_slot_get_irq()\r
-    //\r
-    switch (mHostBridgeDevId) {\r
-      case 0x1275: // BHYVE\r
-      case INTEL_82441_DEVICE_ID:\r
-        Idx -= 1;\r
-        break;\r
-      case INTEL_Q35_MCH_DEVICE_ID:\r
-        //\r
-        // SeaBIOS contains the following comment:\r
-        // "Slots 0-24 rotate slot:pin mapping similar to piix above, but\r
-        //  with a different starting index - see q35-acpi-dsdt.dsl.\r
-        //\r
-        //  Slots 25-31 all use LNKA mapping (or LNKE, but A:D = E:H)"\r
-        //\r
-        if (RootSlot > 24) {\r
-          //\r
-          // in this case, subtract back out RootSlot from Idx\r
-          // (SeaBIOS never adds it to begin with, but that would make our\r
-          //  device path traversal loop above too awkward)\r
-          //\r
-          Idx -= RootSlot;\r
-        }\r
-        break;\r
-      default:\r
-        ASSERT (FALSE); // should never get here\r
-    }\r
-    Idx %= ARRAY_SIZE (PciHostIrqs);\r
-    IrqLine = PciHostIrqs[Idx];\r
-\r
-    DEBUG_CODE_BEGIN ();\r
-    {\r
-      CHAR16        *DevPathString;\r
-      STATIC CHAR16 Fallback[] = L"<failed to convert>";\r
-      UINTN         Segment, Bus, Device, Function;\r
-\r
-      DevPathString = ConvertDevicePathToText (DevPath, FALSE, FALSE);\r
-      if (DevPathString == NULL) {\r
-        DevPathString = Fallback;\r
-      }\r
-      Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);\r
-      ASSERT_EFI_ERROR (Status);\r
-\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
-      if (DevPathString != Fallback) {\r
-        FreePool (DevPathString);\r
-      }\r
-    }\r
-    DEBUG_CODE_END ();\r
-\r
-    //\r
-    // Set PCI Interrupt Line register for this device to PciHostIrqs[Idx]\r
-    //\r
-    Status = PciIo->Pci.Write (\r
-               PciIo,\r
-               EfiPciIoWidthUint8,\r
-               PCI_INT_LINE_OFFSET,\r
-               1,\r
-               &IrqLine\r
-               );\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-VOID\r
-PciAcpiInitialization (\r
-  )\r
-{\r
-  UINTN  Pmba;\r
-\r
-  //\r
-  // Query Host Bridge DID to determine platform type\r
-  //\r
-  mHostBridgeDevId = PcdGet16 (PcdOvmfHostBridgePciDevId);\r
-  switch (mHostBridgeDevId) {\r
-    case 0x1275: // BHYVE\r
-    case INTEL_82441_DEVICE_ID:\r
-      Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);\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
-      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
-      break;\r
-    default:\r
-      DEBUG ((DEBUG_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",\r
-        __FUNCTION__, mHostBridgeDevId));\r
-      ASSERT (FALSE);\r
-      return;\r
-  }\r
-\r
-  //\r
-  // Initialize PCI_INTERRUPT_LINE for applicable present PCI devices\r
-  //\r
-  VisitAllPciInstances (SetPciIntLine);\r
-\r
-  //\r
-  // Set ACPI SCI_EN bit in PMCNTRL\r
-  //\r
-  IoOr16 ((PciRead32 (Pmba) & ~BIT0) + 4, BIT0);\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-ConnectRecursivelyIfPciMassStorage (\r
-  IN EFI_HANDLE           Handle,\r
-  IN EFI_PCI_IO_PROTOCOL  *Instance,\r
-  IN PCI_TYPE00           *PciHeader\r
-  )\r
-{\r
-  EFI_STATUS                Status;\r
-  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
-  CHAR16                    *DevPathStr;\r
-\r
-  //\r
-  // Recognize PCI Mass Storage, and Xen PCI devices\r
-  //\r
-  if (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE)) {\r
-    DevicePath = NULL;\r
-    Status = gBS->HandleProtocol (\r
-                    Handle,\r
-                    &gEfiDevicePathProtocolGuid,\r
-                    (VOID*)&DevicePath\r
-                    );\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-\r
-    //\r
-    // Print Device Path\r
-    //\r
-    DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);\r
-    if (DevPathStr != NULL) {\r
-      DEBUG((\r
-        DEBUG_INFO,\r
-        "Found %s device: %s\n",\r
-        (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE) ?\r
-         L"Mass Storage" :\r
-         L"Xen"\r
-         ),\r
-        DevPathStr\r
-        ));\r
-      FreePool(DevPathStr);\r
-    }\r
-\r
-    Status = gBS->ConnectController (Handle, NULL, NULL, TRUE);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  This notification function is invoked when the\r
-  EMU Variable FVB has been changed.\r
-\r
-  @param  Event                 The event that occurred\r
-  @param  Context               For EFI compatibility.  Not used.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-EmuVariablesUpdatedCallback (\r
-  IN  EFI_EVENT Event,\r
-  IN  VOID      *Context\r
-  )\r
-{\r
-  DEBUG ((DEBUG_INFO, "EmuVariablesUpdatedCallback\n"));\r
-  UpdateNvVarsOnFileSystem ();\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-VisitingFileSystemInstance (\r
-  IN EFI_HANDLE  Handle,\r
-  IN VOID        *Instance,\r
-  IN VOID        *Context\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
-  }\r
-\r
-  Status = ConnectNvVarsToFileSystem (Handle);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  ConnectedToFileSystem = TRUE;\r
-  mEmuVariableEvent =\r
-    EfiCreateProtocolNotifyEvent (\r
-      &gEfiDevicePathProtocolGuid,\r
-      TPL_CALLBACK,\r
-      EmuVariablesUpdatedCallback,\r
-      NULL,\r
-      &mEmuVariableEventReg\r
-      );\r
-  PcdStatus = PcdSet64S (PcdEmuVariableEvent,\r
-                (UINT64)(UINTN) mEmuVariableEvent);\r
-  ASSERT_RETURN_ERROR (PcdStatus);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-VOID\r
-PlatformBdsRestoreNvVarsFromHardDisk (\r
-  )\r
-{\r
-  VisitAllPciInstances (ConnectRecursivelyIfPciMassStorage);\r
-  VisitAllInstancesOfProtocol (\r
-    &gEfiSimpleFileSystemProtocolGuid,\r
-    VisitingFileSystemInstance,\r
-    NULL\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
-  UINTN         Index;\r
-\r
-  DEBUG ((DEBUG_INFO, "PlatformBdsConnectSequence\n"));\r
-\r
-  Index = 0;\r
-\r
-  //\r
-  // Here we can get the customized platform connect sequence\r
-  // Notes: we can connect with new variable which record the\r
-  // last time boots connect device path sequence\r
-  //\r
-  while (gPlatformConnectSequence[Index] != NULL) {\r
-    //\r
-    // Build the platform boot option\r
-    //\r
-    EfiBootManagerConnectDevicePath (gPlatformConnectSequence[Index], NULL);\r
-    Index++;\r
-  }\r
-\r
-  //\r
-  // Just use the simple policy to connect all devices\r
-  //\r
-  DEBUG ((DEBUG_INFO, "EfiBootManagerConnectAll\n"));\r
-  EfiBootManagerConnectAll ();\r
-}\r
-\r
-/**\r
-  Save the S3 boot script.\r
-\r
-  Note that DxeSmmReadyToLock must be signaled after this function returns;\r
-  otherwise the script wouldn't be saved actually.\r
-**/\r
-#if defined(__GNUC__)\r
-__attribute__((unused))\r
-#endif\r
-STATIC\r
-VOID\r
-SaveS3BootScript (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS                 Status;\r
-  EFI_S3_SAVE_STATE_PROTOCOL *BootScript;\r
-  STATIC CONST UINT8         Info[] = { 0xDE, 0xAD, 0xBE, 0xEF };\r
-\r
-  Status = gBS->LocateProtocol (&gEfiS3SaveStateProtocolGuid, NULL,\r
-                  (VOID **) &BootScript);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Despite the opcode documentation in the PI spec, the protocol\r
-  // implementation embeds a deep copy of the info in the boot script, rather\r
-  // than storing just a pointer to runtime or NVS storage.\r
-  //\r
-  Status = BootScript->Write(BootScript, EFI_BOOT_SCRIPT_INFORMATION_OPCODE,\r
-                         (UINT32) sizeof Info,\r
-                         (EFI_PHYSICAL_ADDRESS)(UINTN) &Info);\r
-  ASSERT_EFI_ERROR (Status);\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
-  EFI_BOOT_MODE                      BootMode;\r
-\r
-  DEBUG ((DEBUG_INFO, "PlatformBootManagerAfterConsole\n"));\r
-\r
-  if (PcdGetBool (PcdOvmfFlashVariablesEnable)) {\r
-    DEBUG ((DEBUG_INFO, "PlatformBdsPolicyBehavior: not restoring NvVars "\r
-      "from disk since flash variables appear to be supported.\n"));\r
-  } else {\r
-    //\r
-    // Try to restore variables from the hard disk early so\r
-    // they can be used for the other BDS connect operations.\r
-    //\r
-    /* XXX Calling this causes Keyboard to be removed from ConIn which\r
-       results in unresponsive guest boot loaders in the GUI. Restore it\r
-       when we figure out what is needed to get NvVars storage done\r
-       properly.\r
-     */\r
-    /*PlatformBdsRestoreNvVarsFromHardDisk ();*/\r
-  }\r
-\r
-  //\r
-  // Get current Boot Mode\r
-  //\r
-  BootMode = GetBootModeHob ();\r
-  DEBUG ((DEBUG_INFO, "Boot Mode:%x\n", BootMode));\r
-\r
-  //\r
-  // Go the different platform policy with different boot mode\r
-  // Notes: this part code can be change with the table policy\r
-  //\r
-  ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);\r
-\r
-  //\r
-  // Logo show\r
-  //\r
-  BootLogoEnableLogo ();\r
-\r
-  //\r
-  // Set PCI Interrupt Line registers and ACPI SCI_EN\r
-  //\r
-  PciAcpiInitialization ();\r
-\r
-  //\r
-  // Process TPM PPI request\r
-  //\r
-  Tcg2PhysicalPresenceLibProcessRequest (NULL);\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
-    &gUefiShellFileGuid, L"EFI Internal Shell", LOAD_OPTION_ACTIVE\r
-    );\r
-\r
-  RemoveStaleFvFileOptions ();\r
-\r
-  PlatformBmPrintScRegisterHandler ();\r
-}\r
-\r
-/**\r
-  This notification function is invoked when an instance of the\r
-  EFI_DEVICE_PATH_PROTOCOL is produced.\r
-\r
-  @param  Event                 The event that occurred\r
-  @param  Context               For EFI compatibility.  Not used.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-NotifyDevPath (\r
-  IN  EFI_EVENT Event,\r
-  IN  VOID      *Context\r
-  )\r
-{\r
-  EFI_HANDLE                            Handle;\r
-  EFI_STATUS                            Status;\r
-  UINTN                                 BufferSize;\r
-  EFI_DEVICE_PATH_PROTOCOL             *DevPathNode;\r
-  ATAPI_DEVICE_PATH                    *Atapi;\r
-\r
-  //\r
-  // Examine all new handles\r
-  //\r
-  for (;;) {\r
-    //\r
-    // Get the next handle\r
-    //\r
-    BufferSize = sizeof (Handle);\r
-    Status = gBS->LocateHandle (\r
-              ByRegisterNotify,\r
-              NULL,\r
-              mEfiDevPathNotifyReg,\r
-              &BufferSize,\r
-              &Handle\r
-              );\r
-\r
-    //\r
-    // If not found, we're done\r
-    //\r
-    if (EFI_NOT_FOUND == Status) {\r
-      break;\r
-    }\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      continue;\r
-    }\r
-\r
-    //\r
-    // Get the DevicePath protocol on that handle\r
-    //\r
-    Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid,\r
-                    (VOID **)&DevPathNode);\r
-    ASSERT_EFI_ERROR (Status);\r
-\r
-    while (!IsDevicePathEnd (DevPathNode)) {\r
-      //\r
-      // Find the handler to dump this device path node\r
-      //\r
-      if (\r
-           (DevicePathType(DevPathNode) == MESSAGING_DEVICE_PATH) &&\r
-           (DevicePathSubType(DevPathNode) == MSG_ATAPI_DP)\r
-         ) {\r
-        Atapi = (ATAPI_DEVICE_PATH*) DevPathNode;\r
-        PciOr16 (\r
-          PCI_LIB_ADDRESS (\r
-            0,\r
-            1,\r
-            1,\r
-            (Atapi->PrimarySecondary == 1) ? 0x42: 0x40\r
-            ),\r
-          BIT15\r
-          );\r
-      }\r
-\r
-      //\r
-      // Next device path node\r
-      //\r
-      DevPathNode = NextDevicePathNode (DevPathNode);\r
-    }\r
-  }\r
-\r
-  return;\r
-}\r
-\r
-\r
-VOID\r
-InstallDevicePathCallback (\r
-  VOID\r
-  )\r
-{\r
-  DEBUG ((DEBUG_INFO, "Registered NotifyDevPath Event\n"));\r
-  mEfiDevPathEvent = EfiCreateProtocolNotifyEvent (\r
-                          &gEfiDevicePathProtocolGuid,\r
-                          TPL_CALLBACK,\r
-                          NotifyDevPath,\r
-                          NULL,\r
-                          &mEfiDevPathNotifyReg\r
-                          );\r
-}\r
-\r
-/**\r
-  This function is called each second during the boot manager waits the\r
-  timeout.\r
-\r
-  @param TimeoutRemain  The remaining timeout.\r
-**/\r
-VOID\r
-EFIAPI\r
-PlatformBootManagerWaitCallback (\r
-  UINT16          TimeoutRemain\r
-  )\r
-{\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black;\r
-  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White;\r
-  UINT16                              Timeout;\r
-\r
-  Timeout = PcdGet16 (PcdPlatformBootTimeOut);\r
-\r
-  Black.Raw = 0x00000000;\r
-  White.Raw = 0x00FFFFFF;\r
-\r
-  BootLogoUpdateProgress (\r
-    White.Pixel,\r
-    Black.Pixel,\r
-    L"Start boot option",\r
-    White.Pixel,\r
-    (Timeout - TimeoutRemain) * 100 / Timeout,\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
diff --git a/OvmfPkg/Bhyve/Library/PlatformBootManagerLib/BdsPlatform.h b/OvmfPkg/Bhyve/Library/PlatformBootManagerLib/BdsPlatform.h
deleted file mode 100644 (file)
index 382fe19..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/** @file\r
-  Platform BDS customizations include file.\r
-\r
-  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
-  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
-  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-Module Name:\r
-\r
-  BdsPlatform.h\r
-\r
-Abstract:\r
-\r
-  Head file for BDS Platform specific code\r
-\r
-**/\r
-\r
-#ifndef _PLATFORM_SPECIFIC_BDS_PLATFORM_H_\r
-#define _PLATFORM_SPECIFIC_BDS_PLATFORM_H_\r
-\r
-\r
-#include <PiDxe.h>\r
-\r
-#include <IndustryStandard/Pci.h>\r
-#include <IndustryStandard/Acpi.h>\r
-#include <IndustryStandard/SmBios.h>\r
-#include <IndustryStandard/PeImage.h>\r
-#include <IndustryStandard/Virtio095.h>\r
-\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiRuntimeServicesTableLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/PcdLib.h>\r
-#include <Library/PciLib.h>\r
-#include <Library/UefiBootManagerLib.h>\r
-#include <Library/BootLogoLib.h>\r
-#include <Library/HobLib.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/DxeServicesTableLib.h>\r
-#include <Library/DevicePathLib.h>\r
-#include <Library/IoLib.h>\r
-#include <Library/NvVarsFileLib.h>\r
-#include <Library/QemuFwCfgLib.h>\r
-#include <Library/QemuFwCfgS3Lib.h>\r
-#include <Library/QemuBootOrderLib.h>\r
-\r
-#include <Protocol/Decompress.h>\r
-#include <Protocol/PciIo.h>\r
-#include <Protocol/FirmwareVolume2.h>\r
-#include <Protocol/SimpleFileSystem.h>\r
-#include <Protocol/PciRootBridgeIo.h>\r
-#include <Protocol/S3SaveState.h>\r
-#include <Protocol/DxeSmmReadyToLock.h>\r
-#include <Protocol/LoadedImage.h>\r
-\r
-#include <Guid/Acpi.h>\r
-#include <Guid/SmBios.h>\r
-#include <Guid/HobList.h>\r
-#include <Guid/GlobalVariable.h>\r
-#include <Guid/EventGroup.h>\r
-#include <Guid/DebugAgentGuid.h>\r
-\r
-#include <OvmfPlatforms.h>\r
-\r
-extern EFI_DEVICE_PATH_PROTOCOL   *gPlatformConnectSequence[];\r
-extern ACPI_HID_DEVICE_PATH       gPnpPs2KeyboardDeviceNode;\r
-extern ACPI_HID_DEVICE_PATH       gPnp16550ComPortDeviceNode;\r
-extern UART_DEVICE_PATH           gUartDeviceNode;\r
-extern VENDOR_DEVICE_PATH         gTerminalTypeDeviceNode;\r
-\r
-#define PCI_DEVICE_PATH_NODE(Func, Dev) \\r
-  { \\r
-    { \\r
-      HARDWARE_DEVICE_PATH, \\r
-      HW_PCI_DP, \\r
-      { \\r
-        (UINT8) (sizeof (PCI_DEVICE_PATH)), \\r
-        (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \\r
-      } \\r
-    }, \\r
-    (Func), \\r
-    (Dev) \\r
-  }\r
-\r
-#define PNPID_DEVICE_PATH_NODE(PnpId) \\r
-  { \\r
-    { \\r
-      ACPI_DEVICE_PATH, \\r
-      ACPI_DP, \\r
-      { \\r
-        (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \\r
-        (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \\r
-      }, \\r
-    }, \\r
-    EISA_PNP_ID((PnpId)), \\r
-    0 \\r
-  }\r
-\r
-#define gPciIsaBridge \\r
-  PCI_DEVICE_PATH_NODE(0, 0x1f)\r
-\r
-#define gP2PBridge \\r
-  PCI_DEVICE_PATH_NODE(0, 0x1e)\r
-\r
-#define gPnpPs2Keyboard \\r
-  PNPID_DEVICE_PATH_NODE(0x0303)\r
-\r
-#define gPnp16550ComPort \\r
-  PNPID_DEVICE_PATH_NODE(0x0501)\r
-\r
-#define gUart \\r
-  { \\r
-    { \\r
-      MESSAGING_DEVICE_PATH, \\r
-      MSG_UART_DP, \\r
-      { \\r
-        (UINT8) (sizeof (UART_DEVICE_PATH)), \\r
-        (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8) \\r
-      } \\r
-    }, \\r
-    0, \\r
-    115200, \\r
-    8, \\r
-    1, \\r
-    1 \\r
-  }\r
-\r
-#define gPcAnsiTerminal \\r
-  { \\r
-    { \\r
-      MESSAGING_DEVICE_PATH, \\r
-      MSG_VENDOR_DP, \\r
-      { \\r
-        (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \\r
-        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \\r
-      } \\r
-    }, \\r
-    DEVICE_PATH_MESSAGING_PC_ANSI \\r
-  }\r
-\r
-#define gEndEntire \\r
-  { \\r
-    END_DEVICE_PATH_TYPE, \\r
-    END_ENTIRE_DEVICE_PATH_SUBTYPE, \\r
-    { \\r
-      END_DEVICE_PATH_LENGTH, \\r
-      0 \\r
-    } \\r
-  }\r
-\r
-#define PCI_CLASS_SCC          0x07\r
-#define PCI_SUBCLASS_SERIAL    0x00\r
-#define PCI_IF_16550           0x02\r
-#define IS_PCI_16550SERIAL(_p)           IS_CLASS3 (_p, PCI_CLASS_SCC, PCI_SUBCLASS_SERIAL, PCI_IF_16550)\r
-#define IS_PCI_ISA_PDECODE(_p)        IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA_PDECODE, 0)\r
-\r
-typedef struct {\r
-  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
-  UINTN                     ConnectType;\r
-} PLATFORM_CONSOLE_CONNECT_ENTRY;\r
-\r
-#define CONSOLE_OUT BIT0\r
-#define CONSOLE_IN  BIT1\r
-#define STD_ERROR   BIT2\r
-extern PLATFORM_CONSOLE_CONNECT_ENTRY  gPlatformConsole[];\r
-\r
-//\r
-// Platform BDS Functions\r
-//\r
-\r
-VOID\r
-PlatformInitializeConsole (\r
-  IN PLATFORM_CONSOLE_CONNECT_ENTRY   *PlatformConsole\r
-  );\r
-\r
-/**\r
-  Loads and boots UEFI Linux via the FwCfg interface.\r
-\r
-  @retval    EFI_NOT_FOUND - The Linux kernel was not found\r
-\r
-**/\r
-EFI_STATUS\r
-TryRunningQemuKernel (\r
-  VOID\r
-  );\r
-\r
-#endif // _PLATFORM_SPECIFIC_BDS_PLATFORM_H_\r
diff --git a/OvmfPkg/Bhyve/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/OvmfPkg/Bhyve/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
deleted file mode 100644 (file)
index 105123b..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-## @file\r
-#  Platform BDS customizations library.\r
-#\r
-#  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
-#  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
-#\r
-#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-#\r
-##\r
-\r
-[Defines]\r
-  INF_VERSION                    = 0x00010005\r
-  BASE_NAME                      = PlatformBootManagerLib\r
-  FILE_GUID                      = b0de5f0d-f676-42da-8d00-86997ee0dbb4\r
-  MODULE_TYPE                    = DXE_DRIVER\r
-  VERSION_STRING                 = 1.0\r
-  LIBRARY_CLASS                  = PlatformBootManagerLib|DXE_DRIVER\r
-\r
-#\r
-# The following information is for reference only and not required by the build tools.\r
-#\r
-#  VALID_ARCHITECTURES           = IA32 X64 EBC\r
-#\r
-\r
-[Sources]\r
-  BdsPlatform.c\r
-  PlatformData.c\r
-  BdsPlatform.h\r
-\r
-[Packages]\r
-  MdePkg/MdePkg.dec\r
-  MdeModulePkg/MdeModulePkg.dec\r
-  SourceLevelDebugPkg/SourceLevelDebugPkg.dec\r
-  OvmfPkg/OvmfPkg.dec\r
-  SecurityPkg/SecurityPkg.dec\r
-  ShellPkg/ShellPkg.dec\r
-\r
-[LibraryClasses]\r
-  BaseLib\r
-  MemoryAllocationLib\r
-  UefiBootServicesTableLib\r
-  BaseMemoryLib\r
-  DebugLib\r
-  PcdLib\r
-  UefiBootManagerLib\r
-  BootLogoLib\r
-  DevicePathLib\r
-  PciLib\r
-  NvVarsFileLib\r
-  ReportStatusCodeLib\r
-  UefiLib\r
-  PlatformBmPrintScLib\r
-  Tcg2PhysicalPresenceLib\r
-\r
-[Pcd]\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable\r
-  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId\r
-  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut\r
-\r
-[Pcd.IA32, Pcd.X64]\r
-  gEfiMdePkgTokenSpaceGuid.PcdFSBClock\r
-\r
-[Protocols]\r
-  gEfiDecompressProtocolGuid\r
-  gEfiPciRootBridgeIoProtocolGuid\r
-  gEfiS3SaveStateProtocolGuid                   # PROTOCOL SOMETIMES_CONSUMED\r
-  gEfiDxeSmmReadyToLockProtocolGuid             # PROTOCOL SOMETIMES_PRODUCED\r
-  gEfiLoadedImageProtocolGuid                   # PROTOCOL SOMETIMES_PRODUCED\r
-  gEfiFirmwareVolume2ProtocolGuid               # PROTOCOL SOMETIMES_CONSUMED\r
-\r
-[Guids]\r
-  gEfiEndOfDxeEventGroupGuid\r
-  gRootBridgesConnectedEventGroupGuid\r
-  gUefiShellFileGuid\r
diff --git a/OvmfPkg/Bhyve/Library/PlatformBootManagerLib/PlatformData.c b/OvmfPkg/Bhyve/Library/PlatformBootManagerLib/PlatformData.c
deleted file mode 100644 (file)
index 73674d5..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/** @file\r
-  Defined the platform specific device path which will be used by\r
-  platform Bbd to perform the platform policy connect.\r
-\r
-  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
-  Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>\r
-  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "BdsPlatform.h"\r
-#include <Guid/QemuRamfb.h>\r
-\r
-//\r
-// Debug Agent UART Device Path structure\r
-//\r
-#pragma pack(1)\r
-typedef struct {\r
-  VENDOR_DEVICE_PATH        VendorHardware;\r
-  UART_DEVICE_PATH          Uart;\r
-  VENDOR_DEVICE_PATH        TerminalType;\r
-  EFI_DEVICE_PATH_PROTOCOL  End;\r
-} VENDOR_UART_DEVICE_PATH;\r
-#pragma pack()\r
-\r
-//\r
-// USB Keyboard Device Path structure\r
-//\r
-#pragma pack (1)\r
-typedef struct {\r
-  USB_CLASS_DEVICE_PATH    Keyboard;\r
-  EFI_DEVICE_PATH_PROTOCOL End;\r
-} USB_KEYBOARD_DEVICE_PATH;\r
-#pragma pack ()\r
-\r
-//\r
-// QemuRamfb Device Path structure\r
-//\r
-#pragma pack (1)\r
-typedef struct {\r
-  VENDOR_DEVICE_PATH        Vendor;\r
-  ACPI_ADR_DEVICE_PATH      AcpiAdr;\r
-  EFI_DEVICE_PATH_PROTOCOL  End;\r
-} VENDOR_RAMFB_DEVICE_PATH;\r
-#pragma pack ()\r
-\r
-ACPI_HID_DEVICE_PATH       gPnpPs2KeyboardDeviceNode  = gPnpPs2Keyboard;\r
-ACPI_HID_DEVICE_PATH       gPnp16550ComPortDeviceNode = gPnp16550ComPort;\r
-UART_DEVICE_PATH           gUartDeviceNode            = gUart;\r
-VENDOR_DEVICE_PATH         gTerminalTypeDeviceNode    = gPcAnsiTerminal;\r
-\r
-//\r
-// Platform specific keyboard device path\r
-//\r
-\r
-\r
-//\r
-// Debug Agent UART Device Path\r
-//\r
-VENDOR_UART_DEVICE_PATH gDebugAgentUartDevicePath = {\r
-  {\r
-    {\r
-      HARDWARE_DEVICE_PATH,\r
-      HW_VENDOR_DP,\r
-      {\r
-        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
-        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
-      }\r
-    },\r
-    EFI_DEBUG_AGENT_GUID,\r
-  },\r
-  {\r
-    {\r
-      MESSAGING_DEVICE_PATH,\r
-      MSG_UART_DP,\r
-      {\r
-        (UINT8) (sizeof (UART_DEVICE_PATH)),\r
-        (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8)\r
-      }\r
-    },\r
-    0,  // Reserved\r
-    0,  // BaudRate - Default\r
-    0,  // DataBits - Default\r
-    0,  // Parity   - Default\r
-    0,  // StopBits - Default\r
-  },\r
-  gPcAnsiTerminal,\r
-  gEndEntire\r
-};\r
-\r
-STATIC USB_KEYBOARD_DEVICE_PATH gUsbKeyboardDevicePath = {\r
-  {\r
-    {\r
-      MESSAGING_DEVICE_PATH,\r
-      MSG_USB_CLASS_DP,\r
-      {\r
-        (UINT8)sizeof (USB_CLASS_DEVICE_PATH),\r
-        (UINT8)(sizeof (USB_CLASS_DEVICE_PATH) >> 8)\r
-      }\r
-    },\r
-    0xFFFF, // VendorId: any\r
-    0xFFFF, // ProductId: any\r
-    3,      // DeviceClass: HID\r
-    1,      // DeviceSubClass: boot\r
-    1       // DeviceProtocol: keyboard\r
-  },\r
-  gEndEntire\r
-};\r
-\r
-STATIC VENDOR_RAMFB_DEVICE_PATH gQemuRamfbDevicePath = {\r
-  {\r
-    {\r
-      HARDWARE_DEVICE_PATH,\r
-      HW_VENDOR_DP,\r
-      {\r
-        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
-        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
-      }\r
-    },\r
-    QEMU_RAMFB_GUID,\r
-  },\r
-  {\r
-    {\r
-      ACPI_DEVICE_PATH,\r
-      ACPI_ADR_DP,\r
-      {\r
-        (UINT8) (sizeof (ACPI_ADR_DEVICE_PATH)),\r
-        (UINT8) ((sizeof (ACPI_ADR_DEVICE_PATH)) >> 8)\r
-      }\r
-    },\r
-    ACPI_DISPLAY_ADR (\r
-      1,                                       // DeviceIdScheme\r
-      0,                                       // HeadId\r
-      0,                                       // NonVgaOutput\r
-      1,                                       // BiosCanDetect\r
-      0,                                       // VendorInfo\r
-      ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL,  // Type\r
-      0,                                       // Port\r
-      0                                        // Index\r
-      ),\r
-  },\r
-  gEndEntire\r
-};\r
-\r
-//\r
-// Predefined platform default console device path\r
-//\r
-PLATFORM_CONSOLE_CONNECT_ENTRY   gPlatformConsole[] = {\r
-  {\r
-    (EFI_DEVICE_PATH_PROTOCOL *) &gDebugAgentUartDevicePath,\r
-    (CONSOLE_OUT | CONSOLE_IN | STD_ERROR)\r
-  },\r
-  {\r
-    (EFI_DEVICE_PATH_PROTOCOL *)&gUsbKeyboardDevicePath,\r
-    CONSOLE_IN\r
-  },\r
-  {\r
-    (EFI_DEVICE_PATH_PROTOCOL *)&gQemuRamfbDevicePath,\r
-    CONSOLE_OUT\r
-  },\r
-  {\r
-    NULL,\r
-    0\r
-  }\r
-};\r
-\r
-//\r
-// Predefined platform connect sequence\r
-//\r
-EFI_DEVICE_PATH_PROTOCOL    *gPlatformConnectSequence[] = { NULL };\r
-\r
diff --git a/OvmfPkg/Include/Library/BhyveFwCtlLib.h b/OvmfPkg/Include/Library/BhyveFwCtlLib.h
new file mode 100644 (file)
index 0000000..13028ec
--- /dev/null
@@ -0,0 +1,47 @@
+/** @file\r
+  bhyve firmware configuration access\r
+\r
+  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+  Copyright (c) 2015 Nahanni Systems\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef __BHYVE_FW_CTL_LIB__\r
+#define __BHYVE_FW_CTL_LIB__\r
+\r
+/**\r
+  Sysctl-like interface to read host information via a dot-separated\r
+  ASCII OID.\r
+\r
+  The information is copied into the buffer specified by Item. The\r
+  size of the buffer is given by the location specified by Size\r
+  before the call, and that location gives the amount of data copied\r
+  after a successfull call, and after a call that returns a truncated\r
+  value with an error return of RETURN_BUFFER_TOO_SMALL.\r
+\r
+  The size of the available data can be determined by passing a NULL\r
+  argument for Item. The size will be returned in the location pointed\r
+  to by Size.\r
+\r
+  @param[]  Name    - ASCII OID name\r
+  @param[]  Data    - return buffer pointer\r
+  @param[]  Size    - pointer to length\r
+\r
+  @return    RETURN_SUCCESS          Valid data/len returned.\r
+          RETURN_UNSUPPORTED        f/w interface not present.\r
+          RETURN_NOT_FOUND      OID not found.\r
+        RETURN_BUFFER_TOO_SMALL      Return message truncated.\r
+        RETURN_INVALID_PARAMETER  Buffer too large\r
+        RETURN_PROTOCOL_ERROR     Unknown error from host\r
+ **/\r
+RETURN_STATUS\r
+EFIAPI\r
+BhyveFwCtlGet (\r
+  IN   CONST CHAR8    *Name,\r
+  OUT  VOID        *Item,\r
+  IN OUT  UINTN        *Size\r
+  );\r
+\r
+#endif\r
diff --git a/OvmfPkg/Library/BhyveFwCtlLib/BhyveFwCtlLib.c b/OvmfPkg/Library/BhyveFwCtlLib/BhyveFwCtlLib.c
new file mode 100644 (file)
index 0000000..2c45ad7
--- /dev/null
@@ -0,0 +1,426 @@
+/** @file\r
+\r
+  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+  Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (C) 2013, Red Hat, Inc.\r
+  Copyright (c) 2015, Nahanni Systems.\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "Uefi.h"\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/BhyveFwCtlLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+#define FW_PORT        0x510\r
+#define FW_IPORT    0x511\r
+\r
+/* Transport protocol basic operations */\r
+#define OP_NULL        1\r
+#define OP_ECHO        2\r
+#define OP_GET        3\r
+#define OP_GET_LEN    4\r
+#define OP_SET        5\r
+\r
+/* Transport protocol error returns */\r
+#define T_ESUCCESS    0\r
+#define T_ENOENT    2\r
+#define T_E2BIG        7\r
+#define T_EMSGSIZE    40\r
+\r
+#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))\r
+\r
+STATIC CONST CHAR8 mBhyveSig[4] = { 'B', 'H', 'Y', 'V' };\r
+\r
+STATIC BOOLEAN mBhyveFwCtlSupported = FALSE;\r
+\r
+STATIC INTN mBhyveFwCtlTxid = 0xa5;\r
+\r
+/* XXX Maybe a better inbuilt version of this ? */\r
+struct BIoVec {\r
+  VOID        *Base;\r
+  UINTN        Len;\r
+};\r
+\r
+struct MsgRxHdr {\r
+  UINT32    Sz;\r
+  UINT32    Op;\r
+  UINT32    TxId;\r
+  UINT32    Err;\r
+};\r
+\r
+STATIC\r
+RETURN_STATUS\r
+EFIAPI\r
+BhyveFwCtl_CvtErr (\r
+   IN UINT32    errno\r
+   )\r
+{\r
+  RETURN_STATUS        Status;\r
+\r
+  switch (errno) {\r
+  case T_ESUCCESS:\r
+    Status = RETURN_SUCCESS;\r
+    break;\r
+  case T_ENOENT:\r
+    Status = RETURN_NOT_FOUND;\r
+    break;\r
+  case T_E2BIG:\r
+    Status = RETURN_INVALID_PARAMETER;\r
+    break;\r
+  case T_EMSGSIZE:\r
+    Status = RETURN_BUFFER_TOO_SMALL;\r
+    break;\r
+  default:\r
+    Status = RETURN_PROTOCOL_ERROR;\r
+    break;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+STATIC\r
+UINTN\r
+EFIAPI\r
+BIov_WLen (\r
+   IN struct BIoVec b[]\r
+   )\r
+{\r
+  UINTN        i;\r
+  UINTN        tLen;\r
+\r
+  tLen = 0;\r
+\r
+  if (b != NULL) {\r
+    for (i = 0; b[i].Base != NULL; i++)\r
+      tLen += ROUNDUP (b[i].Len, sizeof(UINT32));\r
+  }\r
+\r
+  return tLen;\r
+}\r
+\r
+/**\r
+   Utility to send 1-3 bhyes of input as a 4-byte value\r
+   with trailing zeroes.\r
+ **/\r
+STATIC\r
+UINT32\r
+BIov_Send_Rem (\r
+   IN UINT32        *Data,\r
+   IN UINTN        Len\r
+   )\r
+{\r
+  union {\r
+    UINT8    c[4];\r
+    UINT32    w;\r
+  } u;\r
+  UINT8        *cdata;\r
+  UINTN        i;\r
+\r
+  cdata = (UINT8 *)Data;\r
+  u.w = 0;\r
+\r
+  for (i = 0; i < Len; i++)\r
+    u.c[i] = *cdata++;\r
+\r
+  return u.w;\r
+}\r
+\r
+/**\r
+   Send a block of data out the i/o port as 4-byte quantities,\r
+   appending trailing zeroes on the last if required.\r
+ **/\r
+STATIC\r
+VOID\r
+BIov_Send (\r
+  IN char    *Data,\r
+  IN UINTN    Len\r
+  )\r
+{\r
+  UINT32    *LData;\r
+\r
+  LData = (UINT32 *)Data;\r
+\r
+  while (Len > sizeof(UINT32)) {\r
+    IoWrite32 (FW_PORT, *LData++);\r
+    Len -= sizeof(UINT32);\r
+  }\r
+\r
+  if (Len > 0) {\r
+    IoWrite32 (FW_PORT, BIov_Send_Rem (LData, Len));\r
+  }\r
+}\r
+\r
+/**\r
+   Send data described by an array of iovecs out the i/o port.\r
+ **/\r
+STATIC\r
+VOID\r
+BIov_SendAll (\r
+   IN  struct BIoVec b[]\r
+   )\r
+{\r
+  INTN        i;\r
+\r
+  if (b != NULL) {\r
+    for (i = 0; b[i].Base; i++) {\r
+      BIov_Send (b[i].Base, b[i].Len);\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+   Prepend the transport header to a block of data and send.\r
+ **/\r
+STATIC\r
+VOID\r
+EFIAPI\r
+BhyveFwCtl_MsgSend(\r
+   IN  UINTN    OpCode,\r
+   IN  struct BIoVec Data[]\r
+   )\r
+{\r
+  struct BIoVec hIov[4];\r
+  UINT32        Hdr[3];\r
+  UINTN         i;\r
+\r
+  /* Set up header as an iovec */\r
+  for (i = 0; i < 3; i++) {\r
+    hIov[i].Base = &Hdr[i];\r
+    hIov[i].Len  = sizeof(Hdr[0]);\r
+  }\r
+  hIov[i].Base = NULL;\r
+  hIov[i].Len = 0;\r
+\r
+  /* Initialize header */\r
+  Hdr[0] = BIov_WLen (hIov) + BIov_WLen (Data);\r
+  Hdr[1] = OpCode;\r
+  Hdr[2] = mBhyveFwCtlTxid;\r
+\r
+  /* Send header and data */\r
+  BIov_SendAll (hIov);\r
+  BIov_SendAll (Data);\r
+}\r
+\r
+/**\r
+   Read a transport response and optional data from the i/o port.\r
+ **/\r
+STATIC\r
+RETURN_STATUS\r
+EFIAPI\r
+BhyveFwCtl_MsgRecv(\r
+   OUT  struct MsgRxHdr    *Rhdr,\r
+   OUT  struct BIoVec    Data[]\r
+   )\r
+{\r
+  RETURN_STATUS        Status;\r
+  UINT32        *Dp;\r
+  UINT32        Rd;\r
+  UINTN         remLen;\r
+  INTN            oLen, xLen;\r
+\r
+  Rd = IoRead32 (FW_PORT);\r
+  if (Rd < sizeof(struct MsgRxHdr)) {\r
+    ;\r
+  }\r
+\r
+  /* Read in header and setup initial error */\r
+  Rhdr->Sz   = Rd;\r
+  Rhdr->Op   = IoRead32 (FW_PORT);\r
+  Rhdr->TxId = IoRead32 (FW_PORT);\r
+  Rhdr->Err  = IoRead32 (FW_PORT);\r
+\r
+  /* Convert transport errno into UEFI error status */\r
+  Status = BhyveFwCtl_CvtErr(Rhdr->Err);\r
+\r
+  remLen = Rd - sizeof(struct MsgRxHdr);\r
+  xLen = 0;\r
+\r
+  /*\r
+   * A few cases to handle:\r
+   *  - the user didn't supply a read buffer\r
+   *  - the buffer is too small for the response\r
+   *  - the response is zero-length\r
+   */\r
+  if (Data != NULL) {\r
+    Dp = (UINT32 *)Data[0].Base;\r
+    oLen = remLen;\r
+    if (remLen > Data[0].Len) {\r
+      Status = RETURN_BUFFER_TOO_SMALL;\r
+      xLen = remLen - Data[0].Len;\r
+      oLen = remLen = Data[0].Len;\r
+    }\r
+    while (remLen > 0) {\r
+      *Dp++ = IoRead32 (FW_PORT);\r
+      remLen -= sizeof(UINT32);\r
+    }\r
+    Data[0].Len = oLen;\r
+  } else {\r
+    /* No user data, but data returned - drop */\r
+    if (remLen > 0) {\r
+      Status = RETURN_BUFFER_TOO_SMALL;\r
+      xLen = remLen;\r
+    }\r
+  }\r
+\r
+  /* Drop additional data */\r
+  while (xLen > 0) {\r
+    (void) IoRead32 (FW_PORT);\r
+    xLen -= sizeof(UINT32);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+STATIC\r
+RETURN_STATUS\r
+EFIAPI\r
+BhyveFwCtl_Msg(\r
+   IN   UINTN    OpCode,\r
+   IN   struct BIoVec Sdata[],\r
+   OUT  struct BIoVec Rdata[]\r
+   )\r
+{\r
+  struct MsgRxHdr     Rh;\r
+  RETURN_STATUS        Status;\r
+\r
+  Status = RETURN_SUCCESS;\r
+\r
+  BhyveFwCtl_MsgSend (OpCode, Sdata);\r
+  Status = BhyveFwCtl_MsgRecv (&Rh, Rdata);\r
+\r
+  mBhyveFwCtlTxid++;\r
+\r
+  return Status;\r
+}\r
+\r
+STATIC\r
+RETURN_STATUS\r
+EFIAPI\r
+BhyveFwCtlGetLen (\r
+  IN   CONST CHAR8    *Name,\r
+  IN OUT  UINTN        *Size\r
+  )\r
+{\r
+  struct BIoVec        Req[2], Resp[2];\r
+  RETURN_STATUS        Status;\r
+\r
+  Req[0].Base = (VOID *)Name;\r
+  Req[0].Len  = AsciiStrLen (Name) + 1;\r
+  Req[1].Base = NULL;\r
+\r
+  Resp[0].Base = Size;\r
+  Resp[0].Len  = sizeof(UINTN);\r
+  Resp[1].Base = NULL;\r
+\r
+  Status = BhyveFwCtl_Msg (OP_GET_LEN, Req, Resp);\r
+\r
+  return Status;\r
+}\r
+\r
+#define FMAXSZ    1024\r
+STATIC struct {\r
+  UINT64    fSize;\r
+  UINT32    fData[FMAXSZ];\r
+} FwGetvalBuf;\r
+\r
+STATIC\r
+RETURN_STATUS\r
+EFIAPI\r
+BhyveFwCtlGetVal (\r
+  IN   CONST CHAR8    *Name,\r
+  OUT  VOID        *Item,\r
+  IN OUT  UINTN        *Size\r
+  )\r
+{\r
+  struct BIoVec        Req[2], Resp[2];\r
+  RETURN_STATUS        Status;\r
+\r
+  /* Make sure temp buffer is larger than passed-in size */\r
+  if (*Size > sizeof(FwGetvalBuf.fData))\r
+      return RETURN_INVALID_PARAMETER;\r
+\r
+  Req[0].Base = (VOID *)Name;\r
+  Req[0].Len  = AsciiStrLen(Name) + 1;\r
+  Req[1].Base = NULL;\r
+\r
+  Resp[0].Base = &FwGetvalBuf;\r
+  Resp[0].Len  = sizeof(UINT64) + *Size;\r
+  Resp[1].Base = NULL;\r
+\r
+  Status = BhyveFwCtl_Msg (OP_GET, Req, Resp);\r
+\r
+  /*\r
+   * Copy out data on success (or on a truncated message).\r
+   * XXX This step can be eliminted with Msg() supporting\r
+   *     multiple iovecs.\r
+   */\r
+  if ((Status == RETURN_SUCCESS) || (Status == RETURN_BUFFER_TOO_SMALL)) {\r
+    *Size = FwGetvalBuf.fSize;\r
+    CopyMem (Item, FwGetvalBuf.fData, *Size);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+   Front end to the internal GET_LEN and GET protocols\r
+ **/\r
+RETURN_STATUS\r
+EFIAPI\r
+BhyveFwCtlGet (\r
+  IN   CONST CHAR8    *Name,\r
+  OUT  VOID        *Item,\r
+  IN OUT  UINTN        *Size\r
+  )\r
+{\r
+  RETURN_STATUS        Status;\r
+\r
+  if (mBhyveFwCtlSupported == FALSE)\r
+    return RETURN_UNSUPPORTED;\r
+\r
+  if (Item == NULL) {\r
+    Status = BhyveFwCtlGetLen (Name, Size);\r
+  } else {\r
+    Status = BhyveFwCtlGetVal (Name, Item, Size);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+   Library initialization. Probe the host to see if the f/w ctl\r
+   interface is supported.\r
+ **/\r
+RETURN_STATUS\r
+EFIAPI\r
+BhyveFwCtlInitialize (\r
+          VOID\r
+         )\r
+{\r
+  UINTN        i;\r
+  UINT8        ch;\r
+\r
+  DEBUG ((DEBUG_INFO, "FwCtlInitialize\n"));\r
+\r
+  IoWrite16 (FW_PORT, 0x0000);\r
+  for (i = 0; i < 4; i++) {\r
+    ch = IoRead8 (FW_IPORT);\r
+    if (ch != mBhyveSig[i]) {\r
+      DEBUG ((DEBUG_INFO, "Host f/w sig mismatch %c/%c\n", ch, mBhyveSig[i]));\r
+      return RETURN_SUCCESS;\r
+    }\r
+  }\r
+\r
+  mBhyveFwCtlSupported = TRUE;\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
diff --git a/OvmfPkg/Library/BhyveFwCtlLib/BhyveFwCtlLib.inf b/OvmfPkg/Library/BhyveFwCtlLib/BhyveFwCtlLib.inf
new file mode 100644 (file)
index 0000000..4643de3
--- /dev/null
@@ -0,0 +1,41 @@
+## @file\r
+#\r
+#  Copyright (C) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+#  Copyright (C) 2015 Nahanni Systems\r
+#  Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = BhyveFwCtlLib\r
+  FILE_GUID                      = fd982666-67f9-11e5-a42a-0025908602f6\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = BhyveFwCtlLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER\r
+\r
+  CONSTRUCTOR                    = BhyveFwCtlInitialize\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = X64\r
+#\r
+\r
+[Sources]\r
+  BhyveFwCtlLib.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  OvmfPkg/OvmfPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  IoLib\r
+  MemoryAllocationLib\r
+  IntrinsicLib\r
+\r
diff --git a/OvmfPkg/Library/PlatformBootManagerLibBhyve/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLibBhyve/BdsPlatform.c
new file mode 100644 (file)
index 0000000..3b94630
--- /dev/null
@@ -0,0 +1,1660 @@
+/** @file\r
+  Platform BDS customizations.\r
+\r
+  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\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/RootBridgesConnectedEventGroup.h>\r
+#include <Protocol/FirmwareVolume2.h>\r
+#include <Library/PlatformBmPrintScLib.h>\r
+#include <Library/Tcg2PhysicalPresenceLib.h>\r
+\r
+#include <Protocol/BlockIo.h>\r
+\r
+//\r
+// Global data\r
+//\r
+\r
+VOID          *mEfiDevPathNotifyReg;\r
+EFI_EVENT     mEfiDevPathEvent;\r
+VOID          *mEmuVariableEventReg;\r
+EFI_EVENT     mEmuVariableEvent;\r
+UINT16        mHostBridgeDevId;\r
+\r
+//\r
+// Table of host IRQs matching PCI IRQs A-D\r
+// (for configuring PCI Interrupt Line register)\r
+//\r
+CONST UINT8 PciHostIrqs[] = {\r
+  0x0a, 0x0a, 0x0b, 0x0b\r
+};\r
+\r
+//\r
+// Type definitions\r
+//\r
+\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *PROTOCOL_INSTANCE_CALLBACK)(\r
+  IN EFI_HANDLE           Handle,\r
+  IN VOID                 *Instance,\r
+  IN VOID                 *Context\r
+  );\r
+\r
+/**\r
+  @param[in]  Handle - Handle of PCI device instance\r
+  @param[in]  PciIo - PCI IO protocol instance\r
+  @param[in]  Pci - PCI Header register block\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *VISIT_PCI_INSTANCE_CALLBACK)(\r
+  IN EFI_HANDLE           Handle,\r
+  IN EFI_PCI_IO_PROTOCOL  *PciIo,\r
+  IN PCI_TYPE00           *Pci\r
+  );\r
+\r
+\r
+//\r
+// Function prototypes\r
+//\r
+\r
+EFI_STATUS\r
+VisitAllInstancesOfProtocol (\r
+  IN EFI_GUID                    *Id,\r
+  IN PROTOCOL_INSTANCE_CALLBACK  CallBackFunction,\r
+  IN VOID                        *Context\r
+  );\r
+\r
+EFI_STATUS\r
+VisitAllPciInstancesOfProtocol (\r
+  IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction\r
+  );\r
+\r
+VOID\r
+InstallDevicePathCallback (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+PlatformRegisterFvBootOption (\r
+  EFI_GUID                         *FileGuid,\r
+  CHAR16                           *Description,\r
+  UINT32                           Attributes\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  INTN                              OptionIndex;\r
+  EFI_BOOT_MANAGER_LOAD_OPTION      NewOption;\r
+  EFI_BOOT_MANAGER_LOAD_OPTION      *BootOptions;\r
+  UINTN                             BootOptionCount;\r
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;\r
+  EFI_LOADED_IMAGE_PROTOCOL         *LoadedImage;\r
+  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;\r
+\r
+  Status = gBS->HandleProtocol (\r
+                  gImageHandle,\r
+                  &gEfiLoadedImageProtocolGuid,\r
+                  (VOID **) &LoadedImage\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);\r
+  DevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle);\r
+  ASSERT (DevicePath != NULL);\r
+  DevicePath = AppendDevicePathNode (\r
+                 DevicePath,\r
+                 (EFI_DEVICE_PATH_PROTOCOL *) &FileNode\r
+                 );\r
+  ASSERT (DevicePath != NULL);\r
+\r
+  Status = EfiBootManagerInitializeLoadOption (\r
+             &NewOption,\r
+             LoadOptionNumberUnassigned,\r
+             LoadOptionTypeBoot,\r
+             Attributes,\r
+             Description,\r
+             DevicePath,\r
+             NULL,\r
+             0\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+  FreePool (DevicePath);\r
+\r
+  BootOptions = EfiBootManagerGetLoadOptions (\r
+                  &BootOptionCount, LoadOptionTypeBoot\r
+                  );\r
+\r
+  OptionIndex = EfiBootManagerFindLoadOption (\r
+                  &NewOption, BootOptions, BootOptionCount\r
+                  );\r
+\r
+  if (OptionIndex == -1) {\r
+    Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+  EfiBootManagerFreeLoadOption (&NewOption);\r
+  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
+}\r
+\r
+/**\r
+  Remove all MemoryMapped(...)/FvFile(...) and Fv(...)/FvFile(...) boot options\r
+  whose device paths do not resolve exactly to an FvFile in the system.\r
+\r
+  This removes any boot options that point to binaries built into the firmware\r
+  and have become stale due to any of the following:\r
+  - DXEFV's base address or size changed (historical),\r
+  - DXEFV's FvNameGuid changed,\r
+  - the FILE_GUID of the pointed-to binary changed,\r
+  - the referenced binary is no longer built into the firmware.\r
+\r
+  EfiBootManagerFindLoadOption() used in PlatformRegisterFvBootOption() only\r
+  avoids exact duplicates.\r
+**/\r
+VOID\r
+RemoveStaleFvFileOptions (\r
+  VOID\r
+  )\r
+{\r
+  EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;\r
+  UINTN                        BootOptionCount;\r
+  UINTN                        Index;\r
+\r
+  BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount,\r
+                  LoadOptionTypeBoot);\r
+\r
+  for (Index = 0; Index < BootOptionCount; ++Index) {\r
+    EFI_DEVICE_PATH_PROTOCOL *Node1, *Node2, *SearchNode;\r
+    EFI_STATUS               Status;\r
+    EFI_HANDLE               FvHandle;\r
+\r
+    //\r
+    // If the device path starts with neither MemoryMapped(...) nor Fv(...),\r
+    // then keep the boot option.\r
+    //\r
+    Node1 = BootOptions[Index].FilePath;\r
+    if (!(DevicePathType (Node1) == HARDWARE_DEVICE_PATH &&\r
+          DevicePathSubType (Node1) == HW_MEMMAP_DP) &&\r
+        !(DevicePathType (Node1) == MEDIA_DEVICE_PATH &&\r
+          DevicePathSubType (Node1) == MEDIA_PIWG_FW_VOL_DP)) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // If the second device path node is not FvFile(...), then keep the boot\r
+    // option.\r
+    //\r
+    Node2 = NextDevicePathNode (Node1);\r
+    if (DevicePathType (Node2) != MEDIA_DEVICE_PATH ||\r
+        DevicePathSubType (Node2) != MEDIA_PIWG_FW_FILE_DP) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Locate the Firmware Volume2 protocol instance that is denoted by the\r
+    // boot option. If this lookup fails (i.e., the boot option references a\r
+    // firmware volume that doesn't exist), then we'll proceed to delete the\r
+    // boot option.\r
+    //\r
+    SearchNode = Node1;\r
+    Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid,\r
+                    &SearchNode, &FvHandle);\r
+\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // The firmware volume was found; now let's see if it contains the FvFile\r
+      // identified by GUID.\r
+      //\r
+      EFI_FIRMWARE_VOLUME2_PROTOCOL     *FvProtocol;\r
+      MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFileNode;\r
+      UINTN                             BufferSize;\r
+      EFI_FV_FILETYPE                   FoundType;\r
+      EFI_FV_FILE_ATTRIBUTES            FileAttributes;\r
+      UINT32                            AuthenticationStatus;\r
+\r
+      Status = gBS->HandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid,\r
+                      (VOID **)&FvProtocol);\r
+      ASSERT_EFI_ERROR (Status);\r
+\r
+      FvFileNode = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)Node2;\r
+      //\r
+      // Buffer==NULL means we request metadata only: BufferSize, FoundType,\r
+      // FileAttributes.\r
+      //\r
+      Status = FvProtocol->ReadFile (\r
+                             FvProtocol,\r
+                             &FvFileNode->FvFileName, // NameGuid\r
+                             NULL,                    // Buffer\r
+                             &BufferSize,\r
+                             &FoundType,\r
+                             &FileAttributes,\r
+                             &AuthenticationStatus\r
+                             );\r
+      if (!EFI_ERROR (Status)) {\r
+        //\r
+        // The FvFile was found. Keep the boot option.\r
+        //\r
+        continue;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Delete the boot option.\r
+    //\r
+    Status = EfiBootManagerDeleteLoadOptionVariable (\r
+               BootOptions[Index].OptionNumber, LoadOptionTypeBoot);\r
+    DEBUG_CODE (\r
+      CHAR16 *DevicePathString;\r
+\r
+      DevicePathString = ConvertDevicePathToText(BootOptions[Index].FilePath,\r
+                           FALSE, FALSE);\r
+      DEBUG ((\r
+        EFI_ERROR (Status) ? EFI_D_WARN : DEBUG_VERBOSE,\r
+        "%a: removing stale Boot#%04x %s: %r\n",\r
+        __FUNCTION__,\r
+        (UINT32)BootOptions[Index].OptionNumber,\r
+        DevicePathString == NULL ? L"<unavailable>" : DevicePathString,\r
+        Status\r
+        ));\r
+      if (DevicePathString != NULL) {\r
+        FreePool (DevicePathString);\r
+      }\r
+      );\r
+  }\r
+\r
+  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
+}\r
+\r
+VOID\r
+PlatformRegisterOptionsAndKeys (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  EFI_INPUT_KEY                Enter;\r
+  EFI_INPUT_KEY                F2;\r
+  EFI_INPUT_KEY                Esc;\r
+  EFI_BOOT_MANAGER_LOAD_OPTION BootOption;\r
+\r
+  //\r
+  // Register ENTER as CONTINUE key\r
+  //\r
+  Enter.ScanCode    = SCAN_NULL;\r
+  Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;\r
+  Status = EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Map F2 to Boot Manager Menu\r
+  //\r
+  F2.ScanCode     = SCAN_F2;\r
+  F2.UnicodeChar  = CHAR_NULL;\r
+  Esc.ScanCode    = SCAN_ESC;\r
+  Esc.UnicodeChar = CHAR_NULL;\r
+  Status = EfiBootManagerGetBootManagerMenu (&BootOption);\r
+  ASSERT_EFI_ERROR (Status);\r
+  Status = EfiBootManagerAddKeyOptionVariable (\r
+             NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL\r
+             );\r
+  ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);\r
+  Status = EfiBootManagerAddKeyOptionVariable (\r
+             NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL\r
+             );\r
+  ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+ConnectRootBridge (\r
+  IN EFI_HANDLE  RootBridgeHandle,\r
+  IN VOID        *Instance,\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
+  VOID\r
+  );\r
+\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
+  EFI_HANDLE    Handle;\r
+  EFI_STATUS    Status;\r
+\r
+  DEBUG ((DEBUG_INFO, "PlatformBootManagerBeforeConsole\n"));\r
+  InstallDevicePathCallback ();\r
+\r
+  VisitAllInstancesOfProtocol (&gEfiPciRootBridgeIoProtocolGuid,\r
+    ConnectRootBridge, NULL);\r
+\r
+  //\r
+  // Signal the ACPI platform driver that it can download QEMU ACPI tables.\r
+  //\r
+  EfiEventGroupSignal (&gRootBridgesConnectedEventGroupGuid);\r
+\r
+  //\r
+  // We can't signal End-of-Dxe earlier than this. Namely, End-of-Dxe triggers\r
+  // the preparation of S3 system information. That logic has a hard dependency\r
+  // on the presence of the FACS ACPI table. Since our ACPI tables are only\r
+  // installed after PCI enumeration completes, we must not trigger the S3 save\r
+  // earlier, hence we can't signal End-of-Dxe earlier.\r
+  //\r
+  EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);\r
+\r
+  //\r
+  // Prevent further changes to LockBoxes or SMRAM.\r
+  //\r
+  Handle = NULL;\r
+  Status = gBS->InstallProtocolInterface (&Handle,\r
+                  &gEfiDxeSmmReadyToLockProtocolGuid, EFI_NATIVE_INTERFACE,\r
+                  NULL);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Dispatch deferred images after EndOfDxe event and ReadyToLock\r
+  // installation.\r
+  //\r
+  EfiBootManagerDispatchDeferredImages ();\r
+\r
+  PlatformInitializeConsole (gPlatformConsole);\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
+EFI_STATUS\r
+EFIAPI\r
+ConnectRootBridge (\r
+  IN EFI_HANDLE  RootBridgeHandle,\r
+  IN VOID        *Instance,\r
+  IN VOID        *Context\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  // Make the PCI bus driver connect the root bridge, non-recursively. This\r
+  // will produce a number of child handles with PciIo on them.\r
+  //\r
+  Status = gBS->ConnectController (\r
+                  RootBridgeHandle, // ControllerHandle\r
+                  NULL,             // DriverImageHandle\r
+                  NULL,             // RemainingDevicePath -- produce all\r
+                                    //   children\r
+                  FALSE             // Recursive\r
+                  );\r
+  return Status;\r
+}\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
+  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
+  PciIo = Instance;\r
+\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
+  //\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
+  //\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
+  //\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
+  @param[in] DeviceHandle  Handle of the LPC Bridge device.\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
+  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;\r
+  CHAR16                    *DevPathStr;\r
+\r
+  DevicePath = NULL;\r
+  Status = gBS->HandleProtocol (\r
+                  DeviceHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID*)&DevicePath\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  TempDevicePath = DevicePath;\r
+\r
+  //\r
+  // Register Keyboard\r
+  //\r
+  DevicePath = AppendDevicePathNode (DevicePath,\r
+                 (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode);\r
+\r
+  EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);\r
+\r
+  //\r
+  // Register COM1\r
+  //\r
+  DevicePath = TempDevicePath;\r
+  gPnp16550ComPortDeviceNode.UID = 0;\r
+\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
+  //\r
+  DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);\r
+  if (DevPathStr != NULL) {\r
+    DEBUG((\r
+      DEBUG_INFO,\r
+      "BdsPlatform.c+%d: COM%d DevPath: %s\n",\r
+      __LINE__,\r
+      gPnp16550ComPortDeviceNode.UID + 1,\r
+      DevPathStr\r
+      ));\r
+    FreePool(DevPathStr);\r
+  }\r
+\r
+  EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);\r
+  EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);\r
+  EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);\r
+\r
+  // Don't register COM2 which can be used for DBG instead so keep it clean\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+GetGopDevicePath (\r
+   IN  EFI_DEVICE_PATH_PROTOCOL *PciDevicePath,\r
+   OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath\r
+   )\r
+{\r
+  UINTN                           Index;\r
+  EFI_STATUS                      Status;\r
+  EFI_HANDLE                      PciDeviceHandle;\r
+  EFI_DEVICE_PATH_PROTOCOL        *TempDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL        *TempPciDevicePath;\r
+  UINTN                           GopHandleCount;\r
+  EFI_HANDLE                      *GopHandleBuffer;\r
+\r
+  if (PciDevicePath == NULL || GopDevicePath == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Initialize the GopDevicePath to be PciDevicePath\r
+  //\r
+  *GopDevicePath    = PciDevicePath;\r
+  TempPciDevicePath = PciDevicePath;\r
+\r
+  Status = gBS->LocateDevicePath (\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  &TempPciDevicePath,\r
+                  &PciDeviceHandle\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Try to connect this handle, so that GOP driver could start on this\r
+  // device and create child handles with GraphicsOutput Protocol installed\r
+  // on them, then we get device paths of these child handles and select\r
+  // them as possible console device.\r
+  //\r
+  gBS->ConnectController (PciDeviceHandle, NULL, NULL, FALSE);\r
+\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiGraphicsOutputProtocolGuid,\r
+                  NULL,\r
+                  &GopHandleCount,\r
+                  &GopHandleBuffer\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Add all the child handles as possible Console Device\r
+    //\r
+    for (Index = 0; Index < GopHandleCount; Index++) {\r
+      Status = gBS->HandleProtocol (GopHandleBuffer[Index],\r
+                      &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath);\r
+      if (EFI_ERROR (Status)) {\r
+        continue;\r
+      }\r
+      if (CompareMem (\r
+            PciDevicePath,\r
+            TempDevicePath,\r
+            GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH\r
+            ) == 0) {\r
+        //\r
+        // In current implementation, we only enable one of the child handles\r
+        // as console device, i.e. sotre one of the child handle's device\r
+        // path to variable "ConOut"\r
+        // In future, we could select all child handles to be console device\r
+        //\r
+\r
+        *GopDevicePath = TempDevicePath;\r
+\r
+        //\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
+      }\r
+    }\r
+    gBS->FreePool (GopHandleBuffer);\r
+  }\r
+\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
+  EFI_STATUS                Status;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL  *GopDevicePath;\r
+\r
+  DevicePath    = NULL;\r
+  GopDevicePath = NULL;\r
+  Status = gBS->HandleProtocol (\r
+                  DeviceHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID*)&DevicePath\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  GetGopDevicePath (DevicePath, &GopDevicePath);\r
+  DevicePath = GopDevicePath;\r
+\r
+  EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Add PCI Serial to ConOut, ConIn, ErrOut.\r
+\r
+  @param[in] DeviceHandle  Handle of the PCI serial device.\r
+\r
+  @retval EFI_SUCCESS  The PCI serial device has been added to ConOut, ConIn,\r
+                       ErrOut.\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
+\r
+  DevicePath = NULL;\r
+  Status = gBS->HandleProtocol (\r
+                  DeviceHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  (VOID*)&DevicePath\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\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
+  return EFI_SUCCESS;\r
+}\r
+\r
+EFI_STATUS\r
+VisitAllInstancesOfProtocol (\r
+  IN EFI_GUID                    *Id,\r
+  IN PROTOCOL_INSTANCE_CALLBACK  CallBackFunction,\r
+  IN VOID                        *Context\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  UINTN                     HandleCount;\r
+  EFI_HANDLE                *HandleBuffer;\r
+  UINTN                     Index;\r
+  VOID                      *Instance;\r
+\r
+  //\r
+  // Start to check all the PciIo to find all possible device\r
+  //\r
+  HandleCount = 0;\r
+  HandleBuffer = NULL;\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  Id,\r
+                  NULL,\r
+                  &HandleCount,\r
+                  &HandleBuffer\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  for (Index = 0; Index < HandleCount; Index++) {\r
+    Status = gBS->HandleProtocol (HandleBuffer[Index], Id, &Instance);\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
+\r
+    Status = (*CallBackFunction) (\r
+               HandleBuffer[Index],\r
+               Instance,\r
+               Context\r
+               );\r
+  }\r
+\r
+  gBS->FreePool (HandleBuffer);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+VisitingAPciInstance (\r
+  IN EFI_HANDLE  Handle,\r
+  IN VOID        *Instance,\r
+  IN VOID        *Context\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_PCI_IO_PROTOCOL       *PciIo;\r
+  PCI_TYPE00                Pci;\r
+\r
+  PciIo = (EFI_PCI_IO_PROTOCOL*) Instance;\r
+\r
+  //\r
+  // Check for all PCI device\r
+  //\r
+  Status = PciIo->Pci.Read (\r
+                    PciIo,\r
+                    EfiPciIoWidthUint32,\r
+                    0,\r
+                    sizeof (Pci) / sizeof (UINT32),\r
+                    &Pci\r
+                    );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return (*(VISIT_PCI_INSTANCE_CALLBACK)(UINTN) Context) (\r
+           Handle,\r
+           PciIo,\r
+           &Pci\r
+           );\r
+\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+VisitAllPciInstances (\r
+  IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction\r
+  )\r
+{\r
+  return VisitAllInstancesOfProtocol (\r
+           &gEfiPciIoProtocolGuid,\r
+           VisitingAPciInstance,\r
+           (VOID*)(UINTN) CallBackFunction\r
+           );\r
+}\r
+\r
+\r
+/**\r
+  Do platform specific PCI Device check and add them to\r
+  ConOut, ConIn, ErrOut.\r
+\r
+  @param[in]  Handle - Handle of PCI device instance\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\r
+                        successfully.\r
+  @retval EFI_STATUS - PCI Device check or Console variable update fail.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DetectAndPreparePlatformPciDevicePath (\r
+  IN EFI_HANDLE           Handle,\r
+  IN EFI_PCI_IO_PROTOCOL  *PciIo,\r
+  IN PCI_TYPE00           *Pci\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+\r
+  Status = PciIo->Attributes (\r
+    PciIo,\r
+    EfiPciIoAttributeOperationEnable,\r
+    EFI_PCI_DEVICE_ENABLE,\r
+    NULL\r
+    );\r
+  ASSERT_EFI_ERROR (Status);\r
+\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
+    // Add IsaKeyboard to ConIn,\r
+    // add IsaSerial to ConOut, ConIn, ErrOut\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
+    // Add them to ConOut, ConIn, ErrOut.\r
+    //\r
+    DEBUG ((DEBUG_INFO, "Found PCI 16550 SERIAL device\n"));\r
+    PreparePciSerialDevicePath (Handle);\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Here we decide which display device to enable in PCI bus\r
+  //\r
+  if (IS_PCI_DISPLAY (Pci)) {\r
+    //\r
+    // Add them to ConOut.\r
+    //\r
+    DEBUG ((DEBUG_INFO, "Found PCI display device\n"));\r
+    PreparePciDisplayDevicePath (Handle);\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Connect the predefined platform default console device.\r
+\r
+  Always try to find and enable PCI display devices.\r
+\r
+  @param[in] PlatformConsole  Predefined platform default console device array.\r
+**/\r
+VOID\r
+PlatformInitializeConsole (\r
+  IN PLATFORM_CONSOLE_CONNECT_ENTRY   *PlatformConsole\r
+  )\r
+{\r
+  UINTN                              Index;\r
+\r
+  //\r
+  // Do platform specific PCI Device check and add them to ConOut, ConIn,\r
+  // ErrOut\r
+  //\r
+  VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath);\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
+    // Update the console variable with the connect type\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
+  }\r
+}\r
+\r
+\r
+/**\r
+  Configure PCI Interrupt Line register for applicable devices\r
+  Ported from SeaBIOS, src/fw/pciinit.c, *_pci_slot_get_irq()\r
+\r
+  @param[in]  Handle - Handle of PCI device instance\r
+  @param[in]  PciIo - PCI IO protocol instance\r
+  @param[in]  PciHdr - PCI Header register block\r
+\r
+  @retval EFI_SUCCESS - PCI Interrupt Line register configured successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SetPciIntLine (\r
+  IN EFI_HANDLE           Handle,\r
+  IN EFI_PCI_IO_PROTOCOL  *PciIo,\r
+  IN PCI_TYPE00           *PciHdr\r
+  )\r
+{\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevPathNode;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevPath;\r
+  UINTN                     RootSlot;\r
+  UINTN                     Idx;\r
+  UINT8                     IrqLine;\r
+  EFI_STATUS                Status;\r
+  UINT32                    RootBusNumber;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  if (PciHdr->Device.InterruptPin != 0) {\r
+\r
+    DevPathNode = DevicePathFromHandle (Handle);\r
+    ASSERT (DevPathNode != NULL);\r
+    DevPath = DevPathNode;\r
+\r
+    RootBusNumber = 0;\r
+    if (DevicePathType (DevPathNode) == ACPI_DEVICE_PATH &&\r
+        DevicePathSubType (DevPathNode) == ACPI_DP &&\r
+        ((ACPI_HID_DEVICE_PATH *)DevPathNode)->HID == EISA_PNP_ID(0x0A03)) {\r
+      RootBusNumber = ((ACPI_HID_DEVICE_PATH *)DevPathNode)->UID;\r
+    }\r
+\r
+    //\r
+    // Compute index into PciHostIrqs[] table by walking\r
+    // the device path and adding up all device numbers\r
+    //\r
+    Status = EFI_NOT_FOUND;\r
+    RootSlot = 0;\r
+    Idx = PciHdr->Device.InterruptPin - 1;\r
+    while (!IsDevicePathEnd (DevPathNode)) {\r
+      if (DevicePathType (DevPathNode) == HARDWARE_DEVICE_PATH &&\r
+          DevicePathSubType (DevPathNode) == HW_PCI_DP) {\r
+\r
+        Idx += ((PCI_DEVICE_PATH *)DevPathNode)->Device;\r
+\r
+        //\r
+        // Unlike SeaBIOS, which starts climbing from the leaf device\r
+        // up toward the root, we traverse the device path starting at\r
+        // the root moving toward the leaf node.\r
+        // The slot number of the top-level parent bridge is needed for\r
+        // Q35 cases with more than 24 slots on the root bus.\r
+        //\r
+        if (Status != EFI_SUCCESS) {\r
+          Status = EFI_SUCCESS;\r
+          RootSlot = ((PCI_DEVICE_PATH *)DevPathNode)->Device;\r
+        }\r
+      }\r
+\r
+      DevPathNode = NextDevicePathNode (DevPathNode);\r
+    }\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+    if (RootBusNumber == 0 && RootSlot == 0) {\r
+      DEBUG((\r
+        DEBUG_ERROR,\r
+        "%a: PCI host bridge (00:00.0) should have no interrupts!\n",\r
+        __FUNCTION__\r
+        ));\r
+      ASSERT (FALSE);\r
+    }\r
+\r
+    //\r
+    // Final PciHostIrqs[] index calculation depends on the platform\r
+    // and should match SeaBIOS src/fw/pciinit.c *_pci_slot_get_irq()\r
+    //\r
+    switch (mHostBridgeDevId) {\r
+      case 0x1275: // BHYVE\r
+      case INTEL_82441_DEVICE_ID:\r
+        Idx -= 1;\r
+        break;\r
+      case INTEL_Q35_MCH_DEVICE_ID:\r
+        //\r
+        // SeaBIOS contains the following comment:\r
+        // "Slots 0-24 rotate slot:pin mapping similar to piix above, but\r
+        //  with a different starting index - see q35-acpi-dsdt.dsl.\r
+        //\r
+        //  Slots 25-31 all use LNKA mapping (or LNKE, but A:D = E:H)"\r
+        //\r
+        if (RootSlot > 24) {\r
+          //\r
+          // in this case, subtract back out RootSlot from Idx\r
+          // (SeaBIOS never adds it to begin with, but that would make our\r
+          //  device path traversal loop above too awkward)\r
+          //\r
+          Idx -= RootSlot;\r
+        }\r
+        break;\r
+      default:\r
+        ASSERT (FALSE); // should never get here\r
+    }\r
+    Idx %= ARRAY_SIZE (PciHostIrqs);\r
+    IrqLine = PciHostIrqs[Idx];\r
+\r
+    DEBUG_CODE_BEGIN ();\r
+    {\r
+      CHAR16        *DevPathString;\r
+      STATIC CHAR16 Fallback[] = L"<failed to convert>";\r
+      UINTN         Segment, Bus, Device, Function;\r
+\r
+      DevPathString = ConvertDevicePathToText (DevPath, FALSE, FALSE);\r
+      if (DevPathString == NULL) {\r
+        DevPathString = Fallback;\r
+      }\r
+      Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);\r
+      ASSERT_EFI_ERROR (Status);\r
+\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
+      if (DevPathString != Fallback) {\r
+        FreePool (DevPathString);\r
+      }\r
+    }\r
+    DEBUG_CODE_END ();\r
+\r
+    //\r
+    // Set PCI Interrupt Line register for this device to PciHostIrqs[Idx]\r
+    //\r
+    Status = PciIo->Pci.Write (\r
+               PciIo,\r
+               EfiPciIoWidthUint8,\r
+               PCI_INT_LINE_OFFSET,\r
+               1,\r
+               &IrqLine\r
+               );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+VOID\r
+PciAcpiInitialization (\r
+  )\r
+{\r
+  UINTN  Pmba;\r
+\r
+  //\r
+  // Query Host Bridge DID to determine platform type\r
+  //\r
+  mHostBridgeDevId = PcdGet16 (PcdOvmfHostBridgePciDevId);\r
+  switch (mHostBridgeDevId) {\r
+    case 0x1275: // BHYVE\r
+    case INTEL_82441_DEVICE_ID:\r
+      Pmba = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);\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
+      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
+      break;\r
+    default:\r
+      DEBUG ((DEBUG_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",\r
+        __FUNCTION__, mHostBridgeDevId));\r
+      ASSERT (FALSE);\r
+      return;\r
+  }\r
+\r
+  //\r
+  // Initialize PCI_INTERRUPT_LINE for applicable present PCI devices\r
+  //\r
+  VisitAllPciInstances (SetPciIntLine);\r
+\r
+  //\r
+  // Set ACPI SCI_EN bit in PMCNTRL\r
+  //\r
+  IoOr16 ((PciRead32 (Pmba) & ~BIT0) + 4, BIT0);\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+ConnectRecursivelyIfPciMassStorage (\r
+  IN EFI_HANDLE           Handle,\r
+  IN EFI_PCI_IO_PROTOCOL  *Instance,\r
+  IN PCI_TYPE00           *PciHeader\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+  CHAR16                    *DevPathStr;\r
+\r
+  //\r
+  // Recognize PCI Mass Storage, and Xen PCI devices\r
+  //\r
+  if (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE)) {\r
+    DevicePath = NULL;\r
+    Status = gBS->HandleProtocol (\r
+                    Handle,\r
+                    &gEfiDevicePathProtocolGuid,\r
+                    (VOID*)&DevicePath\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+    //\r
+    // Print Device Path\r
+    //\r
+    DevPathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);\r
+    if (DevPathStr != NULL) {\r
+      DEBUG((\r
+        DEBUG_INFO,\r
+        "Found %s device: %s\n",\r
+        (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE) ?\r
+         L"Mass Storage" :\r
+         L"Xen"\r
+         ),\r
+        DevPathStr\r
+        ));\r
+      FreePool(DevPathStr);\r
+    }\r
+\r
+    Status = gBS->ConnectController (Handle, NULL, NULL, TRUE);\r
+    if (EFI_ERROR (Status)) {\r
+      return Status;\r
+    }\r
+\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  This notification function is invoked when the\r
+  EMU Variable FVB has been changed.\r
+\r
+  @param  Event                 The event that occurred\r
+  @param  Context               For EFI compatibility.  Not used.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+EmuVariablesUpdatedCallback (\r
+  IN  EFI_EVENT Event,\r
+  IN  VOID      *Context\r
+  )\r
+{\r
+  DEBUG ((DEBUG_INFO, "EmuVariablesUpdatedCallback\n"));\r
+  UpdateNvVarsOnFileSystem ();\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+VisitingFileSystemInstance (\r
+  IN EFI_HANDLE  Handle,\r
+  IN VOID        *Instance,\r
+  IN VOID        *Context\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
+  }\r
+\r
+  Status = ConnectNvVarsToFileSystem (Handle);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  ConnectedToFileSystem = TRUE;\r
+  mEmuVariableEvent =\r
+    EfiCreateProtocolNotifyEvent (\r
+      &gEfiDevicePathProtocolGuid,\r
+      TPL_CALLBACK,\r
+      EmuVariablesUpdatedCallback,\r
+      NULL,\r
+      &mEmuVariableEventReg\r
+      );\r
+  PcdStatus = PcdSet64S (PcdEmuVariableEvent,\r
+                (UINT64)(UINTN) mEmuVariableEvent);\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+VOID\r
+PlatformBdsRestoreNvVarsFromHardDisk (\r
+  )\r
+{\r
+  VisitAllPciInstances (ConnectRecursivelyIfPciMassStorage);\r
+  VisitAllInstancesOfProtocol (\r
+    &gEfiSimpleFileSystemProtocolGuid,\r
+    VisitingFileSystemInstance,\r
+    NULL\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
+  UINTN         Index;\r
+\r
+  DEBUG ((DEBUG_INFO, "PlatformBdsConnectSequence\n"));\r
+\r
+  Index = 0;\r
+\r
+  //\r
+  // Here we can get the customized platform connect sequence\r
+  // Notes: we can connect with new variable which record the\r
+  // last time boots connect device path sequence\r
+  //\r
+  while (gPlatformConnectSequence[Index] != NULL) {\r
+    //\r
+    // Build the platform boot option\r
+    //\r
+    EfiBootManagerConnectDevicePath (gPlatformConnectSequence[Index], NULL);\r
+    Index++;\r
+  }\r
+\r
+  //\r
+  // Just use the simple policy to connect all devices\r
+  //\r
+  DEBUG ((DEBUG_INFO, "EfiBootManagerConnectAll\n"));\r
+  EfiBootManagerConnectAll ();\r
+}\r
+\r
+/**\r
+  Save the S3 boot script.\r
+\r
+  Note that DxeSmmReadyToLock must be signaled after this function returns;\r
+  otherwise the script wouldn't be saved actually.\r
+**/\r
+#if defined(__GNUC__)\r
+__attribute__((unused))\r
+#endif\r
+STATIC\r
+VOID\r
+SaveS3BootScript (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                 Status;\r
+  EFI_S3_SAVE_STATE_PROTOCOL *BootScript;\r
+  STATIC CONST UINT8         Info[] = { 0xDE, 0xAD, 0xBE, 0xEF };\r
+\r
+  Status = gBS->LocateProtocol (&gEfiS3SaveStateProtocolGuid, NULL,\r
+                  (VOID **) &BootScript);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Despite the opcode documentation in the PI spec, the protocol\r
+  // implementation embeds a deep copy of the info in the boot script, rather\r
+  // than storing just a pointer to runtime or NVS storage.\r
+  //\r
+  Status = BootScript->Write(BootScript, EFI_BOOT_SCRIPT_INFORMATION_OPCODE,\r
+                         (UINT32) sizeof Info,\r
+                         (EFI_PHYSICAL_ADDRESS)(UINTN) &Info);\r
+  ASSERT_EFI_ERROR (Status);\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
+  EFI_BOOT_MODE                      BootMode;\r
+\r
+  DEBUG ((DEBUG_INFO, "PlatformBootManagerAfterConsole\n"));\r
+\r
+  if (PcdGetBool (PcdOvmfFlashVariablesEnable)) {\r
+    DEBUG ((DEBUG_INFO, "PlatformBdsPolicyBehavior: not restoring NvVars "\r
+      "from disk since flash variables appear to be supported.\n"));\r
+  } else {\r
+    //\r
+    // Try to restore variables from the hard disk early so\r
+    // they can be used for the other BDS connect operations.\r
+    //\r
+    /* XXX Calling this causes Keyboard to be removed from ConIn which\r
+       results in unresponsive guest boot loaders in the GUI. Restore it\r
+       when we figure out what is needed to get NvVars storage done\r
+       properly.\r
+     */\r
+    /*PlatformBdsRestoreNvVarsFromHardDisk ();*/\r
+  }\r
+\r
+  //\r
+  // Get current Boot Mode\r
+  //\r
+  BootMode = GetBootModeHob ();\r
+  DEBUG ((DEBUG_INFO, "Boot Mode:%x\n", BootMode));\r
+\r
+  //\r
+  // Go the different platform policy with different boot mode\r
+  // Notes: this part code can be change with the table policy\r
+  //\r
+  ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION);\r
+\r
+  //\r
+  // Logo show\r
+  //\r
+  BootLogoEnableLogo ();\r
+\r
+  //\r
+  // Set PCI Interrupt Line registers and ACPI SCI_EN\r
+  //\r
+  PciAcpiInitialization ();\r
+\r
+  //\r
+  // Process TPM PPI request\r
+  //\r
+  Tcg2PhysicalPresenceLibProcessRequest (NULL);\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
+    &gUefiShellFileGuid, L"EFI Internal Shell", LOAD_OPTION_ACTIVE\r
+    );\r
+\r
+  RemoveStaleFvFileOptions ();\r
+\r
+  PlatformBmPrintScRegisterHandler ();\r
+}\r
+\r
+/**\r
+  This notification function is invoked when an instance of the\r
+  EFI_DEVICE_PATH_PROTOCOL is produced.\r
+\r
+  @param  Event                 The event that occurred\r
+  @param  Context               For EFI compatibility.  Not used.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+NotifyDevPath (\r
+  IN  EFI_EVENT Event,\r
+  IN  VOID      *Context\r
+  )\r
+{\r
+  EFI_HANDLE                            Handle;\r
+  EFI_STATUS                            Status;\r
+  UINTN                                 BufferSize;\r
+  EFI_DEVICE_PATH_PROTOCOL             *DevPathNode;\r
+  ATAPI_DEVICE_PATH                    *Atapi;\r
+\r
+  //\r
+  // Examine all new handles\r
+  //\r
+  for (;;) {\r
+    //\r
+    // Get the next handle\r
+    //\r
+    BufferSize = sizeof (Handle);\r
+    Status = gBS->LocateHandle (\r
+              ByRegisterNotify,\r
+              NULL,\r
+              mEfiDevPathNotifyReg,\r
+              &BufferSize,\r
+              &Handle\r
+              );\r
+\r
+    //\r
+    // If not found, we're done\r
+    //\r
+    if (EFI_NOT_FOUND == Status) {\r
+      break;\r
+    }\r
+\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Get the DevicePath protocol on that handle\r
+    //\r
+    Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid,\r
+                    (VOID **)&DevPathNode);\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    while (!IsDevicePathEnd (DevPathNode)) {\r
+      //\r
+      // Find the handler to dump this device path node\r
+      //\r
+      if (\r
+           (DevicePathType(DevPathNode) == MESSAGING_DEVICE_PATH) &&\r
+           (DevicePathSubType(DevPathNode) == MSG_ATAPI_DP)\r
+         ) {\r
+        Atapi = (ATAPI_DEVICE_PATH*) DevPathNode;\r
+        PciOr16 (\r
+          PCI_LIB_ADDRESS (\r
+            0,\r
+            1,\r
+            1,\r
+            (Atapi->PrimarySecondary == 1) ? 0x42: 0x40\r
+            ),\r
+          BIT15\r
+          );\r
+      }\r
+\r
+      //\r
+      // Next device path node\r
+      //\r
+      DevPathNode = NextDevicePathNode (DevPathNode);\r
+    }\r
+  }\r
+\r
+  return;\r
+}\r
+\r
+\r
+VOID\r
+InstallDevicePathCallback (\r
+  VOID\r
+  )\r
+{\r
+  DEBUG ((DEBUG_INFO, "Registered NotifyDevPath Event\n"));\r
+  mEfiDevPathEvent = EfiCreateProtocolNotifyEvent (\r
+                          &gEfiDevicePathProtocolGuid,\r
+                          TPL_CALLBACK,\r
+                          NotifyDevPath,\r
+                          NULL,\r
+                          &mEfiDevPathNotifyReg\r
+                          );\r
+}\r
+\r
+/**\r
+  This function is called each second during the boot manager waits the\r
+  timeout.\r
+\r
+  @param TimeoutRemain  The remaining timeout.\r
+**/\r
+VOID\r
+EFIAPI\r
+PlatformBootManagerWaitCallback (\r
+  UINT16          TimeoutRemain\r
+  )\r
+{\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White;\r
+  UINT16                              Timeout;\r
+\r
+  Timeout = PcdGet16 (PcdPlatformBootTimeOut);\r
+\r
+  Black.Raw = 0x00000000;\r
+  White.Raw = 0x00FFFFFF;\r
+\r
+  BootLogoUpdateProgress (\r
+    White.Pixel,\r
+    Black.Pixel,\r
+    L"Start boot option",\r
+    White.Pixel,\r
+    (Timeout - TimeoutRemain) * 100 / Timeout,\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
diff --git a/OvmfPkg/Library/PlatformBootManagerLibBhyve/BdsPlatform.h b/OvmfPkg/Library/PlatformBootManagerLibBhyve/BdsPlatform.h
new file mode 100644 (file)
index 0000000..382fe19
--- /dev/null
@@ -0,0 +1,190 @@
+/** @file\r
+  Platform BDS customizations include file.\r
+\r
+  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+Module Name:\r
+\r
+  BdsPlatform.h\r
+\r
+Abstract:\r
+\r
+  Head file for BDS Platform specific code\r
+\r
+**/\r
+\r
+#ifndef _PLATFORM_SPECIFIC_BDS_PLATFORM_H_\r
+#define _PLATFORM_SPECIFIC_BDS_PLATFORM_H_\r
+\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <IndustryStandard/Pci.h>\r
+#include <IndustryStandard/Acpi.h>\r
+#include <IndustryStandard/SmBios.h>\r
+#include <IndustryStandard/PeImage.h>\r
+#include <IndustryStandard/Virtio095.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/PciLib.h>\r
+#include <Library/UefiBootManagerLib.h>\r
+#include <Library/BootLogoLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/DxeServicesTableLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/NvVarsFileLib.h>\r
+#include <Library/QemuFwCfgLib.h>\r
+#include <Library/QemuFwCfgS3Lib.h>\r
+#include <Library/QemuBootOrderLib.h>\r
+\r
+#include <Protocol/Decompress.h>\r
+#include <Protocol/PciIo.h>\r
+#include <Protocol/FirmwareVolume2.h>\r
+#include <Protocol/SimpleFileSystem.h>\r
+#include <Protocol/PciRootBridgeIo.h>\r
+#include <Protocol/S3SaveState.h>\r
+#include <Protocol/DxeSmmReadyToLock.h>\r
+#include <Protocol/LoadedImage.h>\r
+\r
+#include <Guid/Acpi.h>\r
+#include <Guid/SmBios.h>\r
+#include <Guid/HobList.h>\r
+#include <Guid/GlobalVariable.h>\r
+#include <Guid/EventGroup.h>\r
+#include <Guid/DebugAgentGuid.h>\r
+\r
+#include <OvmfPlatforms.h>\r
+\r
+extern EFI_DEVICE_PATH_PROTOCOL   *gPlatformConnectSequence[];\r
+extern ACPI_HID_DEVICE_PATH       gPnpPs2KeyboardDeviceNode;\r
+extern ACPI_HID_DEVICE_PATH       gPnp16550ComPortDeviceNode;\r
+extern UART_DEVICE_PATH           gUartDeviceNode;\r
+extern VENDOR_DEVICE_PATH         gTerminalTypeDeviceNode;\r
+\r
+#define PCI_DEVICE_PATH_NODE(Func, Dev) \\r
+  { \\r
+    { \\r
+      HARDWARE_DEVICE_PATH, \\r
+      HW_PCI_DP, \\r
+      { \\r
+        (UINT8) (sizeof (PCI_DEVICE_PATH)), \\r
+        (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \\r
+      } \\r
+    }, \\r
+    (Func), \\r
+    (Dev) \\r
+  }\r
+\r
+#define PNPID_DEVICE_PATH_NODE(PnpId) \\r
+  { \\r
+    { \\r
+      ACPI_DEVICE_PATH, \\r
+      ACPI_DP, \\r
+      { \\r
+        (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \\r
+        (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \\r
+      }, \\r
+    }, \\r
+    EISA_PNP_ID((PnpId)), \\r
+    0 \\r
+  }\r
+\r
+#define gPciIsaBridge \\r
+  PCI_DEVICE_PATH_NODE(0, 0x1f)\r
+\r
+#define gP2PBridge \\r
+  PCI_DEVICE_PATH_NODE(0, 0x1e)\r
+\r
+#define gPnpPs2Keyboard \\r
+  PNPID_DEVICE_PATH_NODE(0x0303)\r
+\r
+#define gPnp16550ComPort \\r
+  PNPID_DEVICE_PATH_NODE(0x0501)\r
+\r
+#define gUart \\r
+  { \\r
+    { \\r
+      MESSAGING_DEVICE_PATH, \\r
+      MSG_UART_DP, \\r
+      { \\r
+        (UINT8) (sizeof (UART_DEVICE_PATH)), \\r
+        (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8) \\r
+      } \\r
+    }, \\r
+    0, \\r
+    115200, \\r
+    8, \\r
+    1, \\r
+    1 \\r
+  }\r
+\r
+#define gPcAnsiTerminal \\r
+  { \\r
+    { \\r
+      MESSAGING_DEVICE_PATH, \\r
+      MSG_VENDOR_DP, \\r
+      { \\r
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \\r
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \\r
+      } \\r
+    }, \\r
+    DEVICE_PATH_MESSAGING_PC_ANSI \\r
+  }\r
+\r
+#define gEndEntire \\r
+  { \\r
+    END_DEVICE_PATH_TYPE, \\r
+    END_ENTIRE_DEVICE_PATH_SUBTYPE, \\r
+    { \\r
+      END_DEVICE_PATH_LENGTH, \\r
+      0 \\r
+    } \\r
+  }\r
+\r
+#define PCI_CLASS_SCC          0x07\r
+#define PCI_SUBCLASS_SERIAL    0x00\r
+#define PCI_IF_16550           0x02\r
+#define IS_PCI_16550SERIAL(_p)           IS_CLASS3 (_p, PCI_CLASS_SCC, PCI_SUBCLASS_SERIAL, PCI_IF_16550)\r
+#define IS_PCI_ISA_PDECODE(_p)        IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA_PDECODE, 0)\r
+\r
+typedef struct {\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+  UINTN                     ConnectType;\r
+} PLATFORM_CONSOLE_CONNECT_ENTRY;\r
+\r
+#define CONSOLE_OUT BIT0\r
+#define CONSOLE_IN  BIT1\r
+#define STD_ERROR   BIT2\r
+extern PLATFORM_CONSOLE_CONNECT_ENTRY  gPlatformConsole[];\r
+\r
+//\r
+// Platform BDS Functions\r
+//\r
+\r
+VOID\r
+PlatformInitializeConsole (\r
+  IN PLATFORM_CONSOLE_CONNECT_ENTRY   *PlatformConsole\r
+  );\r
+\r
+/**\r
+  Loads and boots UEFI Linux via the FwCfg interface.\r
+\r
+  @retval    EFI_NOT_FOUND - The Linux kernel was not found\r
+\r
+**/\r
+EFI_STATUS\r
+TryRunningQemuKernel (\r
+  VOID\r
+  );\r
+\r
+#endif // _PLATFORM_SPECIFIC_BDS_PLATFORM_H_\r
diff --git a/OvmfPkg/Library/PlatformBootManagerLibBhyve/PlatformBootManagerLibBhyve.inf b/OvmfPkg/Library/PlatformBootManagerLibBhyve/PlatformBootManagerLibBhyve.inf
new file mode 100644 (file)
index 0000000..c1fb511
--- /dev/null
@@ -0,0 +1,75 @@
+## @file\r
+#  Platform BDS customizations library.\r
+#\r
+#  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+#  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = PlatformBootManagerLibBhyve\r
+  FILE_GUID                      = b0de5f0d-f676-42da-8d00-86997ee0dbb4\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = PlatformBootManagerLib|DXE_DRIVER\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 EBC\r
+#\r
+\r
+[Sources]\r
+  BdsPlatform.c\r
+  PlatformData.c\r
+  BdsPlatform.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  SourceLevelDebugPkg/SourceLevelDebugPkg.dec\r
+  OvmfPkg/OvmfPkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  MemoryAllocationLib\r
+  UefiBootServicesTableLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  PcdLib\r
+  UefiBootManagerLib\r
+  BootLogoLib\r
+  DevicePathLib\r
+  PciLib\r
+  NvVarsFileLib\r
+  ReportStatusCodeLib\r
+  UefiLib\r
+  PlatformBmPrintScLib\r
+  Tcg2PhysicalPresenceLib\r
+\r
+[Pcd]\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdEmuVariableEvent\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashVariablesEnable\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId\r
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut\r
+\r
+[Pcd.IA32, Pcd.X64]\r
+  gEfiMdePkgTokenSpaceGuid.PcdFSBClock\r
+\r
+[Protocols]\r
+  gEfiDecompressProtocolGuid\r
+  gEfiPciRootBridgeIoProtocolGuid\r
+  gEfiS3SaveStateProtocolGuid                   # PROTOCOL SOMETIMES_CONSUMED\r
+  gEfiDxeSmmReadyToLockProtocolGuid             # PROTOCOL SOMETIMES_PRODUCED\r
+  gEfiLoadedImageProtocolGuid                   # PROTOCOL SOMETIMES_PRODUCED\r
+  gEfiFirmwareVolume2ProtocolGuid               # PROTOCOL SOMETIMES_CONSUMED\r
+\r
+[Guids]\r
+  gEfiEndOfDxeEventGroupGuid\r
+  gRootBridgesConnectedEventGroupGuid\r
+  gUefiShellFileGuid\r
diff --git a/OvmfPkg/Library/PlatformBootManagerLibBhyve/PlatformData.c b/OvmfPkg/Library/PlatformBootManagerLibBhyve/PlatformData.c
new file mode 100644 (file)
index 0000000..73674d5
--- /dev/null
@@ -0,0 +1,171 @@
+/** @file\r
+  Defined the platform specific device path which will be used by\r
+  platform Bbd to perform the platform policy connect.\r
+\r
+  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+  Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "BdsPlatform.h"\r
+#include <Guid/QemuRamfb.h>\r
+\r
+//\r
+// Debug Agent UART Device Path structure\r
+//\r
+#pragma pack(1)\r
+typedef struct {\r
+  VENDOR_DEVICE_PATH        VendorHardware;\r
+  UART_DEVICE_PATH          Uart;\r
+  VENDOR_DEVICE_PATH        TerminalType;\r
+  EFI_DEVICE_PATH_PROTOCOL  End;\r
+} VENDOR_UART_DEVICE_PATH;\r
+#pragma pack()\r
+\r
+//\r
+// USB Keyboard Device Path structure\r
+//\r
+#pragma pack (1)\r
+typedef struct {\r
+  USB_CLASS_DEVICE_PATH    Keyboard;\r
+  EFI_DEVICE_PATH_PROTOCOL End;\r
+} USB_KEYBOARD_DEVICE_PATH;\r
+#pragma pack ()\r
+\r
+//\r
+// QemuRamfb Device Path structure\r
+//\r
+#pragma pack (1)\r
+typedef struct {\r
+  VENDOR_DEVICE_PATH        Vendor;\r
+  ACPI_ADR_DEVICE_PATH      AcpiAdr;\r
+  EFI_DEVICE_PATH_PROTOCOL  End;\r
+} VENDOR_RAMFB_DEVICE_PATH;\r
+#pragma pack ()\r
+\r
+ACPI_HID_DEVICE_PATH       gPnpPs2KeyboardDeviceNode  = gPnpPs2Keyboard;\r
+ACPI_HID_DEVICE_PATH       gPnp16550ComPortDeviceNode = gPnp16550ComPort;\r
+UART_DEVICE_PATH           gUartDeviceNode            = gUart;\r
+VENDOR_DEVICE_PATH         gTerminalTypeDeviceNode    = gPcAnsiTerminal;\r
+\r
+//\r
+// Platform specific keyboard device path\r
+//\r
+\r
+\r
+//\r
+// Debug Agent UART Device Path\r
+//\r
+VENDOR_UART_DEVICE_PATH gDebugAgentUartDevicePath = {\r
+  {\r
+    {\r
+      HARDWARE_DEVICE_PATH,\r
+      HW_VENDOR_DP,\r
+      {\r
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
+      }\r
+    },\r
+    EFI_DEBUG_AGENT_GUID,\r
+  },\r
+  {\r
+    {\r
+      MESSAGING_DEVICE_PATH,\r
+      MSG_UART_DP,\r
+      {\r
+        (UINT8) (sizeof (UART_DEVICE_PATH)),\r
+        (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8)\r
+      }\r
+    },\r
+    0,  // Reserved\r
+    0,  // BaudRate - Default\r
+    0,  // DataBits - Default\r
+    0,  // Parity   - Default\r
+    0,  // StopBits - Default\r
+  },\r
+  gPcAnsiTerminal,\r
+  gEndEntire\r
+};\r
+\r
+STATIC USB_KEYBOARD_DEVICE_PATH gUsbKeyboardDevicePath = {\r
+  {\r
+    {\r
+      MESSAGING_DEVICE_PATH,\r
+      MSG_USB_CLASS_DP,\r
+      {\r
+        (UINT8)sizeof (USB_CLASS_DEVICE_PATH),\r
+        (UINT8)(sizeof (USB_CLASS_DEVICE_PATH) >> 8)\r
+      }\r
+    },\r
+    0xFFFF, // VendorId: any\r
+    0xFFFF, // ProductId: any\r
+    3,      // DeviceClass: HID\r
+    1,      // DeviceSubClass: boot\r
+    1       // DeviceProtocol: keyboard\r
+  },\r
+  gEndEntire\r
+};\r
+\r
+STATIC VENDOR_RAMFB_DEVICE_PATH gQemuRamfbDevicePath = {\r
+  {\r
+    {\r
+      HARDWARE_DEVICE_PATH,\r
+      HW_VENDOR_DP,\r
+      {\r
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
+      }\r
+    },\r
+    QEMU_RAMFB_GUID,\r
+  },\r
+  {\r
+    {\r
+      ACPI_DEVICE_PATH,\r
+      ACPI_ADR_DP,\r
+      {\r
+        (UINT8) (sizeof (ACPI_ADR_DEVICE_PATH)),\r
+        (UINT8) ((sizeof (ACPI_ADR_DEVICE_PATH)) >> 8)\r
+      }\r
+    },\r
+    ACPI_DISPLAY_ADR (\r
+      1,                                       // DeviceIdScheme\r
+      0,                                       // HeadId\r
+      0,                                       // NonVgaOutput\r
+      1,                                       // BiosCanDetect\r
+      0,                                       // VendorInfo\r
+      ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL,  // Type\r
+      0,                                       // Port\r
+      0                                        // Index\r
+      ),\r
+  },\r
+  gEndEntire\r
+};\r
+\r
+//\r
+// Predefined platform default console device path\r
+//\r
+PLATFORM_CONSOLE_CONNECT_ENTRY   gPlatformConsole[] = {\r
+  {\r
+    (EFI_DEVICE_PATH_PROTOCOL *) &gDebugAgentUartDevicePath,\r
+    (CONSOLE_OUT | CONSOLE_IN | STD_ERROR)\r
+  },\r
+  {\r
+    (EFI_DEVICE_PATH_PROTOCOL *)&gUsbKeyboardDevicePath,\r
+    CONSOLE_IN\r
+  },\r
+  {\r
+    (EFI_DEVICE_PATH_PROTOCOL *)&gQemuRamfbDevicePath,\r
+    CONSOLE_OUT\r
+  },\r
+  {\r
+    NULL,\r
+    0\r
+  }\r
+};\r
+\r
+//\r
+// Predefined platform connect sequence\r
+//\r
+EFI_DEVICE_PATH_PROTOCOL    *gPlatformConnectSequence[] = { NULL };\r
+\r
index f16c00ad5b99dd55e275d08cd9fe86ad48779be7..55bb8ea91a00aec90dee45496bb2b8c75bc055c4 100644 (file)
@@ -1,7 +1,9 @@
 ## @file\r
 #  EFI/Framework Open Virtual Machine Firmware (OVMF) platform\r
 #\r
+#  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
 #  Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2014, Pluribus Networks, Inc.\r
 #\r
 #  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
@@ -18,6 +20,9 @@
   Csm/Include\r
 \r
 [LibraryClasses]\r
+  ##  @libraryclass  Access bhyve's firmware control interface.\r
+  BhyveFwCtlLib|Include/Library/BhyveFwCtlLib.h\r
+\r
   ##  @libraryclass  Loads and boots a Linux kernel image\r
   #\r
   LoadLinuxLib|Include/Library/LoadLinuxLib.h\r