]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add BhyvePkg, to support the bhyve hypervisor
authorRebecca Cran <rebecca@bsdio.com>
Mon, 13 Jul 2020 05:41:31 +0000 (23:41 -0600)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Fri, 31 Jul 2020 13:03:10 +0000 (13:03 +0000)
BhyvePkg supports the bhyve hypervisor, which is a hypervisor/virtual
machine manager available on FreeBSD, macOS and Illumos.

Signed-off-by: Rebecca Cran <rebecca@bsdio.com>
Message-Id: <20200713054131.479627-2-rebecca@bsdio.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
53 files changed:
OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c [new file with mode: 0644]
OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.h [new file with mode: 0644]
OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatformDxe.inf [new file with mode: 0644]
OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c [new file with mode: 0644]
OvmfPkg/Bhyve/AcpiPlatformDxe/EntryPoint.c [new file with mode: 0644]
OvmfPkg/Bhyve/AcpiPlatformDxe/PciDecoding.c [new file with mode: 0644]
OvmfPkg/Bhyve/AcpiTables/AcpiTables.inf [new file with mode: 0644]
OvmfPkg/Bhyve/AcpiTables/Dsdt.asl [new file with mode: 0644]
OvmfPkg/Bhyve/AcpiTables/Facp.aslc [new file with mode: 0644]
OvmfPkg/Bhyve/AcpiTables/Facs.aslc [new file with mode: 0644]
OvmfPkg/Bhyve/AcpiTables/Hpet.aslc [new file with mode: 0644]
OvmfPkg/Bhyve/AcpiTables/Madt.aslc [new file with mode: 0644]
OvmfPkg/Bhyve/AcpiTables/Mcfg.aslc [new file with mode: 0644]
OvmfPkg/Bhyve/AcpiTables/Platform.h [new file with mode: 0644]
OvmfPkg/Bhyve/AcpiTables/Spcr.aslc [new file with mode: 0644]
OvmfPkg/Bhyve/AcpiTables/Ssdt.asl [new file with mode: 0644]
OvmfPkg/Bhyve/BhyvePkg.dec [new file with mode: 0644]
OvmfPkg/Bhyve/BhyvePkgDefines.fdf.inc [new file with mode: 0644]
OvmfPkg/Bhyve/BhyvePkgX64.dsc [new file with mode: 0644]
OvmfPkg/Bhyve/BhyvePkgX64.fdf [new file with mode: 0644]
OvmfPkg/Bhyve/BhyveRfbDxe/BhyveRfbDxe.inf [new file with mode: 0644]
OvmfPkg/Bhyve/BhyveRfbDxe/ComponentName.c [new file with mode: 0644]
OvmfPkg/Bhyve/BhyveRfbDxe/Gop.h [new file with mode: 0644]
OvmfPkg/Bhyve/BhyveRfbDxe/GopDriver.c [new file with mode: 0644]
OvmfPkg/Bhyve/BhyveRfbDxe/GopScreen.c [new file with mode: 0644]
OvmfPkg/Bhyve/BhyveRfbDxe/VbeShim.asm [new file with mode: 0644]
OvmfPkg/Bhyve/BhyveRfbDxe/VbeShim.c [new file with mode: 0644]
OvmfPkg/Bhyve/BhyveRfbDxe/VbeShim.h [new file with mode: 0644]
OvmfPkg/Bhyve/BhyveRfbDxe/VbeShim.sh [new file with mode: 0644]
OvmfPkg/Bhyve/FvmainCompactScratchEnd.fdf.inc [new file with mode: 0644]
OvmfPkg/Bhyve/Include/Library/BhyveFwCtlLib.h [new file with mode: 0644]
OvmfPkg/Bhyve/Library/BhyveFwCtlLib/BhyveFwCtlLib.c [new file with mode: 0644]
OvmfPkg/Bhyve/Library/BhyveFwCtlLib/BhyveFwCtlLib.inf [new file with mode: 0644]
OvmfPkg/Bhyve/Library/PlatformBootManagerLib/BdsPlatform.c [new file with mode: 0644]
OvmfPkg/Bhyve/Library/PlatformBootManagerLib/BdsPlatform.h [new file with mode: 0644]
OvmfPkg/Bhyve/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf [new file with mode: 0644]
OvmfPkg/Bhyve/Library/PlatformBootManagerLib/PlatformData.c [new file with mode: 0644]
OvmfPkg/Bhyve/License.txt [new file with mode: 0644]
OvmfPkg/Bhyve/PlatformPei/AmdSev.c [new file with mode: 0644]
OvmfPkg/Bhyve/PlatformPei/ClearCache.c [new file with mode: 0644]
OvmfPkg/Bhyve/PlatformPei/Cmos.c [new file with mode: 0644]
OvmfPkg/Bhyve/PlatformPei/Cmos.h [new file with mode: 0644]
OvmfPkg/Bhyve/PlatformPei/FeatureControl.c [new file with mode: 0644]
OvmfPkg/Bhyve/PlatformPei/Fv.c [new file with mode: 0644]
OvmfPkg/Bhyve/PlatformPei/MemDetect.c [new file with mode: 0644]
OvmfPkg/Bhyve/PlatformPei/Platform.c [new file with mode: 0644]
OvmfPkg/Bhyve/PlatformPei/Platform.h [new file with mode: 0644]
OvmfPkg/Bhyve/PlatformPei/PlatformPei.inf [new file with mode: 0644]
OvmfPkg/Bhyve/SmbiosPlatformDxe/Bhyve.c [new file with mode: 0644]
OvmfPkg/Bhyve/SmbiosPlatformDxe/SmbiosPlatformDxe.c [new file with mode: 0644]
OvmfPkg/Bhyve/SmbiosPlatformDxe/SmbiosPlatformDxe.h [new file with mode: 0644]
OvmfPkg/Bhyve/SmbiosPlatformDxe/SmbiosPlatformDxe.inf [new file with mode: 0644]
OvmfPkg/Bhyve/VarStore.fdf.inc [new file with mode: 0644]

diff --git a/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c b/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.c
new file mode 100644 (file)
index 0000000..31bbf6c
--- /dev/null
@@ -0,0 +1,251 @@
+/** @file\r
+  OVMF ACPI Platform Driver\r
+\r
+  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+  Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "AcpiPlatform.h"\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+InstallAcpiTable (\r
+  IN   EFI_ACPI_TABLE_PROTOCOL       *AcpiProtocol,\r
+  IN   VOID                          *AcpiTableBuffer,\r
+  IN   UINTN                         AcpiTableBufferSize,\r
+  OUT  UINTN                         *TableKey\r
+  )\r
+{\r
+  return AcpiProtocol->InstallAcpiTable (\r
+                         AcpiProtocol,\r
+                         AcpiTableBuffer,\r
+                         AcpiTableBufferSize,\r
+                         TableKey\r
+                         );\r
+}\r
+\r
+\r
+/**\r
+  Locate the first instance of a protocol.  If the protocol requested is an\r
+  FV protocol, then it will return the first FV that contains the ACPI table\r
+  storage file.\r
+\r
+  @param  Instance      Return pointer to the first instance of the protocol\r
+\r
+  @return EFI_SUCCESS           The function completed successfully.\r
+  @return EFI_NOT_FOUND         The protocol could not be located.\r
+  @return EFI_OUT_OF_RESOURCES  There are not enough resources to find the protocol.\r
+\r
+**/\r
+EFI_STATUS\r
+LocateFvInstanceWithTables (\r
+  OUT EFI_FIRMWARE_VOLUME2_PROTOCOL **Instance\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_HANDLE                    *HandleBuffer;\r
+  UINTN                         NumberOfHandles;\r
+  EFI_FV_FILETYPE               FileType;\r
+  UINT32                        FvStatus;\r
+  EFI_FV_FILE_ATTRIBUTES        Attributes;\r
+  UINTN                         Size;\r
+  UINTN                         Index;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;\r
+\r
+  FvStatus = 0;\r
+\r
+  //\r
+  // Locate protocol.\r
+  //\r
+  Status = gBS->LocateHandleBuffer (\r
+                   ByProtocol,\r
+                   &gEfiFirmwareVolume2ProtocolGuid,\r
+                   NULL,\r
+                   &NumberOfHandles,\r
+                   &HandleBuffer\r
+                   );\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // Defined errors at this time are not found and out of resources.\r
+    //\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Looking for FV with ACPI storage file\r
+  //\r
+  for (Index = 0; Index < NumberOfHandles; Index++) {\r
+    //\r
+    // Get the protocol on this handle\r
+    // This should not fail because of LocateHandleBuffer\r
+    //\r
+    Status = gBS->HandleProtocol (\r
+                     HandleBuffer[Index],\r
+                     &gEfiFirmwareVolume2ProtocolGuid,\r
+                     (VOID**) &FvInstance\r
+                     );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    //\r
+    // See if it has the ACPI storage file\r
+    //\r
+    Status = FvInstance->ReadFile (\r
+                           FvInstance,\r
+                           (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),\r
+                           NULL,\r
+                           &Size,\r
+                           &FileType,\r
+                           &Attributes,\r
+                           &FvStatus\r
+                           );\r
+\r
+    //\r
+    // If we found it, then we are done\r
+    //\r
+    if (Status == EFI_SUCCESS) {\r
+      *Instance = FvInstance;\r
+      break;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Our exit status is determined by the success of the previous operations\r
+  // If the protocol was found, Instance already points to it.\r
+  //\r
+\r
+  //\r
+  // Free any allocated buffers\r
+  //\r
+  gBS->FreePool (HandleBuffer);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Find ACPI tables in an FV and install them.\r
+\r
+  This is now a fall-back path. Normally, we will search for tables provided\r
+  by the VMM first.\r
+\r
+  If that fails, we use this function to load the ACPI tables from an FV. The\r
+  sources for the FV based tables is located under OvmfPkg/AcpiTables.\r
+\r
+  @param  AcpiTable     Protocol instance pointer\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InstallOvmfFvTables (\r
+  IN  EFI_ACPI_TABLE_PROTOCOL     *AcpiTable\r
+  )\r
+{\r
+  EFI_STATUS                           Status;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL        *FwVol;\r
+  INTN                                 Instance;\r
+  EFI_ACPI_COMMON_HEADER               *CurrentTable;\r
+  UINTN                                TableHandle;\r
+  UINT32                               FvStatus;\r
+  UINTN                                TableSize;\r
+  UINTN                                Size;\r
+  EFI_ACPI_TABLE_INSTALL_ACPI_TABLE    TableInstallFunction;\r
+\r
+  Instance     = 0;\r
+  CurrentTable = NULL;\r
+  TableHandle  = 0;\r
+\r
+  TableInstallFunction = BhyveInstallAcpiTable;\r
+\r
+  //\r
+  // set FwVol (and use an ASSERT() below) to suppress incorrect\r
+  // compiler/analyzer warnings\r
+  //\r
+  FwVol = NULL;\r
+  //\r
+  // Locate the firmware volume protocol\r
+  //\r
+  Status = LocateFvInstanceWithTables (&FwVol);\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_ABORTED;\r
+  }\r
+  ASSERT (FwVol != NULL);\r
+\r
+  //\r
+  // Read tables from the storage file.\r
+  //\r
+  while (Status == EFI_SUCCESS) {\r
+\r
+    Status = FwVol->ReadSection (\r
+                      FwVol,\r
+                      (EFI_GUID*)PcdGetPtr (PcdAcpiTableStorageFile),\r
+                      EFI_SECTION_RAW,\r
+                      Instance,\r
+                      (VOID**) &CurrentTable,\r
+                      &Size,\r
+                      &FvStatus\r
+                      );\r
+    if (!EFI_ERROR (Status)) {\r
+      //\r
+      // Add the table\r
+      //\r
+      TableHandle = 0;\r
+\r
+      TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length;\r
+      ASSERT (Size >= TableSize);\r
+\r
+      //\r
+      // Install ACPI table\r
+      //\r
+      Status = TableInstallFunction (\r
+                 AcpiTable,\r
+                 CurrentTable,\r
+                 TableSize,\r
+                 &TableHandle\r
+                 );\r
+\r
+      //\r
+      // Free memory allocated by ReadSection\r
+      //\r
+      gBS->FreePool (CurrentTable);\r
+\r
+      if (EFI_ERROR (Status)) {\r
+        return EFI_ABORTED;\r
+      }\r
+\r
+      //\r
+      // Increment the instance\r
+      //\r
+      Instance++;\r
+      CurrentTable = NULL;\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Effective entrypoint of Acpi Platform driver.\r
+\r
+  @param  ImageHandle\r
+  @param  SystemTable\r
+\r
+  @return EFI_SUCCESS\r
+  @return EFI_LOAD_ERROR\r
+  @return EFI_OUT_OF_RESOURCES\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InstallAcpiTables (\r
+  IN   EFI_ACPI_TABLE_PROTOCOL       *AcpiTable\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  Status = InstallOvmfFvTables (AcpiTable);\r
+\r
+  return Status;\r
+}\r
+\r
diff --git a/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.h b/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatform.h
new file mode 100644 (file)
index 0000000..d30cd11
--- /dev/null
@@ -0,0 +1,77 @@
+/** @file\r
+  Sample ACPI Platform Driver\r
+\r
+  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+  Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef _ACPI_PLATFORM_H_INCLUDED_\r
+#define _ACPI_PLATFORM_H_INCLUDED_\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Protocol/AcpiTable.h>\r
+#include <Protocol/FirmwareVolume2.h>\r
+#include <Protocol/PciIo.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/XenPlatformLib.h>\r
+\r
+#include <IndustryStandard/Acpi.h>\r
+\r
+typedef struct {\r
+  EFI_PCI_IO_PROTOCOL *PciIo;\r
+  UINT64              PciAttributes;\r
+} ORIGINAL_ATTRIBUTES;\r
+\r
+typedef struct S3_CONTEXT S3_CONTEXT;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+InstallAcpiTable (\r
+  IN   EFI_ACPI_TABLE_PROTOCOL       *AcpiProtocol,\r
+  IN   VOID                          *AcpiTableBuffer,\r
+  IN   UINTN                         AcpiTableBufferSize,\r
+  OUT  UINTN                         *TableKey\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+BhyveInstallAcpiTable(\r
+  IN   EFI_ACPI_TABLE_PROTOCOL       *AcpiProtocol,\r
+  IN   VOID                          *AcpiTableBuffer,\r
+  IN   UINTN                         AcpiTableBufferSize,\r
+  OUT  UINTN                         *TableKey\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+InstallXenTables (\r
+  IN   EFI_ACPI_TABLE_PROTOCOL       *AcpiProtocol\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+InstallAcpiTables (\r
+  IN   EFI_ACPI_TABLE_PROTOCOL       *AcpiTable\r
+  );\r
+\r
+VOID\r
+EnablePciDecoding (\r
+  OUT ORIGINAL_ATTRIBUTES **OriginalAttributes,\r
+  OUT UINTN               *Count\r
+  );\r
+\r
+VOID\r
+RestorePciDecoding (\r
+  IN ORIGINAL_ATTRIBUTES *OriginalAttributes,\r
+  IN UINTN               Count\r
+  );\r
+\r
+#endif\r
+\r
diff --git a/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatformDxe.inf b/OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatformDxe.inf
new file mode 100644 (file)
index 0000000..bf0f487
--- /dev/null
@@ -0,0 +1,65 @@
+## @file\r
+#  OVMF ACPI Platform Driver\r
+#\r
+#  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+#  Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = AcpiPlatform\r
+  FILE_GUID                      = D5F92408-BAB5-44CA-8A60-C212F01D7E9D\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = AcpiPlatformEntryPoint\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
+  AcpiPlatform.c\r
+  AcpiPlatform.h\r
+  EntryPoint.c\r
+  PciDecoding.c\r
+  Bhyve.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  OvmfPkg/Bhyve/BhyvePkg.dec\r
+  UefiCpuPkg/UefiCpuPkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiLib\r
+  PcdLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  UefiBootServicesTableLib\r
+  UefiDriverEntryPoint\r
+  BhyveFwCtlLib\r
+  MemoryAllocationLib\r
+  BaseLib\r
+  DxeServicesTableLib\r
+  OrderedCollectionLib\r
+\r
+[Protocols]\r
+  gEfiAcpiTableProtocolGuid                     # PROTOCOL ALWAYS_CONSUMED\r
+  gEfiFirmwareVolume2ProtocolGuid               # PROTOCOL SOMETIMES_CONSUMED\r
+  gEfiPciIoProtocolGuid                         # PROTOCOL SOMETIMES_CONSUMED\r
+\r
+[Guids]\r
+  gRootBridgesConnectedEventGroupGuid\r
+\r
+[Pcd]\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiTableStorageFile\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration\r
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress\r
+\r
+[Depex]\r
+  gEfiAcpiTableProtocolGuid\r
diff --git a/OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c b/OvmfPkg/Bhyve/AcpiPlatformDxe/Bhyve.c
new file mode 100644 (file)
index 0000000..6d42264
--- /dev/null
@@ -0,0 +1,132 @@
+/*\r
+ * Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+ * Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
+ * Copyright (C) 2012, Red Hat, Inc.\r
+ * Copyright (c) 2014, Pluribus Networks, Inc.\r
+ *\r
+ * SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ */\r
+#include "AcpiPlatform.h"\r
+\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/BhyveFwCtlLib.h>\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+BhyveInstallAcpiMadtTable (\r
+  IN   EFI_ACPI_TABLE_PROTOCOL       *AcpiProtocol,\r
+  IN   VOID                          *AcpiTableBuffer,\r
+  IN   UINTN                         AcpiTableBufferSize,\r
+  OUT  UINTN                         *TableKey\r
+  )\r
+{\r
+  UINT32                                              CpuCount;\r
+  UINTN                                               cSize;\r
+  UINTN                                               NewBufferSize;\r
+  EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *Madt;\r
+  EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC_STRUCTURE         *LocalApic;\r
+  EFI_ACPI_1_0_IO_APIC_STRUCTURE                      *IoApic;\r
+  EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE    *Iso;\r
+  VOID                                                *Ptr;\r
+  UINTN                                               Loop;\r
+  EFI_STATUS                                          Status;\r
+\r
+  ASSERT (AcpiTableBufferSize >= sizeof (EFI_ACPI_DESCRIPTION_HEADER));\r
+\r
+  // Query the host for the number of vCPUs\r
+  CpuCount = 0;\r
+  cSize = sizeof(CpuCount);\r
+  if (BhyveFwCtlGet ("hw.ncpu", &CpuCount, &cSize) == RETURN_SUCCESS) {\r
+    DEBUG ((DEBUG_INFO, "Retrieved CpuCount %d\n", CpuCount));\r
+    ASSERT (CpuCount >= 1);\r
+  } else {\r
+    DEBUG ((DEBUG_INFO, "CpuCount retrieval error\n"));\r
+    CpuCount = 1;\r
+  }\r
+\r
+  NewBufferSize = 1                     * sizeof (*Madt) +\r
+                  CpuCount              * sizeof (*LocalApic) +\r
+                  1                     * sizeof (*IoApic) +\r
+                  1                     * sizeof (*Iso);\r
+\r
+  Madt = AllocatePool (NewBufferSize);\r
+  if (Madt == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  CopyMem (&(Madt->Header), AcpiTableBuffer, sizeof (EFI_ACPI_DESCRIPTION_HEADER));\r
+  Madt->Header.Length    = (UINT32) NewBufferSize;\r
+  Madt->LocalApicAddress = 0xFEE00000;\r
+  Madt->Flags            = EFI_ACPI_1_0_PCAT_COMPAT;\r
+  Ptr = Madt + 1;\r
+\r
+  LocalApic = Ptr;\r
+  for (Loop = 0; Loop < CpuCount; ++Loop) {\r
+    LocalApic->Type            = EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC;\r
+    LocalApic->Length          = sizeof (*LocalApic);\r
+    LocalApic->AcpiProcessorId = (UINT8) Loop;\r
+    LocalApic->ApicId          = (UINT8) Loop;\r
+    LocalApic->Flags           = 1; // enabled\r
+    ++LocalApic;\r
+  }\r
+  Ptr = LocalApic;\r
+\r
+  IoApic = Ptr;\r
+  IoApic->Type             = EFI_ACPI_1_0_IO_APIC;\r
+  IoApic->Length           = sizeof (*IoApic);\r
+  IoApic->IoApicId         = (UINT8) CpuCount;\r
+  IoApic->Reserved         = EFI_ACPI_RESERVED_BYTE;\r
+  IoApic->IoApicAddress    = 0xFEC00000;\r
+  IoApic->SystemVectorBase = 0x00000000;\r
+  Ptr = IoApic + 1;\r
+\r
+  //\r
+  // IRQ0 (8254 Timer) => IRQ2 (PIC) Interrupt Source Override Structure\r
+  //\r
+  Iso = Ptr;\r
+  Iso->Type                        = EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE;\r
+  Iso->Length                      = sizeof (*Iso);\r
+  Iso->Bus                         = 0x00; // ISA\r
+  Iso->Source                      = 0x00; // IRQ0\r
+  Iso->GlobalSystemInterruptVector = 0x00000002;\r
+  Iso->Flags                       = 0x0000; // Conforms to specs of the bus\r
+  Ptr = Iso + 1;\r
+\r
+  ASSERT ((UINTN) ((UINT8 *)Ptr - (UINT8 *)Madt) == NewBufferSize);\r
+  Status = InstallAcpiTable (AcpiProtocol, Madt, NewBufferSize, TableKey);\r
+\r
+  FreePool (Madt);\r
+\r
+  return Status;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+BhyveInstallAcpiTable (\r
+  IN   EFI_ACPI_TABLE_PROTOCOL       *AcpiProtocol,\r
+  IN   VOID                          *AcpiTableBuffer,\r
+  IN   UINTN                         AcpiTableBufferSize,\r
+  OUT  UINTN                         *TableKey\r
+  )\r
+{\r
+  EFI_ACPI_DESCRIPTION_HEADER        *Hdr;\r
+  EFI_ACPI_TABLE_INSTALL_ACPI_TABLE  TableInstallFunction;\r
+\r
+  Hdr = (EFI_ACPI_DESCRIPTION_HEADER*) AcpiTableBuffer;\r
+  switch (Hdr->Signature) {\r
+  case EFI_ACPI_1_0_APIC_SIGNATURE:\r
+    TableInstallFunction = BhyveInstallAcpiMadtTable;\r
+    break;\r
+  default:\r
+    TableInstallFunction = InstallAcpiTable;\r
+  }\r
+\r
+  return TableInstallFunction (\r
+           AcpiProtocol,\r
+           AcpiTableBuffer,\r
+           AcpiTableBufferSize,\r
+           TableKey\r
+           );\r
+}\r
diff --git a/OvmfPkg/Bhyve/AcpiPlatformDxe/EntryPoint.c b/OvmfPkg/Bhyve/AcpiPlatformDxe/EntryPoint.c
new file mode 100644 (file)
index 0000000..f66f892
--- /dev/null
@@ -0,0 +1,90 @@
+/** @file\r
+  Entry point of OVMF ACPI Platform Driver\r
+\r
+  Copyright (C) 2015, Red Hat, Inc.\r
+  Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+**/\r
+\r
+#include <Guid/RootBridgesConnectedEventGroup.h>\r
+#include "AcpiPlatform.h"\r
+\r
+STATIC\r
+EFI_ACPI_TABLE_PROTOCOL *\r
+FindAcpiTableProtocol (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+  EFI_ACPI_TABLE_PROTOCOL *AcpiTable;\r
+\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiAcpiTableProtocolGuid,\r
+                  NULL,\r
+                  (VOID**)&AcpiTable\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+  return AcpiTable;\r
+}\r
+\r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+OnRootBridgesConnected (\r
+  IN EFI_EVENT Event,\r
+  IN VOID      *Context\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  DEBUG ((DEBUG_INFO,\r
+    "%a: root bridges have been connected, installing ACPI tables\n",\r
+    __FUNCTION__));\r
+  Status = InstallAcpiTables (FindAcpiTableProtocol ());\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "%a: InstallAcpiTables: %r\n", __FUNCTION__, Status));\r
+  }\r
+  gBS->CloseEvent (Event);\r
+}\r
+\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+AcpiPlatformEntryPoint (\r
+  IN EFI_HANDLE         ImageHandle,\r
+  IN EFI_SYSTEM_TABLE   *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+  EFI_EVENT  RootBridgesConnected;\r
+\r
+  //\r
+  // If the platform doesn't support PCI, or PCI enumeration has been disabled,\r
+  // install the tables at once, and let the entry point's return code reflect\r
+  // the full functionality.\r
+  //\r
+  if (PcdGetBool (PcdPciDisableBusEnumeration)) {\r
+    DEBUG ((DEBUG_INFO, "%a: PCI or its enumeration disabled, installing "\r
+      "ACPI tables\n", __FUNCTION__));\r
+    return InstallAcpiTables (FindAcpiTableProtocol ());\r
+  }\r
+\r
+  //\r
+  // Otherwise, delay installing the ACPI tables until root bridges are\r
+  // connected. The entry point's return status will only reflect the callback\r
+  // setup. (Note that we're a DXE_DRIVER; our entry point function is invoked\r
+  // strictly before BDS is entered and can connect the root bridges.)\r
+  //\r
+  Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_CALLBACK,\r
+                  OnRootBridgesConnected, NULL /* Context */,\r
+                  &gRootBridgesConnectedEventGroupGuid, &RootBridgesConnected);\r
+  if (!EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_INFO,\r
+      "%a: waiting for root bridges to be connected, registered callback\n",\r
+      __FUNCTION__));\r
+  }\r
+\r
+  return Status;\r
+}\r
diff --git a/OvmfPkg/Bhyve/AcpiPlatformDxe/PciDecoding.c b/OvmfPkg/Bhyve/AcpiPlatformDxe/PciDecoding.c
new file mode 100644 (file)
index 0000000..7389410
--- /dev/null
@@ -0,0 +1,192 @@
+/** @file\r
+  Temporarily enable IO and MMIO decoding for all PCI devices while QEMU\r
+  regenerates the ACPI tables.\r
+\r
+  Copyright (C) 2016, Red Hat, Inc.\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+**/\r
+\r
+#include <Library/MemoryAllocationLib.h>\r
+\r
+#include "AcpiPlatform.h"\r
+\r
+\r
+/**\r
+  Collect all PciIo protocol instances in the system. Save their original\r
+  attributes, and enable IO and MMIO decoding for each.\r
+\r
+  This is a best effort function; it doesn't return status codes. Its\r
+  caller is supposed to proceed even if this function fails.\r
+\r
+  @param[out] OriginalAttributes  On output, a dynamically allocated array of\r
+                                  ORIGINAL_ATTRIBUTES elements. The array lists\r
+                                  the PciIo protocol instances found in the\r
+                                  system at the time of the call, plus the\r
+                                  original PCI attributes for each.\r
+\r
+                                  Before returning, the function enables IO and\r
+                                  MMIO decoding for each PciIo instance it\r
+                                  finds.\r
+\r
+                                  On error, or when no such instances are\r
+                                  found, OriginalAttributes is set to NULL.\r
+\r
+  @param[out] Count               On output, the number of elements in\r
+                                  OriginalAttributes. On error it is set to\r
+                                  zero.\r
+**/\r
+VOID\r
+EnablePciDecoding (\r
+  OUT ORIGINAL_ATTRIBUTES **OriginalAttributes,\r
+  OUT UINTN               *Count\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  UINTN               NoHandles;\r
+  EFI_HANDLE          *Handles;\r
+  ORIGINAL_ATTRIBUTES *OrigAttrs;\r
+  UINTN               Idx;\r
+\r
+  *OriginalAttributes = NULL;\r
+  *Count              = 0;\r
+\r
+  if (PcdGetBool (PcdPciDisableBusEnumeration)) {\r
+    //\r
+    // The platform downloads ACPI tables from QEMU in general, but there are\r
+    // no root bridges in this execution. We're done.\r
+    //\r
+    return;\r
+  }\r
+\r
+  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiPciIoProtocolGuid,\r
+                  NULL /* SearchKey */, &NoHandles, &Handles);\r
+  if (Status == EFI_NOT_FOUND) {\r
+    //\r
+    // No PCI devices were found on either of the root bridges. We're done.\r
+    //\r
+    return;\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_WARN, "%a: LocateHandleBuffer(): %r\n", __FUNCTION__,\r
+      Status));\r
+    return;\r
+  }\r
+\r
+  OrigAttrs = AllocatePool (NoHandles * sizeof *OrigAttrs);\r
+  if (OrigAttrs == NULL) {\r
+    DEBUG ((DEBUG_WARN, "%a: AllocatePool(): out of resources\n",\r
+      __FUNCTION__));\r
+    goto FreeHandles;\r
+  }\r
+\r
+  for (Idx = 0; Idx < NoHandles; ++Idx) {\r
+    EFI_PCI_IO_PROTOCOL *PciIo;\r
+    UINT64              Attributes;\r
+\r
+    //\r
+    // Look up PciIo on the handle and stash it\r
+    //\r
+    Status = gBS->HandleProtocol (Handles[Idx], &gEfiPciIoProtocolGuid,\r
+                    (VOID**)&PciIo);\r
+    ASSERT_EFI_ERROR (Status);\r
+    OrigAttrs[Idx].PciIo = PciIo;\r
+\r
+    //\r
+    // Stash the current attributes\r
+    //\r
+    Status = PciIo->Attributes (PciIo, EfiPciIoAttributeOperationGet, 0,\r
+                      &OrigAttrs[Idx].PciAttributes);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((DEBUG_WARN, "%a: EfiPciIoAttributeOperationGet: %r\n",\r
+        __FUNCTION__, Status));\r
+      goto RestoreAttributes;\r
+    }\r
+\r
+    //\r
+    // Retrieve supported attributes\r
+    //\r
+    Status = PciIo->Attributes (PciIo, EfiPciIoAttributeOperationSupported, 0,\r
+                      &Attributes);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((DEBUG_WARN, "%a: EfiPciIoAttributeOperationSupported: %r\n",\r
+        __FUNCTION__, Status));\r
+      goto RestoreAttributes;\r
+    }\r
+\r
+    //\r
+    // Enable IO and MMIO decoding\r
+    //\r
+    Attributes &= EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY;\r
+    Status = PciIo->Attributes (PciIo, EfiPciIoAttributeOperationEnable,\r
+                      Attributes, NULL);\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((DEBUG_WARN, "%a: EfiPciIoAttributeOperationEnable: %r\n",\r
+        __FUNCTION__, Status));\r
+      goto RestoreAttributes;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Success\r
+  //\r
+  FreePool (Handles);\r
+  *OriginalAttributes = OrigAttrs;\r
+  *Count              = NoHandles;\r
+  return;\r
+\r
+RestoreAttributes:\r
+  while (Idx > 0) {\r
+    --Idx;\r
+    OrigAttrs[Idx].PciIo->Attributes (OrigAttrs[Idx].PciIo,\r
+                            EfiPciIoAttributeOperationSet,\r
+                            OrigAttrs[Idx].PciAttributes,\r
+                            NULL\r
+                            );\r
+  }\r
+  FreePool (OrigAttrs);\r
+\r
+FreeHandles:\r
+  FreePool (Handles);\r
+}\r
+\r
+\r
+/**\r
+  Restore the original PCI attributes saved with EnablePciDecoding().\r
+\r
+  @param[in] OriginalAttributes  The array allocated and populated by\r
+                                 EnablePciDecoding(). This parameter may be\r
+                                 NULL. If OriginalAttributes is NULL, then the\r
+                                 function is a no-op; otherwise the PciIo\r
+                                 attributes will be restored, and the\r
+                                 OriginalAttributes array will be freed.\r
+\r
+  @param[in] Count               The Count value stored by EnablePciDecoding(),\r
+                                 the number of elements in OriginalAttributes.\r
+                                 Count may be zero if and only if\r
+                                 OriginalAttributes is NULL.\r
+**/\r
+VOID\r
+RestorePciDecoding (\r
+  IN ORIGINAL_ATTRIBUTES *OriginalAttributes,\r
+  IN UINTN               Count\r
+  )\r
+{\r
+  UINTN Idx;\r
+\r
+  ASSERT ((OriginalAttributes == NULL) == (Count == 0));\r
+  if (OriginalAttributes == NULL) {\r
+    return;\r
+  }\r
+\r
+  for (Idx = 0; Idx < Count; ++Idx) {\r
+    OriginalAttributes[Idx].PciIo->Attributes (\r
+                                     OriginalAttributes[Idx].PciIo,\r
+                                     EfiPciIoAttributeOperationSet,\r
+                                     OriginalAttributes[Idx].PciAttributes,\r
+                                     NULL\r
+                                     );\r
+  }\r
+  FreePool (OriginalAttributes);\r
+}\r
diff --git a/OvmfPkg/Bhyve/AcpiTables/AcpiTables.inf b/OvmfPkg/Bhyve/AcpiTables/AcpiTables.inf
new file mode 100644 (file)
index 0000000..18a9e2a
--- /dev/null
@@ -0,0 +1,39 @@
+## @file\r
+#  Component description file for PlatformAcpiTables module.\r
+#\r
+#  ACPI table data and ASL sources required to boot the platform.\r
+#\r
+#  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+#  Copyright (c) 2008 - 2018, 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
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = PlatformAcpiTables\r
+  FILE_GUID                      = 7E374E25-8E01-4FEE-87F2-390C23C606CD\r
+  MODULE_TYPE                    = USER_DEFINED\r
+  VERSION_STRING                 = 1.0\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
+  Platform.h\r
+  Madt.aslc\r
+  Facp.aslc\r
+  Facs.aslc\r
+  Dsdt.asl\r
+  Hpet.aslc\r
+  Spcr.aslc\r
+  Mcfg.aslc\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+\r
diff --git a/OvmfPkg/Bhyve/AcpiTables/Dsdt.asl b/OvmfPkg/Bhyve/AcpiTables/Dsdt.asl
new file mode 100644 (file)
index 0000000..17e2cf6
--- /dev/null
@@ -0,0 +1,1140 @@
+/*\r
+ * Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+ *\r
+ * SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ */\r
+\r
+/*\r
+ * Intel ACPI Component Architecture\r
+ * AML Disassembler version 20100528\r
+ *\r
+ * Disassembly of DSDT.dat, Sat Apr 18 15:41:05 2015\r
+ *\r
+ *\r
+ * Original Table Header:\r
+ *     Signature        "DSDT"\r
+ *     Length           0x000008FA (2298)\r
+ *     Revision         0x02\r
+ *     Checksum         0xC4\r
+ *     OEM ID           "BHYVE "\r
+ *     OEM Table ID     "BVDSDT  "\r
+ *     OEM Revision     0x00000001 (1)\r
+ *     Compiler ID      "INTL"\r
+ *     Compiler Version 0x20150204 (538247684)\r
+ */\r
+DefinitionBlock ("DSDT.aml", "DSDT", 2, "BHYVE", "BVDSDT", 0x00000001)\r
+{\r
+    Name (_S5, Package (0x02)\r
+    {\r
+        0x05,\r
+        Zero\r
+    })\r
+    Name (PICM, Zero)\r
+    Method (_PIC, 1, NotSerialized)\r
+    {\r
+        Store (Arg0, PICM)\r
+    }\r
+\r
+    Scope (_SB)\r
+    {\r
+        Device (PC00)\r
+        {\r
+            Name (_HID, EisaId ("PNP0A03"))\r
+            Name (_ADR, Zero)\r
+            Method (_BBN, 0, NotSerialized)\r
+            {\r
+                Return (Zero)\r
+            }\r
+\r
+            Name (_CRS, ResourceTemplate ()\r
+            {\r
+                WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,\r
+                    0x0000,             // Granularity\r
+                    0x0000,             // Range Minimum\r
+                    0x00FF,             // Range Maximum\r
+                    0x0000,             // Translation Offset\r
+                    0x0100,             // Length\r
+                    ,, )\r
+                IO (Decode16,\r
+                    0x03C0,             // Range Minimum\r
+                    0x03C0,             // Range Maximum\r
+                    0x00,               // Alignment\r
+                    0x20,               // Length\r
+                    )\r
+                IO (Decode16,\r
+                    0x0CF8,             // Range Minimum\r
+                    0x0CF8,             // Range Maximum\r
+                    0x01,               // Alignment\r
+                    0x08,               // Length\r
+                    )\r
+                WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,\r
+                    0x0000,             // Granularity\r
+                    0x0000,             // Range Minimum\r
+                    0x0CF7,             // Range Maximum\r
+                    0x0000,             // Translation Offset\r
+                    0x0CF8,             // Length\r
+                    ,, , TypeStatic)\r
+                WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,\r
+                    0x0000,             // Granularity\r
+                    0x0D00,             // Range Minimum\r
+                    0xFFFF,             // Range Maximum\r
+                    0x0000,             // Translation Offset\r
+                    0xF300,             // Length\r
+                    ,, , TypeStatic)\r
+                DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,\r
+                    0x00000000,         // Granularity\r
+                    0x000A0000,         // Range Minimum\r
+                    0x000BFFFF,         // Range Maximum\r
+                    0x00000000,         // Translation Offset\r
+                    0x00020000,         // Length\r
+                    ,, , AddressRangeMemory, TypeStatic)\r
+                DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,\r
+                    0x00000000,         // Granularity\r
+                    0xC0000000,         // Range Minimum\r
+                    0xDFFFFFFF,         // Range Maximum\r
+                    0x00000000,         // Translation Offset\r
+                    0x20000000,         // Range Length\r
+                    ,, PW32)\r
+                DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,\r
+                    0x00000000,         // Granularity\r
+                    0xF0000000,         // Range Minimum\r
+                    0xF07FFFFF,         // Range Maximum\r
+                    0x00000000,         // Translation Offset\r
+                    0x00800000,         // Range Length\r
+                    ,, FB32)\r
+                QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite,\r
+                    0x0000000000000000, // Granularity\r
+                    0x000000D000000000, // Range Minimum\r
+                    0x000000D0000FFFFF, // Range Maximum\r
+                    0x0000000000000000, // Translation Offset\r
+                    0x0000000000100000, // Length\r
+                    ,, , AddressRangeMemory, TypeStatic)\r
+            })\r
+            Name (PPRT, Package ()\r
+            {\r
+                Package () { 0x0000FFFF, 0, LPC.LNKF, Zero },\r
+                Package () { 0x0000FFFF, 1, LPC.LNKG, Zero },\r
+                Package () { 0x0000FFFF, 2, LPC.LNKH, Zero },\r
+                Package () { 0x0000FFFF, 3, LPC.LNKA, Zero },\r
+\r
+                Package () { 0x0001FFFF, 0, LPC.LNKG, Zero },\r
+                Package () { 0x0001FFFF, 1, LPC.LNKH, Zero },\r
+                Package () { 0x0001FFFF, 2, LPC.LNKA, Zero },\r
+                Package () { 0x0001FFFF, 3, LPC.LNKB, Zero },\r
+\r
+                Package () { 0x0002FFFF, 0, LPC.LNKH, Zero },\r
+                Package () { 0x0002FFFF, 1, LPC.LNKA, Zero },\r
+                Package () { 0x0002FFFF, 2, LPC.LNKB, Zero },\r
+                Package () { 0x0002FFFF, 3, LPC.LNKC, Zero },\r
+\r
+                Package () { 0x0003FFFF, 0, LPC.LNKA, Zero },\r
+                Package () { 0x0003FFFF, 1, LPC.LNKB, Zero },\r
+                Package () { 0x0003FFFF, 2, LPC.LNKC, Zero },\r
+                Package () { 0x0003FFFF, 3, LPC.LNKD, Zero },\r
+\r
+                Package () { 0x0004FFFF, 0, LPC.LNKB, Zero },\r
+                Package () { 0x0004FFFF, 1, LPC.LNKC, Zero },\r
+                Package () { 0x0004FFFF, 2, LPC.LNKD, Zero },\r
+                Package () { 0x0004FFFF, 3, LPC.LNKE, Zero },\r
+\r
+                Package () { 0x0005FFFF, 0, LPC.LNKC, Zero },\r
+                Package () { 0x0005FFFF, 1, LPC.LNKD, Zero },\r
+                Package () { 0x0005FFFF, 2, LPC.LNKE, Zero },\r
+                Package () { 0x0005FFFF, 3, LPC.LNKF, Zero },\r
+\r
+                Package () { 0x0006FFFF, 0, LPC.LNKD, Zero },\r
+                Package () { 0x0006FFFF, 1, LPC.LNKE, Zero },\r
+                Package () { 0x0006FFFF, 2, LPC.LNKF, Zero },\r
+                Package () { 0x0006FFFF, 3, LPC.LNKG, Zero },\r
+\r
+                Package () { 0x0007FFFF, 0, LPC.LNKE, Zero },\r
+                Package () { 0x0007FFFF, 1, LPC.LNKF, Zero },\r
+                Package () { 0x0007FFFF, 2, LPC.LNKG, Zero },\r
+                Package () { 0x0007FFFF, 3, LPC.LNKH, Zero },\r
+\r
+                Package () { 0x0008FFFF, 0, LPC.LNKF, Zero },\r
+                Package () { 0x0008FFFF, 1, LPC.LNKG, Zero },\r
+                Package () { 0x0008FFFF, 2, LPC.LNKH, Zero },\r
+                Package () { 0x0008FFFF, 3, LPC.LNKA, Zero },\r
+\r
+                Package () { 0x0009FFFF, 0, LPC.LNKG, Zero },\r
+                Package () { 0x0009FFFF, 1, LPC.LNKH, Zero },\r
+                Package () { 0x0009FFFF, 2, LPC.LNKA, Zero },\r
+                Package () { 0x0009FFFF, 3, LPC.LNKB, Zero },\r
+\r
+                Package () { 0x000AFFFF, 0, LPC.LNKH, Zero },\r
+                Package () { 0x000AFFFF, 1, LPC.LNKA, Zero },\r
+                Package () { 0x000AFFFF, 2, LPC.LNKB, Zero },\r
+                Package () { 0x000AFFFF, 3, LPC.LNKC, Zero },\r
+\r
+                Package () { 0x000BFFFF, 0, LPC.LNKA, Zero },\r
+                Package () { 0x000BFFFF, 1, LPC.LNKB, Zero },\r
+                Package () { 0x000BFFFF, 2, LPC.LNKC, Zero },\r
+                Package () { 0x000BFFFF, 3, LPC.LNKD, Zero },\r
+\r
+                Package () { 0x000CFFFF, 0, LPC.LNKB, Zero },\r
+                Package () { 0x000CFFFF, 1, LPC.LNKC, Zero },\r
+                Package () { 0x000CFFFF, 2, LPC.LNKD, Zero },\r
+                Package () { 0x000CFFFF, 3, LPC.LNKE, Zero },\r
+\r
+                Package () { 0x000DFFFF, 0, LPC.LNKC, Zero },\r
+                Package () { 0x000DFFFF, 1, LPC.LNKD, Zero },\r
+                Package () { 0x000DFFFF, 2, LPC.LNKE, Zero },\r
+                Package () { 0x000DFFFF, 3, LPC.LNKF, Zero },\r
+\r
+                Package () { 0x000EFFFF, 0, LPC.LNKD, Zero },\r
+                Package () { 0x000EFFFF, 1, LPC.LNKE, Zero },\r
+                Package () { 0x000EFFFF, 2, LPC.LNKF, Zero },\r
+                Package () { 0x000EFFFF, 3, LPC.LNKG, Zero },\r
+\r
+                Package () { 0x000FFFFF, 0, LPC.LNKE, Zero },\r
+                Package () { 0x000FFFFF, 1, LPC.LNKF, Zero },\r
+                Package () { 0x000FFFFF, 2, LPC.LNKG, Zero },\r
+                Package () { 0x000FFFFF, 3, LPC.LNKH, Zero },\r
+\r
+                Package () { 0x0010FFFF, 0, LPC.LNKF, Zero },\r
+                Package () { 0x0010FFFF, 1, LPC.LNKG, Zero },\r
+                Package () { 0x0010FFFF, 2, LPC.LNKH, Zero },\r
+                Package () { 0x0010FFFF, 3, LPC.LNKA, Zero },\r
+\r
+                Package () { 0x0011FFFF, 0, LPC.LNKG, Zero },\r
+                Package () { 0x0011FFFF, 1, LPC.LNKH, Zero },\r
+                Package () { 0x0011FFFF, 2, LPC.LNKA, Zero },\r
+                Package () { 0x0011FFFF, 3, LPC.LNKB, Zero },\r
+\r
+                Package () { 0x0012FFFF, 0, LPC.LNKH, Zero },\r
+                Package () { 0x0012FFFF, 1, LPC.LNKA, Zero },\r
+                Package () { 0x0012FFFF, 2, LPC.LNKB, Zero },\r
+                Package () { 0x0012FFFF, 3, LPC.LNKC, Zero },\r
+\r
+                Package () { 0x0013FFFF, 0, LPC.LNKA, Zero },\r
+                Package () { 0x0013FFFF, 1, LPC.LNKB, Zero },\r
+                Package () { 0x0013FFFF, 2, LPC.LNKC, Zero },\r
+                Package () { 0x0013FFFF, 3, LPC.LNKD, Zero },\r
+\r
+                Package () { 0x0014FFFF, 0, LPC.LNKB, Zero },\r
+                Package () { 0x0014FFFF, 1, LPC.LNKC, Zero },\r
+                Package () { 0x0014FFFF, 2, LPC.LNKD, Zero },\r
+                Package () { 0x0014FFFF, 3, LPC.LNKE, Zero },\r
+\r
+                Package () { 0x0015FFFF, 0, LPC.LNKC, Zero },\r
+                Package () { 0x0015FFFF, 1, LPC.LNKD, Zero },\r
+                Package () { 0x0015FFFF, 2, LPC.LNKE, Zero },\r
+                Package () { 0x0015FFFF, 3, LPC.LNKF, Zero },\r
+\r
+                Package () { 0x0016FFFF, 0, LPC.LNKD, Zero },\r
+                Package () { 0x0016FFFF, 1, LPC.LNKE, Zero },\r
+                Package () { 0x0016FFFF, 2, LPC.LNKF, Zero },\r
+                Package () { 0x0016FFFF, 3, LPC.LNKG, Zero },\r
+\r
+                Package () { 0x0017FFFF, 0, LPC.LNKE, Zero },\r
+                Package () { 0x0017FFFF, 1, LPC.LNKF, Zero },\r
+                Package () { 0x0017FFFF, 2, LPC.LNKG, Zero },\r
+                Package () { 0x0017FFFF, 3, LPC.LNKH, Zero },\r
+\r
+                Package () { 0x0018FFFF, 0, LPC.LNKF, Zero },\r
+                Package () { 0x0018FFFF, 1, LPC.LNKG, Zero },\r
+                Package () { 0x0018FFFF, 2, LPC.LNKH, Zero },\r
+                Package () { 0x0018FFFF, 3, LPC.LNKA, Zero },\r
+\r
+                Package () { 0x0019FFFF, 0, LPC.LNKG, Zero },\r
+                Package () { 0x0019FFFF, 1, LPC.LNKH, Zero },\r
+                Package () { 0x0019FFFF, 2, LPC.LNKA, Zero },\r
+                Package () { 0x0019FFFF, 3, LPC.LNKB, Zero },\r
+\r
+                Package () { 0x001AFFFF, 0, LPC.LNKH, Zero },\r
+                Package () { 0x001AFFFF, 1, LPC.LNKA, Zero },\r
+                Package () { 0x001AFFFF, 2, LPC.LNKB, Zero },\r
+                Package () { 0x001AFFFF, 3, LPC.LNKC, Zero },\r
+\r
+                Package () { 0x001BFFFF, 0, LPC.LNKA, Zero },\r
+                Package () { 0x001BFFFF, 1, LPC.LNKB, Zero },\r
+                Package () { 0x001BFFFF, 2, LPC.LNKC, Zero },\r
+                Package () { 0x001BFFFF, 3, LPC.LNKD, Zero },\r
+\r
+                Package () { 0x001CFFFF, 0, LPC.LNKB, Zero },\r
+                Package () { 0x001CFFFF, 1, LPC.LNKC, Zero },\r
+                Package () { 0x001CFFFF, 2, LPC.LNKD, Zero },\r
+                Package () { 0x001CFFFF, 3, LPC.LNKE, Zero },\r
+\r
+                Package () { 0x001DFFFF, 0, LPC.LNKC, Zero },\r
+                Package () { 0x001DFFFF, 1, LPC.LNKD, Zero },\r
+                Package () { 0x001DFFFF, 2, LPC.LNKE, Zero },\r
+                Package () { 0x001DFFFF, 3, LPC.LNKF, Zero },\r
+\r
+                Package () { 0x001EFFFF, 0, LPC.LNKD, Zero },\r
+                Package () { 0x001EFFFF, 1, LPC.LNKE, Zero },\r
+                Package () { 0x001EFFFF, 2, LPC.LNKF, Zero },\r
+                Package () { 0x001EFFFF, 3, LPC.LNKG, Zero },\r
+\r
+                Package () { 0x001FFFFF, 0, LPC.LNKE, Zero },\r
+                Package () { 0x001FFFFF, 1, LPC.LNKF, Zero },\r
+                Package () { 0x001FFFFF, 2, LPC.LNKG, Zero },\r
+                Package () { 0x001FFFFF, 3, LPC.LNKH, Zero }\r
+            })\r
+            Name (APRT, Package ()\r
+            {\r
+                Package () { 0x0000FFFF, 0, Zero, 0x15 },\r
+                Package () { 0x0000FFFF, 1, Zero, 0x16 },\r
+                Package () { 0x0000FFFF, 2, Zero, 0x17 },\r
+                Package () { 0x0000FFFF, 3, Zero, 0x10 },\r
+\r
+                Package () { 0x0001FFFF, 0, Zero, 0x16 },\r
+                Package () { 0x0001FFFF, 1, Zero, 0x17 },\r
+                Package () { 0x0001FFFF, 2, Zero, 0x10 },\r
+                Package () { 0x0001FFFF, 3, Zero, 0x11 },\r
+\r
+                Package () { 0x0002FFFF, 0, Zero, 0x17 },\r
+                Package () { 0x0002FFFF, 1, Zero, 0x10 },\r
+                Package () { 0x0002FFFF, 2, Zero, 0x11 },\r
+                Package () { 0x0002FFFF, 3, Zero, 0x12 },\r
+\r
+                Package () { 0x0003FFFF, 0, Zero, 0x10 },\r
+                Package () { 0x0003FFFF, 1, Zero, 0x11 },\r
+                Package () { 0x0003FFFF, 2, Zero, 0x12 },\r
+                Package () { 0x0003FFFF, 3, Zero, 0x13 },\r
+\r
+                Package () { 0x0004FFFF, 0, Zero, 0x11 },\r
+                Package () { 0x0004FFFF, 1, Zero, 0x12 },\r
+                Package () { 0x0004FFFF, 2, Zero, 0x13 },\r
+                Package () { 0x0004FFFF, 3, Zero, 0x14 },\r
+\r
+                Package () { 0x0005FFFF, 0, Zero, 0x12 },\r
+                Package () { 0x0005FFFF, 1, Zero, 0x13 },\r
+                Package () { 0x0005FFFF, 2, Zero, 0x14 },\r
+                Package () { 0x0005FFFF, 3, Zero, 0x15 },\r
+\r
+                Package () { 0x0006FFFF, 0, Zero, 0x13 },\r
+                Package () { 0x0006FFFF, 1, Zero, 0x14 },\r
+                Package () { 0x0006FFFF, 2, Zero, 0x15 },\r
+                Package () { 0x0006FFFF, 3, Zero, 0x16 },\r
+\r
+                Package () { 0x0007FFFF, 0, Zero, 0x14 },\r
+                Package () { 0x0007FFFF, 1, Zero, 0x15 },\r
+                Package () { 0x0007FFFF, 2, Zero, 0x16 },\r
+                Package () { 0x0007FFFF, 3, Zero, 0x17 },\r
+\r
+                Package () { 0x0008FFFF, 0, Zero, 0x15 },\r
+                Package () { 0x0008FFFF, 1, Zero, 0x16 },\r
+                Package () { 0x0008FFFF, 2, Zero, 0x17 },\r
+                Package () { 0x0008FFFF, 3, Zero, 0x10 },\r
+\r
+                Package () { 0x0009FFFF, 0, Zero, 0x16 },\r
+                Package () { 0x0009FFFF, 1, Zero, 0x17 },\r
+                Package () { 0x0009FFFF, 2, Zero, 0x10 },\r
+                Package () { 0x0009FFFF, 3, Zero, 0x11 },\r
+\r
+                Package () { 0x000AFFFF, 0, Zero, 0x17 },\r
+                Package () { 0x000AFFFF, 1, Zero, 0x10 },\r
+                Package () { 0x000AFFFF, 2, Zero, 0x11 },\r
+                Package () { 0x000AFFFF, 3, Zero, 0x12 },\r
+\r
+                Package () { 0x000BFFFF, 0, Zero, 0x10 },\r
+                Package () { 0x000BFFFF, 1, Zero, 0x11 },\r
+                Package () { 0x000BFFFF, 2, Zero, 0x12 },\r
+                Package () { 0x000BFFFF, 3, Zero, 0x13 },\r
+\r
+                Package () { 0x000CFFFF, 0, Zero, 0x11 },\r
+                Package () { 0x000CFFFF, 1, Zero, 0x12 },\r
+                Package () { 0x000CFFFF, 2, Zero, 0x13 },\r
+                Package () { 0x000CFFFF, 3, Zero, 0x14 },\r
+\r
+                Package () { 0x000DFFFF, 0, Zero, 0x12 },\r
+                Package () { 0x000DFFFF, 1, Zero, 0x13 },\r
+                Package () { 0x000DFFFF, 2, Zero, 0x14 },\r
+                Package () { 0x000DFFFF, 3, Zero, 0x15 },\r
+\r
+                Package () { 0x000EFFFF, 0, Zero, 0x13 },\r
+                Package () { 0x000EFFFF, 1, Zero, 0x14 },\r
+                Package () { 0x000EFFFF, 2, Zero, 0x15 },\r
+                Package () { 0x000EFFFF, 3, Zero, 0x16 },\r
+\r
+                Package () { 0x000FFFFF, 0, Zero, 0x14 },\r
+                Package () { 0x000FFFFF, 1, Zero, 0x15 },\r
+                Package () { 0x000FFFFF, 2, Zero, 0x16 },\r
+                Package () { 0x000FFFFF, 3, Zero, 0x17 },\r
+\r
+                Package () { 0x0010FFFF, 0, Zero, 0x15 },\r
+                Package () { 0x0010FFFF, 1, Zero, 0x16 },\r
+                Package () { 0x0010FFFF, 2, Zero, 0x17 },\r
+                Package () { 0x0010FFFF, 3, Zero, 0x10 },\r
+\r
+                Package () { 0x0011FFFF, 0, Zero, 0x16 },\r
+                Package () { 0x0011FFFF, 1, Zero, 0x17 },\r
+                Package () { 0x0011FFFF, 2, Zero, 0x10 },\r
+                Package () { 0x0011FFFF, 3, Zero, 0x11 },\r
+\r
+                Package () { 0x0012FFFF, 0, Zero, 0x17 },\r
+                Package () { 0x0012FFFF, 1, Zero, 0x10 },\r
+                Package () { 0x0012FFFF, 2, Zero, 0x11 },\r
+                Package () { 0x0012FFFF, 3, Zero, 0x12 },\r
+\r
+                Package () { 0x0013FFFF, 0, Zero, 0x10 },\r
+                Package () { 0x0013FFFF, 1, Zero, 0x11 },\r
+                Package () { 0x0013FFFF, 2, Zero, 0x12 },\r
+                Package () { 0x0013FFFF, 3, Zero, 0x13 },\r
+\r
+                Package () { 0x0014FFFF, 0, Zero, 0x11 },\r
+                Package () { 0x0014FFFF, 1, Zero, 0x12 },\r
+                Package () { 0x0014FFFF, 2, Zero, 0x13 },\r
+                Package () { 0x0014FFFF, 3, Zero, 0x14 },\r
+\r
+                Package () { 0x0015FFFF, 0, Zero, 0x12 },\r
+                Package () { 0x0015FFFF, 1, Zero, 0x13 },\r
+                Package () { 0x0015FFFF, 2, Zero, 0x14 },\r
+                Package () { 0x0015FFFF, 3, Zero, 0x15 },\r
+\r
+                Package () { 0x0016FFFF, 0, Zero, 0x13 },\r
+                Package () { 0x0016FFFF, 1, Zero, 0x14 },\r
+                Package () { 0x0016FFFF, 2, Zero, 0x15 },\r
+                Package () { 0x0016FFFF, 3, Zero, 0x16 },\r
+\r
+                Package () { 0x0017FFFF, 0, Zero, 0x14 },\r
+                Package () { 0x0017FFFF, 1, Zero, 0x15 },\r
+                Package () { 0x0017FFFF, 2, Zero, 0x16 },\r
+                Package () { 0x0017FFFF, 3, Zero, 0x17 },\r
+\r
+                Package () { 0x0018FFFF, 0, Zero, 0x15 },\r
+                Package () { 0x0018FFFF, 1, Zero, 0x16 },\r
+                Package () { 0x0018FFFF, 2, Zero, 0x17 },\r
+                Package () { 0x0018FFFF, 3, Zero, 0x10 },\r
+\r
+                Package () { 0x0019FFFF, 0, Zero, 0x16 },\r
+                Package () { 0x0019FFFF, 1, Zero, 0x17 },\r
+                Package () { 0x0019FFFF, 2, Zero, 0x10 },\r
+                Package () { 0x0019FFFF, 3, Zero, 0x11 },\r
+\r
+                Package () { 0x001AFFFF, 0, Zero, 0x17 },\r
+                Package () { 0x001AFFFF, 1, Zero, 0x10 },\r
+                Package () { 0x001AFFFF, 2, Zero, 0x11 },\r
+                Package () { 0x001AFFFF, 3, Zero, 0x12 },\r
+\r
+                Package () { 0x001BFFFF, 0, Zero, 0x10 },\r
+                Package () { 0x001BFFFF, 1, Zero, 0x11 },\r
+                Package () { 0x001BFFFF, 2, Zero, 0x12 },\r
+                Package () { 0x001BFFFF, 3, Zero, 0x13 },\r
+\r
+                Package () { 0x001CFFFF, 0, Zero, 0x11 },\r
+                Package () { 0x001CFFFF, 1, Zero, 0x12 },\r
+                Package () { 0x001CFFFF, 2, Zero, 0x13 },\r
+                Package () { 0x001CFFFF, 3, Zero, 0x14 },\r
+\r
+                Package () { 0x001DFFFF, 0, Zero, 0x12 },\r
+                Package () { 0x001DFFFF, 1, Zero, 0x13 },\r
+                Package () { 0x001DFFFF, 2, Zero, 0x14 },\r
+                Package () { 0x001DFFFF, 3, Zero, 0x15 },\r
+\r
+                Package () { 0x001EFFFF, 0, Zero, 0x13 },\r
+                Package () { 0x001EFFFF, 1, Zero, 0x14 },\r
+                Package () { 0x001EFFFF, 2, Zero, 0x15 },\r
+                Package () { 0x001EFFFF, 3, Zero, 0x16 },\r
+\r
+                Package () { 0x001FFFFF, 0, Zero, 0x14 },\r
+                Package () { 0x001FFFFF, 1, Zero, 0x15 },\r
+                Package () { 0x001FFFFF, 2, Zero, 0x16 },\r
+                Package () { 0x001FFFFF, 3, Zero, 0x17 }\r
+            })\r
+            Method (_PRT, 0, NotSerialized)\r
+            {\r
+                If (PICM)\r
+                {\r
+                    Return (APRT)\r
+                }\r
+                Else\r
+                {\r
+                    Return (PPRT)\r
+                }\r
+            }\r
+\r
+            Device (LPC)\r
+            {\r
+                Name (_ADR, 0x001F0000)\r
+                OperationRegion (LPCR, PCI_Config, Zero, 0x0100)\r
+                Field (LPCR, AnyAcc, NoLock, Preserve)\r
+                {\r
+                    Offset (0x60),\r
+                    PIRA,   8,\r
+                    PIRB,   8,\r
+                    PIRC,   8,\r
+                    PIRD,   8,\r
+                    Offset (0x68),\r
+                    PIRE,   8,\r
+                    PIRF,   8,\r
+                    PIRG,   8,\r
+                    PIRH,   8\r
+                }\r
+\r
+                Device (KBD)\r
+                {\r
+                  Name (_HID, EISAID ("PNP0303"))\r
+                  Name (_CID, EISAID ("PNP030B"))\r
+                  Name (_CRS, ResourceTemplate ()\r
+                  {\r
+                    IO (Decode16,\r
+                        0x0060,             // Range Minimum\r
+                        0x0060,             // Range Maximum\r
+                        0x00,               // Alignment\r
+                        0x01,               // Length\r
+                        )\r
+                    IO (Decode16,\r
+                        0x0064,             // Range Minimum\r
+                        0x0064,             // Range Maximum\r
+                        0x00,               // Alignment\r
+                        0x01,               // Length\r
+                        )\r
+                    IRQNoFlags ()\r
+                        {1}\r
+                  })\r
+                }\r
+\r
+                Device (MOU)\r
+                {\r
+                  Name (_HID, EISAID ("PNP0F03"))\r
+                  Name (_CID, EISAID ("PNP0F13"))\r
+                  Name (_CRS, ResourceTemplate ()\r
+                  {\r
+                    IRQNoFlags ()\r
+                        {12}\r
+                  })\r
+                }\r
+\r
+                Method (PIRV, 1, NotSerialized)\r
+                {\r
+                    If (And (Arg0, 0x80))\r
+                    {\r
+                        Return (Zero)\r
+                    }\r
+\r
+                    And (Arg0, 0x0F, Local0)\r
+                    If (LLess (Local0, 0x03))\r
+                    {\r
+                        Return (Zero)\r
+                    }\r
+\r
+                    If (LEqual (Local0, 0x08))\r
+                    {\r
+                        Return (Zero)\r
+                    }\r
+\r
+                    If (LEqual (Local0, 0x0D))\r
+                    {\r
+                        Return (Zero)\r
+                    }\r
+\r
+                    Return (One)\r
+                }\r
+\r
+                Device (LNKA)\r
+                {\r
+                    Name (_HID, EisaId ("PNP0C0F"))\r
+                    Name (_UID, One)\r
+                    Method (_STA, 0, NotSerialized)\r
+                    {\r
+                        If (PIRV (PIRA))\r
+                        {\r
+                            Return (0x0B)\r
+                        }\r
+                        Else\r
+                        {\r
+                            Return (0x09)\r
+                        }\r
+                    }\r
+\r
+                    Name (_PRS, ResourceTemplate ()\r
+                    {\r
+                        IRQ (Level, ActiveLow, Shared, )\r
+                            {3,4,5,6,7,9,10,11,12,14,15}\r
+                    })\r
+                    Name (CB01, ResourceTemplate ()\r
+                    {\r
+                        IRQ (Level, ActiveLow, Shared, )\r
+                            {}\r
+                    })\r
+                    CreateWordField (CB01, One, CIRA)\r
+                    Method (_CRS, 0, NotSerialized)\r
+                    {\r
+                        And (PIRA, 0x8F, Local0)\r
+                        If (PIRV (Local0))\r
+                        {\r
+                            ShiftLeft (One, Local0, CIRA)\r
+                        }\r
+                        Else\r
+                        {\r
+                            Store (Zero, CIRA)\r
+                        }\r
+\r
+                        Return (CB01)\r
+                    }\r
+\r
+                    Method (_DIS, 0, NotSerialized)\r
+                    {\r
+                        Store (0x80, PIRA)\r
+                    }\r
+\r
+                    Method (_SRS, 1, NotSerialized)\r
+                    {\r
+                        CreateWordField (Arg0, One, SIRA)\r
+                        FindSetRightBit (SIRA, Local0)\r
+                        Store (Decrement (Local0), PIRA)\r
+                    }\r
+                }\r
+\r
+                Device (LNKB)\r
+                {\r
+                    Name (_HID, EisaId ("PNP0C0F"))\r
+                    Name (_UID, 0x02)\r
+                    Method (_STA, 0, NotSerialized)\r
+                    {\r
+                        If (PIRV (PIRB))\r
+                        {\r
+                            Return (0x0B)\r
+                        }\r
+                        Else\r
+                        {\r
+                            Return (0x09)\r
+                        }\r
+                    }\r
+\r
+                    Name (_PRS, ResourceTemplate ()\r
+                    {\r
+                        IRQ (Level, ActiveLow, Shared, )\r
+                            {3,4,5,6,7,9,10,11,12,14,15}\r
+                    })\r
+                    Name (CB02, ResourceTemplate ()\r
+                    {\r
+                        IRQ (Level, ActiveLow, Shared, )\r
+                            {}\r
+                    })\r
+                    CreateWordField (CB02, One, CIRB)\r
+                    Method (_CRS, 0, NotSerialized)\r
+                    {\r
+                        And (PIRB, 0x8F, Local0)\r
+                        If (PIRV (Local0))\r
+                        {\r
+                            ShiftLeft (One, Local0, CIRB)\r
+                        }\r
+                        Else\r
+                        {\r
+                            Store (Zero, CIRB)\r
+                        }\r
+\r
+                        Return (CB02)\r
+                    }\r
+\r
+                    Method (_DIS, 0, NotSerialized)\r
+                    {\r
+                        Store (0x80, PIRB)\r
+                    }\r
+\r
+                    Method (_SRS, 1, NotSerialized)\r
+                    {\r
+                        CreateWordField (Arg0, One, SIRB)\r
+                        FindSetRightBit (SIRB, Local0)\r
+                        Store (Decrement (Local0), PIRB)\r
+                    }\r
+                }\r
+\r
+                Device (LNKC)\r
+                {\r
+                    Name (_HID, EisaId ("PNP0C0F"))\r
+                    Name (_UID, 0x03)\r
+                    Method (_STA, 0, NotSerialized)\r
+                    {\r
+                        If (PIRV (PIRC))\r
+                        {\r
+                            Return (0x0B)\r
+                        }\r
+                        Else\r
+                        {\r
+                            Return (0x09)\r
+                        }\r
+                    }\r
+\r
+                    Name (_PRS, ResourceTemplate ()\r
+                    {\r
+                        IRQ (Level, ActiveLow, Shared, )\r
+                            {3,4,5,6,7,9,10,11,12,14,15}\r
+                    })\r
+                    Name (CB03, ResourceTemplate ()\r
+                    {\r
+                        IRQ (Level, ActiveLow, Shared, )\r
+                            {}\r
+                    })\r
+                    CreateWordField (CB03, One, CIRC)\r
+                    Method (_CRS, 0, NotSerialized)\r
+                    {\r
+                        And (PIRC, 0x8F, Local0)\r
+                        If (PIRV (Local0))\r
+                        {\r
+                            ShiftLeft (One, Local0, CIRC)\r
+                        }\r
+                        Else\r
+                        {\r
+                            Store (Zero, CIRC)\r
+                        }\r
+\r
+                        Return (CB03)\r
+                    }\r
+\r
+                    Method (_DIS, 0, NotSerialized)\r
+                    {\r
+                        Store (0x80, PIRC)\r
+                    }\r
+\r
+                    Method (_SRS, 1, NotSerialized)\r
+                    {\r
+                        CreateWordField (Arg0, One, SIRC)\r
+                        FindSetRightBit (SIRC, Local0)\r
+                        Store (Decrement (Local0), PIRC)\r
+                    }\r
+                }\r
+\r
+                Device (LNKD)\r
+                {\r
+                    Name (_HID, EisaId ("PNP0C0F"))\r
+                    Name (_UID, 0x04)\r
+                    Method (_STA, 0, NotSerialized)\r
+                    {\r
+                        If (PIRV (PIRD))\r
+                        {\r
+                            Return (0x0B)\r
+                        }\r
+                        Else\r
+                        {\r
+                            Return (0x09)\r
+                        }\r
+                    }\r
+\r
+                    Name (_PRS, ResourceTemplate ()\r
+                    {\r
+                        IRQ (Level, ActiveLow, Shared, )\r
+                            {3,4,5,6,7,9,10,11,12,14,15}\r
+                    })\r
+                    Name (CB04, ResourceTemplate ()\r
+                    {\r
+                        IRQ (Level, ActiveLow, Shared, )\r
+                            {}\r
+                    })\r
+                    CreateWordField (CB04, One, CIRD)\r
+                    Method (_CRS, 0, NotSerialized)\r
+                    {\r
+                        And (PIRD, 0x8F, Local0)\r
+                        If (PIRV (Local0))\r
+                        {\r
+                            ShiftLeft (One, Local0, CIRD)\r
+                        }\r
+                        Else\r
+                        {\r
+                            Store (Zero, CIRD)\r
+                        }\r
+\r
+                        Return (CB04)\r
+                    }\r
+\r
+                    Method (_DIS, 0, NotSerialized)\r
+                    {\r
+                        Store (0x80, PIRD)\r
+                    }\r
+\r
+                    Method (_SRS, 1, NotSerialized)\r
+                    {\r
+                        CreateWordField (Arg0, One, SIRD)\r
+                        FindSetRightBit (SIRD, Local0)\r
+                        Store (Decrement (Local0), PIRD)\r
+                    }\r
+                }\r
+\r
+                Device (LNKE)\r
+                {\r
+                    Name (_HID, EisaId ("PNP0C0F"))\r
+                    Name (_UID, 0x05)\r
+                    Method (_STA, 0, NotSerialized)\r
+                    {\r
+                        If (PIRV (PIRE))\r
+                        {\r
+                            Return (0x0B)\r
+                        }\r
+                        Else\r
+                        {\r
+                            Return (0x09)\r
+                        }\r
+                    }\r
+\r
+                    Name (_PRS, ResourceTemplate ()\r
+                    {\r
+                        IRQ (Level, ActiveLow, Shared, )\r
+                            {3,4,5,6,7,9,10,11,12,14,15}\r
+                    })\r
+                    Name (CB05, ResourceTemplate ()\r
+                    {\r
+                        IRQ (Level, ActiveLow, Shared, )\r
+                            {}\r
+                    })\r
+                    CreateWordField (CB05, One, CIRE)\r
+                    Method (_CRS, 0, NotSerialized)\r
+                    {\r
+                        And (PIRE, 0x8F, Local0)\r
+                        If (PIRV (Local0))\r
+                        {\r
+                            ShiftLeft (One, Local0, CIRE)\r
+                        }\r
+                        Else\r
+                        {\r
+                            Store (Zero, CIRE)\r
+                        }\r
+\r
+                        Return (CB05)\r
+                    }\r
+\r
+                    Method (_DIS, 0, NotSerialized)\r
+                    {\r
+                        Store (0x80, PIRE)\r
+                    }\r
+\r
+                    Method (_SRS, 1, NotSerialized)\r
+                    {\r
+                        CreateWordField (Arg0, One, SIRE)\r
+                        FindSetRightBit (SIRE, Local0)\r
+                        Store (Decrement (Local0), PIRE)\r
+                    }\r
+                }\r
+\r
+                Device (LNKF)\r
+                {\r
+                    Name (_HID, EisaId ("PNP0C0F"))\r
+                    Name (_UID, 0x06)\r
+                    Method (_STA, 0, NotSerialized)\r
+                    {\r
+                        If (PIRV (PIRF))\r
+                        {\r
+                            Return (0x0B)\r
+                        }\r
+                        Else\r
+                        {\r
+                            Return (0x09)\r
+                        }\r
+                    }\r
+\r
+                    Name (_PRS, ResourceTemplate ()\r
+                    {\r
+                        IRQ (Level, ActiveLow, Shared, )\r
+                            {3,4,5,6,7,9,10,11,12,14,15}\r
+                    })\r
+                    Name (CB06, ResourceTemplate ()\r
+                    {\r
+                        IRQ (Level, ActiveLow, Shared, )\r
+                            {}\r
+                    })\r
+                    CreateWordField (CB06, One, CIRF)\r
+                    Method (_CRS, 0, NotSerialized)\r
+                    {\r
+                        And (PIRF, 0x8F, Local0)\r
+                        If (PIRV (Local0))\r
+                        {\r
+                            ShiftLeft (One, Local0, CIRF)\r
+                        }\r
+                        Else\r
+                        {\r
+                            Store (Zero, CIRF)\r
+                        }\r
+\r
+                        Return (CB06)\r
+                    }\r
+\r
+                    Method (_DIS, 0, NotSerialized)\r
+                    {\r
+                        Store (0x80, PIRF)\r
+                    }\r
+\r
+                    Method (_SRS, 1, NotSerialized)\r
+                    {\r
+                        CreateWordField (Arg0, One, SIRF)\r
+                        FindSetRightBit (SIRF, Local0)\r
+                        Store (Decrement (Local0), PIRF)\r
+                    }\r
+                }\r
+\r
+                Device (LNKG)\r
+                {\r
+                    Name (_HID, EisaId ("PNP0C0F"))\r
+                    Name (_UID, 0x07)\r
+                    Method (_STA, 0, NotSerialized)\r
+                    {\r
+                        If (PIRV (PIRG))\r
+                        {\r
+                            Return (0x0B)\r
+                        }\r
+                        Else\r
+                        {\r
+                            Return (0x09)\r
+                        }\r
+                    }\r
+\r
+                    Name (_PRS, ResourceTemplate ()\r
+                    {\r
+                        IRQ (Level, ActiveLow, Shared, )\r
+                            {3,4,5,6,7,9,10,11,12,14,15}\r
+                    })\r
+                    Name (CB07, ResourceTemplate ()\r
+                    {\r
+                        IRQ (Level, ActiveLow, Shared, )\r
+                            {}\r
+                    })\r
+                    CreateWordField (CB07, One, CIRG)\r
+                    Method (_CRS, 0, NotSerialized)\r
+                    {\r
+                        And (PIRG, 0x8F, Local0)\r
+                        If (PIRV (Local0))\r
+                        {\r
+                            ShiftLeft (One, Local0, CIRG)\r
+                        }\r
+                        Else\r
+                        {\r
+                            Store (Zero, CIRG)\r
+                        }\r
+\r
+                        Return (CB07)\r
+                    }\r
+\r
+                    Method (_DIS, 0, NotSerialized)\r
+                    {\r
+                        Store (0x80, PIRG)\r
+                    }\r
+\r
+                    Method (_SRS, 1, NotSerialized)\r
+                    {\r
+                        CreateWordField (Arg0, One, SIRG)\r
+                        FindSetRightBit (SIRG, Local0)\r
+                        Store (Decrement (Local0), PIRG)\r
+                    }\r
+                }\r
+\r
+                Device (LNKH)\r
+                {\r
+                    Name (_HID, EisaId ("PNP0C0F"))\r
+                    Name (_UID, 0x08)\r
+                    Method (_STA, 0, NotSerialized)\r
+                    {\r
+                        If (PIRV (PIRH))\r
+                        {\r
+                            Return (0x0B)\r
+                        }\r
+                        Else\r
+                        {\r
+                            Return (0x09)\r
+                        }\r
+                    }\r
+\r
+                    Name (_PRS, ResourceTemplate ()\r
+                    {\r
+                        IRQ (Level, ActiveLow, Shared, )\r
+                            {3,4,5,6,7,9,10,11,12,14,15}\r
+                    })\r
+                    Name (CB08, ResourceTemplate ()\r
+                    {\r
+                        IRQ (Level, ActiveLow, Shared, )\r
+                            {}\r
+                    })\r
+                    CreateWordField (CB08, One, CIRH)\r
+                    Method (_CRS, 0, NotSerialized)\r
+                    {\r
+                        And (PIRH, 0x8F, Local0)\r
+                        If (PIRV (Local0))\r
+                        {\r
+                            ShiftLeft (One, Local0, CIRH)\r
+                        }\r
+                        Else\r
+                        {\r
+                            Store (Zero, CIRH)\r
+                        }\r
+\r
+                        Return (CB08)\r
+                    }\r
+\r
+                    Method (_DIS, 0, NotSerialized)\r
+                    {\r
+                        Store (0x80, PIRH)\r
+                    }\r
+\r
+                    Method (_SRS, 1, NotSerialized)\r
+                    {\r
+                        CreateWordField (Arg0, One, SIRH)\r
+                        FindSetRightBit (SIRH, Local0)\r
+                        Store (Decrement (Local0), PIRH)\r
+                    }\r
+                }\r
+\r
+                Device (SIO)\r
+                {\r
+                    Name (_HID, EisaId ("PNP0C02"))\r
+                    Name (_CRS, ResourceTemplate ()\r
+                    {\r
+                        IO (Decode16,\r
+                            0x0220,             // Range Minimum\r
+                            0x0220,             // Range Maximum\r
+                            0x01,               // Alignment\r
+                            0x04,               // Length\r
+                            )\r
+                        IO (Decode16,\r
+                            0x0224,             // Range Minimum\r
+                            0x0224,             // Range Maximum\r
+                            0x01,               // Alignment\r
+                            0x04,               // Length\r
+                            )\r
+                        Memory32Fixed (ReadWrite,\r
+                            0xE0000000,         // Address Base\r
+                            0x10000000,         // Address Length\r
+                            )\r
+                        IO (Decode16,\r
+                            0x04D0,             // Range Minimum\r
+                            0x04D0,             // Range Maximum\r
+                            0x01,               // Alignment\r
+                            0x02,               // Length\r
+                            )\r
+                        IO (Decode16,\r
+                            0x0061,             // Range Minimum\r
+                            0x0061,             // Range Maximum\r
+                            0x01,               // Alignment\r
+                            0x01,               // Length\r
+                            )\r
+                        IO (Decode16,\r
+                            0x0400,             // Range Minimum\r
+                            0x0400,             // Range Maximum\r
+                            0x01,               // Alignment\r
+                            0x08,               // Length\r
+                            )\r
+                        IO (Decode16,\r
+                            0x00B2,             // Range Minimum\r
+                            0x00B2,             // Range Maximum\r
+                            0x01,               // Alignment\r
+                            0x01,               // Length\r
+                            )\r
+                        IO (Decode16,\r
+                            0x0084,             // Range Minimum\r
+                            0x0084,             // Range Maximum\r
+                            0x01,               // Alignment\r
+                            0x01,               // Length\r
+                            )\r
+                        IO (Decode16,\r
+                            0x0072,             // Range Minimum\r
+                            0x0072,             // Range Maximum\r
+                            0x01,               // Alignment\r
+                            0x06,               // Length\r
+                            )\r
+                    })\r
+                }\r
+\r
+                Device (COM1)\r
+                {\r
+                    Name (_HID, EisaId ("PNP0501"))\r
+                    Name (_UID, One)\r
+                    Name (_CRS, ResourceTemplate ()\r
+                    {\r
+                        IO (Decode16,\r
+                            0x03F8,             // Range Minimum\r
+                            0x03F8,             // Range Maximum\r
+                            0x01,               // Alignment\r
+                            0x08,               // Length\r
+                            )\r
+                        IRQNoFlags ()\r
+                            {4}\r
+                    })\r
+                }\r
+\r
+                Device (COM2)\r
+                {\r
+                    Name (_HID, EisaId ("PNP0501"))\r
+                    Name (_UID, 0x02)\r
+                    Name (_CRS, ResourceTemplate ()\r
+                    {\r
+                        IO (Decode16,\r
+                            0x02F8,             // Range Minimum\r
+                            0x02F8,             // Range Maximum\r
+                            0x01,               // Alignment\r
+                            0x08,               // Length\r
+                            )\r
+                        IRQNoFlags ()\r
+                            {3}\r
+                    })\r
+                }\r
+\r
+                Device (RTC)\r
+                {\r
+                    Name (_HID, EisaId ("PNP0B00"))\r
+                    Name (_CRS, ResourceTemplate ()\r
+                    {\r
+                        IO (Decode16,\r
+                            0x0070,             // Range Minimum\r
+                            0x0070,             // Range Maximum\r
+                            0x00,               // Alignment\r
+                            0x02,               // Length\r
+                            )\r
+                        IRQNoFlags ()\r
+                            {8}\r
+                        IO (Decode16,\r
+                            0x0072,             // Range Minimum\r
+                            0x0072,             // Range Maximum\r
+                            0x02,               // Alignment\r
+                            0x06,               // Length\r
+                            )\r
+                    })\r
+                }\r
+\r
+                Device (PIC)\r
+                {\r
+                    Name (_HID, EisaId ("PNP0000"))\r
+                    Name (_CRS, ResourceTemplate ()\r
+                    {\r
+                        IO (Decode16,\r
+                            0x0020,             // Range Minimum\r
+                            0x0020,             // Range Maximum\r
+                            0x01,               // Alignment\r
+                            0x02,               // Length\r
+                            )\r
+                        IO (Decode16,\r
+                            0x00A0,             // Range Minimum\r
+                            0x00A0,             // Range Maximum\r
+                            0x01,               // Alignment\r
+                            0x02,               // Length\r
+                            )\r
+                        IRQNoFlags ()\r
+                            {2}\r
+                    })\r
+                }\r
+\r
+                Device (TIMR)\r
+                {\r
+                    Name (_HID, EisaId ("PNP0100"))\r
+                    Name (_CRS, ResourceTemplate ()\r
+                    {\r
+                        IO (Decode16,\r
+                            0x0040,             // Range Minimum\r
+                            0x0040,             // Range Maximum\r
+                            0x01,               // Alignment\r
+                            0x04,               // Length\r
+                            )\r
+                        IRQNoFlags ()\r
+                            {0}\r
+                    })\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    Scope (_SB.PC00)\r
+    {\r
+        Device (HPET)\r
+        {\r
+            Name (_HID, EisaId ("PNP0103"))\r
+            Name (_UID, Zero)\r
+            Name (_CRS, ResourceTemplate ()\r
+            {\r
+                Memory32Fixed (ReadWrite,\r
+                    0xFED00000,         // Address Base\r
+                    0x00000400,         // Address Length\r
+                    )\r
+            })\r
+        }\r
+    }\r
+}\r
+\r
diff --git a/OvmfPkg/Bhyve/AcpiTables/Facp.aslc b/OvmfPkg/Bhyve/AcpiTables/Facp.aslc
new file mode 100644 (file)
index 0000000..b3d703e
--- /dev/null
@@ -0,0 +1,76 @@
+/*\r
+ * Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+ * Copyright (c) 2014, Pluribus Networks, Inc.\r
+ *\r
+ * SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ */\r
+\r
+#include "Platform.h"\r
+\r
+#define EFI_ACPI_OEM_TABLE_ID     SIGNATURE_64('B','V','F','A','C','P',' ',' ')\r
+\r
+EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE FACP = {\r
+  {\r
+    EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,\r
+    sizeof (EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE),\r
+    EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION,\r
+    0,                          // to make sum of entire table == 0\r
+    {EFI_ACPI_OEM_ID},          // OEMID is a 6 bytes long field\r
+    EFI_ACPI_OEM_TABLE_ID,      // OEM table identification(8 bytes long)\r
+    EFI_ACPI_OEM_REVISION,      // OEM revision number\r
+    EFI_ACPI_CREATOR_ID,        // ASL compiler vendor ID\r
+    EFI_ACPI_CREATOR_REVISION   // ASL compiler revision number\r
+  },\r
+  0,                // Physical addesss of FACS\r
+  0,                // Physical address of DSDT\r
+  INT_MODEL,        // System Interrupt Model\r
+  RESERVED,         // reserved\r
+  SCI_INT_VECTOR,   // System vector of SCI interrupt\r
+  SMI_CMD_IO_PORT,  // Port address of SMI command port\r
+  ACPI_ENABLE,      // value to write to port smi_cmd to enable ACPI\r
+  ACPI_DISABLE,     // value to write to port smi_cmd to disable ACPI\r
+  S4BIOS_REQ,       // Value to write to SMI CMD port to enter the S4BIOS state\r
+  0,                // PState control\r
+  PM1a_EVT_BLK,     // Port address of Power Mgt 1a Event Reg Blk\r
+  PM1b_EVT_BLK,     // Port address of Power Mgt 1b Event Reg Blk\r
+  PM1a_CNT_BLK,     // Port address of Power Mgt 1a Ctrl Reg Blk\r
+  PM1b_CNT_BLK,     // Port address of Power Mgt 1b Ctrl Reg Blk\r
+  PM2_CNT_BLK,      // Port address of Power Mgt 2  Ctrl Reg Blk\r
+  PM_TMR_BLK,       // Port address of Power Mgt Timer Ctrl Reg Blk\r
+  GPE0_BLK,         // Port addr of General Purpose Event 0 Reg Blk\r
+  GPE1_BLK,         // Port addr of General Purpose Event 1 Reg Blk\r
+  PM1_EVT_LEN,      // Byte Length of ports at pm1X_evt_blk\r
+  PM1_CNT_LEN,      // Byte Length of ports at pm1X_cnt_blk\r
+  PM2_CNT_LEN,      // Byte Length of ports at pm2_cnt_blk\r
+  PM_TM_LEN,        // Byte Length of ports at pm_tm_blk\r
+  GPE0_BLK_LEN,     // Byte Length of ports at gpe0_blk\r
+  GPE1_BLK_LEN,     // Byte Length of ports at gpe1_blk\r
+  GPE1_BASE,        // offset in gpe model where gpe1 events start\r
+  0,                // _CST support\r
+  P_LVL2_LAT,       // worst case HW latency to enter/exit C2 state\r
+  P_LVL3_LAT,       // worst case HW latency to enter/exit C3 state\r
+  FLUSH_SIZE,       // Size of area read to flush caches\r
+  FLUSH_STRIDE,     // Stride used in flushing caches\r
+  DUTY_OFFSET,      // bit location of duty cycle field in p_cnt reg\r
+  DUTY_WIDTH,       // bit width of duty cycle field in p_cnt reg\r
+  DAY_ALRM,         // index to day-of-month alarm in RTC CMOS RAM\r
+  MON_ALRM,         // index to month-of-year alarm in RTC CMOS RAM\r
+  CENTURY,          // index to century in RTC CMOS RAM\r
+  IAPC_BOOT_ARCH,   // Boot architecture flag\r
+  RESERVED,         // reserved\r
+  FACP_FLAGS,\r
+  FACP_RESET_REG,\r
+  FACP_RESET_VAL,\r
+};\r
+\r
+VOID*\r
+ReferenceAcpiTable (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Reference the table being generated to prevent the optimizer from removing the\r
+  // data structure from the exeutable\r
+  //\r
+  return (VOID*)&FACP;\r
+}\r
diff --git a/OvmfPkg/Bhyve/AcpiTables/Facs.aslc b/OvmfPkg/Bhyve/AcpiTables/Facs.aslc
new file mode 100644 (file)
index 0000000..05b6410
--- /dev/null
@@ -0,0 +1,80 @@
+/** @file\r
+  FACS Table\r
+\r
+  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+  Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <IndustryStandard/Acpi.h>\r
+\r
+EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE FACS = {\r
+  EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE,\r
+  sizeof (EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE),\r
+\r
+  //\r
+  // Hardware Signature will be updated at runtime\r
+  //\r
+  0x00000000,\r
+  0x00,\r
+  0x00,\r
+  0x00,\r
+  {\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE,\r
+    EFI_ACPI_RESERVED_BYTE\r
+  }\r
+};\r
+\r
+\r
+VOID*\r
+ReferenceAcpiTable (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Reference the table being generated to prevent the optimizer from removing the\r
+  // data structure from the exeutable\r
+  //\r
+  return (VOID*)&FACS;\r
+}\r
+\r
diff --git a/OvmfPkg/Bhyve/AcpiTables/Hpet.aslc b/OvmfPkg/Bhyve/AcpiTables/Hpet.aslc
new file mode 100644 (file)
index 0000000..73bb784
--- /dev/null
@@ -0,0 +1,72 @@
+/*\r
+ * Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+ * Copyright (c) 2014, Pluribus Networks, Inc.\r
+ *\r
+ * SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ */\r
+\r
+#include <IndustryStandard/HighPrecisionEventTimerTable.h>\r
+\r
+#include "Platform.h"\r
+\r
+#define EFI_ACPI_HPET_DESCRIPTION_TABLE_SIGNATURE  SIGNATURE_32('H', 'P', 'E', 'T')\r
+#define EFI_ACPI_OEM_TABLE_ID                      SIGNATURE_64('B','V','H','P','E','T',' ',' ')\r
+\r
+//\r
+// Ensure proper structure formats\r
+//\r
+#pragma pack (1)\r
+\r
+//\r
+// ACPI HPET structure\r
+//\r
+typedef struct {\r
+  EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_HEADER  Header;\r
+} EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_DESCRIPTION_TABLE;\r
+\r
+#pragma pack ()\r
+\r
+//\r
+// HPET Description Table\r
+//\r
+EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_DESCRIPTION_TABLE Hpet = {\r
+  {\r
+    {\r
+      EFI_ACPI_HPET_DESCRIPTION_TABLE_SIGNATURE,\r
+      sizeof (EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_DESCRIPTION_TABLE),\r
+      EFI_ACPI_HIGH_PRECISION_EVENT_TIMER_TABLE_REVISION,\r
+      0x00,                              // Checksum will be updated at runtime\r
+      {EFI_ACPI_OEM_ID},\r
+      EFI_ACPI_OEM_TABLE_ID,\r
+      EFI_ACPI_OEM_REVISION,\r
+      EFI_ACPI_CREATOR_ID,\r
+      EFI_ACPI_CREATOR_REVISION\r
+    },\r
+\r
+    //\r
+    // HPET specific fields\r
+    //\r
+    0x0000A400,                          // EventTimerBlockId\r
+    {\r
+      EFI_ACPI_2_0_SYSTEM_MEMORY,\r
+      0,\r
+      0,\r
+      EFI_ACPI_RESERVED_BYTE,\r
+      0xFED00000,\r
+    },\r
+    0                                    // HpetNumber\r
+  }\r
+};\r
+\r
+\r
+VOID*\r
+ReferenceAcpiTable (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Reference the table being generated to prevent the optimizer from removing the\r
+  // data structure from the exeutable\r
+  //\r
+  return (VOID*)&Hpet;\r
+}\r
diff --git a/OvmfPkg/Bhyve/AcpiTables/Madt.aslc b/OvmfPkg/Bhyve/AcpiTables/Madt.aslc
new file mode 100644 (file)
index 0000000..e8e956e
--- /dev/null
@@ -0,0 +1,145 @@
+/** @file\r
+  MADT Table\r
+\r
+  This file contains a structure definition for the ACPI 1.0 Multiple APIC\r
+  Description Table (MADT).\r
+\r
+  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+  Copyright (c) 2014, Pluribus Networks, Inc.\r
+  Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <IndustryStandard/Acpi.h>\r
+#include <Platform.h>\r
+\r
+#define EFI_ACPI_OEM_TABLE_ID                      SIGNATURE_64('B','V','M','A','D','T',' ',' ')\r
+\r
+//\r
+// Local APIC address\r
+//\r
+#define EFI_ACPI_LOCAL_APIC_ADDRESS 0xFEE00000\r
+\r
+//\r
+// Multiple APIC Flags are defined in AcpiX.0.h\r
+//\r
+#define EFI_ACPI_1_0_MULTIPLE_APIC_FLAGS (EFI_ACPI_1_0_PCAT_COMPAT)\r
+\r
+//\r
+// Define the number of each table type.\r
+// This is where the table layout is modified.\r
+//\r
+#define EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT           1\r
+#define EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT      1\r
+#define EFI_ACPI_IO_APIC_COUNT                        1\r
+\r
+//\r
+// Ensure proper structure formats\r
+//\r
+#pragma pack (1)\r
+\r
+//\r
+// ACPI 1.0 MADT structure\r
+//\r
+typedef struct {\r
+  EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER   Header;\r
+\r
+#if EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT > 0\r
+  EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC_STRUCTURE           LocalApic[EFI_ACPI_PROCESSOR_LOCAL_APIC_COUNT];\r
+#endif\r
+\r
+#if EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT > 0\r
+  EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE      Iso[EFI_ACPI_INTERRUPT_SOURCE_OVERRIDE_COUNT];\r
+#endif\r
+\r
+#if EFI_ACPI_IO_APIC_COUNT > 0\r
+  EFI_ACPI_1_0_IO_APIC_STRUCTURE                        IoApic[EFI_ACPI_IO_APIC_COUNT];\r
+#endif\r
+\r
+} EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE;\r
+\r
+#pragma pack ()\r
+\r
+//\r
+// Multiple APIC Description Table\r
+//\r
+EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE Madt = {\r
+  {\r
+    {\r
+      EFI_ACPI_1_0_APIC_SIGNATURE,\r
+      sizeof (EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE),\r
+      EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,\r
+      0x00,                                                     // Checksum will be updated at runtime\r
+      {EFI_ACPI_OEM_ID},\r
+      EFI_ACPI_OEM_TABLE_ID,\r
+      EFI_ACPI_OEM_REVISION,\r
+      EFI_ACPI_CREATOR_ID,\r
+      EFI_ACPI_CREATOR_REVISION\r
+    },\r
+\r
+    //\r
+    // MADT specific fields\r
+    //\r
+    EFI_ACPI_LOCAL_APIC_ADDRESS,\r
+    EFI_ACPI_1_0_MULTIPLE_APIC_FLAGS,\r
+  },\r
+\r
+  //\r
+  // Processor Local APIC Structure\r
+  //\r
+  {\r
+    {\r
+      EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC,                        // Type\r
+      sizeof (EFI_ACPI_1_0_PROCESSOR_LOCAL_APIC_STRUCTURE),     // Length\r
+      0x00,                                                     // Processor ID\r
+      0x00,                                                     // Local APIC ID\r
+      0x00000001                                                // Flags - Enabled by default\r
+    }\r
+  },\r
+\r
+  //\r
+  // Interrupt Source Override Structure\r
+  //\r
+  {\r
+    {\r
+      //\r
+      // IRQ0=>IRQ2 Interrupt Source Override Structure\r
+      //\r
+      EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE,                   // Type\r
+      sizeof (EFI_ACPI_1_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE),// Length\r
+      0x00,                                                     // Bus - ISA\r
+      0x00,                                                     // Source - IRQ0\r
+      0x00000002,                                               // Global System Interrupt - IRQ2\r
+      0x0005                                                    // Flags - Conforms to specifications of the bus\r
+    },\r
+  },\r
+\r
+  //\r
+  // IO APIC Structure\r
+  //\r
+  {\r
+    {\r
+      EFI_ACPI_1_0_IO_APIC,                                     // Type\r
+      sizeof (EFI_ACPI_1_0_IO_APIC_STRUCTURE),                  // Length\r
+      0x01,                                                     // IO APIC ID\r
+      EFI_ACPI_RESERVED_BYTE,                                   // Reserved\r
+      0xFEC00000,                                               // IO APIC Address (physical)\r
+      0x00000000                                                // Global System Interrupt Base\r
+    }\r
+  },\r
+};\r
+\r
+\r
+VOID*\r
+ReferenceAcpiTable (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Reference the table being generated to prevent the optimizer from removing the\r
+  // data structure from the exeutable\r
+  //\r
+  return (VOID*)&Madt;\r
+}\r
diff --git a/OvmfPkg/Bhyve/AcpiTables/Mcfg.aslc b/OvmfPkg/Bhyve/AcpiTables/Mcfg.aslc
new file mode 100644 (file)
index 0000000..62a98d3
--- /dev/null
@@ -0,0 +1,57 @@
+/*\r
+ * Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+ * Copyright (c) 2015, Nahanni Systems, Inc.\r
+ *\r
+ * SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ */\r
+\r
+#include "Platform.h"\r
+\r
+#define EFI_ACPI_OEM_TABLE_ID                      SIGNATURE_64('B','V','M','C','F','G',' ',' ')\r
+\r
+#pragma pack(1)\r
+\r
+typedef struct {\r
+  EFI_ACPI_DESCRIPTION_HEADER   Header;\r
+  UINT64                        Reserved0;\r
+  UINT64                        BaseAddress;\r
+  UINT16                        PciSegmentGroupNumber;\r
+  UINT8                         StartBusNumber;\r
+  UINT8                         EndBusNumber;\r
+  UINT32                        Reserved1;\r
+} EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE;\r
+\r
+#pragma pack()\r
+\r
+EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE MCFG = {\r
+  {\r
+    EFI_ACPI_2_0_MEMORY_MAPPED_CONFIGURATION_BASE_ADDRESS_TABLE_SIGNATURE,\r
+    sizeof (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE),\r
+    EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION,\r
+    0,                          // to make sum of entire table == 0\r
+    {EFI_ACPI_OEM_ID},          // OEMID is a 6 bytes long field\r
+    EFI_ACPI_OEM_TABLE_ID,      // OEM table identification(8 bytes long)\r
+    EFI_ACPI_OEM_REVISION,      // OEM revision number\r
+    EFI_ACPI_CREATOR_ID,        // ASL compiler vendor ID\r
+    EFI_ACPI_CREATOR_REVISION   // ASL compiler revision number\r
+  },\r
+  0,                            // Reserved\r
+  0x00000000E0000000,           // BaseAddress\r
+  0x0000,                       // PciSegmentGroupNumber\r
+  0,                            // StartBusNumber\r
+  255,                          // EndBusNumber\r
+  0                             // Reserved\r
+};\r
+\r
+\r
+VOID *\r
+ReferenceAcpiTable (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Reference the table being generated to prevent the optimizer from removing the\r
+  // data structure from the exeutable\r
+  //\r
+  return (VOID*)&MCFG;\r
+}\r
diff --git a/OvmfPkg/Bhyve/AcpiTables/Platform.h b/OvmfPkg/Bhyve/AcpiTables/Platform.h
new file mode 100644 (file)
index 0000000..fc43ab4
--- /dev/null
@@ -0,0 +1,72 @@
+/** @file\r
+  Platform specific defines for constructing ACPI tables\r
+\r
+  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+  Copyright (c) 2014, Pluribus Networks, Inc.\r
+  Copyright (c) 2012, 2013, Red Hat, Inc.\r
+  Copyright (c) 2008, Intel Corporation. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef _Platform_h_INCLUDED_\r
+#define _Platform_h_INCLUDED_\r
+\r
+#include <IndustryStandard/Acpi.h>\r
+#include <IndustryStandard/SerialPortConsoleRedirectionTable.h>\r
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>\r
+\r
+//\r
+// ACPI table information used to initialize tables.\r
+//\r
+#define EFI_ACPI_OEM_ID           'B','H','Y','V','E',' '   // OEMID 6 bytes long\r
+#define EFI_ACPI_OEM_REVISION     0x1\r
+#define EFI_ACPI_CREATOR_ID       SIGNATURE_32('B','H','Y','V')\r
+#define EFI_ACPI_CREATOR_REVISION 0x00000001\r
+\r
+#define INT_MODEL       0x01\r
+#define SCI_INT_VECTOR  0x0009\r
+#define SMI_CMD_IO_PORT 0xB2\r
+#define ACPI_ENABLE     0xA0\r
+#define ACPI_DISABLE    0xA1\r
+#define S4BIOS_REQ      0x00\r
+#define PM1a_EVT_BLK    0x00000400      /* TNXXX */\r
+#define PM1b_EVT_BLK    0x00000000\r
+#define PM1a_CNT_BLK    0x00000404      /* TNXXX */\r
+#define PM1b_CNT_BLK    0x00000000\r
+#define PM2_CNT_BLK     0x00000000\r
+#define PM_TMR_BLK      0x00000408\r
+#define GPE0_BLK        0x00000000\r
+#define GPE1_BLK        0x00000000\r
+#define PM1_EVT_LEN     0x04\r
+#define PM1_CNT_LEN     0x02\r
+#define PM2_CNT_LEN     0x00\r
+#define PM_TM_LEN       0x04\r
+#define GPE0_BLK_LEN    0x00\r
+#define GPE1_BLK_LEN    0x00\r
+#define GPE1_BASE       0x00\r
+#define RESERVED        0x00\r
+#define P_LVL2_LAT      0x0000\r
+#define P_LVL3_LAT      0x0000\r
+#define FLUSH_SIZE      0x0000\r
+#define FLUSH_STRIDE    0x0000\r
+#define DUTY_OFFSET     0x00\r
+#define DUTY_WIDTH      0x00\r
+#define DAY_ALRM        0x00\r
+#define MON_ALRM        0x00\r
+#define CENTURY         0x32\r
+#define IAPC_BOOT_ARCH  0x12    /* 8042 present, disable PCIe ASPM */\r
+#define FACP_FLAGS      (EFI_ACPI_1_0_WBINVD | EFI_ACPI_1_0_PROC_C1 |         \\r
+                        EFI_ACPI_1_0_SLP_BUTTON | EFI_ACPI_1_0_TMR_VAL_EXT |  \\r
+                        EFI_ACPI_2_0_RESET_REG_SUP |                          \\r
+                        EFI_ACPI_3_0_FORCE_APIC_PHYSICAL_DESTINATION_MODE)\r
+#define FACP_RESET_REG  {                                               \\r
+        EFI_ACPI_3_0_SYSTEM_IO,         /* Address Space ID */          \\r
+        8,                              /* Bit Width */                 \\r
+        0,                              /* Bit Offset */                \\r
+        EFI_ACPI_3_0_BYTE,              /* Byte Access */               \\r
+        0xCF9                           /* I/O Port */                  \\r
+}\r
+#define FACP_RESET_VAL  0x6\r
+#endif\r
diff --git a/OvmfPkg/Bhyve/AcpiTables/Spcr.aslc b/OvmfPkg/Bhyve/AcpiTables/Spcr.aslc
new file mode 100644 (file)
index 0000000..ec5114a
--- /dev/null
@@ -0,0 +1,63 @@
+/*\r
+ * Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+ * Copyright (c) 2015, Nahanni Systems, Inc.\r
+ *\r
+ * SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ */\r
+\r
+#include "Platform.h"\r
+\r
+#define EFI_ACPI_OEM_TABLE_ID     SIGNATURE_64('B','V','S','P','C','R',' ',' ')\r
+\r
+EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE SPCR = {\r
+  {\r
+    EFI_ACPI_2_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,\r
+    sizeof (EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE),\r
+    EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION,\r
+    0,                          // to make sum of entire table == 0\r
+    {EFI_ACPI_OEM_ID},          // OEMID is a 6 bytes long field\r
+    EFI_ACPI_OEM_TABLE_ID,      // OEM table identification(8 bytes long)\r
+    EFI_ACPI_OEM_REVISION,      // OEM revision number\r
+    EFI_ACPI_CREATOR_ID,        // ASL compiler vendor ID\r
+    EFI_ACPI_CREATOR_REVISION   // ASL compiler revision number\r
+  },\r
+  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERFACE_TYPE_16550,\r
+  { 0 },                        // Reserved\r
+  {                             // BaseAddress\r
+    0x01,                       //   AddressSpaceId\r
+    0x08,                       //   RegisterBitWidth\r
+    0x00,                       //   RegisterBitOffset\r
+    0x00,                       //   Reserved\r
+    0x03F8                      //   Address (COM1)\r
+  },\r
+  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_8259,\r
+  4,                            // Irq\r
+  0,                            // GlobalSystemInterrupt\r
+  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_115200,\r
+  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_PARITY_NO_PARITY,\r
+  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_STOP_BITS_1,\r
+  0x03,                         // FlowControl: RTS/CTS | DCD\r
+  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_TERMINAL_TYPE_VT_UTF8,\r
+  0,                            // Language\r
+  0,                            // PciDeviceId\r
+  0,                            // PciVendorId\r
+  0,                            // PciBusNumber\r
+  0,                            // PciDeviceNumber\r
+  0,                            // PciFunctionNumber\r
+  0,                            // PciFlags\r
+  0,                            // PciSegment\r
+  0                             // Reserved\r
+};\r
+\r
+\r
+VOID *\r
+ReferenceAcpiTable (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Reference the table being generated to prevent the optimizer from removing the\r
+  // data structure from the exeutable\r
+  //\r
+  return (VOID*)&SPCR;\r
+}\r
diff --git a/OvmfPkg/Bhyve/AcpiTables/Ssdt.asl b/OvmfPkg/Bhyve/AcpiTables/Ssdt.asl
new file mode 100644 (file)
index 0000000..175ab3b
--- /dev/null
@@ -0,0 +1,15 @@
+/** @file\r
+  Placeholder for runtime-generated objects.\r
+\r
+  This empty table provides only a header for dynamic copying and extension,\r
+  and a trigger for QemuInstallAcpiSsdtTable().\r
+\r
+  Copyright (C) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+  Copyright (C) 2012 Red Hat, Inc.\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+DefinitionBlock ("Ssdt.aml", "SSDT", 1, "REDHAT", "OVMF    ", 1) {\r
+}\r
diff --git a/OvmfPkg/Bhyve/BhyvePkg.dec b/OvmfPkg/Bhyve/BhyvePkg.dec
new file mode 100644 (file)
index 0000000..8884b62
--- /dev/null
@@ -0,0 +1,171 @@
+#\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
diff --git a/OvmfPkg/Bhyve/BhyvePkgDefines.fdf.inc b/OvmfPkg/Bhyve/BhyvePkgDefines.fdf.inc
new file mode 100644 (file)
index 0000000..66e0e4d
--- /dev/null
@@ -0,0 +1,85 @@
+## @file\r
+#  FDF include file that defines the main macros and sets the dependent PCDs.\r
+#\r
+#  Copyright (C) 2014, Red Hat, Inc.\r
+#  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+DEFINE BLOCK_SIZE        = 0x1000\r
+\r
+#\r
+# A firmware binary built with FD_SIZE_IN_KB=1024, and a firmware binary built\r
+# with FD_SIZE_IN_KB=2048, use the same variable store layout.\r
+#\r
+# Setting FD_SIZE_IN_KB to 4096 results in a different (much larger) variable\r
+# store structure that is incompatible with both of the above-mentioned\r
+# firmware binaries.\r
+#\r
+!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)\r
+DEFINE VARS_SIZE         = 0x20000\r
+DEFINE VARS_BLOCKS       = 0x20\r
+DEFINE VARS_LIVE_SIZE    = 0xE000\r
+DEFINE VARS_SPARE_SIZE   = 0x10000\r
+!endif\r
+\r
+!if $(FD_SIZE_IN_KB) == 1024\r
+DEFINE FW_BASE_ADDRESS   = 0xFFF00000\r
+DEFINE FW_SIZE           = 0x00100000\r
+DEFINE FW_BLOCKS         = 0x100\r
+DEFINE CODE_BASE_ADDRESS = 0xFFF20000\r
+DEFINE CODE_SIZE         = 0x000E0000\r
+DEFINE CODE_BLOCKS       = 0xE0\r
+DEFINE FVMAIN_SIZE       = 0x000CC000\r
+DEFINE SECFV_OFFSET      = 0x000EC000\r
+DEFINE SECFV_SIZE        = 0x14000\r
+!endif\r
+\r
+!if $(FD_SIZE_IN_KB) == 2048\r
+DEFINE FW_BASE_ADDRESS   = 0xFFE00000\r
+DEFINE FW_SIZE           = 0x00200000\r
+DEFINE FW_BLOCKS         = 0x200\r
+DEFINE CODE_BASE_ADDRESS = 0xFFE20000\r
+DEFINE CODE_SIZE         = 0x001E0000\r
+DEFINE CODE_BLOCKS       = 0x1E0\r
+DEFINE FVMAIN_SIZE       = 0x001AC000\r
+DEFINE SECFV_OFFSET      = 0x001CC000\r
+DEFINE SECFV_SIZE        = 0x34000\r
+!endif\r
+\r
+!if $(FD_SIZE_IN_KB) == 4096\r
+DEFINE VARS_SIZE         = 0x84000\r
+DEFINE VARS_BLOCKS       = 0x84\r
+DEFINE VARS_LIVE_SIZE    = 0x40000\r
+DEFINE VARS_SPARE_SIZE   = 0x42000\r
+\r
+DEFINE FW_BASE_ADDRESS   = 0xFFC00000\r
+DEFINE FW_SIZE           = 0x00400000\r
+DEFINE FW_BLOCKS         = 0x400\r
+DEFINE CODE_BASE_ADDRESS = 0xFFC84000\r
+DEFINE CODE_SIZE         = 0x0037C000\r
+DEFINE CODE_BLOCKS       = 0x37C\r
+DEFINE FVMAIN_SIZE       = 0x00348000\r
+DEFINE SECFV_OFFSET      = 0x003CC000\r
+DEFINE SECFV_SIZE        = 0x34000\r
+!endif\r
+\r
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress     = $(FW_BASE_ADDRESS)\r
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize    = $(FW_SIZE)\r
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize = $(BLOCK_SIZE)\r
+\r
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase = $(FW_BASE_ADDRESS)\r
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize = $(VARS_LIVE_SIZE)\r
+\r
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogBase = gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize\r
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize = $(BLOCK_SIZE)\r
+\r
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwWorkingBase = gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogBase + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageEventLogSize\r
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize = $(BLOCK_SIZE)\r
+\r
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwSpareBase = gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize\r
+SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize = $(VARS_SPARE_SIZE)\r
+\r
+DEFINE MEMFD_BASE_ADDRESS = 0x800000\r
diff --git a/OvmfPkg/Bhyve/BhyvePkgX64.dsc b/OvmfPkg/Bhyve/BhyvePkgX64.dsc
new file mode 100644 (file)
index 0000000..8eba48d
--- /dev/null
@@ -0,0 +1,847 @@
+#\r
+#  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+#  Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
+#  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
+#  Copyright (c) 2014, Pluribus Networks, Inc.\r
+#\r
+#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+################################################################################\r
+#\r
+# Defines Section - statements that will be processed to create a Makefile.\r
+#\r
+################################################################################\r
+[Defines]\r
+  PLATFORM_NAME                  = Bhyve\r
+  PLATFORM_GUID                  = 562b76ee-ceb2-4f4f-adfe-a4c8dc46e4ff\r
+  PLATFORM_VERSION               = 0.1\r
+  DSC_SPECIFICATION              = 0x00010005\r
+  OUTPUT_DIRECTORY               = Build/BhyveX64\r
+  SUPPORTED_ARCHITECTURES        = X64\r
+  BUILD_TARGETS                  = NOOPT|DEBUG|RELEASE\r
+  SKUID_IDENTIFIER               = DEFAULT\r
+  FLASH_DEFINITION               = OvmfPkg/Bhyve/BhyvePkgX64.fdf\r
+\r
+  #\r
+  # Defines for default states.  These can be changed on the command line.\r
+  # -D FLAG=VALUE\r
+  #\r
+  DEFINE SECURE_BOOT_ENABLE      = FALSE\r
+  DEFINE SMM_REQUIRE             = FALSE\r
+  DEFINE SOURCE_DEBUG_ENABLE     = FALSE\r
+  DEFINE TPM_ENABLE              = FALSE\r
+  DEFINE TPM_CONFIG_ENABLE       = FALSE\r
+\r
+  #\r
+  # Network definition\r
+  #\r
+  DEFINE NETWORK_TLS_ENABLE             = FALSE\r
+  DEFINE NETWORK_IP6_ENABLE             = FALSE\r
+  DEFINE NETWORK_HTTP_BOOT_ENABLE       = FALSE\r
+  DEFINE NETWORK_ALLOW_HTTP_CONNECTIONS = TRUE\r
+\r
+!include NetworkPkg/NetworkDefines.dsc.inc\r
+\r
+  #\r
+  # Flash size selection. Setting FD_SIZE_IN_KB on the command line directly to\r
+  # one of the supported values, in place of any of the convenience macros, is\r
+  # permitted.\r
+  #\r
+!ifdef $(FD_SIZE_1MB)\r
+  DEFINE FD_SIZE_IN_KB           = 1024\r
+!else\r
+!ifdef $(FD_SIZE_2MB)\r
+  DEFINE FD_SIZE_IN_KB           = 2048\r
+!else\r
+!ifdef $(FD_SIZE_4MB)\r
+  DEFINE FD_SIZE_IN_KB           = 4096\r
+!else\r
+  DEFINE FD_SIZE_IN_KB           = 4096\r
+!endif\r
+!endif\r
+!endif\r
+\r
+[BuildOptions]\r
+  GCC:RELEASE_*_*_CC_FLAGS             = -DMDEPKG_NDEBUG\r
+  INTEL:RELEASE_*_*_CC_FLAGS           = /D MDEPKG_NDEBUG\r
+  MSFT:RELEASE_*_*_CC_FLAGS            = /D MDEPKG_NDEBUG\r
+!if $(TOOL_CHAIN_TAG) != "XCODE5" && $(TOOL_CHAIN_TAG) != "CLANGPDB"\r
+  GCC:*_*_*_CC_FLAGS                   = -mno-mmx -mno-sse\r
+!endif\r
+!if $(SOURCE_DEBUG_ENABLE) == TRUE\r
+  MSFT:*_*_X64_GENFW_FLAGS  = --keepexceptiontable\r
+  GCC:*_*_X64_GENFW_FLAGS   = --keepexceptiontable\r
+  INTEL:*_*_X64_GENFW_FLAGS = --keepexceptiontable\r
+!endif\r
+\r
+  #\r
+  # Disable deprecated APIs.\r
+  #\r
+  MSFT:*_*_*_CC_FLAGS = /D DISABLE_NEW_DEPRECATED_INTERFACES\r
+  INTEL:*_*_*_CC_FLAGS = /D DISABLE_NEW_DEPRECATED_INTERFACES\r
+  GCC:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES\r
+\r
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]\r
+  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000\r
+  XCODE:*_*_*_DLINK_FLAGS = -seg1addr 0x1000 -segalign 0x1000\r
+  XCODE:*_*_*_MTOC_FLAGS = -align 0x1000\r
+  CLANGPDB:*_*_*_DLINK_FLAGS = /ALIGN:4096\r
+\r
+# Force PE/COFF sections to be aligned at 4KB boundaries to support page level\r
+# protection of DXE_SMM_DRIVER/SMM_CORE modules\r
+[BuildOptions.common.EDKII.DXE_SMM_DRIVER, BuildOptions.common.EDKII.SMM_CORE]\r
+  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000\r
+  XCODE:*_*_*_DLINK_FLAGS = -seg1addr 0x1000 -segalign 0x1000\r
+  XCODE:*_*_*_MTOC_FLAGS = -align 0x1000\r
+  CLANGPDB:*_*_*_DLINK_FLAGS = /ALIGN:4096\r
+\r
+################################################################################\r
+#\r
+# SKU Identification section - list of all SKU IDs supported by this Platform.\r
+#\r
+################################################################################\r
+[SkuIds]\r
+  0|DEFAULT\r
+\r
+################################################################################\r
+#\r
+# Library Class section - list of all Library Classes needed by this Platform.\r
+#\r
+################################################################################\r
+[LibraryClasses]\r
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf\r
+  TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLibBhyve.inf\r
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf\r
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf\r
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf\r
+  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf\r
+  BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf\r
+  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf\r
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf\r
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf\r
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf\r
+  CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf\r
+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf\r
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf\r
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf\r
+  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf\r
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf\r
+  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf\r
+  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf\r
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf\r
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf\r
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf\r
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf\r
+  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf\r
+  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf\r
+  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf\r
+  PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf\r
+  PciCapLib|OvmfPkg/Library/BasePciCapLib/BasePciCapLib.inf\r
+  PciCapPciSegmentLib|OvmfPkg/Library/BasePciCapPciSegmentLib/BasePciCapPciSegmentLib.inf\r
+  PciCapPciIoLib|OvmfPkg/Library/UefiPciCapPciIoLib/UefiPciCapPciIoLib.inf\r
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf\r
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf\r
+  SerialPortLib|PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf\r
+  MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf\r
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf\r
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf\r
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf\r
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf\r
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf\r
+  DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf\r
+  NvVarsFileLib|OvmfPkg/Library/NvVarsFileLib/NvVarsFileLib.inf\r
+  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf\r
+  UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf\r
+  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf\r
+  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
+  VirtioLib|OvmfPkg/Library/VirtioLib/VirtioLib.inf\r
+  MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/BaseMemEncryptSevLib.inf\r
+  LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf\r
+\r
+  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf\r
+  FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf\r
+\r
+!if $(SOURCE_DEBUG_ENABLE) == TRUE\r
+  PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf\r
+  DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf\r
+!else\r
+  PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf\r
+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf\r
+!endif\r
+\r
+  ResetSystemLib|OvmfPkg/Library/ResetSystemLib/BaseResetSystemLibBhyve.inf\r
+  LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf\r
+  IoApicLib|PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf\r
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf\r
+\r
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf\r
+!if $(NETWORK_TLS_ENABLE) == TRUE\r
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf\r
+!else\r
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf\r
+!endif\r
+\r
+!if $(SECURE_BOOT_ENABLE) == TRUE\r
+  PlatformSecureLib|OvmfPkg/Bhyve/Library/PlatformSecureLib/PlatformSecureLib.inf\r
+  AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf\r
+!else\r
+  AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf\r
+!endif\r
+  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf\r
+\r
+\r
+  #\r
+  # Network libraries\r
+  #\r
+!include NetworkPkg/NetworkLibs.dsc.inc\r
+\r
+!if $(NETWORK_TLS_ENABLE) == TRUE\r
+  TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf\r
+!endif\r
+\r
+  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf\r
+  ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf\r
+  S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf\r
+  SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf\r
+  OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf\r
+  XenPlatformLib|OvmfPkg/Library/XenPlatformLib/XenPlatformLib.inf\r
+\r
+\r
+!if $(TPM_ENABLE) == TRUE\r
+  Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf\r
+  Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibQemu/DxeTcg2PhysicalPresenceLib.inf\r
+  Tcg2PpVendorLib|SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.inf\r
+  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf\r
+!else\r
+  Tcg2PhysicalPresenceLib|OvmfPkg/Library/Tcg2PhysicalPresenceLibNull/DxeTcg2PhysicalPresenceLib.inf\r
+  TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf\r
+!endif\r
+\r
+[LibraryClasses.common]\r
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf\r
+\r
+[LibraryClasses.common.SEC]\r
+!ifdef $(DEBUG_ON_SERIAL_PORT)\r
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf\r
+!else\r
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformRomDebugLibIoPort.inf\r
+!endif\r
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf\r
+  ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf\r
+!if $(SOURCE_DEBUG_ENABLE) == TRUE\r
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf\r
+!endif\r
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf\r
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf\r
+  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf\r
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf\r
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf\r
+\r
+[LibraryClasses.common.PEI_CORE]\r
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf\r
+  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf\r
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf\r
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf\r
+  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf\r
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf\r
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf\r
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf\r
+!ifdef $(DEBUG_ON_SERIAL_PORT)\r
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf\r
+!else\r
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf\r
+!endif\r
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf\r
+\r
+[LibraryClasses.common.PEIM]\r
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf\r
+  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf\r
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf\r
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf\r
+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf\r
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf\r
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf\r
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf\r
+!ifdef $(DEBUG_ON_SERIAL_PORT)\r
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf\r
+!else\r
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf\r
+!endif\r
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf\r
+  ResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf\r
+  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf\r
+!if $(SOURCE_DEBUG_ENABLE) == TRUE\r
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf\r
+!endif\r
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf\r
+  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf\r
+\r
+!if $(TPM_ENABLE) == TRUE\r
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf\r
+  Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2DeviceLibDTpm.inf\r
+!endif\r
+\r
+[LibraryClasses.common.DXE_CORE]\r
+  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf\r
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf\r
+  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf\r
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf\r
+!ifdef $(DEBUG_ON_SERIAL_PORT)\r
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf\r
+!else\r
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf\r
+!endif\r
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf\r
+!if $(SOURCE_DEBUG_ENABLE) == TRUE\r
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf\r
+!endif\r
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf\r
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf\r
+\r
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]\r
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf\r
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf\r
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf\r
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf\r
+  ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf\r
+!ifdef $(DEBUG_ON_SERIAL_PORT)\r
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf\r
+!else\r
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf\r
+!endif\r
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf\r
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf\r
+  PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf\r
+\r
+[LibraryClasses.common.UEFI_DRIVER]\r
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf\r
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf\r
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf\r
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf\r
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf\r
+!ifdef $(DEBUG_ON_SERIAL_PORT)\r
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf\r
+!else\r
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf\r
+!endif\r
+  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf\r
+  PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf\r
+\r
+[LibraryClasses.common.DXE_DRIVER]\r
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf\r
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf\r
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf\r
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf\r
+  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf\r
+!ifdef $(DEBUG_ON_SERIAL_PORT)\r
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf\r
+!else\r
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf\r
+!endif\r
+  PlatformBootManagerLib|OvmfPkg/Bhyve/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf\r
+  PlatformBmPrintScLib|OvmfPkg/Library/PlatformBmPrintScLib/PlatformBmPrintScLib.inf\r
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf\r
+  LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf\r
+!if $(SOURCE_DEBUG_ENABLE) == TRUE\r
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf\r
+!endif\r
+  PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf\r
+  MpInitLib|UefiCpuPkg/Library/MpInitLibUp/MpInitLibUp.inf\r
+!if $(TPM_ENABLE) == TRUE\r
+  Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibTcg2/Tpm2DeviceLibTcg2.inf\r
+!endif\r
+\r
+[LibraryClasses.common.UEFI_APPLICATION]\r
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf\r
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf\r
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf\r
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf\r
+!ifdef $(DEBUG_ON_SERIAL_PORT)\r
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf\r
+!else\r
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf\r
+!endif\r
+  PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf\r
+\r
+[LibraryClasses.common.DXE_SMM_DRIVER]\r
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf\r
+  MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAllocationLib.inf\r
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf\r
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf\r
+  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf\r
+  MmServicesTableLib|MdePkg/Library/MmServicesTableLib/MmServicesTableLib.inf\r
+  SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf\r
+!ifdef $(DEBUG_ON_SERIAL_PORT)\r
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf\r
+!else\r
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf\r
+!endif\r
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuExceptionHandlerLib.inf\r
+!if $(SOURCE_DEBUG_ENABLE) == TRUE\r
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf\r
+!endif\r
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf\r
+  PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf\r
+\r
+[LibraryClasses.common.SMM_CORE]\r
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf\r
+  SmmCorePlatformHookLib|MdeModulePkg/Library/SmmCorePlatformHookLibNull/SmmCorePlatformHookLibNull.inf\r
+  MemoryAllocationLib|MdeModulePkg/Library/PiSmmCoreMemoryAllocationLib/PiSmmCoreMemoryAllocationLib.inf\r
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf\r
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf\r
+  SmmMemLib|MdePkg/Library/SmmMemLib/SmmMemLib.inf\r
+  SmmServicesTableLib|MdeModulePkg/Library/PiSmmCoreSmmServicesTableLib/PiSmmCoreSmmServicesTableLib.inf\r
+!ifdef $(DEBUG_ON_SERIAL_PORT)\r
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf\r
+!else\r
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf\r
+!endif\r
+  PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf\r
+\r
+################################################################################\r
+#\r
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform.\r
+#\r
+################################################################################\r
+[PcdsFeatureFlag]\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdHiiOsRuntimeSupport|FALSE\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportUefiDecompress|FALSE\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|FALSE\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE\r
+\r
+[PcdsFixedAtBuild]\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|TRUE\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE\r
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10\r
+!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800\r
+!if $(NETWORK_TLS_ENABLE) == FALSE\r
+  # match PcdFlashNvStorageVariableSize purely for convenience\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000\r
+!endif\r
+!endif\r
+!if $(FD_SIZE_IN_KB) == 4096\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x8400\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x8400\r
+!if $(NETWORK_TLS_ENABLE) == FALSE\r
+  # match PcdFlashNvStorageVariableSize purely for convenience\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x40000\r
+!endif\r
+!endif\r
+!if $(NETWORK_TLS_ENABLE) == TRUE\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0x80000\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVolatileVariableSize|0x40000\r
+!endif\r
+\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0\r
+\r
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07\r
+\r
+  # DEBUG_INIT      0x00000001  // Initialization\r
+  # DEBUG_WARN      0x00000002  // Warnings\r
+  # DEBUG_LOAD      0x00000004  // Load events\r
+  # DEBUG_FS        0x00000008  // EFI File system\r
+  # DEBUG_POOL      0x00000010  // Alloc & Free (pool)\r
+  # DEBUG_PAGE      0x00000020  // Alloc & Free (page)\r
+  # DEBUG_INFO      0x00000040  // Informational debug messages\r
+  # DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers\r
+  # DEBUG_VARIABLE  0x00000100  // Variable\r
+  # DEBUG_BM        0x00000400  // Boot Manager\r
+  # DEBUG_BLKIO     0x00001000  // BlkIo Driver\r
+  # DEBUG_NET       0x00004000  // SNP Driver\r
+  # DEBUG_UNDI      0x00010000  // UNDI Driver\r
+  # DEBUG_LOADFILE  0x00020000  // LoadFile\r
+  # DEBUG_EVENT     0x00080000  // Event messages\r
+  # DEBUG_GCD       0x00100000  // Global Coherency Database changes\r
+  # DEBUG_CACHE     0x00200000  // Memory range cachability changes\r
+  # DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may\r
+  #                             // significantly impact boot performance\r
+  # DEBUG_ERROR     0x80000000  // Error\r
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F\r
+\r
+!if $(SOURCE_DEBUG_ENABLE) == TRUE\r
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17\r
+!else\r
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F\r
+!endif\r
+\r
+  # This PCD is used to set the base address of the PCI express hierarchy. It\r
+  # is only consulted when OVMF runs on Q35. In that case it is programmed into\r
+  # the PCIEXBAR register.\r
+  #\r
+  # On Q35 machine types that QEMU intends to support in the long term, QEMU\r
+  # never lets the RAM below 4 GB exceed 2816 MB.\r
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xB0000000\r
+\r
+!if $(SOURCE_DEBUG_ENABLE) == TRUE\r
+  gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|0x2\r
+!endif\r
+\r
+  #\r
+  # Network Pcds\r
+  #\r
+!include NetworkPkg/NetworkPcds.dsc.inc\r
+\r
+  # Point to the MdeModulePkg/Application/UiApp/UiApp.inf\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }\r
+\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand|FALSE\r
+\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor|L"BHYVE"\r
+\r
+################################################################################\r
+#\r
+# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform\r
+#\r
+################################################################################\r
+\r
+[PcdsDynamicDefault]\r
+  # only set when\r
+  #   ($(SMM_REQUIRE) == FALSE)\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0\r
+\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|TRUE\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable|FALSE\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId|0\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase|0x0\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoSize|0x0\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Base|0x0\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Size|0x0\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Base|0x0\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Size|0x800000000\r
+\r
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|0\r
+\r
+  # Set video resolution for text setup.\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480\r
+\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE\r
+\r
+  # Noexec settings for DXE.\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE\r
+\r
+  # UefiCpuPkg PCDs related to initial AP bringup and general AP management.\r
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64\r
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000\r
+\r
+  # Set memory encryption mask\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask|0x0\r
+\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x00\r
+\r
+!if $(TPM_ENABLE) == TRUE\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}\r
+!endif\r
+\r
+  # MdeModulePkg resolution sets up the system display resolution\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|0\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|0\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|0\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|0\r
+\r
+[PcdsDynamicHii]\r
+!if $(TPM_ENABLE) == TRUE && $(TPM_CONFIG_ENABLE) == TRUE\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTcgPhysicalPresenceInterfaceVer|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x0|"1.3"|NV,BS\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableRev|L"TCG2_VERSION"|gTcg2ConfigFormSetGuid|0x8|3|NV,BS\r
+!endif\r
+\r
+################################################################################\r
+#\r
+# Components Section - list of all EDK II Modules needed by this Platform.\r
+#\r
+################################################################################\r
+[Components]\r
+  OvmfPkg/ResetVector/ResetVector.inf\r
+\r
+  #\r
+  # SEC Phase modules\r
+  #\r
+  OvmfPkg/Sec/SecMain.inf {\r
+    <LibraryClasses>\r
+      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf\r
+  }\r
+\r
+  #\r
+  # PEI Phase modules\r
+  #\r
+  MdeModulePkg/Core/Pei/PeiMain.inf\r
+  MdeModulePkg/Universal/PCD/Pei/Pcd.inf  {\r
+    <LibraryClasses>\r
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf\r
+  }\r
+  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf {\r
+    <LibraryClasses>\r
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf\r
+  }\r
+  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf {\r
+    <LibraryClasses>\r
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf\r
+  }\r
+  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf\r
+\r
+  OvmfPkg/Bhyve/PlatformPei/PlatformPei.inf\r
+  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf {\r
+    <LibraryClasses>\r
+  }\r
+\r
+!if $(TPM_ENABLE) == TRUE\r
+  OvmfPkg/Bhyve/Tcg/Tcg2Config/Tcg2ConfigPei.inf\r
+  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf {\r
+    <LibraryClasses>\r
+      HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf\r
+      NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf\r
+      NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf\r
+      NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf\r
+      NULL|SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.inf\r
+      NULL|SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.inf\r
+  }\r
+!endif\r
+\r
+  #\r
+  # DXE Phase modules\r
+  #\r
+  MdeModulePkg/Core/Dxe/DxeMain.inf {\r
+    <LibraryClasses>\r
+      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf\r
+      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf\r
+  }\r
+\r
+  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf\r
+  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf\r
+  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf  {\r
+   <LibraryClasses>\r
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf\r
+  }\r
+\r
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf\r
+\r
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {\r
+    <LibraryClasses>\r
+!if $(SECURE_BOOT_ENABLE) == TRUE\r
+      NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf\r
+!endif\r
+!if $(TPM_ENABLE) == TRUE\r
+      NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf\r
+!endif\r
+  }\r
+\r
+  MdeModulePkg/Universal/EbcDxe/EbcDxe.inf\r
+  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf\r
+  UefiCpuPkg/CpuDxe/CpuDxe.inf\r
+  PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf\r
+  OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf\r
+  OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf\r
+  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {\r
+    <LibraryClasses>\r
+      PciHostBridgeLib|OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf\r
+      NULL|OvmfPkg/Library/PlatformHasIoMmuLib/PlatformHasIoMmuLib.inf\r
+  }\r
+  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf {\r
+    <LibraryClasses>\r
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf\r
+  }\r
+  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf\r
+  MdeModulePkg/Universal/Metronome/Metronome.inf\r
+  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf\r
+  MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf\r
+  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf {\r
+    <LibraryClasses>\r
+!ifdef $(CSM_ENABLE)\r
+      NULL|OvmfPkg/Bhyve/Csm/CsmSupportLib/CsmSupportLib.inf\r
+      NULL|OvmfPkg/Csm/LegacyBootManagerLib/LegacyBootManagerLib.inf\r
+!endif\r
+  }\r
+  MdeModulePkg/Logo/LogoDxe.inf\r
+  MdeModulePkg/Application/UiApp/UiApp.inf {\r
+    <LibraryClasses>\r
+      NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf\r
+      NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf\r
+      NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf\r
+!ifdef $(CSM_ENABLE)\r
+      NULL|OvmfPkg/Csm/LegacyBootManagerLib/LegacyBootManagerLib.inf\r
+      NULL|OvmfPkg/Csm/LegacyBootMaintUiLib/LegacyBootMaintUiLib.inf\r
+!endif\r
+  }\r
+  OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf\r
+  OvmfPkg/Virtio10Dxe/Virtio10.inf\r
+  OvmfPkg/VirtioBlkDxe/VirtioBlk.inf\r
+  OvmfPkg/VirtioScsiDxe/VirtioScsi.inf\r
+  OvmfPkg/VirtioRngDxe/VirtioRng.inf\r
+  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf\r
+  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf\r
+  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf\r
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf\r
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf\r
+  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf {\r
+    <LibraryClasses>\r
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf\r
+  }\r
+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf\r
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf {\r
+    <LibraryClasses>\r
+      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf\r
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf\r
+  }\r
+  MdeModulePkg/Universal/PrintDxe/PrintDxe.inf\r
+  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf\r
+  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf\r
+  MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf\r
+  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf\r
+  FatPkg/EnhancedFatDxe/Fat.inf\r
+  MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf\r
+  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf\r
+  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf\r
+  OvmfPkg/SataControllerDxe/SataControllerDxe.inf\r
+  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf\r
+  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf\r
+  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf\r
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
+  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
+  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf\r
+  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf\r
+\r
+  OvmfPkg/Bhyve/BhyveRfbDxe/BhyveRfbDxe.inf {\r
+    <LibraryClasses>\r
+      BltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf\r
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf\r
+  }\r
+\r
+  #\r
+  # ISA Support\r
+  #\r
+  OvmfPkg/SioBusDxe/SioBusDxe.inf\r
+  MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf\r
+  MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf\r
+  MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf\r
+\r
+  #\r
+  # SMBIOS Support\r
+  #\r
+  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf\r
+  OvmfPkg/Bhyve/SmbiosPlatformDxe/SmbiosPlatformDxe.inf\r
+\r
+  #\r
+  # ACPI Support\r
+  #\r
+  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf\r
+  OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatformDxe.inf\r
+  OvmfPkg/Bhyve/AcpiTables/AcpiTables.inf\r
+  MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf\r
+  MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf\r
+  MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf\r
+\r
+  #\r
+  # Network Support\r
+  #\r
+!include NetworkPkg/NetworkComponents.dsc.inc\r
+\r
+!if $(NETWORK_TLS_ENABLE) == TRUE\r
+  NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf {\r
+    <LibraryClasses>\r
+      NULL|OvmfPkg/Bhyve/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf\r
+  }\r
+!endif\r
+  OvmfPkg/VirtioNetDxe/VirtioNet.inf\r
+\r
+!ifdef $(CSM_ENABLE)\r
+  IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf {\r
+    <LibraryClasses>\r
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf\r
+  }\r
+!endif\r
+#  OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf\r
+!ifdef $(CSM_ENABLE)\r
+  OvmfPkg/Bhyve/Csm/BhyveCsm16/BhyveCsm16.inf\r
+!endif\r
+\r
+!if $(TOOL_CHAIN_TAG) != "XCODE5"\r
+  ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf {\r
+    <PcdsFixedAtBuild>\r
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE\r
+  }\r
+!endif\r
+  ShellPkg/Application/Shell/Shell.inf {\r
+    <LibraryClasses>\r
+      ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf\r
+      NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf\r
+      NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf\r
+      NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf\r
+      NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf\r
+      NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf\r
+      NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf\r
+      NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf\r
+!if $(NETWORK_IP6_ENABLE) == TRUE\r
+      NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf\r
+!endif\r
+      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf\r
+      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf\r
+      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf\r
+\r
+    <PcdsFixedAtBuild>\r
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF\r
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE\r
+      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000\r
+  }\r
+\r
+!if $(SECURE_BOOT_ENABLE) == TRUE\r
+  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf\r
+  OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf\r
+!endif\r
+\r
+  OvmfPkg/PlatformDxe/Platform.inf\r
+  OvmfPkg/AmdSevDxe/AmdSevDxe.inf\r
+  OvmfPkg/IoMmuDxe/IoMmuDxe.inf\r
+\r
+\r
+  #\r
+  # Variable driver stack (non-SMM)\r
+  #\r
+  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf\r
+  OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf {\r
+    <LibraryClasses>\r
+      PlatformFvbLib|OvmfPkg/Library/EmuVariableFvbLib/EmuVariableFvbLib.inf\r
+  }\r
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf\r
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {\r
+    <LibraryClasses>\r
+      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf\r
+  }\r
+\r
+\r
+  #\r
+  # TPM support\r
+  #\r
+!if $(TPM_ENABLE) == TRUE\r
+  SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf {\r
+    <LibraryClasses>\r
+      Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterDxe.inf\r
+      NULL|SecurityPkg/Library/Tpm2DeviceLibDTpm/Tpm2InstanceLibDTpm.inf\r
+      HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf\r
+      NULL|SecurityPkg/Library/HashInstanceLibSha1/HashInstanceLibSha1.inf\r
+      NULL|SecurityPkg/Library/HashInstanceLibSha256/HashInstanceLibSha256.inf\r
+      NULL|SecurityPkg/Library/HashInstanceLibSha384/HashInstanceLibSha384.inf\r
+      NULL|SecurityPkg/Library/HashInstanceLibSha512/HashInstanceLibSha512.inf\r
+      NULL|SecurityPkg/Library/HashInstanceLibSm3/HashInstanceLibSm3.inf\r
+  }\r
+!if $(TPM_CONFIG_ENABLE) == TRUE\r
+  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf\r
+!endif\r
+!endif\r
diff --git a/OvmfPkg/Bhyve/BhyvePkgX64.fdf b/OvmfPkg/Bhyve/BhyvePkgX64.fdf
new file mode 100644 (file)
index 0000000..e2852aa
--- /dev/null
@@ -0,0 +1,490 @@
+#\r
+#  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+#  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
+#  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
+#  Copyright (c) 2014, Pluribus Networks, Inc.\r
+#\r
+#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+################################################################################\r
+\r
+[Defines]\r
+!include OvmfPkg/Bhyve/BhyvePkgDefines.fdf.inc\r
+\r
+#\r
+# Build the variable store and the firmware code as one unified flash device\r
+# image.\r
+#\r
+[FD.BHYVE]\r
+BaseAddress   = $(FW_BASE_ADDRESS)\r
+Size          = $(FW_SIZE)\r
+ErasePolarity = 1\r
+BlockSize     = $(BLOCK_SIZE)\r
+NumBlocks     = $(FW_BLOCKS)\r
+\r
+!include VarStore.fdf.inc\r
+\r
+$(VARS_SIZE)|$(FVMAIN_SIZE)\r
+FV = FVMAIN_COMPACT\r
+\r
+$(SECFV_OFFSET)|$(SECFV_SIZE)\r
+FV = SECFV\r
+\r
+#\r
+# Build the variable store and the firmware code as separate flash device\r
+# images.\r
+#\r
+[FD.BHYVE_VARS]\r
+BaseAddress   = $(FW_BASE_ADDRESS)\r
+Size          = $(VARS_SIZE)\r
+ErasePolarity = 1\r
+BlockSize     = $(BLOCK_SIZE)\r
+NumBlocks     = $(VARS_BLOCKS)\r
+\r
+!include VarStore.fdf.inc\r
+\r
+[FD.BHYVE_CODE]\r
+BaseAddress   = $(CODE_BASE_ADDRESS)\r
+Size          = $(CODE_SIZE)\r
+ErasePolarity = 1\r
+BlockSize     = $(BLOCK_SIZE)\r
+NumBlocks     = $(CODE_BLOCKS)\r
+\r
+0x00000000|$(FVMAIN_SIZE)\r
+FV = FVMAIN_COMPACT\r
+\r
+$(FVMAIN_SIZE)|$(SECFV_SIZE)\r
+FV = SECFV\r
+\r
+################################################################################\r
+\r
+[FD.MEMFD]\r
+BaseAddress   = $(MEMFD_BASE_ADDRESS)\r
+Size          = 0xC00000\r
+ErasePolarity = 1\r
+BlockSize     = 0x10000\r
+NumBlocks     = 0xC0\r
+\r
+0x000000|0x006000\r
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize\r
+\r
+0x006000|0x001000\r
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize\r
+\r
+0x007000|0x001000\r
+gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize\r
+\r
+0x010000|0x010000\r
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize\r
+\r
+0x020000|0x0E0000\r
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize\r
+FV = PEIFV\r
+\r
+0x100000|0xB00000\r
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize\r
+FV = DXEFV\r
+\r
+################################################################################\r
+\r
+[FV.SECFV]\r
+FvNameGuid         = 763BED0D-DE9F-48F5-81F1-3E90E1B1A015\r
+BlockSize          = 0x1000\r
+FvAlignment        = 16\r
+ERASE_POLARITY     = 1\r
+MEMORY_MAPPED      = TRUE\r
+STICKY_WRITE       = TRUE\r
+LOCK_CAP           = TRUE\r
+LOCK_STATUS        = TRUE\r
+WRITE_DISABLED_CAP = TRUE\r
+WRITE_ENABLED_CAP  = TRUE\r
+WRITE_STATUS       = TRUE\r
+WRITE_LOCK_CAP     = TRUE\r
+WRITE_LOCK_STATUS  = TRUE\r
+READ_DISABLED_CAP  = TRUE\r
+READ_ENABLED_CAP   = TRUE\r
+READ_STATUS        = TRUE\r
+READ_LOCK_CAP      = TRUE\r
+READ_LOCK_STATUS   = TRUE\r
+\r
+#\r
+# SEC Phase modules\r
+#\r
+# The code in this FV handles the initial firmware startup, and\r
+# decompresses the PEI and DXE FVs which handles the rest of the boot sequence.\r
+#\r
+INF  OvmfPkg/Sec/SecMain.inf\r
+\r
+INF  RuleOverride=RESET_VECTOR OvmfPkg/ResetVector/ResetVector.inf\r
+\r
+################################################################################\r
+[FV.PEIFV]\r
+FvNameGuid         = 6938079B-B503-4E3D-9D24-B28337A25806\r
+BlockSize          = 0x10000\r
+FvAlignment        = 16\r
+ERASE_POLARITY     = 1\r
+MEMORY_MAPPED      = TRUE\r
+STICKY_WRITE       = TRUE\r
+LOCK_CAP           = TRUE\r
+LOCK_STATUS        = TRUE\r
+WRITE_DISABLED_CAP = TRUE\r
+WRITE_ENABLED_CAP  = TRUE\r
+WRITE_STATUS       = TRUE\r
+WRITE_LOCK_CAP     = TRUE\r
+WRITE_LOCK_STATUS  = TRUE\r
+READ_DISABLED_CAP  = TRUE\r
+READ_ENABLED_CAP   = TRUE\r
+READ_STATUS        = TRUE\r
+READ_LOCK_CAP      = TRUE\r
+READ_LOCK_STATUS   = TRUE\r
+\r
+APRIORI PEI {\r
+  INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf\r
+}\r
+\r
+#\r
+#  PEI Phase modules\r
+#\r
+INF  MdeModulePkg/Core/Pei/PeiMain.inf\r
+INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf\r
+INF  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf\r
+INF  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf\r
+INF  OvmfPkg/Bhyve/PlatformPei/PlatformPei.inf\r
+INF  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf\r
+INF  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf\r
+!if $(SMM_REQUIRE) == TRUE\r
+INF  OvmfPkg/Bhyve/SmmAccess/SmmAccessPei.inf\r
+!endif\r
+\r
+!if $(TPM_ENABLE) == TRUE\r
+INF  OvmfPkg/Bhyve/Tcg/Tcg2Config/Tcg2ConfigPei.inf\r
+INF  SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf\r
+!endif\r
+\r
+################################################################################\r
+\r
+[FV.DXEFV]\r
+FvForceRebase      = FALSE\r
+FvNameGuid         = 7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1\r
+BlockSize          = 0x10000\r
+FvAlignment        = 16\r
+ERASE_POLARITY     = 1\r
+MEMORY_MAPPED      = TRUE\r
+STICKY_WRITE       = TRUE\r
+LOCK_CAP           = TRUE\r
+LOCK_STATUS        = TRUE\r
+WRITE_DISABLED_CAP = TRUE\r
+WRITE_ENABLED_CAP  = TRUE\r
+WRITE_STATUS       = TRUE\r
+WRITE_LOCK_CAP     = TRUE\r
+WRITE_LOCK_STATUS  = TRUE\r
+READ_DISABLED_CAP  = TRUE\r
+READ_ENABLED_CAP   = TRUE\r
+READ_STATUS        = TRUE\r
+READ_LOCK_CAP      = TRUE\r
+READ_LOCK_STATUS   = TRUE\r
+\r
+APRIORI DXE {\r
+  INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf\r
+  INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf\r
+  INF  OvmfPkg/AmdSevDxe/AmdSevDxe.inf\r
+!if $(SMM_REQUIRE) == FALSE\r
+  INF  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf\r
+!endif\r
+}\r
+\r
+#\r
+# DXE Phase modules\r
+#\r
+INF  MdeModulePkg/Core/Dxe/DxeMain.inf\r
+\r
+INF  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf\r
+INF  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf\r
+INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf\r
+\r
+INF  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf\r
+INF  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf\r
+INF  MdeModulePkg/Universal/EbcDxe/EbcDxe.inf\r
+INF  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf\r
+INF  UefiCpuPkg/CpuDxe/CpuDxe.inf\r
+INF  PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf\r
+INF  OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf\r
+INF  OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf\r
+INF  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf\r
+INF  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf\r
+INF  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf\r
+INF  MdeModulePkg/Universal/Metronome/Metronome.inf\r
+INF  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf\r
+\r
+INF  OvmfPkg/VirtioPciDeviceDxe/VirtioPciDeviceDxe.inf\r
+INF  OvmfPkg/Virtio10Dxe/Virtio10.inf\r
+INF  OvmfPkg/VirtioBlkDxe/VirtioBlk.inf\r
+INF  OvmfPkg/VirtioScsiDxe/VirtioScsi.inf\r
+INF  OvmfPkg/VirtioRngDxe/VirtioRng.inf\r
+\r
+!if $(SECURE_BOOT_ENABLE) == TRUE\r
+  INF  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf\r
+!endif\r
+\r
+INF  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf\r
+INF  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf\r
+INF  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf\r
+INF  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf\r
+INF  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf\r
+INF  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf\r
+INF  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf\r
+INF  MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf\r
+INF  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf\r
+INF  MdeModulePkg/Application/UiApp/UiApp.inf\r
+INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf\r
+INF  MdeModulePkg/Universal/PrintDxe/PrintDxe.inf\r
+INF  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf\r
+INF  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf\r
+INF  MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf\r
+INF  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf\r
+INF  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf\r
+INF  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf\r
+INF  OvmfPkg/SataControllerDxe/SataControllerDxe.inf\r
+INF  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf\r
+INF  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf\r
+INF  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf\r
+INF  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf\r
+INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf\r
+INF  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf\r
+INF  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf\r
+\r
+\r
+INF  OvmfPkg/SioBusDxe/SioBusDxe.inf\r
+INF  MdeModulePkg/Bus/Pci/PciSioSerialDxe/PciSioSerialDxe.inf\r
+INF  MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf\r
+INF  MdeModulePkg/Bus/Isa/Ps2MouseDxe/Ps2MouseDxe.inf\r
+\r
+INF  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf\r
+INF  OvmfPkg/Bhyve/SmbiosPlatformDxe/SmbiosPlatformDxe.inf\r
+\r
+INF  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf\r
+INF  OvmfPkg/Bhyve/AcpiPlatformDxe/AcpiPlatformDxe.inf\r
+INF  RuleOverride=ACPITABLE OvmfPkg/Bhyve/AcpiTables/AcpiTables.inf\r
+INF  MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf\r
+INF  MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf\r
+INF  MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf\r
+\r
+INF  FatPkg/EnhancedFatDxe/Fat.inf\r
+INF  MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf\r
+\r
+!if $(TOOL_CHAIN_TAG) != "XCODE5"\r
+INF  ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf\r
+!endif\r
+INF  ShellPkg/Application/Shell/Shell.inf\r
+\r
+INF MdeModulePkg/Logo/LogoDxe.inf\r
+\r
+#\r
+# Network modules\r
+#\r
+!if $(E1000_ENABLE)\r
+  FILE DRIVER = 5D695E11-9B3F-4b83-B25F-4A8D5D69BE07 {\r
+    SECTION PE32 = Intel3.5/EFIX64/E3522X2.EFI\r
+  }\r
+!endif\r
+!include NetworkPkg/Network.fdf.inc\r
+  INF  OvmfPkg/VirtioNetDxe/VirtioNet.inf\r
+\r
+!ifdef $(CSM_ENABLE)\r
+INF  IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf\r
+!endif\r
+#INF  OvmfPkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf\r
+!ifdef $(CSM_ENABLE)\r
+INF  RuleOverride=CSM OvmfPkg/Bhyve/Csm/BhyveCsm16/BhyveCsm16.inf\r
+!endif\r
+\r
+INF  OvmfPkg/PlatformDxe/Platform.inf\r
+INF  OvmfPkg/AmdSevDxe/AmdSevDxe.inf\r
+INF  OvmfPkg/IoMmuDxe/IoMmuDxe.inf\r
+INF  OvmfPkg/Bhyve/BhyveRfbDxe/BhyveRfbDxe.inf\r
+\r
+!if $(SMM_REQUIRE) == TRUE\r
+INF  OvmfPkg/Bhyve/SmmAccess/SmmAccess2Dxe.inf\r
+INF  OvmfPkg/Bhyve/SmmControl2Dxe/SmmControl2Dxe.inf\r
+INF  UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf\r
+INF  MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf\r
+INF  MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf\r
+INF  UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf\r
+INF  MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf\r
+INF  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf\r
+\r
+#\r
+# Variable driver stack (SMM)\r
+#\r
+INF  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf\r
+INF  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf\r
+INF  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf\r
+INF  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf\r
+\r
+!else\r
+\r
+#\r
+# Variable driver stack (non-SMM)\r
+#\r
+INF  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf\r
+INF  OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf\r
+INF  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf\r
+INF  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf\r
+!endif\r
+\r
+#\r
+# TPM support\r
+#\r
+!if $(TPM_ENABLE) == TRUE\r
+INF  SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf\r
+!if $(TPM_CONFIG_ENABLE) == TRUE\r
+INF  SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf\r
+!endif\r
+!endif\r
+\r
+################################################################################\r
+\r
+[FV.FVMAIN_COMPACT]\r
+FvNameGuid         = 48DB5E17-707C-472D-91CD-1613E7EF51B0\r
+FvAlignment        = 16\r
+ERASE_POLARITY     = 1\r
+MEMORY_MAPPED      = TRUE\r
+STICKY_WRITE       = TRUE\r
+LOCK_CAP           = TRUE\r
+LOCK_STATUS        = TRUE\r
+WRITE_DISABLED_CAP = TRUE\r
+WRITE_ENABLED_CAP  = TRUE\r
+WRITE_STATUS       = TRUE\r
+WRITE_LOCK_CAP     = TRUE\r
+WRITE_LOCK_STATUS  = TRUE\r
+READ_DISABLED_CAP  = TRUE\r
+READ_ENABLED_CAP   = TRUE\r
+READ_STATUS        = TRUE\r
+READ_LOCK_CAP      = TRUE\r
+READ_LOCK_STATUS   = TRUE\r
+\r
+FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {\r
+   SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {\r
+     #\r
+     # These firmware volumes will have files placed in them uncompressed,\r
+     # and then both firmware volumes will be compressed in a single\r
+     # compression operation in order to achieve better overall compression.\r
+     #\r
+     SECTION FV_IMAGE = PEIFV\r
+     SECTION FV_IMAGE = DXEFV\r
+   }\r
+ }\r
+\r
+!include FvmainCompactScratchEnd.fdf.inc\r
+\r
+################################################################################\r
+\r
+[Rule.Common.SEC]\r
+  FILE SEC = $(NAMED_GUID) {\r
+    PE32     PE32           $(INF_OUTPUT)/$(MODULE_NAME).efi\r
+    UI       STRING ="$(MODULE_NAME)" Optional\r
+    VERSION  STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)\r
+  }\r
+\r
+[Rule.Common.PEI_CORE]\r
+  FILE PEI_CORE = $(NAMED_GUID) {\r
+    PE32     PE32   Align=Auto    $(INF_OUTPUT)/$(MODULE_NAME).efi\r
+    UI       STRING ="$(MODULE_NAME)" Optional\r
+    VERSION  STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)\r
+  }\r
+\r
+[Rule.Common.PEIM]\r
+  FILE PEIM = $(NAMED_GUID) {\r
+     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex\r
+     PE32      PE32   Align=Auto         $(INF_OUTPUT)/$(MODULE_NAME).efi\r
+     UI       STRING="$(MODULE_NAME)" Optional\r
+     VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)\r
+  }\r
+\r
+[Rule.Common.DXE_CORE]\r
+  FILE DXE_CORE = $(NAMED_GUID) {\r
+    PE32     PE32           $(INF_OUTPUT)/$(MODULE_NAME).efi\r
+    UI       STRING="$(MODULE_NAME)" Optional\r
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)\r
+  }\r
+\r
+[Rule.Common.DXE_DRIVER]\r
+  FILE DRIVER = $(NAMED_GUID) {\r
+    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex\r
+    PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi\r
+    UI       STRING="$(MODULE_NAME)" Optional\r
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)\r
+    RAW ACPI  Optional               |.acpi\r
+    RAW ASL   Optional               |.aml\r
+  }\r
+\r
+[Rule.Common.DXE_RUNTIME_DRIVER]\r
+  FILE DRIVER = $(NAMED_GUID) {\r
+    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex\r
+    PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi\r
+    UI       STRING="$(MODULE_NAME)" Optional\r
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)\r
+  }\r
+\r
+[Rule.Common.UEFI_DRIVER]\r
+  FILE DRIVER = $(NAMED_GUID) {\r
+    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex\r
+    PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi\r
+    UI       STRING="$(MODULE_NAME)" Optional\r
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)\r
+  }\r
+\r
+[Rule.Common.UEFI_DRIVER.BINARY]\r
+  FILE DRIVER = $(NAMED_GUID) {\r
+    DXE_DEPEX DXE_DEPEX Optional      |.depex\r
+    PE32      PE32                    |.efi\r
+    UI        STRING="$(MODULE_NAME)" Optional\r
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)\r
+  }\r
+\r
+[Rule.Common.UEFI_APPLICATION]\r
+  FILE APPLICATION = $(NAMED_GUID) {\r
+    PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi\r
+    UI       STRING="$(MODULE_NAME)" Optional\r
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)\r
+  }\r
+\r
+[Rule.Common.UEFI_APPLICATION.BINARY]\r
+  FILE APPLICATION = $(NAMED_GUID) {\r
+    PE32      PE32                    |.efi\r
+    UI        STRING="$(MODULE_NAME)" Optional\r
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)\r
+  }\r
+\r
+[Rule.Common.USER_DEFINED.ACPITABLE]\r
+  FILE FREEFORM = $(NAMED_GUID) {\r
+    RAW ACPI               |.acpi\r
+    RAW ASL                |.aml\r
+  }\r
+\r
+[Rule.Common.USER_DEFINED.CSM]\r
+  FILE FREEFORM = $(NAMED_GUID) {\r
+    RAW BIN                |.bin\r
+  }\r
+\r
+[Rule.Common.SEC.RESET_VECTOR]\r
+  FILE RAW = $(NAMED_GUID) {\r
+    RAW BIN   Align = 16   |.bin\r
+  }\r
+\r
+[Rule.Common.SMM_CORE]\r
+  FILE SMM_CORE = $(NAMED_GUID) {\r
+    PE32     PE32           $(INF_OUTPUT)/$(MODULE_NAME).efi\r
+    UI       STRING="$(MODULE_NAME)" Optional\r
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)\r
+  }\r
+\r
+[Rule.Common.DXE_SMM_DRIVER]\r
+  FILE SMM = $(NAMED_GUID) {\r
+    SMM_DEPEX    SMM_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex\r
+    PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi\r
+    UI       STRING="$(MODULE_NAME)" Optional\r
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)\r
+  }\r
diff --git a/OvmfPkg/Bhyve/BhyveRfbDxe/BhyveRfbDxe.inf b/OvmfPkg/Bhyve/BhyveRfbDxe/BhyveRfbDxe.inf
new file mode 100644 (file)
index 0000000..8fd72cb
--- /dev/null
@@ -0,0 +1,68 @@
+## @file\r
+# GOP driver\r
+#\r
+# Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+# Portions copyright (c) 2011, Apple Inc. All rights reserved.\r
+#\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = EmuGopDxe\r
+  FILE_GUID                      = 1b290126-5760-424e-8aa2-3faf4d0d7978\r
+  MODULE_TYPE                    = UEFI_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+\r
+  ENTRY_POINT                    = InitializeEmuGop\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
+#  DRIVER_BINDING                =  gEmuGopDriverBinding\r
+#  COMPONENT_NAME                =  gEmuGopComponentName\r
+#\r
+\r
+[Sources]\r
+  ComponentName.c\r
+  GopScreen.c\r
+  GopDriver.c\r
+  Gop.h\r
+  VbeShim.c\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  OvmfPkg/Bhyve/BhyvePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  BaseMemoryLib\r
+  BltLib\r
+  DebugLib\r
+  DevicePathLib\r
+  MemoryAllocationLib\r
+  PciLib\r
+  PcdLib\r
+  PrintLib\r
+  UefiLib\r
+  UefiBootServicesTableLib\r
+  UefiDriverEntryPoint\r
+\r
+\r
+[Protocols]\r
+  gEfiGraphicsOutputProtocolGuid   # PROTOCOL BY_START\r
+  gEfiDevicePathProtocolGuid       # PROTOCOL TO_START\r
+  gEfiPciIoProtocolGuid            # PROTOCOL TO_START\r
+\r
+[Pcd]\r
+#  gOptionRomPkgTokenSpaceGuid.PcdDriverSupportedEfiVersion\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution\r
+\r
diff --git a/OvmfPkg/Bhyve/BhyveRfbDxe/ComponentName.c b/OvmfPkg/Bhyve/BhyveRfbDxe/ComponentName.c
new file mode 100644 (file)
index 0000000..673cd23
--- /dev/null
@@ -0,0 +1,201 @@
+/** @file\r
+\r
+Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
+Portions copyright (c) 2010,Apple Inc. All rights reserved.<BR>\r
+\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+Module Name:\r
+\r
+  ComponentName.c\r
+\r
+Abstract:\r
+\r
+**/\r
+\r
+#include "Gop.h"\r
+\r
+//\r
+// EFI Component Name Functions\r
+//\r
+EFI_STATUS\r
+EFIAPI\r
+EmuGopComponentNameGetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **DriverName\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EmuGopComponentNameGetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,\r
+  IN  EFI_HANDLE                                      ControllerHandle,\r
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,\r
+  IN  CHAR8                                           *Language,\r
+  OUT CHAR16                                          **ControllerName\r
+  );\r
+\r
+//\r
+// EFI Component Name Protocol\r
+//\r
+EFI_COMPONENT_NAME_PROTOCOL     gEmuGopComponentName = {\r
+  EmuGopComponentNameGetDriverName,\r
+  EmuGopComponentNameGetControllerName,\r
+  "eng"\r
+};\r
+\r
+//\r
+// EFI Component Name 2 Protocol\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gEmuGopComponentName2 = {\r
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) EmuGopComponentNameGetDriverName,\r
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) EmuGopComponentNameGetControllerName,\r
+  "en"\r
+};\r
+\r
+\r
+EFI_UNICODE_STRING_TABLE mEmuGopDriverNameTable[] = {\r
+  { "eng", L"Emulator GOP Driver" },\r
+  { NULL , NULL }\r
+};\r
+\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the driver.\r
+\r
+  This function retrieves the user readable name of a driver in the form of a\r
+  Unicode string. If the driver specified by This has a user readable name in\r
+  the language specified by Language, then a pointer to the driver name is\r
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
+  by This does not support the language specified by Language,\r
+  then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+  @param  Language[in]          A pointer to a Null-terminated ASCII string\r
+                                array indicating the language. This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified\r
+                                in RFC 4646 or ISO 639-2 language code format.\r
+\r
+  @param  DriverName[out]       A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                driver specified by This in the language\r
+                                specified by Language.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by\r
+                                This and the language specified by Language was\r
+                                returned in DriverName.\r
+\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EmuGopComponentNameGetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **DriverName\r
+  )\r
+{\r
+  return LookupUnicodeString2 (\r
+           Language,\r
+           This->SupportedLanguages,\r
+           mEmuGopDriverNameTable,\r
+           DriverName,\r
+           (BOOLEAN)(This == &gEmuGopComponentName)\r
+           );\r
+}\r
+\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the controller\r
+  that is being managed by a driver.\r
+\r
+  This function retrieves the user readable name of the controller specified by\r
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
+  driver specified by This has a user readable name in the language specified by\r
+  Language, then a pointer to the controller name is returned in ControllerName,\r
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently\r
+  managing the controller specified by ControllerHandle and ChildHandle,\r
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not\r
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+  @param  ControllerHandle[in]  The handle of a controller that the driver\r
+                                specified by This is managing.  This handle\r
+                                specifies the controller whose name is to be\r
+                                returned.\r
+\r
+  @param  ChildHandle[in]       The handle of the child controller to retrieve\r
+                                the name of.  This is an optional parameter that\r
+                                may be NULL.  It will be NULL for device\r
+                                drivers.  It will also be NULL for a bus drivers\r
+                                that wish to retrieve the name of the bus\r
+                                controller.  It will not be NULL for a bus\r
+                                driver that wishes to retrieve the name of a\r
+                                child controller.\r
+\r
+  @param  Language[in]          A pointer to a Null-terminated ASCII string\r
+                                array indicating the language.  This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified in\r
+                                RFC 4646 or ISO 639-2 language code format.\r
+\r
+  @param  ControllerName[out]   A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                controller specified by ControllerHandle and\r
+                                ChildHandle in the language specified by\r
+                                Language from the point of view of the driver\r
+                                specified by This.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in\r
+                                the language specified by Language for the\r
+                                driver specified by This was returned in\r
+                                DriverName.\r
+\r
+  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.\r
+\r
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
+                                EFI_HANDLE.\r
+\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently\r
+                                managing the controller specified by\r
+                                ControllerHandle and ChildHandle.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EmuGopComponentNameGetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,\r
+  IN  EFI_HANDLE                                      ControllerHandle,\r
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,\r
+  IN  CHAR8                                           *Language,\r
+  OUT CHAR16                                          **ControllerName\r
+  )\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r
diff --git a/OvmfPkg/Bhyve/BhyveRfbDxe/Gop.h b/OvmfPkg/Bhyve/BhyveRfbDxe/Gop.h
new file mode 100644 (file)
index 0000000..d196a8e
--- /dev/null
@@ -0,0 +1,149 @@
+/*++ @file\r
+\r
+Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>\r
+Portions copyright (c) 2010,Apple Inc. All rights reserved.<BR>\r
+\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef __UGA_H_\r
+#define __UGA_H_\r
+\r
+#include <Uefi.h>\r
+#include <Protocol/GraphicsOutput.h>\r
+#include <Protocol/PciIo.h>\r
+#include <Protocol/DriverSupportedEfiVersion.h>\r
+#include <Protocol/DevicePath.h>\r
+\r
+#include <Guid/EventGroup.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DevicePathLib.h>\r
+\r
+#include <IndustryStandard/Pci.h>\r
+\r
+#define GRAPHICS_OUTPUT_INVALID_MODE_NUMBER 0xffff\r
+\r
+typedef struct {\r
+  UINT32                     HorizontalResolution;\r
+  UINT32                     VerticalResolution;\r
+  UINT32                     ColorDepth;\r
+  UINT32                     RefreshRate;\r
+} GOP_MODE_DATA;\r
+\r
+#define PIXEL_RED_SHIFT   0\r
+#define PIXEL_GREEN_SHIFT 3\r
+#define PIXEL_BLUE_SHIFT  6\r
+\r
+#define PIXEL_RED_MASK    (BIT7 | BIT6 | BIT5)\r
+#define PIXEL_GREEN_MASK  (BIT4 | BIT3 | BIT2)\r
+#define PIXEL_BLUE_MASK   (BIT1 | BIT0)\r
+\r
+#define PIXEL_TO_COLOR_BYTE(pixel, mask, shift) ((UINT8) ((pixel & mask) << shift))\r
+#define PIXEL_TO_RED_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel, PIXEL_RED_MASK, PIXEL_RED_SHIFT)\r
+#define PIXEL_TO_GREEN_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel, PIXEL_GREEN_MASK, PIXEL_GREEN_SHIFT)\r
+#define PIXEL_TO_BLUE_BYTE(pixel) PIXEL_TO_COLOR_BYTE(pixel, PIXEL_BLUE_MASK, PIXEL_BLUE_SHIFT)\r
+\r
+#define RGB_BYTES_TO_PIXEL(Red, Green, Blue) \\r
+  (UINT8) ( (((Red) >> PIXEL_RED_SHIFT) & PIXEL_RED_MASK) | \\r
+            (((Green) >> PIXEL_GREEN_SHIFT) & PIXEL_GREEN_MASK) | \\r
+            (((Blue) >> PIXEL_BLUE_SHIFT) & PIXEL_BLUE_MASK) )\r
+\r
+#define PIXEL24_RED_MASK    0x00ff0000\r
+#define PIXEL24_GREEN_MASK  0x0000ff00\r
+#define PIXEL24_BLUE_MASK   0x000000ff\r
+\r
+extern EFI_DRIVER_BINDING_PROTOCOL gEmuGopDriverBinding;\r
+extern EFI_COMPONENT_NAME_PROTOCOL gEmuGopComponentName;\r
+\r
+#define EMU_UGA_CLASS_NAME       L"EmuGopWindow"\r
+\r
+#define GOP_PRIVATE_DATA_SIGNATURE  SIGNATURE_32 ('G', 'o', 'p', 'N')\r
+typedef struct {\r
+  UINT64                            Signature;\r
+\r
+  EFI_HANDLE                        Handle;\r
+  EFI_PCI_IO_PROTOCOL               *PciIo;\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL      GraphicsOutput;\r
+  EFI_DEVICE_PATH_PROTOCOL          *GopDevicePath;\r
+\r
+  EFI_UNICODE_STRING_TABLE          *ControllerNameTable;\r
+\r
+  //\r
+  // GOP Private Data for QueryMode ()\r
+  //\r
+  GOP_MODE_DATA                     *ModeData;\r
+\r
+  UINT64                            FbAddr;\r
+  UINT32                            FbSize;\r
+} GOP_PRIVATE_DATA;\r
+\r
+\r
+#define GOP_PRIVATE_DATA_FROM_THIS(a)  \\r
+         CR(a, GOP_PRIVATE_DATA, GraphicsOutput, GOP_PRIVATE_DATA_SIGNATURE)\r
+\r
+typedef struct {\r
+  UINT32            FbSize;\r
+  UINT16            Width;\r
+  UINT16            Height;\r
+  UINT16            Depth;\r
+  UINT16            RefreshRate;\r
+} BHYVE_FBUF_MEMREGS;\r
+\r
+//\r
+// Global Protocol Variables\r
+//\r
+extern EFI_DRIVER_BINDING_PROTOCOL  gEmuGopDriverBinding;\r
+extern EFI_COMPONENT_NAME_PROTOCOL  gEmuGopComponentName;\r
+extern EFI_COMPONENT_NAME2_PROTOCOL gEmuGopComponentName2;\r
+\r
+//\r
+// Gop Hardware abstraction internal worker functions\r
+//\r
+EFI_STATUS\r
+EmuGopConstructor (\r
+  IN  GOP_PRIVATE_DATA    *Private\r
+  );\r
+\r
+EFI_STATUS\r
+EmuGopDestructor (\r
+  IN  GOP_PRIVATE_DATA    *Private\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+ShutdownGopEvent (\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
+  );\r
+\r
+VOID\r
+BhyveSetGraphicsMode (\r
+  GOP_PRIVATE_DATA  *Private,\r
+  UINT16             Width,\r
+  UINT16             Height,\r
+  UINT16             Depth\r
+  );\r
+\r
+VOID\r
+BhyveGetMemregs (\r
+  GOP_PRIVATE_DATA  *Private,\r
+  BHYVE_FBUF_MEMREGS *Memregs\r
+  );\r
+\r
+VOID\r
+InstallVbeShim (\r
+  IN CONST CHAR16         *CardName,\r
+  IN EFI_PHYSICAL_ADDRESS FrameBufferBase\r
+  );\r
+\r
+#endif\r
diff --git a/OvmfPkg/Bhyve/BhyveRfbDxe/GopDriver.c b/OvmfPkg/Bhyve/BhyveRfbDxe/GopDriver.c
new file mode 100644 (file)
index 0000000..bab4fbd
--- /dev/null
@@ -0,0 +1,543 @@
+/*++ @file\r
+\r
+Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
+Portions copyright (c) 2010,Apple Inc. All rights reserved.<BR>\r
+\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "Gop.h"\r
+#include <IndustryStandard/Acpi.h>\r
+\r
+STATIC VOID\r
+BhyveGetGraphicsMode (\r
+  EFI_PCI_IO_PROTOCOL *PciIo,\r
+  UINT16              *Width,\r
+  UINT16              *Height,\r
+  UINT16              *Depth\r
+  );\r
+\r
+\r
+/**\r
+  Tests to see if this driver supports a given controller. If a child device is provided,\r
+  it further tests to see if this driver supports creating a handle for the specified child device.\r
+\r
+  This function checks to see if the driver specified by This supports the device specified by\r
+  ControllerHandle. Drivers will typically use the device path attached to\r
+  ControllerHandle and/or the services from the bus I/O abstraction attached to\r
+  ControllerHandle to determine if the driver supports ControllerHandle. This function\r
+  may be called many times during platform initialization. In order to reduce boot times, the tests\r
+  performed by this function must be very small, and take as little time as possible to execute. This\r
+  function must not change the state of any hardware devices, and this function must be aware that the\r
+  device specified by ControllerHandle may already be managed by the same driver or a\r
+  different driver. This function must match its calls to AllocatePages() with FreePages(),\r
+  AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().\r
+  Because ControllerHandle may have been previously started by the same driver, if a protocol is\r
+  already in the opened state, then it must not be closed with CloseProtocol(). This is required\r
+  to guarantee the state of ControllerHandle is not modified by this function.\r
+\r
+  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+  @param[in]  ControllerHandle     The handle of the controller to test. This handle\r
+                                   must support a protocol interface that supplies\r
+                                   an I/O abstraction to the driver.\r
+  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This\r
+                                   parameter is ignored by device drivers, and is optional for bus\r
+                                   drivers. For bus drivers, if this parameter is not NULL, then\r
+                                   the bus driver must determine if the bus controller specified\r
+                                   by ControllerHandle and the child controller specified\r
+                                   by RemainingDevicePath are both supported by this\r
+                                   bus driver.\r
+\r
+  @retval EFI_SUCCESS              The device specified by ControllerHandle and\r
+                                   RemainingDevicePath is supported by the driver specified by This.\r
+  @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and\r
+                                   RemainingDevicePath is already being managed by the driver\r
+                                   specified by This.\r
+  @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and\r
+                                   RemainingDevicePath is already being managed by a different\r
+                                   driver or an application that requires exclusive access.\r
+                                   Currently not implemented.\r
+  @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and\r
+                                   RemainingDevicePath is not supported by the driver specified by This.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EmuGopDriverBindingSupported (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,\r
+  IN  EFI_HANDLE                      Handle,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_PCI_IO_PROTOCOL       *PciIo;\r
+  PCI_TYPE00                Pci;\r
+  UINT16                    Width, Height, Depth;\r
+\r
+  //\r
+  // Open the IO Abstraction(s) needed to perform the supported test\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Handle,\r
+                  &gEfiPciIoProtocolGuid,\r
+                  (VOID **) &PciIo,\r
+                  This->DriverBindingHandle,\r
+                  Handle,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // See if this is a PCI Framebuffer Controller by looking at the Command register and\r
+  // Class Code Register\r
+  //\r
+  Status = PciIo->Pci.Read (\r
+                        PciIo,\r
+                        EfiPciIoWidthUint32,\r
+                        PCI_BAR_IDX0,\r
+                        sizeof (Pci) / sizeof (UINT32),\r
+                        &Pci\r
+                        );\r
+  if (EFI_ERROR (Status)) {\r
+    Status = EFI_UNSUPPORTED;\r
+    goto Done;\r
+  }\r
+\r
+  Status = EFI_UNSUPPORTED;\r
+  if (Pci.Hdr.VendorId == 0xFB5D && Pci.Hdr.DeviceId == 0x40FB) {\r
+    DEBUG((DEBUG_INFO, "BHYVE framebuffer device detected\n"));\r
+    Status = EFI_SUCCESS;\r
+\r
+    BhyveGetGraphicsMode(PciIo, &Width, &Height, &Depth);\r
+    PcdSet32S (PcdVideoHorizontalResolution, Width);\r
+    PcdSet32S (PcdVideoVerticalResolution, Height);\r
+  }\r
+\r
+Done:\r
+  //\r
+  // Close the PCI I/O Protocol\r
+  //\r
+  gBS->CloseProtocol (\r
+        Handle,\r
+        &gEfiPciIoProtocolGuid,\r
+        This->DriverBindingHandle,\r
+        Handle\r
+        );\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Starts a device controller or a bus controller.\r
+\r
+  The Start() function is designed to be invoked from the EFI boot service ConnectController().\r
+  As a result, much of the error checking on the parameters to Start() has been moved into this\r
+  common boot service. It is legal to call Start() from other locations,\r
+  but the following calling restrictions must be followed, or the system behavior will not be deterministic.\r
+  1. ControllerHandle must be a valid EFI_HANDLE.\r
+  2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned\r
+     EFI_DEVICE_PATH_PROTOCOL.\r
+  3. Prior to calling Start(), the Supported() function for the driver specified by This must\r
+     have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.\r
+\r
+  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+  @param[in]  ControllerHandle     The handle of the controller to start. This handle\r
+                                   must support a protocol interface that supplies\r
+                                   an I/O abstraction to the driver.\r
+  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This\r
+                                   parameter is ignored by device drivers, and is optional for bus\r
+                                   drivers. For a bus driver, if this parameter is NULL, then handles\r
+                                   for all the children of Controller are created by this driver.\r
+                                   If this parameter is not NULL and the first Device Path Node is\r
+                                   not the End of Device Path Node, then only the handle for the\r
+                                   child device specified by the first Device Path Node of\r
+                                   RemainingDevicePath is created by this driver.\r
+                                   If the first Device Path Node of RemainingDevicePath is\r
+                                   the End of Device Path Node, no child handle is created by this\r
+                                   driver.\r
+\r
+  @retval EFI_SUCCESS              The device was started.\r
+  @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.\r
+  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.\r
+  @retval Others                   The driver failded to start the device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EmuGopDriverBindingStart (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,\r
+  IN  EFI_HANDLE                      Handle,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL        *RemainingDevicePath\r
+  )\r
+{\r
+  BHYVE_FBUF_MEMREGS      Memregs;\r
+  GOP_PRIVATE_DATA        *Private;\r
+  EFI_STATUS              Status;\r
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *MmioDesc;\r
+\r
+  //\r
+  // Allocate Private context data for SGO inteface.\r
+  //\r
+  Private = NULL;\r
+  Status = gBS->AllocatePool (\r
+                  EfiBootServicesData,\r
+                  sizeof (GOP_PRIVATE_DATA),\r
+                  (VOID **)&Private\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  // Set up context record\r
+  //\r
+  Private->Signature           = GOP_PRIVATE_DATA_SIGNATURE;\r
+  Private->Handle              = Handle;\r
+  Private->ControllerNameTable = NULL;\r
+\r
+  //\r
+  // Open PCI I/O Protocol\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  Handle,\r
+                  &gEfiPciIoProtocolGuid,\r
+                  (VOID **) &Private->PciIo,\r
+                  This->DriverBindingHandle,\r
+                  Handle,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Check if fbuf mmio BAR is present\r
+  //\r
+  MmioDesc = NULL;\r
+  Status = Private->PciIo->GetBarAttributes (\r
+                      Private->PciIo,\r
+                      PCI_BAR_IDX0,\r
+                      NULL,\r
+                      (VOID**) &MmioDesc\r
+                      );\r
+  if (EFI_ERROR (Status) ||\r
+      MmioDesc->ResType != ACPI_ADDRESS_SPACE_TYPE_MEM) {\r
+    DEBUG ((DEBUG_INFO, "BHYVE GOP: No mmio bar\n"));\r
+  } else {\r
+    DEBUG ((DEBUG_INFO, "BHYVE GOP: Using mmio bar @ 0x%lx\n",\r
+            MmioDesc->AddrRangeMin));\r
+    BhyveGetMemregs(Private, &Memregs);\r
+    Private->FbSize = Memregs.FbSize;\r
+  }\r
+  if (MmioDesc != NULL) {\r
+    FreePool (MmioDesc);\r
+  }\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Check if fbuf frame-buffer BAR is present\r
+  //\r
+  MmioDesc = NULL;\r
+  Status = Private->PciIo->GetBarAttributes (\r
+                      Private->PciIo,\r
+                      PCI_BAR_IDX1,\r
+                      NULL,\r
+                      (VOID**) &MmioDesc\r
+                      );\r
+  if (EFI_ERROR (Status) ||\r
+      MmioDesc->ResType != ACPI_ADDRESS_SPACE_TYPE_MEM) {\r
+    DEBUG ((DEBUG_INFO, "BHYVE GOP: No frame-buffer bar\n"));\r
+  } else {\r
+    DEBUG ((DEBUG_INFO, "BHYVE GOP: Using frame-buffer bar @ 0x%lx\n",\r
+            MmioDesc->AddrRangeMin));\r
+    Private->FbAddr = MmioDesc->AddrRangeMin;\r
+    // XXX assert BAR is >= size\r
+  }\r
+\r
+  if (MmioDesc != NULL) {\r
+    FreePool (MmioDesc);\r
+  }\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  DEBUG ((DEBUG_INFO, "BHYVE GOP: Framebuf addr 0x%lx, size %x\n",\r
+         Private->FbAddr, Private->FbSize));\r
+\r
+  Status = EmuGopConstructor (Private);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Publish the Gop interface to the world\r
+  //\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &Private->Handle,\r
+                  &gEfiGraphicsOutputProtocolGuid,    &Private->GraphicsOutput,\r
+                  NULL\r
+                  );\r
+\r
+  DEBUG((DEBUG_INFO, "BHYVE framebuffer device started\n"));\r
+\r
+  //\r
+  // Install int10 handler\r
+  //\r
+#ifndef CSM_ENABLE\r
+  InstallVbeShim (L"Framebuffer", Private->FbAddr);\r
+#endif\r
+\r
+Done:\r
+  if (EFI_ERROR (Status)) {\r
+    if (Private != NULL) {\r
+      //\r
+      // On Error Free back private data\r
+      //\r
+      if (Private->ControllerNameTable != NULL) {\r
+        FreeUnicodeStringTable (Private->ControllerNameTable);\r
+      }\r
+\r
+      gBS->FreePool (Private);\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+\r
+/**\r
+  Stops a device controller or a bus controller.\r
+\r
+  The Stop() function is designed to be invoked from the EFI boot service DisconnectController().\r
+  As a result, much of the error checking on the parameters to Stop() has been moved\r
+  into this common boot service. It is legal to call Stop() from other locations,\r
+  but the following calling restrictions must be followed, or the system behavior will not be deterministic.\r
+  1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this\r
+     same driver's Start() function.\r
+  2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid\r
+     EFI_HANDLE. In addition, all of these handles must have been created in this driver's\r
+     Start() function, and the Start() function must have called OpenProtocol() on\r
+     ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.\r
+\r
+  @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+  @param[in]  ControllerHandle  A handle to the device being stopped. The handle must\r
+                                support a bus specific I/O protocol for the driver\r
+                                to use to stop the device.\r
+  @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.\r
+  @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL\r
+                                if NumberOfChildren is 0.\r
+\r
+  @retval EFI_SUCCESS           The device was stopped.\r
+  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EmuGopDriverBindingStop (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                   Handle,\r
+  IN  UINTN                        NumberOfChildren,\r
+  IN  EFI_HANDLE                   *ChildHandleBuffer\r
+  )\r
+{\r
+  EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;\r
+  EFI_STATUS                   Status;\r
+  GOP_PRIVATE_DATA             *Private;\r
+\r
+  DEBUG((DEBUG_INFO, "BHYVE framebuffer device stopping\n"));\r
+\r
+  Status = gBS->OpenProtocol (\r
+                  Handle,\r
+                  &gEfiGraphicsOutputProtocolGuid,\r
+                  (VOID **)&GraphicsOutput,\r
+                  This->DriverBindingHandle,\r
+                  Handle,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    //\r
+    // If the GOP interface does not exist the driver is not started\r
+    //\r
+    return EFI_NOT_STARTED;\r
+  }\r
+\r
+  //\r
+  // Get our private context information\r
+  //\r
+  Private = GOP_PRIVATE_DATA_FROM_THIS (GraphicsOutput);\r
+\r
+  //\r
+  // Remove the SGO interface from the system\r
+  //\r
+  Status = gBS->UninstallMultipleProtocolInterfaces (\r
+                  Private->Handle,\r
+                  &gEfiGraphicsOutputProtocolGuid,    &Private->GraphicsOutput,\r
+                  NULL\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Shutdown the hardware\r
+    //\r
+    Status = EmuGopDestructor (Private);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+\r
+    gBS->CloseProtocol (\r
+          Handle,\r
+          &gEfiPciIoProtocolGuid,\r
+          This->DriverBindingHandle,\r
+          Private->Handle\r
+          );\r
+\r
+    //\r
+    // Free our instance data\r
+    //\r
+    FreeUnicodeStringTable (Private->ControllerNameTable);\r
+\r
+    gBS->FreePool (Private);\r
+\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+///\r
+/// This protocol provides the services required to determine if a driver supports a given controller.\r
+/// If a controller is supported, then it also provides routines to start and stop the controller.\r
+///\r
+EFI_DRIVER_BINDING_PROTOCOL gEmuGopDriverBinding = {\r
+  EmuGopDriverBindingSupported,\r
+  EmuGopDriverBindingStart,\r
+  EmuGopDriverBindingStop,\r
+  0xa,\r
+  NULL,\r
+  NULL\r
+};\r
+\r
+\r
+\r
+/**\r
+  The user Entry Point for module EmuGop. The user code starts with this function.\r
+\r
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.\r
+  @param[in] SystemTable    A pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCCESS       The entry point is executed successfully.\r
+  @retval other             Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeEmuGop (\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS              Status;\r
+\r
+  Status = EfiLibInstallDriverBindingComponentName2 (\r
+             ImageHandle,\r
+             SystemTable,\r
+             &gEmuGopDriverBinding,\r
+             ImageHandle,\r
+             &gEmuGopComponentName,\r
+             &gEmuGopComponentName2\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+\r
+  return Status;\r
+}\r
+\r
+STATIC VOID\r
+BhyveGetGraphicsMode (\r
+  EFI_PCI_IO_PROTOCOL *PciIo,\r
+  UINT16              *Width,\r
+  UINT16              *Height,\r
+  UINT16              *Depth\r
+  )\r
+{\r
+  BHYVE_FBUF_MEMREGS BhyveRegs;\r
+  UINT64       Offset;\r
+  EFI_STATUS   Status;\r
+\r
+\r
+  Offset = (UINT64)&BhyveRegs.Width - (UINT64)&BhyveRegs;\r
+\r
+  Status = PciIo->Mem.Read (\r
+      PciIo,\r
+      EfiPciIoWidthUint16,\r
+      PCI_BAR_IDX0,\r
+      Offset,\r
+      3,\r
+      &BhyveRegs.Width\r
+      );\r
+\r
+  *Width  = BhyveRegs.Width;\r
+  *Height = BhyveRegs.Height;\r
+  *Depth  = BhyveRegs.Depth;\r
+\r
+  DEBUG ((DEBUG_INFO, "BHYVE Get Graphics Mode: w %d, h %d\n", *Width, *Height));\r
+\r
+  ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
+VOID\r
+BhyveSetGraphicsMode (\r
+  GOP_PRIVATE_DATA  *Private,\r
+  UINT16             Width,\r
+  UINT16             Height,\r
+  UINT16             Depth\r
+  )\r
+{\r
+  BHYVE_FBUF_MEMREGS BhyveRegs;\r
+  UINT64       Offset;\r
+  EFI_STATUS   Status;\r
+\r
+  DEBUG ((DEBUG_INFO, "BHYVE Set Graphics Mode: w %d, h %d\n", Width, Height));\r
+\r
+  BhyveRegs.Width  = Width;\r
+  BhyveRegs.Height = Height;\r
+  BhyveRegs.Depth  = Depth;\r
+  Offset = (UINT64)&BhyveRegs.Width - (UINT64)&BhyveRegs;\r
+\r
+  Status = Private->PciIo->Mem.Write (\r
+      Private->PciIo,\r
+      EfiPciIoWidthUint16,\r
+      PCI_BAR_IDX0,\r
+      Offset,\r
+      3,\r
+      &BhyveRegs.Width\r
+      );\r
+  ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
+VOID\r
+BhyveGetMemregs (\r
+  GOP_PRIVATE_DATA  *Private,\r
+  BHYVE_FBUF_MEMREGS *Memregs\r
+  )\r
+{\r
+  EFI_STATUS   Status;\r
+\r
+  Status = Private->PciIo->Mem.Read (\r
+      Private->PciIo,\r
+      EfiPciIoWidthUint32,\r
+      PCI_BAR_IDX0,\r
+      0,\r
+      3,\r
+      Memregs\r
+      );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  DEBUG ((DEBUG_INFO, "BHYVE Get Memregs, size %d width %d height %d\n",\r
+         Memregs->FbSize, Memregs->Width, Memregs->Height));\r
+}\r
diff --git a/OvmfPkg/Bhyve/BhyveRfbDxe/GopScreen.c b/OvmfPkg/Bhyve/BhyveRfbDxe/GopScreen.c
new file mode 100644 (file)
index 0000000..0760ffb
--- /dev/null
@@ -0,0 +1,393 @@
+/*++ @file\r
+\r
+Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+Copyright (c) 2015, Nahanni Systems, Inc.\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+Portions copyright (c) 2010 - 2011, Apple Inc. All rights reserved.\r
+\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+Module Name:\r
+\r
+    EmuGopScreen.c\r
+\r
+Abstract:\r
+\r
+  This file produces the graphics abstration of UGA. It is called by\r
+  EmuGopDriver.c file which deals with the EFI 1.1 driver model.\r
+  This file just does graphics.\r
+\r
+**/\r
+\r
+#include "Gop.h"\r
+#include <Library/FrameBufferBltLib.h>\r
+\r
+\r
+EFI_EVENT               mGopScreenExitBootServicesEvent;\r
+\r
+GOP_MODE_DATA mGopModeData[] = {\r
+    { 0,     0,    32, 0 },    // Filled in with user-spec'd resolution\r
+    { 1024,  768,  32, 0 },\r
+    { 800,   600,  32, 0 },\r
+    { 640,   480,  32, 0 }\r
+    };\r
+\r
+STATIC\r
+VOID\r
+BhyveGopCompleteModeInfo (\r
+  IN  GOP_MODE_DATA  *ModeData,\r
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info\r
+  )\r
+{\r
+  Info->Version = 0;\r
+  if (ModeData->ColorDepth == 8) {\r
+    Info->PixelFormat = PixelBitMask;\r
+    Info->PixelInformation.RedMask = PIXEL_RED_MASK;\r
+    Info->PixelInformation.GreenMask = PIXEL_GREEN_MASK;\r
+    Info->PixelInformation.BlueMask = PIXEL_BLUE_MASK;\r
+    Info->PixelInformation.ReservedMask = 0;\r
+  } else if (ModeData->ColorDepth == 24) {\r
+    Info->PixelFormat = PixelBitMask;\r
+    Info->PixelInformation.RedMask = PIXEL24_RED_MASK;\r
+    Info->PixelInformation.GreenMask = PIXEL24_GREEN_MASK;\r
+    Info->PixelInformation.BlueMask = PIXEL24_BLUE_MASK;\r
+    Info->PixelInformation.ReservedMask = 0;\r
+  } else if (ModeData->ColorDepth == 32) {\r
+    DEBUG ((DEBUG_INFO, "%dx%d PixelBlueGreenRedReserved8BitPerColor\n",\r
+     ModeData->HorizontalResolution, ModeData->VerticalResolution));\r
+    Info->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;\r
+  }\r
+  Info->PixelsPerScanLine = Info->HorizontalResolution;\r
+}\r
+\r
+\r
+/**\r
+  Returns information for an available graphics mode that the graphics device\r
+  and the set of active video output devices supports.\r
+\r
+  @param  This                  The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.\r
+  @param  ModeNumber            The mode number to return information on.\r
+  @param  SizeOfInfo            A pointer to the size, in bytes, of the Info buffer.\r
+  @param  Info                  A pointer to callee allocated buffer that returns information about ModeNumber.\r
+\r
+  @retval EFI_SUCCESS           Mode information returned.\r
+  @retval EFI_BUFFER_TOO_SMALL  The Info buffer was too small.\r
+  @retval EFI_DEVICE_ERROR      A hardware error occurred trying to retrieve the video mode.\r
+  @retval EFI_NOT_STARTED       Video display is not initialized. Call SetMode ()\r
+  @retval EFI_INVALID_PARAMETER One of the input args was NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EmuGopQuerytMode (\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,\r
+  IN  UINT32                                ModeNumber,\r
+  OUT UINTN                                 *SizeOfInfo,\r
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info\r
+  )\r
+{\r
+  GOP_PRIVATE_DATA  *Private;\r
+  GOP_MODE_DATA     *ModeData;\r
+\r
+  Private = GOP_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  if (Info == NULL || SizeOfInfo == NULL || (UINTN) ModeNumber >= This->Mode->MaxMode) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  *Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
+  if (*Info == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
+\r
+  ModeData = &Private->ModeData[ModeNumber];\r
+  (*Info)->Version = 0;\r
+  (*Info)->HorizontalResolution = ModeData->HorizontalResolution;\r
+  (*Info)->VerticalResolution   = ModeData->VerticalResolution;\r
+  (*Info)->PixelFormat = PixelBitMask;\r
+  (*Info)->PixelsPerScanLine = (*Info)->HorizontalResolution;\r
+  BhyveGopCompleteModeInfo(ModeData, *Info);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+/**\r
+  Set the video device into the specified mode and clears the visible portions of\r
+  the output display to black.\r
+\r
+  @param  This              The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.\r
+  @param  ModeNumber        Abstraction that defines the current video mode.\r
+\r
+  @retval EFI_SUCCESS       The graphics mode specified by ModeNumber was selected.\r
+  @retval EFI_DEVICE_ERROR  The device had an error and could not complete the request.\r
+  @retval EFI_UNSUPPORTED   ModeNumber is not supported by this device.\r
+\r
+**/\r
+\r
+FRAME_BUFFER_CONFIGURE *fbconf;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+EmuGopSetMode (\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL  *This,\r
+  IN  UINT32                        ModeNumber\r
+  )\r
+{\r
+  GOP_PRIVATE_DATA                *Private;\r
+  GOP_MODE_DATA                   *ModeData;\r
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL   Fill;\r
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *Info;\r
+\r
+  UINTN confsize = 0;\r
+  fbconf = NULL;\r
+\r
+  Private = GOP_PRIVATE_DATA_FROM_THIS (This);\r
+\r
+  if (ModeNumber >= This->Mode->MaxMode) {\r
+    // Tell bhyve that we are switching out of vesa\r
+    BhyveSetGraphicsMode(Private, 0, 0, 0);\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  DEBUG ((DEBUG_INFO, "BHYVE GopSetMode %d\n", ModeNumber));\r
+\r
+  ModeData = &Private->ModeData[ModeNumber];\r
+  This->Mode->Mode = ModeNumber;\r
+  Private->GraphicsOutput.Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;\r
+  Private->GraphicsOutput.Mode->Info->VerticalResolution = ModeData->VerticalResolution;\r
+  Private->GraphicsOutput.Mode->Info->PixelsPerScanLine = ModeData->HorizontalResolution;\r
+\r
+  Info = This->Mode->Info;\r
+  BhyveGopCompleteModeInfo(ModeData, Info);\r
+\r
+  This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;\r
+  This->Mode->Info->VerticalResolution = ModeData->VerticalResolution;\r
+  This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
+  This->Mode->FrameBufferBase = Private->GraphicsOutput.Mode->FrameBufferBase;\r
+\r
+  /*\r
+  This->Mode->FrameBufferSize = Info->HorizontalResolution * Info->VerticalResolution\r
+                                * ((ModeData->ColorDepth + 7) / 8);\r
+  */\r
+  This->Mode->FrameBufferSize = Private->FbSize;\r
+  DEBUG ((DEBUG_INFO, "BHYVE GOP FrameBufferBase: 0x%x, FrameBufferSize: 0x%x\n", This->Mode->FrameBufferBase, This->Mode->FrameBufferSize));\r
+\r
+  BhyveSetGraphicsMode(Private, (UINT16)ModeData->HorizontalResolution, (UINT16)ModeData->VerticalResolution, (UINT16)ModeData->ColorDepth);\r
+\r
+  RETURN_STATUS ret = FrameBufferBltConfigure (\r
+    (VOID*)(UINTN) This->Mode->FrameBufferBase,\r
+    This->Mode->Info, fbconf, &confsize\r
+    );\r
+  if (ret == EFI_BUFFER_TOO_SMALL || ret == EFI_INVALID_PARAMETER) {\r
+          fbconf = AllocatePool(confsize);\r
+          ret = FrameBufferBltConfigure(\r
+                         (VOID*)(UINTN)This->Mode->FrameBufferBase,\r
+                         This->Mode->Info, fbconf, &confsize);\r
+          ASSERT(ret == EFI_SUCCESS);\r
+  }\r
+\r
+  Fill.Red   = 0;\r
+  Fill.Green = 0;\r
+  Fill.Blue  = 0;\r
+  This->Blt (\r
+          This,\r
+          &Fill,\r
+          EfiBltVideoFill,\r
+          0,\r
+          0,\r
+          0,\r
+          0,\r
+          ModeData->HorizontalResolution,\r
+          ModeData->VerticalResolution,\r
+          ModeData->HorizontalResolution * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
+          );\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+/**\r
+  Blt a rectangle of pixels on the graphics screen. Blt stands for BLock Transfer.\r
+\r
+  @param  This         Protocol instance pointer.\r
+  @param  BltBuffer    Buffer containing data to blit into video buffer. This\r
+                       buffer has a size of Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)\r
+  @param  BltOperation Operation to perform on BlitBuffer and video memory\r
+  @param  SourceX      X coordinate of source for the BltBuffer.\r
+  @param  SourceY      Y coordinate of source for the BltBuffer.\r
+  @param  DestinationX X coordinate of destination for the BltBuffer.\r
+  @param  DestinationY Y coordinate of destination for the BltBuffer.\r
+  @param  Width        Width of rectangle in BltBuffer in pixels.\r
+  @param  Height       Hight of rectangle in BltBuffer in pixels.\r
+  @param  Delta        OPTIONAL\r
+\r
+  @retval EFI_SUCCESS           The Blt operation completed.\r
+  @retval EFI_INVALID_PARAMETER BltOperation is not valid.\r
+  @retval EFI_DEVICE_ERROR      A hardware error occured writting to the video buffer.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EmuGopBlt (\r
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL            *This,\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_PIXEL           *BltBuffer,   OPTIONAL\r
+  IN  EFI_GRAPHICS_OUTPUT_BLT_OPERATION       BltOperation,\r
+  IN  UINTN                                   SourceX,\r
+  IN  UINTN                                   SourceY,\r
+  IN  UINTN                                   DestinationX,\r
+  IN  UINTN                                   DestinationY,\r
+  IN  UINTN                                   Width,\r
+  IN  UINTN                                   Height,\r
+  IN  UINTN                                   Delta         OPTIONAL\r
+  )\r
+{\r
+  EFI_TPL           OriginalTPL;\r
+  EFI_STATUS        Status;\r
+\r
+  if ((UINT32)BltOperation >= EfiGraphicsOutputBltOperationMax) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (Width == 0 || Height == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // We have to raise to TPL Notify, so we make an atomic write the frame buffer.\r
+  // We would not want a timer based event (Cursor, ...) to come in while we are\r
+  // doing this operation.\r
+  //\r
+  OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY);\r
+\r
+  switch (BltOperation) {\r
+  case EfiBltVideoToBltBuffer:\r
+  case EfiBltBufferToVideo:\r
+  case EfiBltVideoFill:\r
+  case EfiBltVideoToVideo:\r
+    Status = FrameBufferBlt (\r
+     fbconf,\r
+      BltBuffer,\r
+      BltOperation,\r
+      SourceX,\r
+      SourceY,\r
+      DestinationX,\r
+      DestinationY,\r
+      Width,\r
+      Height,\r
+      Delta\r
+      );\r
+    break;\r
+\r
+  default:\r
+    Status = EFI_INVALID_PARAMETER;\r
+    ASSERT (FALSE);\r
+  }\r
+\r
+  gBS->RestoreTPL (OriginalTPL);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+//\r
+// Construction and Destruction functions\r
+//\r
+\r
+EFI_STATUS\r
+EmuGopConstructor (\r
+  GOP_PRIVATE_DATA    *Private\r
+  )\r
+{\r
+  // Set mode 0 to be the requested resolution\r
+  mGopModeData[0].HorizontalResolution = PcdGet32 ( PcdVideoHorizontalResolution);\r
+  mGopModeData[0].VerticalResolution = PcdGet32 ( PcdVideoVerticalResolution );\r
+\r
+  Private->ModeData = mGopModeData;\r
+\r
+  Private->GraphicsOutput.QueryMode      = EmuGopQuerytMode;\r
+  Private->GraphicsOutput.SetMode        = EmuGopSetMode;\r
+  Private->GraphicsOutput.Blt            = EmuGopBlt;\r
+\r
+  //\r
+  // Allocate buffer for Graphics Output Protocol mode information\r
+  //\r
+  Private->GraphicsOutput.Mode = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE));\r
+  if (Private->GraphicsOutput.Mode == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  Private->GraphicsOutput.Mode->Info = AllocatePool (sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));\r
+  if (Private->GraphicsOutput.Mode->Info == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+\r
+  DEBUG ((DEBUG_INFO, "BHYVE Gop Constructor\n"));\r
+\r
+  Private->GraphicsOutput.Mode->MaxMode = sizeof(mGopModeData) / sizeof(GOP_MODE_DATA);\r
+  //\r
+  // Till now, we have no idea about the window size.\r
+  //\r
+  Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALID_MODE_NUMBER;\r
+  Private->GraphicsOutput.Mode->Info->Version = 0;\r
+  Private->GraphicsOutput.Mode->Info->HorizontalResolution = 0;\r
+  Private->GraphicsOutput.Mode->Info->VerticalResolution = 0;\r
+  Private->GraphicsOutput.Mode->Info->PixelFormat = PixelBitMask;\r
+  Private->GraphicsOutput.Mode->SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);\r
+  Private->GraphicsOutput.Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) Private->FbAddr;\r
+  Private->GraphicsOutput.Mode->FrameBufferSize = Private->FbSize;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+EFI_STATUS\r
+EmuGopDestructor (\r
+  GOP_PRIVATE_DATA     *Private\r
+  )\r
+{\r
+  //\r
+  // Free graphics output protocol occupied resource\r
+  //\r
+  if (Private->GraphicsOutput.Mode != NULL) {\r
+    if (Private->GraphicsOutput.Mode->Info != NULL) {\r
+      FreePool (Private->GraphicsOutput.Mode->Info);\r
+    }\r
+    FreePool (Private->GraphicsOutput.Mode);\r
+    Private->GraphicsOutput.Mode = NULL;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+VOID\r
+EFIAPI\r
+ShutdownGopEvent (\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
+  )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  This is the UGA screen's callback notification function for exit-boot-services.\r
+  All we do here is call EmuGopDestructor().\r
+\r
+Arguments:\r
+\r
+  Event   - not used\r
+  Context - pointer to the Private structure.\r
+\r
+Returns:\r
+\r
+  None.\r
+\r
+**/\r
+{\r
+  EmuGopDestructor (Context);\r
+}\r
+\r
diff --git a/OvmfPkg/Bhyve/BhyveRfbDxe/VbeShim.asm b/OvmfPkg/Bhyve/BhyveRfbDxe/VbeShim.asm
new file mode 100644 (file)
index 0000000..f7a1ec2
--- /dev/null
@@ -0,0 +1,342 @@
+;------------------------------------------------------------------------------\r
+; @file\r
+; A minimal Int10h stub that allows the Windows 2008 R2 SP1 UEFI guest's buggy,\r
+; default VGA driver to switch to 1024x768x32.\r
+;\r
+; Copyright (C) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+; Copyright (C) 2015, Nahanni Systems, Inc.\r
+; Copyright (C) 2014, Red Hat, Inc.\r
+; Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>\r
+;\r
+; SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+; enable this macro for debug messages\r
+%define DEBUG\r
+\r
+%macro DebugLog 1\r
+%ifdef DEBUG\r
+  push       si\r
+  mov        si, %1\r
+  call       PrintStringSi\r
+  pop        si\r
+%endif\r
+%endmacro\r
+\r
+\r
+BITS 16\r
+ORG 0\r
+\r
+VbeInfo:\r
+TIMES 256 nop\r
+\r
+VbeModeInfo:\r
+VbeMode1:\r
+TIMES 50  nop\r
+VbeMode2:\r
+TIMES 50  nop\r
+VbeMode3:\r
+TIMES 50  nop\r
+VbeMode4:\r
+TIMES 50  nop\r
+TIMES 56  nop  ; filler for 256 bytes\r
+\r
+Handler:\r
+  cmp        ax, 0x4f00\r
+  je         GetInfo\r
+  cmp        ax, 0x4f01\r
+  je         GetModeInfo\r
+  cmp        ax, 0x4f02\r
+  je         SetMode\r
+  cmp        ax, 0x4f03\r
+  je         GetMode\r
+  cmp        ax, 0x4f10\r
+  je         GetPmCapabilities\r
+  cmp        ax, 0x4f15\r
+  je         ReadEdid\r
+  cmp        ah, 0x00\r
+  je         SetModeLegacy\r
+  DebugLog   StrUnkownFunction\r
+Hang:\r
+  jmp        Hang\r
+\r
+\r
+GetInfo:\r
+  push       es\r
+  push       di\r
+  push       ds\r
+  push       si\r
+  push       cx\r
+\r
+  DebugLog   StrEnterGetInfo\r
+\r
+  ; target (es:di) set on input\r
+  push       cs\r
+  pop        ds\r
+  mov        si, VbeInfo\r
+  ; source (ds:si) set now\r
+\r
+  mov        cx, 256\r
+  cld\r
+  rep movsb\r
+\r
+  pop        cx\r
+  pop        si\r
+  pop        ds\r
+  pop        di\r
+  pop        es\r
+  jmp        Success\r
+\r
+\r
+GetModeInfo:\r
+  push       es\r
+  push       di\r
+  push       ds\r
+  push       si\r
+  push       cx\r
+\r
+  DebugLog   StrEnterGetModeInfo\r
+\r
+  and        cx, ~0x4000 ; clear potentially set LFB bit in mode number\r
+\r
+  cmp        cx, 0x013f\r
+  je         gKnownMode1\r
+  cmp        cx, 0x0140\r
+  je         gKnownMode2\r
+  cmp        cx, 0x0141\r
+  je         gKnownMode3\r
+\r
+  DebugLog   StrUnkownMode\r
+  jmp        Hang\r
+gKnownMode1:\r
+  DebugLog   StrMode1\r
+  mov        si, VbeMode1\r
+  jmp        CopyModeInfo\r
+gKnownMode2:\r
+  DebugLog   StrMode2\r
+  mov        si, VbeMode2\r
+  jmp        CopyModeInfo\r
+gKnownMode3:\r
+  DebugLog   StrMode3\r
+  mov        si, VbeMode3\r
+  jmp        CopyModeInfo\r
+gKnownMode4:\r
+  DebugLog   StrMode4\r
+  mov        si, VbeMode4\r
+  jmp        CopyModeInfo\r
+\r
+CopyModeInfo:\r
+  ; target (es:di) set on input\r
+  push       cs\r
+  pop        ds\r
+  ;mov        si, VbeModeInfo\r
+  ; source (ds:si) set now\r
+\r
+  ;mov        cx, 256\r
+  mov        cx, 50\r
+  cld\r
+  rep movsb\r
+\r
+  pop        cx\r
+  pop        si\r
+  pop        ds\r
+  pop        di\r
+  pop        es\r
+  jmp        Success\r
+\r
+\r
+SetMode:\r
+  push       dx\r
+  push       ax\r
+\r
+  DebugLog   StrEnterSetMode\r
+\r
+  and        bx, ~0x4000 ; clear potentially set LFB bit in mode number\r
+  cmp        bx, 0x013f\r
+  je         KnownMode1\r
+  cmp        bx, 0x0140\r
+  je         KnownMode2\r
+  cmp        bx, 0x0141\r
+  je         KnownMode3\r
+  DebugLog   StrUnkownMode\r
+  jmp        Hang\r
+KnownMode1:\r
+  DebugLog   StrMode1\r
+  jmp        SetModeDone\r
+KnownMode2:\r
+  DebugLog   StrMode2\r
+  jmp        SetModeDone\r
+KnownMode3:\r
+  DebugLog   StrMode3\r
+  jmp        SetModeDone\r
+KnownMode4:\r
+  DebugLog   StrMode4\r
+\r
+SetModeDone:\r
+  mov        [CurMode], bl\r
+  mov        [CurMode+1], bh\r
+  pop        ax\r
+  pop        dx\r
+  jmp        Success\r
+\r
+\r
+GetMode:\r
+  DebugLog   StrEnterGetMode\r
+  mov        bl, [CurMode]\r
+  mov        bh, [CurMode+1]\r
+  jmp        Success\r
+\r
+\r
+GetPmCapabilities:\r
+  DebugLog   StrGetPmCapabilities\r
+  mov        bx, 0x0080\r
+  jmp        Success\r
+\r
+\r
+ReadEdid:\r
+  push       es\r
+  push       di\r
+  push       ds\r
+  push       si\r
+  push       cx\r
+\r
+  DebugLog   StrReadEdid\r
+\r
+  ; target (es:di) set on input\r
+  push       cs\r
+  pop        ds\r
+  mov        si, Edid\r
+  ; source (ds:si) set now\r
+\r
+  mov        cx, 128\r
+  cld\r
+  rep movsb\r
+\r
+  pop        cx\r
+  pop        si\r
+  pop        ds\r
+  pop        di\r
+  pop        es\r
+  jmp        Success\r
+\r
+\r
+SetModeLegacy:\r
+  DebugLog   StrEnterSetModeLegacy\r
+\r
+  cmp        al, 0x03\r
+  je         sKnownMode3\r
+  cmp        al, 0x12\r
+  je         sKnownMode4\r
+  DebugLog   StrUnkownMode\r
+  jmp        Hang\r
+sKnownMode3:\r
+  DebugLog   StrLegacyMode3\r
+  mov        al, 0 ; 0x30\r
+  jmp        SetModeLegacyDone\r
+sKnownMode4:\r
+  mov        al, 0 ;0x20\r
+SetModeLegacyDone:\r
+  DebugLog   StrExitSuccess\r
+  iret\r
+\r
+\r
+Success:\r
+  DebugLog   StrExitSuccess\r
+  mov        ax, 0x004f\r
+  iret\r
+\r
+\r
+Unsupported:\r
+  DebugLog   StrExitUnsupported\r
+  mov        ax, 0x024f\r
+  iret\r
+\r
+\r
+%ifdef DEBUG\r
+PrintStringSi:\r
+  pusha\r
+  push       ds ; save original\r
+  push       cs\r
+  pop        ds\r
+  mov        dx, 0x220             ; bhyve debug cons port\r
+  mov        ax, 0\r
+PrintStringSiLoop:\r
+  lodsb\r
+  cmp        al, 0\r
+  je         PrintStringSiDone\r
+  out        dx, al\r
+  jmp        PrintStringSiLoop\r
+PrintStringSiDone:\r
+  pop        ds ; restore original\r
+  popa\r
+  ret\r
+\r
+\r
+StrExitSuccess:\r
+  db 'vOk', 0x0d, 0x0a, 0\r
+\r
+StrExitUnsupported:\r
+  db 'vUnsupported', 0x0d, 0x0a, 0\r
+\r
+StrUnkownFunction:\r
+  db 'vUnknown Function', 0x0d, 0x0a, 0\r
+\r
+StrEnterGetInfo:\r
+  db 'vGetInfo', 0x0d, 0x0a, 0\r
+\r
+StrEnterGetModeInfo:\r
+  db 'vGetModeInfo', 0x0d, 0x0a, 0\r
+\r
+StrEnterGetMode:\r
+  db 'vGetMode', 0x0d, 0x0a, 0\r
+\r
+StrEnterSetMode:\r
+  db 'vSetMode', 0x0d, 0x0a, 0\r
+\r
+StrEnterSetModeLegacy:\r
+  db 'vSetModeLegacy', 0x0d, 0x0a, 0\r
+\r
+StrUnkownMode:\r
+  db 'vUnkown Mode', 0x0d, 0x0a, 0\r
+\r
+StrGetPmCapabilities:\r
+  db 'vGetPmCapabilities', 0x0d, 0x0a, 0\r
+\r
+StrReadEdid:\r
+  db 'vReadEdid', 0x0d, 0x0a, 0\r
+\r
+StrLegacyMode3:\r
+  db 'vLegacyMode3', 0x0d, 0x0a, 0\r
+\r
+\r
+StrMode1:\r
+  db 'mode_640x480x32', 0x0d, 0x0a, 0\r
+StrMode2:\r
+  db 'mode_800x600x32', 0x0d, 0x0a, 0\r
+StrMode3:\r
+  db 'mode_1024x768x32', 0x0d, 0x0a, 0\r
+StrMode4:\r
+  db 'mode_unused', 0x0d, 0x0a, 0\r
+%endif\r
+\r
+CurMode:\r
+  db 0x00, 0x00\r
+\r
+;\r
+; EDID stores monitor information. For now, just send back an null item.\r
+;\r
+Edid:\r
+  db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+  db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+  db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+  db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+  db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+  db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+  db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+  db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+  db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+  db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+  db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+  db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+  db 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
diff --git a/OvmfPkg/Bhyve/BhyveRfbDxe/VbeShim.c b/OvmfPkg/Bhyve/BhyveRfbDxe/VbeShim.c
new file mode 100644 (file)
index 0000000..740b966
--- /dev/null
@@ -0,0 +1,259 @@
+/** @file\r
+  Install a fake VGABIOS service handler (real mode Int10h) for the buggy\r
+  Windows 2008 R2 SP1 UEFI guest.\r
+\r
+  The handler is never meant to be directly executed by a VCPU; it's there for\r
+  the internal real mode emulator of Windows 2008 R2 SP1.\r
+\r
+  The code is based on Ralf Brown's Interrupt List:\r
+  <http://www.cs.cmu.edu/~ralf/files.html>\r
+  <http://www.ctyme.com/rbrown.htm>\r
+\r
+  Copyright (C) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+  Copyright (C) 2015, Nahanni Systems, Inc.\r
+  Copyright (C) 2014, Red Hat, Inc.\r
+  Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <IndustryStandard/LegacyVgaBios.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PciLib.h>\r
+#include <Library/PrintLib.h>\r
+\r
+#include "Gop.h"\r
+#include "VbeShim.h"\r
+\r
+#pragma pack (1)\r
+typedef struct {\r
+  UINT16 Offset;\r
+  UINT16 Segment;\r
+} IVT_ENTRY;\r
+#pragma pack ()\r
+\r
+//\r
+// This string is displayed by Windows 2008 R2 SP1 in the Screen Resolution,\r
+// Advanced Settings dialog. It should be short.\r
+//\r
+STATIC CONST CHAR8 mProductRevision[] = "2.0";\r
+\r
+#define NUM_VBE_MODES 3\r
+STATIC CONST UINT16 vbeModeIds[] = {\r
+  0x13f,  // 640x480x32\r
+  0x140,  // 800x600x32\r
+  0x141   // 1024x768x32\r
+};\r
+\r
+// Modes can be toggled with bit-0\r
+#define VBE_MODE_ENABLED  0x00BB\r
+#define VBE_MODE_DISABLED 0x00BA\r
+\r
+STATIC VBE2_MODE_INFO vbeModes[] = {\r
+  { // 0x13f 640x480x32\r
+\r
+    // ModeAttr - BytesPerScanLine\r
+    VBE_MODE_DISABLED, 0x07, 0x00, 0x40, 0x40, 0xA000, 0x00, 0x0000, 640*4,\r
+    // Width, Height..., Vbe3\r
+    640, 480, 16, 8, 1, 32, 1, 0x06, 0, 0, 1,\r
+    // Masks\r
+    0x08, 0x10, 0x08, 0x08, 0x08, 0x00, 0x08, 0x18, 0x00,\r
+    // Framebuffer\r
+    0xdeadbeef, 0x0000, 0x0000\r
+  },\r
+  { // 0x140 800x600x32\r
+\r
+    // ModeAttr - BytesPerScanLine\r
+    VBE_MODE_DISABLED, 0x07, 0x00, 0x40, 0x40, 0xA000, 0x00, 0x0000, 800*4,\r
+    // Width, Height..., Vbe3\r
+    800, 600, 16, 8, 1, 32, 1, 0x06, 0, 0, 1,\r
+    // Masks\r
+    0x08, 0x10, 0x08, 0x08, 0x08, 0x00, 0x08, 0x18, 0x00,\r
+    // Framebuffer\r
+    0xdeadbeef, 0x0000, 0x0000\r
+  },\r
+  { // 0x141 1024x768x32\r
+\r
+    // ModeAttr - BytesPerScanLine\r
+    VBE_MODE_ENABLED, 0x07, 0x00, 0x40, 0x40, 0xA000, 0x00, 0x0000, 1024*4,\r
+    // Width, Height..., Vbe3\r
+    1024, 768, 16, 8, 1, 32, 1, 0x06, 0, 0, 1,\r
+    // Masks\r
+    0x08, 0x10, 0x08, 0x08, 0x08, 0x00, 0x08, 0x18, 0x00,\r
+    // Framebuffer\r
+    0xdeadbeef, 0x0000, 0x0000\r
+  }\r
+};\r
+\r
+/**\r
+  Install the VBE Info and VBE Mode Info structures, and the VBE service\r
+  handler routine in the C segment. Point the real-mode Int10h interrupt vector\r
+  to the handler. The only advertised mode is 1024x768x32.\r
+\r
+  @param[in] CardName         Name of the video card to be exposed in the\r
+                              Product Name field of the VBE Info structure.\r
+  @param[in] FrameBufferBase  Guest-physical base address of the video card's\r
+                              frame buffer.\r
+**/\r
+VOID\r
+InstallVbeShim (\r
+  IN CONST CHAR16         *CardName,\r
+  IN EFI_PHYSICAL_ADDRESS FrameBufferBase\r
+  )\r
+{\r
+  EFI_PHYSICAL_ADDRESS Segment0, SegmentC, SegmentF;\r
+  UINTN                Segment0Pages;\r
+  IVT_ENTRY            *Int0x10;\r
+  EFI_STATUS           Status;\r
+  UINTN                Pam1Address;\r
+  UINT8                Pam1;\r
+  UINTN                SegmentCPages;\r
+  VBE_INFO             *VbeInfoFull;\r
+  VBE_INFO_BASE        *VbeInfo;\r
+  UINT8                *Ptr;\r
+  UINTN                Printed;\r
+  VBE_MODE_INFO        *VbeModeInfo;\r
+  UINTN                i;\r
+\r
+  Segment0 = 0x00000;\r
+  SegmentC = 0xC0000;\r
+  SegmentF = 0xF0000;\r
+\r
+  //\r
+  // Attempt to cover the real mode IVT with an allocation. This is a UEFI\r
+  // driver, hence the arch protocols have been installed previously. Among\r
+  // those, the CPU arch protocol has configured the IDT, so we can overwrite\r
+  // the IVT used in real mode.\r
+  //\r
+  // The allocation request may fail, eg. if LegacyBiosDxe has already run.\r
+  //\r
+  Segment0Pages = 1;\r
+  Int0x10       = (IVT_ENTRY *)(UINTN)Segment0 + 0x10;\r
+  Status = gBS->AllocatePages (AllocateAddress, EfiBootServicesCode,\r
+                  Segment0Pages, &Segment0);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    EFI_PHYSICAL_ADDRESS Handler;\r
+\r
+    //\r
+    // Check if a video BIOS handler has been installed previously -- we\r
+    // shouldn't override a real video BIOS with our shim, nor our own shim if\r
+    // it's already present.\r
+    //\r
+    Handler = (Int0x10->Segment << 4) + Int0x10->Offset;\r
+    if (Handler >= SegmentC && Handler < SegmentF) {\r
+      DEBUG ((DEBUG_VERBOSE, "%a: Video BIOS handler found at %04x:%04x\n",\r
+        __FUNCTION__, Int0x10->Segment, Int0x10->Offset));\r
+      return;\r
+    }\r
+\r
+    //\r
+    // Otherwise we'll overwrite the Int10h vector, even though we may not own\r
+    // the page at zero.\r
+    //\r
+    DEBUG ((DEBUG_VERBOSE, "%a: failed to allocate page at zero: %r\n",\r
+      __FUNCTION__, Status));\r
+  } else {\r
+    //\r
+    // We managed to allocate the page at zero. SVN r14218 guarantees that it\r
+    // is NUL-filled.\r
+    //\r
+    ASSERT (Int0x10->Segment == 0x0000);\r
+    ASSERT (Int0x10->Offset  == 0x0000);\r
+  }\r
+\r
+  //\r
+  // Put the shim in place first.\r
+  //\r
+  Pam1Address = PCI_LIB_ADDRESS (0, 0, 0, 0x5A);\r
+  //\r
+  // low nibble covers 0xC0000 to 0xC3FFF\r
+  // high nibble covers 0xC4000 to 0xC7FFF\r
+  // bit1 in each nibble is Write Enable\r
+  // bit0 in each nibble is Read Enable\r
+  //\r
+  Pam1 = PciRead8 (Pam1Address);\r
+  PciWrite8 (Pam1Address, Pam1 | (BIT1 | BIT0));\r
+\r
+  //\r
+  // We never added memory space durig PEI or DXE for the C segment, so we\r
+  // don't need to (and can't) allocate from there. Also, guest operating\r
+  // systems will see a hole in the UEFI memory map there.\r
+  //\r
+  SegmentCPages = 4;\r
+\r
+  ASSERT (sizeof mVbeShim <= EFI_PAGES_TO_SIZE (SegmentCPages));\r
+  CopyMem ((VOID *)(UINTN)SegmentC, mVbeShim, sizeof mVbeShim);\r
+\r
+  //\r
+  // Fill in the VBE INFO structure.\r
+  //\r
+  VbeInfoFull = (VBE_INFO *)(UINTN)SegmentC;\r
+  VbeInfo     = &VbeInfoFull->Base;\r
+  Ptr         = VbeInfoFull->Buffer;\r
+\r
+  CopyMem (VbeInfo->Signature, "VESA", 4);\r
+  VbeInfo->VesaVersion = 0x0200;\r
+\r
+  VbeInfo->OemNameAddress = (UINT32)SegmentC << 12 | (UINT16)((UINTN)Ptr-SegmentC);\r
+  CopyMem (Ptr, "FBSD", 5);\r
+  Ptr += 5;\r
+\r
+  VbeInfo->Capabilities = BIT1 | BIT0; // DAC can be switched into 8-bit mode\r
+\r
+  VbeInfo->ModeListAddress = (UINT32)SegmentC << 12 | (UINT16)((UINTN)Ptr-SegmentC);\r
+  for (i = 0; i < NUM_VBE_MODES; i ++) {\r
+     *(UINT16*)Ptr = vbeModeIds[i];  // mode number\r
+     Ptr += 2;\r
+  }\r
+  *(UINT16*)Ptr = 0xFFFF; // mode list terminator\r
+  Ptr += 2;\r
+\r
+  VbeInfo->VideoMem64K = (UINT16)((1024 * 768 * 4 + 65535) / 65536);\r
+  VbeInfo->OemSoftwareVersion = 0x0200;\r
+\r
+  VbeInfo->VendorNameAddress = (UINT32)SegmentC << 12 | (UINT16)((UINTN)Ptr-SegmentC);\r
+  CopyMem (Ptr, "FBSD", 5);\r
+  Ptr += 5;\r
+\r
+  VbeInfo->ProductNameAddress = (UINT32)SegmentC << 12 | (UINT16)((UINTN)Ptr-SegmentC);\r
+  Printed = AsciiSPrint ((CHAR8 *)Ptr,\r
+              sizeof VbeInfoFull->Buffer - (Ptr - VbeInfoFull->Buffer), "%s",\r
+              CardName);\r
+  Ptr += Printed + 1;\r
+\r
+  VbeInfo->ProductRevAddress = (UINT32)SegmentC << 12 | (UINT16)((UINTN)Ptr-SegmentC);\r
+  CopyMem (Ptr, mProductRevision, sizeof mProductRevision);\r
+  Ptr += sizeof mProductRevision;\r
+\r
+  ASSERT (sizeof VbeInfoFull->Buffer >= Ptr - VbeInfoFull->Buffer);\r
+  ZeroMem (Ptr, sizeof VbeInfoFull->Buffer - (Ptr - VbeInfoFull->Buffer));\r
+\r
+  //\r
+  // Fill in the VBE MODE INFO structure list\r
+  //\r
+  VbeModeInfo = (VBE_MODE_INFO *)(VbeInfoFull + 1);\r
+  Ptr = (UINT8 *)VbeModeInfo;\r
+  for (i = 0; i < NUM_VBE_MODES; i++) {\r
+    vbeModes[i].LfbAddress = (UINT32)FrameBufferBase;\r
+    CopyMem (Ptr, &vbeModes[i], 0x32);\r
+    Ptr += 0x32;\r
+  }\r
+\r
+  ZeroMem (Ptr, 56);     // Clear remaining bytes\r
+\r
+  //\r
+  // Clear Write Enable (bit1), keep Read Enable (bit0) set\r
+  //\r
+  PciWrite8 (Pam1Address, (Pam1 & ~BIT1) | BIT0);\r
+\r
+  //\r
+  // Second, point the Int10h vector at the shim.\r
+  //\r
+  Int0x10->Segment = (UINT16) ((UINT32)SegmentC >> 4);\r
+  Int0x10->Offset  = (UINT16) ((UINTN) (VbeModeInfo + 1) - SegmentC);\r
+\r
+  DEBUG ((DEBUG_INFO, "%a: VBE shim installed to %x:%x\n",\r
+         __FUNCTION__, Int0x10->Segment, Int0x10->Offset));\r
+}\r
diff --git a/OvmfPkg/Bhyve/BhyveRfbDxe/VbeShim.h b/OvmfPkg/Bhyve/BhyveRfbDxe/VbeShim.h
new file mode 100644 (file)
index 0000000..72b8a3f
--- /dev/null
@@ -0,0 +1,912 @@
+//\r
+// THIS FILE WAS GENERATED BY "VbeShim.sh". DO NOT EDIT.\r
+//\r
+#ifndef _VBE_SHIM_H_\r
+#define _VBE_SHIM_H_\r
+STATIC CONST UINT8 mVbeShim[] = {\r
+  /* 00000000 nop                            */  0x90,\r
+  /* 00000001 nop                            */  0x90,\r
+  /* 00000002 nop                            */  0x90,\r
+  /* 00000003 nop                            */  0x90,\r
+  /* 00000004 nop                            */  0x90,\r
+  /* 00000005 nop                            */  0x90,\r
+  /* 00000006 nop                            */  0x90,\r
+  /* 00000007 nop                            */  0x90,\r
+  /* 00000008 nop                            */  0x90,\r
+  /* 00000009 nop                            */  0x90,\r
+  /* 0000000A nop                            */  0x90,\r
+  /* 0000000B nop                            */  0x90,\r
+  /* 0000000C nop                            */  0x90,\r
+  /* 0000000D nop                            */  0x90,\r
+  /* 0000000E nop                            */  0x90,\r
+  /* 0000000F nop                            */  0x90,\r
+  /* 00000010 nop                            */  0x90,\r
+  /* 00000011 nop                            */  0x90,\r
+  /* 00000012 nop                            */  0x90,\r
+  /* 00000013 nop                            */  0x90,\r
+  /* 00000014 nop                            */  0x90,\r
+  /* 00000015 nop                            */  0x90,\r
+  /* 00000016 nop                            */  0x90,\r
+  /* 00000017 nop                            */  0x90,\r
+  /* 00000018 nop                            */  0x90,\r
+  /* 00000019 nop                            */  0x90,\r
+  /* 0000001A nop                            */  0x90,\r
+  /* 0000001B nop                            */  0x90,\r
+  /* 0000001C nop                            */  0x90,\r
+  /* 0000001D nop                            */  0x90,\r
+  /* 0000001E nop                            */  0x90,\r
+  /* 0000001F nop                            */  0x90,\r
+  /* 00000020 nop                            */  0x90,\r
+  /* 00000021 nop                            */  0x90,\r
+  /* 00000022 nop                            */  0x90,\r
+  /* 00000023 nop                            */  0x90,\r
+  /* 00000024 nop                            */  0x90,\r
+  /* 00000025 nop                            */  0x90,\r
+  /* 00000026 nop                            */  0x90,\r
+  /* 00000027 nop                            */  0x90,\r
+  /* 00000028 nop                            */  0x90,\r
+  /* 00000029 nop                            */  0x90,\r
+  /* 0000002A nop                            */  0x90,\r
+  /* 0000002B nop                            */  0x90,\r
+  /* 0000002C nop                            */  0x90,\r
+  /* 0000002D nop                            */  0x90,\r
+  /* 0000002E nop                            */  0x90,\r
+  /* 0000002F nop                            */  0x90,\r
+  /* 00000030 nop                            */  0x90,\r
+  /* 00000031 nop                            */  0x90,\r
+  /* 00000032 nop                            */  0x90,\r
+  /* 00000033 nop                            */  0x90,\r
+  /* 00000034 nop                            */  0x90,\r
+  /* 00000035 nop                            */  0x90,\r
+  /* 00000036 nop                            */  0x90,\r
+  /* 00000037 nop                            */  0x90,\r
+  /* 00000038 nop                            */  0x90,\r
+  /* 00000039 nop                            */  0x90,\r
+  /* 0000003A nop                            */  0x90,\r
+  /* 0000003B nop                            */  0x90,\r
+  /* 0000003C nop                            */  0x90,\r
+  /* 0000003D nop                            */  0x90,\r
+  /* 0000003E nop                            */  0x90,\r
+  /* 0000003F nop                            */  0x90,\r
+  /* 00000040 nop                            */  0x90,\r
+  /* 00000041 nop                            */  0x90,\r
+  /* 00000042 nop                            */  0x90,\r
+  /* 00000043 nop                            */  0x90,\r
+  /* 00000044 nop                            */  0x90,\r
+  /* 00000045 nop                            */  0x90,\r
+  /* 00000046 nop                            */  0x90,\r
+  /* 00000047 nop                            */  0x90,\r
+  /* 00000048 nop                            */  0x90,\r
+  /* 00000049 nop                            */  0x90,\r
+  /* 0000004A nop                            */  0x90,\r
+  /* 0000004B nop                            */  0x90,\r
+  /* 0000004C nop                            */  0x90,\r
+  /* 0000004D nop                            */  0x90,\r
+  /* 0000004E nop                            */  0x90,\r
+  /* 0000004F nop                            */  0x90,\r
+  /* 00000050 nop                            */  0x90,\r
+  /* 00000051 nop                            */  0x90,\r
+  /* 00000052 nop                            */  0x90,\r
+  /* 00000053 nop                            */  0x90,\r
+  /* 00000054 nop                            */  0x90,\r
+  /* 00000055 nop                            */  0x90,\r
+  /* 00000056 nop                            */  0x90,\r
+  /* 00000057 nop                            */  0x90,\r
+  /* 00000058 nop                            */  0x90,\r
+  /* 00000059 nop                            */  0x90,\r
+  /* 0000005A nop                            */  0x90,\r
+  /* 0000005B nop                            */  0x90,\r
+  /* 0000005C nop                            */  0x90,\r
+  /* 0000005D nop                            */  0x90,\r
+  /* 0000005E nop                            */  0x90,\r
+  /* 0000005F nop                            */  0x90,\r
+  /* 00000060 nop                            */  0x90,\r
+  /* 00000061 nop                            */  0x90,\r
+  /* 00000062 nop                            */  0x90,\r
+  /* 00000063 nop                            */  0x90,\r
+  /* 00000064 nop                            */  0x90,\r
+  /* 00000065 nop                            */  0x90,\r
+  /* 00000066 nop                            */  0x90,\r
+  /* 00000067 nop                            */  0x90,\r
+  /* 00000068 nop                            */  0x90,\r
+  /* 00000069 nop                            */  0x90,\r
+  /* 0000006A nop                            */  0x90,\r
+  /* 0000006B nop                            */  0x90,\r
+  /* 0000006C nop                            */  0x90,\r
+  /* 0000006D nop                            */  0x90,\r
+  /* 0000006E nop                            */  0x90,\r
+  /* 0000006F nop                            */  0x90,\r
+  /* 00000070 nop                            */  0x90,\r
+  /* 00000071 nop                            */  0x90,\r
+  /* 00000072 nop                            */  0x90,\r
+  /* 00000073 nop                            */  0x90,\r
+  /* 00000074 nop                            */  0x90,\r
+  /* 00000075 nop                            */  0x90,\r
+  /* 00000076 nop                            */  0x90,\r
+  /* 00000077 nop                            */  0x90,\r
+  /* 00000078 nop                            */  0x90,\r
+  /* 00000079 nop                            */  0x90,\r
+  /* 0000007A nop                            */  0x90,\r
+  /* 0000007B nop                            */  0x90,\r
+  /* 0000007C nop                            */  0x90,\r
+  /* 0000007D nop                            */  0x90,\r
+  /* 0000007E nop                            */  0x90,\r
+  /* 0000007F nop                            */  0x90,\r
+  /* 00000080 nop                            */  0x90,\r
+  /* 00000081 nop                            */  0x90,\r
+  /* 00000082 nop                            */  0x90,\r
+  /* 00000083 nop                            */  0x90,\r
+  /* 00000084 nop                            */  0x90,\r
+  /* 00000085 nop                            */  0x90,\r
+  /* 00000086 nop                            */  0x90,\r
+  /* 00000087 nop                            */  0x90,\r
+  /* 00000088 nop                            */  0x90,\r
+  /* 00000089 nop                            */  0x90,\r
+  /* 0000008A nop                            */  0x90,\r
+  /* 0000008B nop                            */  0x90,\r
+  /* 0000008C nop                            */  0x90,\r
+  /* 0000008D nop                            */  0x90,\r
+  /* 0000008E nop                            */  0x90,\r
+  /* 0000008F nop                            */  0x90,\r
+  /* 00000090 nop                            */  0x90,\r
+  /* 00000091 nop                            */  0x90,\r
+  /* 00000092 nop                            */  0x90,\r
+  /* 00000093 nop                            */  0x90,\r
+  /* 00000094 nop                            */  0x90,\r
+  /* 00000095 nop                            */  0x90,\r
+  /* 00000096 nop                            */  0x90,\r
+  /* 00000097 nop                            */  0x90,\r
+  /* 00000098 nop                            */  0x90,\r
+  /* 00000099 nop                            */  0x90,\r
+  /* 0000009A nop                            */  0x90,\r
+  /* 0000009B nop                            */  0x90,\r
+  /* 0000009C nop                            */  0x90,\r
+  /* 0000009D nop                            */  0x90,\r
+  /* 0000009E nop                            */  0x90,\r
+  /* 0000009F nop                            */  0x90,\r
+  /* 000000A0 nop                            */  0x90,\r
+  /* 000000A1 nop                            */  0x90,\r
+  /* 000000A2 nop                            */  0x90,\r
+  /* 000000A3 nop                            */  0x90,\r
+  /* 000000A4 nop                            */  0x90,\r
+  /* 000000A5 nop                            */  0x90,\r
+  /* 000000A6 nop                            */  0x90,\r
+  /* 000000A7 nop                            */  0x90,\r
+  /* 000000A8 nop                            */  0x90,\r
+  /* 000000A9 nop                            */  0x90,\r
+  /* 000000AA nop                            */  0x90,\r
+  /* 000000AB nop                            */  0x90,\r
+  /* 000000AC nop                            */  0x90,\r
+  /* 000000AD nop                            */  0x90,\r
+  /* 000000AE nop                            */  0x90,\r
+  /* 000000AF nop                            */  0x90,\r
+  /* 000000B0 nop                            */  0x90,\r
+  /* 000000B1 nop                            */  0x90,\r
+  /* 000000B2 nop                            */  0x90,\r
+  /* 000000B3 nop                            */  0x90,\r
+  /* 000000B4 nop                            */  0x90,\r
+  /* 000000B5 nop                            */  0x90,\r
+  /* 000000B6 nop                            */  0x90,\r
+  /* 000000B7 nop                            */  0x90,\r
+  /* 000000B8 nop                            */  0x90,\r
+  /* 000000B9 nop                            */  0x90,\r
+  /* 000000BA nop                            */  0x90,\r
+  /* 000000BB nop                            */  0x90,\r
+  /* 000000BC nop                            */  0x90,\r
+  /* 000000BD nop                            */  0x90,\r
+  /* 000000BE nop                            */  0x90,\r
+  /* 000000BF nop                            */  0x90,\r
+  /* 000000C0 nop                            */  0x90,\r
+  /* 000000C1 nop                            */  0x90,\r
+  /* 000000C2 nop                            */  0x90,\r
+  /* 000000C3 nop                            */  0x90,\r
+  /* 000000C4 nop                            */  0x90,\r
+  /* 000000C5 nop                            */  0x90,\r
+  /* 000000C6 nop                            */  0x90,\r
+  /* 000000C7 nop                            */  0x90,\r
+  /* 000000C8 nop                            */  0x90,\r
+  /* 000000C9 nop                            */  0x90,\r
+  /* 000000CA nop                            */  0x90,\r
+  /* 000000CB nop                            */  0x90,\r
+  /* 000000CC nop                            */  0x90,\r
+  /* 000000CD nop                            */  0x90,\r
+  /* 000000CE nop                            */  0x90,\r
+  /* 000000CF nop                            */  0x90,\r
+  /* 000000D0 nop                            */  0x90,\r
+  /* 000000D1 nop                            */  0x90,\r
+  /* 000000D2 nop                            */  0x90,\r
+  /* 000000D3 nop                            */  0x90,\r
+  /* 000000D4 nop                            */  0x90,\r
+  /* 000000D5 nop                            */  0x90,\r
+  /* 000000D6 nop                            */  0x90,\r
+  /* 000000D7 nop                            */  0x90,\r
+  /* 000000D8 nop                            */  0x90,\r
+  /* 000000D9 nop                            */  0x90,\r
+  /* 000000DA nop                            */  0x90,\r
+  /* 000000DB nop                            */  0x90,\r
+  /* 000000DC nop                            */  0x90,\r
+  /* 000000DD nop                            */  0x90,\r
+  /* 000000DE nop                            */  0x90,\r
+  /* 000000DF nop                            */  0x90,\r
+  /* 000000E0 nop                            */  0x90,\r
+  /* 000000E1 nop                            */  0x90,\r
+  /* 000000E2 nop                            */  0x90,\r
+  /* 000000E3 nop                            */  0x90,\r
+  /* 000000E4 nop                            */  0x90,\r
+  /* 000000E5 nop                            */  0x90,\r
+  /* 000000E6 nop                            */  0x90,\r
+  /* 000000E7 nop                            */  0x90,\r
+  /* 000000E8 nop                            */  0x90,\r
+  /* 000000E9 nop                            */  0x90,\r
+  /* 000000EA nop                            */  0x90,\r
+  /* 000000EB nop                            */  0x90,\r
+  /* 000000EC nop                            */  0x90,\r
+  /* 000000ED nop                            */  0x90,\r
+  /* 000000EE nop                            */  0x90,\r
+  /* 000000EF nop                            */  0x90,\r
+  /* 000000F0 nop                            */  0x90,\r
+  /* 000000F1 nop                            */  0x90,\r
+  /* 000000F2 nop                            */  0x90,\r
+  /* 000000F3 nop                            */  0x90,\r
+  /* 000000F4 nop                            */  0x90,\r
+  /* 000000F5 nop                            */  0x90,\r
+  /* 000000F6 nop                            */  0x90,\r
+  /* 000000F7 nop                            */  0x90,\r
+  /* 000000F8 nop                            */  0x90,\r
+  /* 000000F9 nop                            */  0x90,\r
+  /* 000000FA nop                            */  0x90,\r
+  /* 000000FB nop                            */  0x90,\r
+  /* 000000FC nop                            */  0x90,\r
+  /* 000000FD nop                            */  0x90,\r
+  /* 000000FE nop                            */  0x90,\r
+  /* 000000FF nop                            */  0x90,\r
+  /* 00000100 nop                            */  0x90,\r
+  /* 00000101 nop                            */  0x90,\r
+  /* 00000102 nop                            */  0x90,\r
+  /* 00000103 nop                            */  0x90,\r
+  /* 00000104 nop                            */  0x90,\r
+  /* 00000105 nop                            */  0x90,\r
+  /* 00000106 nop                            */  0x90,\r
+  /* 00000107 nop                            */  0x90,\r
+  /* 00000108 nop                            */  0x90,\r
+  /* 00000109 nop                            */  0x90,\r
+  /* 0000010A nop                            */  0x90,\r
+  /* 0000010B nop                            */  0x90,\r
+  /* 0000010C nop                            */  0x90,\r
+  /* 0000010D nop                            */  0x90,\r
+  /* 0000010E nop                            */  0x90,\r
+  /* 0000010F nop                            */  0x90,\r
+  /* 00000110 nop                            */  0x90,\r
+  /* 00000111 nop                            */  0x90,\r
+  /* 00000112 nop                            */  0x90,\r
+  /* 00000113 nop                            */  0x90,\r
+  /* 00000114 nop                            */  0x90,\r
+  /* 00000115 nop                            */  0x90,\r
+  /* 00000116 nop                            */  0x90,\r
+  /* 00000117 nop                            */  0x90,\r
+  /* 00000118 nop                            */  0x90,\r
+  /* 00000119 nop                            */  0x90,\r
+  /* 0000011A nop                            */  0x90,\r
+  /* 0000011B nop                            */  0x90,\r
+  /* 0000011C nop                            */  0x90,\r
+  /* 0000011D nop                            */  0x90,\r
+  /* 0000011E nop                            */  0x90,\r
+  /* 0000011F nop                            */  0x90,\r
+  /* 00000120 nop                            */  0x90,\r
+  /* 00000121 nop                            */  0x90,\r
+  /* 00000122 nop                            */  0x90,\r
+  /* 00000123 nop                            */  0x90,\r
+  /* 00000124 nop                            */  0x90,\r
+  /* 00000125 nop                            */  0x90,\r
+  /* 00000126 nop                            */  0x90,\r
+  /* 00000127 nop                            */  0x90,\r
+  /* 00000128 nop                            */  0x90,\r
+  /* 00000129 nop                            */  0x90,\r
+  /* 0000012A nop                            */  0x90,\r
+  /* 0000012B nop                            */  0x90,\r
+  /* 0000012C nop                            */  0x90,\r
+  /* 0000012D nop                            */  0x90,\r
+  /* 0000012E nop                            */  0x90,\r
+  /* 0000012F nop                            */  0x90,\r
+  /* 00000130 nop                            */  0x90,\r
+  /* 00000131 nop                            */  0x90,\r
+  /* 00000132 nop                            */  0x90,\r
+  /* 00000133 nop                            */  0x90,\r
+  /* 00000134 nop                            */  0x90,\r
+  /* 00000135 nop                            */  0x90,\r
+  /* 00000136 nop                            */  0x90,\r
+  /* 00000137 nop                            */  0x90,\r
+  /* 00000138 nop                            */  0x90,\r
+  /* 00000139 nop                            */  0x90,\r
+  /* 0000013A nop                            */  0x90,\r
+  /* 0000013B nop                            */  0x90,\r
+  /* 0000013C nop                            */  0x90,\r
+  /* 0000013D nop                            */  0x90,\r
+  /* 0000013E nop                            */  0x90,\r
+  /* 0000013F nop                            */  0x90,\r
+  /* 00000140 nop                            */  0x90,\r
+  /* 00000141 nop                            */  0x90,\r
+  /* 00000142 nop                            */  0x90,\r
+  /* 00000143 nop                            */  0x90,\r
+  /* 00000144 nop                            */  0x90,\r
+  /* 00000145 nop                            */  0x90,\r
+  /* 00000146 nop                            */  0x90,\r
+  /* 00000147 nop                            */  0x90,\r
+  /* 00000148 nop                            */  0x90,\r
+  /* 00000149 nop                            */  0x90,\r
+  /* 0000014A nop                            */  0x90,\r
+  /* 0000014B nop                            */  0x90,\r
+  /* 0000014C nop                            */  0x90,\r
+  /* 0000014D nop                            */  0x90,\r
+  /* 0000014E nop                            */  0x90,\r
+  /* 0000014F nop                            */  0x90,\r
+  /* 00000150 nop                            */  0x90,\r
+  /* 00000151 nop                            */  0x90,\r
+  /* 00000152 nop                            */  0x90,\r
+  /* 00000153 nop                            */  0x90,\r
+  /* 00000154 nop                            */  0x90,\r
+  /* 00000155 nop                            */  0x90,\r
+  /* 00000156 nop                            */  0x90,\r
+  /* 00000157 nop                            */  0x90,\r
+  /* 00000158 nop                            */  0x90,\r
+  /* 00000159 nop                            */  0x90,\r
+  /* 0000015A nop                            */  0x90,\r
+  /* 0000015B nop                            */  0x90,\r
+  /* 0000015C nop                            */  0x90,\r
+  /* 0000015D nop                            */  0x90,\r
+  /* 0000015E nop                            */  0x90,\r
+  /* 0000015F nop                            */  0x90,\r
+  /* 00000160 nop                            */  0x90,\r
+  /* 00000161 nop                            */  0x90,\r
+  /* 00000162 nop                            */  0x90,\r
+  /* 00000163 nop                            */  0x90,\r
+  /* 00000164 nop                            */  0x90,\r
+  /* 00000165 nop                            */  0x90,\r
+  /* 00000166 nop                            */  0x90,\r
+  /* 00000167 nop                            */  0x90,\r
+  /* 00000168 nop                            */  0x90,\r
+  /* 00000169 nop                            */  0x90,\r
+  /* 0000016A nop                            */  0x90,\r
+  /* 0000016B nop                            */  0x90,\r
+  /* 0000016C nop                            */  0x90,\r
+  /* 0000016D nop                            */  0x90,\r
+  /* 0000016E nop                            */  0x90,\r
+  /* 0000016F nop                            */  0x90,\r
+  /* 00000170 nop                            */  0x90,\r
+  /* 00000171 nop                            */  0x90,\r
+  /* 00000172 nop                            */  0x90,\r
+  /* 00000173 nop                            */  0x90,\r
+  /* 00000174 nop                            */  0x90,\r
+  /* 00000175 nop                            */  0x90,\r
+  /* 00000176 nop                            */  0x90,\r
+  /* 00000177 nop                            */  0x90,\r
+  /* 00000178 nop                            */  0x90,\r
+  /* 00000179 nop                            */  0x90,\r
+  /* 0000017A nop                            */  0x90,\r
+  /* 0000017B nop                            */  0x90,\r
+  /* 0000017C nop                            */  0x90,\r
+  /* 0000017D nop                            */  0x90,\r
+  /* 0000017E nop                            */  0x90,\r
+  /* 0000017F nop                            */  0x90,\r
+  /* 00000180 nop                            */  0x90,\r
+  /* 00000181 nop                            */  0x90,\r
+  /* 00000182 nop                            */  0x90,\r
+  /* 00000183 nop                            */  0x90,\r
+  /* 00000184 nop                            */  0x90,\r
+  /* 00000185 nop                            */  0x90,\r
+  /* 00000186 nop                            */  0x90,\r
+  /* 00000187 nop                            */  0x90,\r
+  /* 00000188 nop                            */  0x90,\r
+  /* 00000189 nop                            */  0x90,\r
+  /* 0000018A nop                            */  0x90,\r
+  /* 0000018B nop                            */  0x90,\r
+  /* 0000018C nop                            */  0x90,\r
+  /* 0000018D nop                            */  0x90,\r
+  /* 0000018E nop                            */  0x90,\r
+  /* 0000018F nop                            */  0x90,\r
+  /* 00000190 nop                            */  0x90,\r
+  /* 00000191 nop                            */  0x90,\r
+  /* 00000192 nop                            */  0x90,\r
+  /* 00000193 nop                            */  0x90,\r
+  /* 00000194 nop                            */  0x90,\r
+  /* 00000195 nop                            */  0x90,\r
+  /* 00000196 nop                            */  0x90,\r
+  /* 00000197 nop                            */  0x90,\r
+  /* 00000198 nop                            */  0x90,\r
+  /* 00000199 nop                            */  0x90,\r
+  /* 0000019A nop                            */  0x90,\r
+  /* 0000019B nop                            */  0x90,\r
+  /* 0000019C nop                            */  0x90,\r
+  /* 0000019D nop                            */  0x90,\r
+  /* 0000019E nop                            */  0x90,\r
+  /* 0000019F nop                            */  0x90,\r
+  /* 000001A0 nop                            */  0x90,\r
+  /* 000001A1 nop                            */  0x90,\r
+  /* 000001A2 nop                            */  0x90,\r
+  /* 000001A3 nop                            */  0x90,\r
+  /* 000001A4 nop                            */  0x90,\r
+  /* 000001A5 nop                            */  0x90,\r
+  /* 000001A6 nop                            */  0x90,\r
+  /* 000001A7 nop                            */  0x90,\r
+  /* 000001A8 nop                            */  0x90,\r
+  /* 000001A9 nop                            */  0x90,\r
+  /* 000001AA nop                            */  0x90,\r
+  /* 000001AB nop                            */  0x90,\r
+  /* 000001AC nop                            */  0x90,\r
+  /* 000001AD nop                            */  0x90,\r
+  /* 000001AE nop                            */  0x90,\r
+  /* 000001AF nop                            */  0x90,\r
+  /* 000001B0 nop                            */  0x90,\r
+  /* 000001B1 nop                            */  0x90,\r
+  /* 000001B2 nop                            */  0x90,\r
+  /* 000001B3 nop                            */  0x90,\r
+  /* 000001B4 nop                            */  0x90,\r
+  /* 000001B5 nop                            */  0x90,\r
+  /* 000001B6 nop                            */  0x90,\r
+  /* 000001B7 nop                            */  0x90,\r
+  /* 000001B8 nop                            */  0x90,\r
+  /* 000001B9 nop                            */  0x90,\r
+  /* 000001BA nop                            */  0x90,\r
+  /* 000001BB nop                            */  0x90,\r
+  /* 000001BC nop                            */  0x90,\r
+  /* 000001BD nop                            */  0x90,\r
+  /* 000001BE nop                            */  0x90,\r
+  /* 000001BF nop                            */  0x90,\r
+  /* 000001C0 nop                            */  0x90,\r
+  /* 000001C1 nop                            */  0x90,\r
+  /* 000001C2 nop                            */  0x90,\r
+  /* 000001C3 nop                            */  0x90,\r
+  /* 000001C4 nop                            */  0x90,\r
+  /* 000001C5 nop                            */  0x90,\r
+  /* 000001C6 nop                            */  0x90,\r
+  /* 000001C7 nop                            */  0x90,\r
+  /* 000001C8 nop                            */  0x90,\r
+  /* 000001C9 nop                            */  0x90,\r
+  /* 000001CA nop                            */  0x90,\r
+  /* 000001CB nop                            */  0x90,\r
+  /* 000001CC nop                            */  0x90,\r
+  /* 000001CD nop                            */  0x90,\r
+  /* 000001CE nop                            */  0x90,\r
+  /* 000001CF nop                            */  0x90,\r
+  /* 000001D0 nop                            */  0x90,\r
+  /* 000001D1 nop                            */  0x90,\r
+  /* 000001D2 nop                            */  0x90,\r
+  /* 000001D3 nop                            */  0x90,\r
+  /* 000001D4 nop                            */  0x90,\r
+  /* 000001D5 nop                            */  0x90,\r
+  /* 000001D6 nop                            */  0x90,\r
+  /* 000001D7 nop                            */  0x90,\r
+  /* 000001D8 nop                            */  0x90,\r
+  /* 000001D9 nop                            */  0x90,\r
+  /* 000001DA nop                            */  0x90,\r
+  /* 000001DB nop                            */  0x90,\r
+  /* 000001DC nop                            */  0x90,\r
+  /* 000001DD nop                            */  0x90,\r
+  /* 000001DE nop                            */  0x90,\r
+  /* 000001DF nop                            */  0x90,\r
+  /* 000001E0 nop                            */  0x90,\r
+  /* 000001E1 nop                            */  0x90,\r
+  /* 000001E2 nop                            */  0x90,\r
+  /* 000001E3 nop                            */  0x90,\r
+  /* 000001E4 nop                            */  0x90,\r
+  /* 000001E5 nop                            */  0x90,\r
+  /* 000001E6 nop                            */  0x90,\r
+  /* 000001E7 nop                            */  0x90,\r
+  /* 000001E8 nop                            */  0x90,\r
+  /* 000001E9 nop                            */  0x90,\r
+  /* 000001EA nop                            */  0x90,\r
+  /* 000001EB nop                            */  0x90,\r
+  /* 000001EC nop                            */  0x90,\r
+  /* 000001ED nop                            */  0x90,\r
+  /* 000001EE nop                            */  0x90,\r
+  /* 000001EF nop                            */  0x90,\r
+  /* 000001F0 nop                            */  0x90,\r
+  /* 000001F1 nop                            */  0x90,\r
+  /* 000001F2 nop                            */  0x90,\r
+  /* 000001F3 nop                            */  0x90,\r
+  /* 000001F4 nop                            */  0x90,\r
+  /* 000001F5 nop                            */  0x90,\r
+  /* 000001F6 nop                            */  0x90,\r
+  /* 000001F7 nop                            */  0x90,\r
+  /* 000001F8 nop                            */  0x90,\r
+  /* 000001F9 nop                            */  0x90,\r
+  /* 000001FA nop                            */  0x90,\r
+  /* 000001FB nop                            */  0x90,\r
+  /* 000001FC nop                            */  0x90,\r
+  /* 000001FD nop                            */  0x90,\r
+  /* 000001FE nop                            */  0x90,\r
+  /* 000001FF nop                            */  0x90,\r
+  /* 00000200 cmp ax,0x4f00                  */  0x3D, 0x00, 0x4F,\r
+  /* 00000203 jz 0x237                       */  0x74, 0x32,\r
+  /* 00000205 cmp ax,0x4f01                  */  0x3D, 0x01, 0x4F,\r
+  /* 00000208 jz 0x257                       */  0x74, 0x4D,\r
+  /* 0000020A cmp ax,0x4f02                  */  0x3D, 0x02, 0x4F,\r
+  /* 0000020D jz word 0x2c8                  */  0x0F, 0x84, 0xB7, 0x00,\r
+  /* 00000211 cmp ax,0x4f03                  */  0x3D, 0x03, 0x4F,\r
+  /* 00000214 jz word 0x325                  */  0x0F, 0x84, 0x0D, 0x01,\r
+  /* 00000218 cmp ax,0x4f10                  */  0x3D, 0x10, 0x4F,\r
+  /* 0000021B jz word 0x337                  */  0x0F, 0x84, 0x18, 0x01,\r
+  /* 0000021F cmp ax,0x4f15                  */  0x3D, 0x15, 0x4F,\r
+  /* 00000222 jz word 0x344                  */  0x0F, 0x84, 0x1E, 0x01,\r
+  /* 00000226 cmp ah,0x0                     */  0x80, 0xFC, 0x00,\r
+  /* 00000229 jz word 0x363                  */  0x0F, 0x84, 0x36, 0x01,\r
+  /* 0000022D push si                        */  0x56,\r
+  /* 0000022E mov si,0x3d7                   */  0xBE, 0xD7, 0x03,\r
+  /* 00000231 call word 0x3ad                */  0xE8, 0x79, 0x01,\r
+  /* 00000234 pop si                         */  0x5E,\r
+  /* 00000235 jmp short 0x235                */  0xEB, 0xFE,\r
+  /* 00000237 push es                        */  0x06,\r
+  /* 00000238 push di                        */  0x57,\r
+  /* 00000239 push ds                        */  0x1E,\r
+  /* 0000023A push si                        */  0x56,\r
+  /* 0000023B push cx                        */  0x51,\r
+  /* 0000023C push si                        */  0x56,\r
+  /* 0000023D mov si,0x3eb                   */  0xBE, 0xEB, 0x03,\r
+  /* 00000240 call word 0x3ad                */  0xE8, 0x6A, 0x01,\r
+  /* 00000243 pop si                         */  0x5E,\r
+  /* 00000244 push cs                        */  0x0E,\r
+  /* 00000245 pop ds                         */  0x1F,\r
+  /* 00000246 mov si,0x0                     */  0xBE, 0x00, 0x00,\r
+  /* 00000249 mov cx,0x100                   */  0xB9, 0x00, 0x01,\r
+  /* 0000024C cld                            */  0xFC,\r
+  /* 0000024D rep movsb                      */  0xF3, 0xA4,\r
+  /* 0000024F pop cx                         */  0x59,\r
+  /* 00000250 pop si                         */  0x5E,\r
+  /* 00000251 pop ds                         */  0x1F,\r
+  /* 00000252 pop di                         */  0x5F,\r
+  /* 00000253 pop es                         */  0x07,\r
+  /* 00000254 jmp word 0x395                 */  0xE9, 0x3E, 0x01,\r
+  /* 00000257 push es                        */  0x06,\r
+  /* 00000258 push di                        */  0x57,\r
+  /* 00000259 push ds                        */  0x1E,\r
+  /* 0000025A push si                        */  0x56,\r
+  /* 0000025B push cx                        */  0x51,\r
+  /* 0000025C push si                        */  0x56,\r
+  /* 0000025D mov si,0x3f6                   */  0xBE, 0xF6, 0x03,\r
+  /* 00000260 call word 0x3ad                */  0xE8, 0x4A, 0x01,\r
+  /* 00000263 pop si                         */  0x5E,\r
+  /* 00000264 and cx,0xbfff                  */  0x81, 0xE1, 0xFF, 0xBF,\r
+  /* 00000268 cmp cx,0x13f                   */  0x81, 0xF9, 0x3F, 0x01,\r
+  /* 0000026C jz 0x284                       */  0x74, 0x16,\r
+  /* 0000026E cmp cx,0x140                   */  0x81, 0xF9, 0x40, 0x01,\r
+  /* 00000272 jz 0x291                       */  0x74, 0x1D,\r
+  /* 00000274 cmp cx,0x141                   */  0x81, 0xF9, 0x41, 0x01,\r
+  /* 00000278 jz 0x29e                       */  0x74, 0x24,\r
+  /* 0000027A push si                        */  0x56,\r
+  /* 0000027B mov si,0x42c                   */  0xBE, 0x2C, 0x04,\r
+  /* 0000027E call word 0x3ad                */  0xE8, 0x2C, 0x01,\r
+  /* 00000281 pop si                         */  0x5E,\r
+  /* 00000282 jmp short 0x235                */  0xEB, 0xB1,\r
+  /* 00000284 push si                        */  0x56,\r
+  /* 00000285 mov si,0x46b                   */  0xBE, 0x6B, 0x04,\r
+  /* 00000288 call word 0x3ad                */  0xE8, 0x22, 0x01,\r
+  /* 0000028B pop si                         */  0x5E,\r
+  /* 0000028C mov si,0x100                   */  0xBE, 0x00, 0x01,\r
+  /* 0000028F jmp short 0x2b8                */  0xEB, 0x27,\r
+  /* 00000291 push si                        */  0x56,\r
+  /* 00000292 mov si,0x47d                   */  0xBE, 0x7D, 0x04,\r
+  /* 00000295 call word 0x3ad                */  0xE8, 0x15, 0x01,\r
+  /* 00000298 pop si                         */  0x5E,\r
+  /* 00000299 mov si,0x132                   */  0xBE, 0x32, 0x01,\r
+  /* 0000029C jmp short 0x2b8                */  0xEB, 0x1A,\r
+  /* 0000029E push si                        */  0x56,\r
+  /* 0000029F mov si,0x48f                   */  0xBE, 0x8F, 0x04,\r
+  /* 000002A2 call word 0x3ad                */  0xE8, 0x08, 0x01,\r
+  /* 000002A5 pop si                         */  0x5E,\r
+  /* 000002A6 mov si,0x164                   */  0xBE, 0x64, 0x01,\r
+  /* 000002A9 jmp short 0x2b8                */  0xEB, 0x0D,\r
+  /* 000002AB push si                        */  0x56,\r
+  /* 000002AC mov si,0x4a2                   */  0xBE, 0xA2, 0x04,\r
+  /* 000002AF call word 0x3ad                */  0xE8, 0xFB, 0x00,\r
+  /* 000002B2 pop si                         */  0x5E,\r
+  /* 000002B3 mov si,0x196                   */  0xBE, 0x96, 0x01,\r
+  /* 000002B6 jmp short 0x2b8                */  0xEB, 0x00,\r
+  /* 000002B8 push cs                        */  0x0E,\r
+  /* 000002B9 pop ds                         */  0x1F,\r
+  /* 000002BA mov cx,0x32                    */  0xB9, 0x32, 0x00,\r
+  /* 000002BD cld                            */  0xFC,\r
+  /* 000002BE rep movsb                      */  0xF3, 0xA4,\r
+  /* 000002C0 pop cx                         */  0x59,\r
+  /* 000002C1 pop si                         */  0x5E,\r
+  /* 000002C2 pop ds                         */  0x1F,\r
+  /* 000002C3 pop di                         */  0x5F,\r
+  /* 000002C4 pop es                         */  0x07,\r
+  /* 000002C5 jmp word 0x395                 */  0xE9, 0xCD, 0x00,\r
+  /* 000002C8 push dx                        */  0x52,\r
+  /* 000002C9 push ax                        */  0x50,\r
+  /* 000002CA push si                        */  0x56,\r
+  /* 000002CB mov si,0x410                   */  0xBE, 0x10, 0x04,\r
+  /* 000002CE call word 0x3ad                */  0xE8, 0xDC, 0x00,\r
+  /* 000002D1 pop si                         */  0x5E,\r
+  /* 000002D2 and bx,0xbfff                  */  0x81, 0xE3, 0xFF, 0xBF,\r
+  /* 000002D6 cmp bx,0x13f                   */  0x81, 0xFB, 0x3F, 0x01,\r
+  /* 000002DA jz 0x2f3                       */  0x74, 0x17,\r
+  /* 000002DC cmp bx,0x140                   */  0x81, 0xFB, 0x40, 0x01,\r
+  /* 000002E0 jz 0x2fd                       */  0x74, 0x1B,\r
+  /* 000002E2 cmp bx,0x141                   */  0x81, 0xFB, 0x41, 0x01,\r
+  /* 000002E6 jz 0x307                       */  0x74, 0x1F,\r
+  /* 000002E8 push si                        */  0x56,\r
+  /* 000002E9 mov si,0x42c                   */  0xBE, 0x2C, 0x04,\r
+  /* 000002EC call word 0x3ad                */  0xE8, 0xBE, 0x00,\r
+  /* 000002EF pop si                         */  0x5E,\r
+  /* 000002F0 jmp word 0x235                 */  0xE9, 0x42, 0xFF,\r
+  /* 000002F3 push si                        */  0x56,\r
+  /* 000002F4 mov si,0x46b                   */  0xBE, 0x6B, 0x04,\r
+  /* 000002F7 call word 0x3ad                */  0xE8, 0xB3, 0x00,\r
+  /* 000002FA pop si                         */  0x5E,\r
+  /* 000002FB jmp short 0x319                */  0xEB, 0x1C,\r
+  /* 000002FD push si                        */  0x56,\r
+  /* 000002FE mov si,0x47d                   */  0xBE, 0x7D, 0x04,\r
+  /* 00000301 call word 0x3ad                */  0xE8, 0xA9, 0x00,\r
+  /* 00000304 pop si                         */  0x5E,\r
+  /* 00000305 jmp short 0x319                */  0xEB, 0x12,\r
+  /* 00000307 push si                        */  0x56,\r
+  /* 00000308 mov si,0x48f                   */  0xBE, 0x8F, 0x04,\r
+  /* 0000030B call word 0x3ad                */  0xE8, 0x9F, 0x00,\r
+  /* 0000030E pop si                         */  0x5E,\r
+  /* 0000030F jmp short 0x319                */  0xEB, 0x08,\r
+  /* 00000311 push si                        */  0x56,\r
+  /* 00000312 mov si,0x4a2                   */  0xBE, 0xA2, 0x04,\r
+  /* 00000315 call word 0x3ad                */  0xE8, 0x95, 0x00,\r
+  /* 00000318 pop si                         */  0x5E,\r
+  /* 00000319 mov [0x4b0],bl                 */  0x88, 0x1E, 0xB0, 0x04,\r
+  /* 0000031D mov [0x4b1],bh                 */  0x88, 0x3E, 0xB1, 0x04,\r
+  /* 00000321 pop ax                         */  0x58,\r
+  /* 00000322 pop dx                         */  0x5A,\r
+  /* 00000323 jmp short 0x395                */  0xEB, 0x70,\r
+  /* 00000325 push si                        */  0x56,\r
+  /* 00000326 mov si,0x405                   */  0xBE, 0x05, 0x04,\r
+  /* 00000329 call word 0x3ad                */  0xE8, 0x81, 0x00,\r
+  /* 0000032C pop si                         */  0x5E,\r
+  /* 0000032D mov bl,[0x4b0]                 */  0x8A, 0x1E, 0xB0, 0x04,\r
+  /* 00000331 mov bh,[0x4b1]                 */  0x8A, 0x3E, 0xB1, 0x04,\r
+  /* 00000335 jmp short 0x395                */  0xEB, 0x5E,\r
+  /* 00000337 push si                        */  0x56,\r
+  /* 00000338 mov si,0x43b                   */  0xBE, 0x3B, 0x04,\r
+  /* 0000033B call word 0x3ad                */  0xE8, 0x6F, 0x00,\r
+  /* 0000033E pop si                         */  0x5E,\r
+  /* 0000033F mov bx,0x80                    */  0xBB, 0x80, 0x00,\r
+  /* 00000342 jmp short 0x395                */  0xEB, 0x51,\r
+  /* 00000344 push es                        */  0x06,\r
+  /* 00000345 push di                        */  0x57,\r
+  /* 00000346 push ds                        */  0x1E,\r
+  /* 00000347 push si                        */  0x56,\r
+  /* 00000348 push cx                        */  0x51,\r
+  /* 00000349 push si                        */  0x56,\r
+  /* 0000034A mov si,0x450                   */  0xBE, 0x50, 0x04,\r
+  /* 0000034D call word 0x3ad                */  0xE8, 0x5D, 0x00,\r
+  /* 00000350 pop si                         */  0x5E,\r
+  /* 00000351 push cs                        */  0x0E,\r
+  /* 00000352 pop ds                         */  0x1F,\r
+  /* 00000353 mov si,0x4b2                   */  0xBE, 0xB2, 0x04,\r
+  /* 00000356 mov cx,0x80                    */  0xB9, 0x80, 0x00,\r
+  /* 00000359 cld                            */  0xFC,\r
+  /* 0000035A rep movsb                      */  0xF3, 0xA4,\r
+  /* 0000035C pop cx                         */  0x59,\r
+  /* 0000035D pop si                         */  0x5E,\r
+  /* 0000035E pop ds                         */  0x1F,\r
+  /* 0000035F pop di                         */  0x5F,\r
+  /* 00000360 pop es                         */  0x07,\r
+  /* 00000361 jmp short 0x395                */  0xEB, 0x32,\r
+  /* 00000363 push si                        */  0x56,\r
+  /* 00000364 mov si,0x41b                   */  0xBE, 0x1B, 0x04,\r
+  /* 00000367 call word 0x3ad                */  0xE8, 0x43, 0x00,\r
+  /* 0000036A pop si                         */  0x5E,\r
+  /* 0000036B cmp al,0x3                     */  0x3C, 0x03,\r
+  /* 0000036D jz 0x37e                       */  0x74, 0x0F,\r
+  /* 0000036F cmp al,0x12                    */  0x3C, 0x12,\r
+  /* 00000371 jz 0x38a                       */  0x74, 0x17,\r
+  /* 00000373 push si                        */  0x56,\r
+  /* 00000374 mov si,0x42c                   */  0xBE, 0x2C, 0x04,\r
+  /* 00000377 call word 0x3ad                */  0xE8, 0x33, 0x00,\r
+  /* 0000037A pop si                         */  0x5E,\r
+  /* 0000037B jmp word 0x235                 */  0xE9, 0xB7, 0xFE,\r
+  /* 0000037E push si                        */  0x56,\r
+  /* 0000037F mov si,0x45c                   */  0xBE, 0x5C, 0x04,\r
+  /* 00000382 call word 0x3ad                */  0xE8, 0x28, 0x00,\r
+  /* 00000385 pop si                         */  0x5E,\r
+  /* 00000386 mov al,0x0                     */  0xB0, 0x00,\r
+  /* 00000388 jmp short 0x38c                */  0xEB, 0x02,\r
+  /* 0000038A mov al,0x0                     */  0xB0, 0x00,\r
+  /* 0000038C push si                        */  0x56,\r
+  /* 0000038D mov si,0x3c2                   */  0xBE, 0xC2, 0x03,\r
+  /* 00000390 call word 0x3ad                */  0xE8, 0x1A, 0x00,\r
+  /* 00000393 pop si                         */  0x5E,\r
+  /* 00000394 iretw                          */  0xCF,\r
+  /* 00000395 push si                        */  0x56,\r
+  /* 00000396 mov si,0x3c2                   */  0xBE, 0xC2, 0x03,\r
+  /* 00000399 call word 0x3ad                */  0xE8, 0x11, 0x00,\r
+  /* 0000039C pop si                         */  0x5E,\r
+  /* 0000039D mov ax,0x4f                    */  0xB8, 0x4F, 0x00,\r
+  /* 000003A0 iretw                          */  0xCF,\r
+  /* 000003A1 push si                        */  0x56,\r
+  /* 000003A2 mov si,0x3c8                   */  0xBE, 0xC8, 0x03,\r
+  /* 000003A5 call word 0x3ad                */  0xE8, 0x05, 0x00,\r
+  /* 000003A8 pop si                         */  0x5E,\r
+  /* 000003A9 mov ax,0x24f                   */  0xB8, 0x4F, 0x02,\r
+  /* 000003AC iretw                          */  0xCF,\r
+  /* 000003AD pushaw                         */  0x60,\r
+  /* 000003AE push ds                        */  0x1E,\r
+  /* 000003AF push cs                        */  0x0E,\r
+  /* 000003B0 pop ds                         */  0x1F,\r
+  /* 000003B1 mov dx,0x220                   */  0xBA, 0x20, 0x02,\r
+  /* 000003B4 mov ax,0x0                     */  0xB8, 0x00, 0x00,\r
+  /* 000003B7 lodsb                          */  0xAC,\r
+  /* 000003B8 cmp al,0x0                     */  0x3C, 0x00,\r
+  /* 000003BA jz 0x3bf                       */  0x74, 0x03,\r
+  /* 000003BC out dx,al                      */  0xEE,\r
+  /* 000003BD jmp short 0x3b7                */  0xEB, 0xF8,\r
+  /* 000003BF pop ds                         */  0x1F,\r
+  /* 000003C0 popaw                          */  0x61,\r
+  /* 000003C1 ret                            */  0xC3,\r
+  /* 000003C2 jna 0x413                      */  0x76, 0x4F,\r
+  /* 000003C4 imul cx,[di],byte +0xa         */  0x6B, 0x0D, 0x0A,\r
+  /* 000003C7 add [bp+0x55],dh               */  0x00, 0x76, 0x55,\r
+  /* 000003CA outsb                          */  0x6E,\r
+  /* 000003CB jnc 0x442                      */  0x73, 0x75,\r
+  /* 000003CD jo 0x43f                       */  0x70, 0x70,\r
+  /* 000003CF outsw                          */  0x6F,\r
+  /* 000003D0 jc 0x446                       */  0x72, 0x74,\r
+  /* 000003D2 fs or ax,0xa                   */  0x65, 0x64, 0x0D, 0x0A, 0x00,\r
+  /* 000003D7 jna 0x42e                      */  0x76, 0x55,\r
+  /* 000003D9 outsb                          */  0x6E,\r
+  /* 000003DA imul bp,[bp+0x6f],byte +0x77   */  0x6B, 0x6E, 0x6F, 0x77,\r
+  /* 000003DE outsb                          */  0x6E,\r
+  /* 000003DF and [bp+0x75],al               */  0x20, 0x46, 0x75,\r
+  /* 000003E2 outsb                          */  0x6E,\r
+  /* 000003E3 arpl [si+0x69],si              */  0x63, 0x74, 0x69,\r
+  /* 000003E6 outsw                          */  0x6F,\r
+  /* 000003E7 outsb                          */  0x6E,\r
+  /* 000003E8 or ax,0xa                      */  0x0D, 0x0A, 0x00,\r
+  /* 000003EB jna 0x434                      */  0x76, 0x47,\r
+  /* 000003ED gs jz 0x439                    */  0x65, 0x74, 0x49,\r
+  /* 000003F0 outsb                          */  0x6E,\r
+  /* 000003F1 outsd                          */  0x66, 0x6F,\r
+  /* 000003F3 or ax,0xa                      */  0x0D, 0x0A, 0x00,\r
+  /* 000003F6 jna 0x43f                      */  0x76, 0x47,\r
+  /* 000003F8 gs jz 0x448                    */  0x65, 0x74, 0x4D,\r
+  /* 000003FB outsw                          */  0x6F,\r
+  /* 000003FC gs dec cx                      */  0x64, 0x65, 0x49,\r
+  /* 000003FF outsb                          */  0x6E,\r
+  /* 00000400 outsd                          */  0x66, 0x6F,\r
+  /* 00000402 or ax,0xa                      */  0x0D, 0x0A, 0x00,\r
+  /* 00000405 jna 0x44e                      */  0x76, 0x47,\r
+  /* 00000407 gs jz 0x457                    */  0x65, 0x74, 0x4D,\r
+  /* 0000040A outsw                          */  0x6F,\r
+  /* 0000040B gs or ax,0xa                   */  0x64, 0x65, 0x0D, 0x0A, 0x00,\r
+  /* 00000410 jna 0x465                      */  0x76, 0x53,\r
+  /* 00000412 gs jz 0x462                    */  0x65, 0x74, 0x4D,\r
+  /* 00000415 outsw                          */  0x6F,\r
+  /* 00000416 gs or ax,0xa                   */  0x64, 0x65, 0x0D, 0x0A, 0x00,\r
+  /* 0000041B jna 0x470                      */  0x76, 0x53,\r
+  /* 0000041D gs jz 0x46d                    */  0x65, 0x74, 0x4D,\r
+  /* 00000420 outsw                          */  0x6F,\r
+  /* 00000421 gs dec sp                      */  0x64, 0x65, 0x4C,\r
+  /* 00000424 gs a32 popaw                   */  0x65, 0x67, 0x61,\r
+  /* 00000427 arpl [bx+di+0xd],di            */  0x63, 0x79, 0x0D,\r
+  /* 0000042A or al,[bx+si]                  */  0x0A, 0x00,\r
+  /* 0000042C jna 0x483                      */  0x76, 0x55,\r
+  /* 0000042E outsb                          */  0x6E,\r
+  /* 0000042F imul bp,[bx+0x77],byte +0x6e   */  0x6B, 0x6F, 0x77, 0x6E,\r
+  /* 00000433 and [di+0x6f],cl               */  0x20, 0x4D, 0x6F,\r
+  /* 00000436 gs or ax,0xa                   */  0x64, 0x65, 0x0D, 0x0A, 0x00,\r
+  /* 0000043B jna 0x484                      */  0x76, 0x47,\r
+  /* 0000043D gs jz 0x490                    */  0x65, 0x74, 0x50,\r
+  /* 00000440 insw                           */  0x6D,\r
+  /* 00000441 inc bx                         */  0x43,\r
+  /* 00000442 popaw                          */  0x61,\r
+  /* 00000443 jo 0x4a6                       */  0x70, 0x61,\r
+  /* 00000445 bound bp,[bx+di+0x6c]          */  0x62, 0x69, 0x6C,\r
+  /* 00000448 imul si,[si+0x69],word 0x7365  */  0x69, 0x74, 0x69, 0x65, 0x73,\r
+  /* 0000044D or ax,0xa                      */  0x0D, 0x0A, 0x00,\r
+  /* 00000450 jna 0x4a4                      */  0x76, 0x52,\r
+  /* 00000452 gs popaw                       */  0x65, 0x61,\r
+  /* 00000454 fs inc bp                      */  0x64, 0x45,\r
+  /* 00000456 imul sp,[fs:si+0xd],word 0xa   */  0x64, 0x69, 0x64, 0x0D, 0x0A, 0x00,\r
+  /* 0000045C jna 0x4aa                      */  0x76, 0x4C,\r
+  /* 0000045E gs a32 popaw                   */  0x65, 0x67, 0x61,\r
+  /* 00000461 arpl [bx+di+0x4d],di           */  0x63, 0x79, 0x4D,\r
+  /* 00000464 outsw                          */  0x6F,\r
+  /* 00000465 xor cx,[gs:di]                 */  0x64, 0x65, 0x33, 0x0D,\r
+  /* 00000469 or al,[bx+si]                  */  0x0A, 0x00,\r
+  /* 0000046B insw                           */  0x6D,\r
+  /* 0000046C outsw                          */  0x6F,\r
+  /* 0000046D gs pop di                      */  0x64, 0x65, 0x5F,\r
+  /* 00000470 ss xor al,0x30                 */  0x36, 0x34, 0x30,\r
+  /* 00000473 js 0x4a9                       */  0x78, 0x34,\r
+  /* 00000475 cmp [bx+si],dh                 */  0x38, 0x30,\r
+  /* 00000477 js 0x4ac                       */  0x78, 0x33,\r
+  /* 00000479 xor cl,[di]                    */  0x32, 0x0D,\r
+  /* 0000047B or al,[bx+si]                  */  0x0A, 0x00,\r
+  /* 0000047D insw                           */  0x6D,\r
+  /* 0000047E outsw                          */  0x6F,\r
+  /* 0000047F gs pop di                      */  0x64, 0x65, 0x5F,\r
+  /* 00000482 cmp [bx+si],dh                 */  0x38, 0x30,\r
+  /* 00000484 xor [bx+si+0x36],bh            */  0x30, 0x78, 0x36,\r
+  /* 00000487 xor [bx+si],dh                 */  0x30, 0x30,\r
+  /* 00000489 js 0x4be                       */  0x78, 0x33,\r
+  /* 0000048B xor cl,[di]                    */  0x32, 0x0D,\r
+  /* 0000048D or al,[bx+si]                  */  0x0A, 0x00,\r
+  /* 0000048F insw                           */  0x6D,\r
+  /* 00000490 outsw                          */  0x6F,\r
+  /* 00000491 gs pop di                      */  0x64, 0x65, 0x5F,\r
+  /* 00000494 xor [bx+si],si                 */  0x31, 0x30,\r
+  /* 00000496 xor dh,[si]                    */  0x32, 0x34,\r
+  /* 00000498 js 0x4d1                       */  0x78, 0x37,\r
+  /* 0000049A cmp [ss:bx+si+0x33],bh         */  0x36, 0x38, 0x78, 0x33,\r
+  /* 0000049E xor cl,[di]                    */  0x32, 0x0D,\r
+  /* 000004A0 or al,[bx+si]                  */  0x0A, 0x00,\r
+  /* 000004A2 insw                           */  0x6D,\r
+  /* 000004A3 outsw                          */  0x6F,\r
+  /* 000004A4 gs pop di                      */  0x64, 0x65, 0x5F,\r
+  /* 000004A7 jnz 0x517                      */  0x75, 0x6E,\r
+  /* 000004A9 jnz 0x51e                      */  0x75, 0x73,\r
+  /* 000004AB fs or ax,0xa                   */  0x65, 0x64, 0x0D, 0x0A, 0x00,\r
+  /* 000004B0 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004B2 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004B4 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004B6 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004B8 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004BA add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004BC add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004BE add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004C0 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004C2 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004C4 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004C6 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004C8 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004CA add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004CC add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004CE add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004D0 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004D2 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004D4 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004D6 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004D8 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004DA add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004DC add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004DE add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004E0 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004E2 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004E4 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004E6 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004E8 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004EA add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004EC add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004EE add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004F0 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004F2 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004F4 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004F6 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004F8 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004FA add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004FC add [bx+si],al                 */  0x00, 0x00,\r
+  /* 000004FE add [bx+si],al                 */  0x00, 0x00,\r
+  /* 00000500 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 00000502 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 00000504 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 00000506 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 00000508 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 0000050A add [bx+si],al                 */  0x00, 0x00,\r
+  /* 0000050C add [bx+si],al                 */  0x00, 0x00,\r
+  /* 0000050E add [bx+si],al                 */  0x00, 0x00,\r
+  /* 00000510 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 00000512 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 00000514 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 00000516 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 00000518 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 0000051A add [bx+si],al                 */  0x00, 0x00,\r
+  /* 0000051C add [bx+si],al                 */  0x00, 0x00,\r
+  /* 0000051E add [bx+si],al                 */  0x00, 0x00,\r
+  /* 00000520 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 00000522 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 00000524 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 00000526 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 00000528 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 0000052A add [bx+si],al                 */  0x00, 0x00,\r
+  /* 0000052C add [bx+si],al                 */  0x00, 0x00,\r
+  /* 0000052E add [bx+si],al                 */  0x00, 0x00,\r
+  /* 00000530 add [bx+si],al                 */  0x00, 0x00,\r
+  /* 00000532 add [bx+si],al                 */  0x00, 0x00,\r
+};\r
+#endif\r
diff --git a/OvmfPkg/Bhyve/BhyveRfbDxe/VbeShim.sh b/OvmfPkg/Bhyve/BhyveRfbDxe/VbeShim.sh
new file mode 100644 (file)
index 0000000..358b568
--- /dev/null
@@ -0,0 +1,80 @@
+#!/bin/sh\r
+###\r
+# @file\r
+# Shell script to assemble and dump the fake Int10h handler from NASM source to\r
+# a C array.\r
+#\r
+# Copyright (C) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+# Copyright (C) 2014, Red Hat, Inc.\r
+# Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>\r
+#\r
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+###\r
+\r
+set -e -u\r
+\r
+STEM=$(dirname -- "$0")/$(basename -- "$0" .sh)\r
+\r
+#\r
+# Install exit handler -- remove temporary files.\r
+#\r
+exit_handler()\r
+{\r
+  rm -f -- "$STEM".bin "$STEM".disasm "$STEM".offsets "$STEM".insns \\r
+      "$STEM".bytes\r
+}\r
+trap exit_handler EXIT\r
+\r
+#\r
+# Assemble the source file.\r
+#\r
+nasm -o "$STEM".bin -- "$STEM".asm\r
+\r
+#\r
+# Disassemble it, in order to get a binary dump associated with the source.\r
+# (ndisasm doesn't recognize the "--" end-of-options delimiter.)\r
+#\r
+ndisasm "$STEM".bin >"$STEM".disasm\r
+\r
+#\r
+# Create three files, each with one column of the disassembly.\r
+#\r
+# The first column contains the offsets, and it starts the comment.\r
+#\r
+cut -c 1-8 -- "$STEM".disasm \\r
+| sed -e 's,^,  /* ,' >"$STEM".offsets\r
+\r
+#\r
+# The second column contains the assembly-language instructions, and it closes\r
+# the comment. We first pad it to 30 characters.\r
+#\r
+cut -c 29- -- "$STEM".disasm \\r
+| sed -e 's,$,                              ,' \\r
+      -e 's,^\(.\{30\}\).*$,\1 */,' >"$STEM".insns\r
+\r
+#\r
+# The third column contains the bytes corresponding to the instruction,\r
+# represented as C integer constants. First strip trailing whitespace from the\r
+# middle column of the input disassembly, then process pairs of nibbles.\r
+#\r
+cut -c 11-28 -- "$STEM".disasm \\r
+| sed -e 's, \+$,,' -e 's/\(..\)/ 0x\1,/g' | sed 's/0x  ,//g' >"$STEM".bytes\r
+\r
+#\r
+# Write the output file, recombining the columns. The output should have CRLF\r
+# line endings.\r
+#\r
+{\r
+  printf '//\n'\r
+  printf '// THIS FILE WAS GENERATED BY "%s". DO NOT EDIT.\n' \\r
+      "$(basename -- "$0")"\r
+  printf '//\n'\r
+  printf '#ifndef _VBE_SHIM_H_\n'\r
+  printf '#define _VBE_SHIM_H_\n'\r
+  printf 'STATIC CONST UINT8 mVbeShim[] = {\n'\r
+  paste -d ' ' -- "$STEM".offsets "$STEM".insns "$STEM".bytes\r
+  printf '};\n'\r
+  printf '#endif\n'\r
+} \\r
+| unix2dos >"$STEM".h\r
diff --git a/OvmfPkg/Bhyve/FvmainCompactScratchEnd.fdf.inc b/OvmfPkg/Bhyve/FvmainCompactScratchEnd.fdf.inc
new file mode 100644 (file)
index 0000000..46f5258
--- /dev/null
@@ -0,0 +1,65 @@
+## @file\r
+#  This FDF include file computes the end of the scratch buffer used in\r
+#  DecompressMemFvs() [OvmfPkg/Sec/SecMain.c]. It is based on the decompressed\r
+#  (ie. original) size of the LZMA-compressed section of the one FFS file in\r
+#  the FVMAIN_COMPACT firmware volume.\r
+#\r
+#  Copyright (C) 2015, Red Hat, Inc.\r
+#\r
+#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+##\r
+\r
+# The GUID EE4E5898-3914-4259-9D6E-DC7BD79403CF means "LzmaCustomDecompress".\r
+# The decompressed output will have the following structure (see the file\r
+# "9E21FD93-9C72-4c15-8C4B-E77F1DB2D792SEC1.guided.dummy" in the\r
+# Build/Ovmf*/*/FV/Ffs/9E21FD93-9C72-4c15-8C4B-E77F1DB2D792/ directory):\r
+#\r
+# Size                 Contents\r
+# -------------------  --------------------------------------------------------\r
+#                   4  EFI_COMMON_SECTION_HEADER, stating size 124 (0x7C) and\r
+#                      type 0x19 (EFI_SECTION_RAW). The purpose of this section\r
+#                      is to pad the start of PEIFV to 128 bytes.\r
+#                 120  Zero bytes (padding).\r
+#\r
+#                   4  EFI_COMMON_SECTION_HEADER, stating size\r
+#                      (PcdOvmfPeiMemFvSize + 4), and type 0x17\r
+#                      (EFI_SECTION_FIRMWARE_VOLUME_IMAGE).\r
+# PcdOvmfPeiMemFvSize  PEIFV. Note that the above sizes pad the offset of this\r
+#                      object to 128 bytes. See also the "guided.dummy.txt"\r
+#                      file in the same directory.\r
+#\r
+#                   4  EFI_COMMON_SECTION_HEADER, stating size 12 (0xC) and\r
+#                      type 0x19 (EFI_SECTION_RAW). The purpose of this section\r
+#                      is to pad the start of DXEFV to 16 bytes.\r
+#                   8  Zero bytes (padding).\r
+#\r
+#                   4  EFI_COMMON_SECTION_HEADER, stating size\r
+#                      (PcdOvmfDxeMemFvSize + 4), and type 0x17\r
+#                      (EFI_SECTION_FIRMWARE_VOLUME_IMAGE).\r
+# PcdOvmfDxeMemFvSize  DXEFV. Note that the above sizes pad the offset of this\r
+#                      object to 16 bytes. See also the "guided.dummy.txt" file\r
+#                      in the same directory.\r
+#\r
+# The total size after decompression is (128 + PcdOvmfPeiMemFvSize + 16 +\r
+# PcdOvmfDxeMemFvSize).\r
+\r
+DEFINE OUTPUT_SIZE = (128 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize + 16 + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize)\r
+\r
+# LzmaCustomDecompressLib uses a constant scratch buffer size of 64KB; see\r
+# SCRATCH_BUFFER_REQUEST_SIZE in\r
+# "MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaDecompress.c".\r
+\r
+DEFINE DECOMP_SCRATCH_SIZE = 0x00010000\r
+\r
+# Note: when we use PcdOvmfDxeMemFvBase in this context, BaseTools have not yet\r
+# offset it with MEMFD's base address. For that reason we have to do it manually.\r
+#\r
+# The calculation below mirrors DecompressMemFvs() [OvmfPkg/Sec/SecMain.c].\r
+\r
+DEFINE OUTPUT_BASE                   = ($(MEMFD_BASE_ADDRESS) + gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase + 0x00100000)\r
+DEFINE DECOMP_SCRATCH_BASE_UNALIGNED = ($(OUTPUT_BASE) + $(OUTPUT_SIZE))\r
+DEFINE DECOMP_SCRATCH_BASE_ALIGNMENT = 0x000FFFFF\r
+DEFINE DECOMP_SCRATCH_BASE_MASK      = 0xFFF00000\r
+DEFINE DECOMP_SCRATCH_BASE           = (($(DECOMP_SCRATCH_BASE_UNALIGNED) + $(DECOMP_SCRATCH_BASE_ALIGNMENT)) & $(DECOMP_SCRATCH_BASE_MASK))\r
+\r
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecompressionScratchEnd = $(DECOMP_SCRATCH_BASE) + $(DECOMP_SCRATCH_SIZE)\r
diff --git a/OvmfPkg/Bhyve/Include/Library/BhyveFwCtlLib.h b/OvmfPkg/Bhyve/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/Bhyve/Library/BhyveFwCtlLib/BhyveFwCtlLib.c b/OvmfPkg/Bhyve/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/Bhyve/Library/BhyveFwCtlLib/BhyveFwCtlLib.inf b/OvmfPkg/Bhyve/Library/BhyveFwCtlLib/BhyveFwCtlLib.inf
new file mode 100644 (file)
index 0000000..e9819f4
--- /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/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
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/Bhyve/Library/PlatformBootManagerLib/BdsPlatform.h b/OvmfPkg/Bhyve/Library/PlatformBootManagerLib/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/Bhyve/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/OvmfPkg/Bhyve/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
new file mode 100644 (file)
index 0000000..105123b
--- /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                      = 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
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
diff --git a/OvmfPkg/Bhyve/License.txt b/OvmfPkg/Bhyve/License.txt
new file mode 100644 (file)
index 0000000..2930e53
--- /dev/null
@@ -0,0 +1,68 @@
+Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>\r
+Copyright (C) 2018, Red Hat, Inc.\r
+Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>\r
+Copyright (C) 2016, Red Hat, Inc.\r
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
+Copyright (c) 2015 Nahanni Systems\r
+Copyright (C) 2015, Red Hat, Inc.\r
+Copyright (C) 2014, Red Hat, Inc.\r
+Copyright (c) 2014, Pluribus Networks, Inc.\r
+Copyright (C) 2013, Red Hat, Inc.\r
+Copyright (c) 2012, 2013, Red Hat, Inc.\r
+Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>\r
+Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>\r
+Portions copyright (c) 2011, Apple Inc. All rights reserved.\r
+Portions copyright (c) 2010,Apple Inc. All rights reserved.<BR>\r
+\r
+\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+Redistribution and use in source and binary forms, with or without\r
+modification, are permitted provided that the following conditions are met:\r
+\r
+1. Redistributions of source code must retain the above copyright notice,\r
+   this list of conditions and the following disclaimer.\r
+\r
+2. Redistributions in binary form must reproduce the above copyright notice,\r
+   this list of conditions and the following disclaimer in the documentation\r
+   and/or other materials provided with the distribution.\r
+\r
+Subject to the terms and conditions of this license, each copyright holder\r
+and contributor hereby grants to those receiving rights under this license\r
+a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+(except for failure to satisfy the conditions of this license) patent\r
+license to make, have made, use, offer to sell, sell, import, and otherwise\r
+transfer this software, where such license applies only to those patent\r
+claims, already acquired or hereafter acquired, licensable by such copyright\r
+holder or contributor that are necessarily infringed by:\r
+\r
+(a) their Contribution(s) (the licensed copyrights of copyright holders and\r
+    non-copyrightable additions of contributors, in source or binary form)\r
+    alone; or\r
+\r
+(b) combination of their Contribution(s) with the work of authorship to\r
+    which such Contribution(s) was added by such copyright holder or\r
+    contributor, if, at the time the Contribution is added, such addition\r
+    causes such combination to be necessarily infringed. The patent license\r
+    shall not apply to any other combinations which include the\r
+    Contribution.\r
+\r
+Except as expressly stated above, no rights or licenses from any copyright\r
+holder or contributor is granted under this license, whether expressly, by\r
+implication, estoppel or otherwise.\r
+\r
+DISCLAIMER\r
+\r
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE\r
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+POSSIBILITY OF SUCH DAMAGE.\r
+\r
diff --git a/OvmfPkg/Bhyve/PlatformPei/AmdSev.c b/OvmfPkg/Bhyve/PlatformPei/AmdSev.c
new file mode 100644 (file)
index 0000000..e484f4b
--- /dev/null
@@ -0,0 +1,106 @@
+/**@file\r
+  Initialize Secure Encrypted Virtualization (SEV) support\r
+\r
+  Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <IndustryStandard/Q35MchIch9.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/MemEncryptSevLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <PiPei.h>\r
+#include <Register/Amd/Cpuid.h>\r
+#include <Register/Cpuid.h>\r
+#include <Register/Intel/SmramSaveStateMap.h>\r
+\r
+#include "Platform.h"\r
+\r
+/**\r
+\r
+  Function checks if SEV support is available, if present then it sets\r
+  the dynamic PcdPteMemoryEncryptionAddressOrMask with memory encryption mask.\r
+\r
+  **/\r
+VOID\r
+AmdSevInitialize (\r
+  VOID\r
+  )\r
+{\r
+  CPUID_MEMORY_ENCRYPTION_INFO_EBX  Ebx;\r
+  UINT64                            EncryptionMask;\r
+  RETURN_STATUS                     PcdStatus;\r
+\r
+  //\r
+  // Check if SEV is enabled\r
+  //\r
+  if (!MemEncryptSevIsEnabled ()) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // CPUID Fn8000_001F[EBX] Bit 0:5 (memory encryption bit position)\r
+  //\r
+  AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, NULL, &Ebx.Uint32, NULL, NULL);\r
+  EncryptionMask = LShiftU64 (1, Ebx.Bits.PtePosBits);\r
+\r
+  //\r
+  // Set Memory Encryption Mask PCD\r
+  //\r
+  PcdStatus = PcdSet64S (PcdPteMemoryEncryptionAddressOrMask, EncryptionMask);\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
+\r
+  DEBUG ((DEBUG_INFO, "SEV is enabled (mask 0x%lx)\n", EncryptionMask));\r
+\r
+  //\r
+  // Set Pcd to Deny the execution of option ROM when security\r
+  // violation.\r
+  //\r
+  PcdStatus = PcdSet32S (PcdOptionRomImageVerificationPolicy, 0x4);\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
+\r
+  //\r
+  // When SMM is required, cover the pages containing the initial SMRAM Save\r
+  // State Map with a memory allocation HOB:\r
+  //\r
+  // There's going to be a time interval between our decrypting those pages for\r
+  // SMBASE relocation and re-encrypting the same pages after SMBASE\r
+  // relocation. We shall ensure that the DXE phase stay away from those pages\r
+  // until after re-encryption, in order to prevent an information leak to the\r
+  // hypervisor.\r
+  //\r
+  if (FeaturePcdGet (PcdSmmSmramRequire) && (mBootMode != BOOT_ON_S3_RESUME)) {\r
+    RETURN_STATUS LocateMapStatus;\r
+    UINTN         MapPagesBase;\r
+    UINTN         MapPagesCount;\r
+\r
+    LocateMapStatus = MemEncryptSevLocateInitialSmramSaveStateMapPages (\r
+                        &MapPagesBase,\r
+                        &MapPagesCount\r
+                        );\r
+    ASSERT_RETURN_ERROR (LocateMapStatus);\r
+\r
+    if (mQ35SmramAtDefaultSmbase) {\r
+      //\r
+      // The initial SMRAM Save State Map has been covered as part of a larger\r
+      // reserved memory allocation in InitializeRamRegions().\r
+      //\r
+      ASSERT (SMM_DEFAULT_SMBASE <= MapPagesBase);\r
+      ASSERT (\r
+        (MapPagesBase + EFI_PAGES_TO_SIZE (MapPagesCount) <=\r
+         SMM_DEFAULT_SMBASE + MCH_DEFAULT_SMBASE_SIZE)\r
+        );\r
+    } else {\r
+      BuildMemoryAllocationHob (\r
+        MapPagesBase,                      // BaseAddress\r
+        EFI_PAGES_TO_SIZE (MapPagesCount), // Length\r
+        EfiBootServicesData                // MemoryType\r
+        );\r
+    }\r
+  }\r
+}\r
diff --git a/OvmfPkg/Bhyve/PlatformPei/ClearCache.c b/OvmfPkg/Bhyve/PlatformPei/ClearCache.c
new file mode 100644 (file)
index 0000000..5c538c5
--- /dev/null
@@ -0,0 +1,111 @@
+/**@file\r
+  Install a callback to clear cache on all processors.\r
+  This is for conformance with the TCG "Platform Reset Attack Mitigation\r
+  Specification". Because clearing the CPU caches at boot doesn't impact\r
+  performance significantly, do it unconditionally, for simplicity's\r
+  sake.\r
+\r
+  Copyright (C) 2018, Red Hat, Inc.\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+**/\r
+\r
+#include <Library/CacheMaintenanceLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Ppi/MpServices.h>\r
+\r
+#include "Platform.h"\r
+\r
+/**\r
+  Invalidate data & instruction caches.\r
+  All APs execute this function in parallel. The BSP executes the function\r
+  separately.\r
+\r
+  @param[in,out] WorkSpace  Pointer to the input/output argument workspace\r
+                            shared by all processors.\r
+**/\r
+STATIC\r
+VOID\r
+EFIAPI\r
+ClearCache (\r
+  IN OUT VOID *WorkSpace\r
+  )\r
+{\r
+  WriteBackInvalidateDataCache ();\r
+  InvalidateInstructionCache ();\r
+}\r
+\r
+/**\r
+  Notification function called when EFI_PEI_MP_SERVICES_PPI becomes available.\r
+\r
+  @param[in] PeiServices      Indirect reference to the PEI Services Table.\r
+  @param[in] NotifyDescriptor Address of the notification descriptor data\r
+                              structure.\r
+  @param[in] Ppi              Address of the PPI that was installed.\r
+\r
+  @return  Status of the notification. The status code returned from this\r
+           function is ignored.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+ClearCacheOnMpServicesAvailable (\r
+  IN EFI_PEI_SERVICES           **PeiServices,\r
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,\r
+  IN VOID                       *Ppi\r
+  )\r
+{\r
+  EFI_PEI_MP_SERVICES_PPI *MpServices;\r
+  EFI_STATUS              Status;\r
+\r
+  DEBUG ((DEBUG_INFO, "%a: %a\n", gEfiCallerBaseName, __FUNCTION__));\r
+\r
+  //\r
+  // Clear cache on all the APs in parallel.\r
+  //\r
+  MpServices = Ppi;\r
+  Status = MpServices->StartupAllAPs (\r
+                         (CONST EFI_PEI_SERVICES **)PeiServices,\r
+                         MpServices,\r
+                         ClearCache,          // Procedure\r
+                         FALSE,               // SingleThread\r
+                         0,                   // TimeoutInMicroSeconds: inf.\r
+                         NULL                 // ProcedureArgument\r
+                         );\r
+  if (EFI_ERROR (Status) && Status != EFI_NOT_STARTED) {\r
+    DEBUG ((DEBUG_ERROR, "%a: StartupAllAps(): %r\n", __FUNCTION__, Status));\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Now clear cache on the BSP too.\r
+  //\r
+  ClearCache (NULL);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+//\r
+// Notification object for registering the callback, for when\r
+// EFI_PEI_MP_SERVICES_PPI becomes available.\r
+//\r
+STATIC CONST EFI_PEI_NOTIFY_DESCRIPTOR mMpServicesNotify = {\r
+  EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | // Flags\r
+  EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
+  &gEfiPeiMpServicesPpiGuid,               // Guid\r
+  ClearCacheOnMpServicesAvailable          // Notify\r
+};\r
+\r
+VOID\r
+InstallClearCacheCallback (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS           Status;\r
+\r
+  Status = PeiServicesNotifyPpi (&mMpServicesNotify);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "%a: failed to set up MP Services callback: %r\n",\r
+      __FUNCTION__, Status));\r
+  }\r
+}\r
diff --git a/OvmfPkg/Bhyve/PlatformPei/Cmos.c b/OvmfPkg/Bhyve/PlatformPei/Cmos.c
new file mode 100644 (file)
index 0000000..9b34e10
--- /dev/null
@@ -0,0 +1,58 @@
+/** @file\r
+  PC/AT CMOS access routines\r
+\r
+  Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+\r
+#include "Cmos.h"\r
+#include "Library/IoLib.h"\r
+\r
+/**\r
+  Reads 8-bits of CMOS data.\r
+\r
+  Reads the 8-bits of CMOS data at the location specified by Index.\r
+  The 8-bit read value is returned.\r
+\r
+  @param  Index  The CMOS location to read.\r
+\r
+  @return The value read.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+CmosRead8 (\r
+  IN      UINTN                     Index\r
+  )\r
+{\r
+  IoWrite8 (0x70, (UINT8) Index);\r
+  return IoRead8 (0x71);\r
+}\r
+\r
+\r
+/**\r
+  Writes 8-bits of CMOS data.\r
+\r
+  Writes 8-bits of CMOS data to the location specified by Index\r
+  with the value specified by Value and returns Value.\r
+\r
+  @param  Index  The CMOS location to write.\r
+  @param  Value  The value to write to CMOS.\r
+\r
+  @return The value written to CMOS.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+CmosWrite8 (\r
+  IN      UINTN                     Index,\r
+  IN      UINT8                     Value\r
+  )\r
+{\r
+  IoWrite8 (0x70, (UINT8) Index);\r
+  IoWrite8 (0x71, Value);\r
+  return Value;\r
+}\r
+\r
diff --git a/OvmfPkg/Bhyve/PlatformPei/Cmos.h b/OvmfPkg/Bhyve/PlatformPei/Cmos.h
new file mode 100644 (file)
index 0000000..3cd9879
--- /dev/null
@@ -0,0 +1,50 @@
+/** @file\r
+  PC/AT CMOS access routines\r
+\r
+  Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef __CMOS_H__\r
+#define __CMOS_H__\r
+\r
+/**\r
+  Reads 8-bits of CMOS data.\r
+\r
+  Reads the 8-bits of CMOS data at the location specified by Index.\r
+  The 8-bit read value is returned.\r
+\r
+  @param  Index  The CMOS location to read.\r
+\r
+  @return The value read.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+CmosRead8 (\r
+  IN      UINTN                     Index\r
+  );\r
+\r
+/**\r
+  Writes 8-bits of CMOS data.\r
+\r
+  Writes 8-bits of CMOS data to the location specified by Index\r
+  with the value specified by Value and returns Value.\r
+\r
+  @param  Index  The CMOS location to write.\r
+  @param  Value  The value to write to CMOS.\r
+\r
+  @return The value written to CMOS.\r
+\r
+**/\r
+UINT8\r
+EFIAPI\r
+CmosWrite8 (\r
+  IN      UINTN                     Index,\r
+  IN      UINT8                     Value\r
+  );\r
+\r
+\r
+#endif\r
+\r
diff --git a/OvmfPkg/Bhyve/PlatformPei/FeatureControl.c b/OvmfPkg/Bhyve/PlatformPei/FeatureControl.c
new file mode 100644 (file)
index 0000000..40d9ebd
--- /dev/null
@@ -0,0 +1,21 @@
+/**@file\r
+  Install a callback when necessary for setting the Feature Control MSR on all\r
+  processors.\r
+\r
+  Copyright (C) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+  Copyright (C) 2016, Red Hat, Inc.\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+**/\r
+\r
+#include "Platform.h"\r
+\r
+VOID\r
+InstallFeatureControlCallback (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Nothing to do.\r
+  //\r
+}\r
diff --git a/OvmfPkg/Bhyve/PlatformPei/Fv.c b/OvmfPkg/Bhyve/PlatformPei/Fv.c
new file mode 100644 (file)
index 0000000..ee4ecab
--- /dev/null
@@ -0,0 +1,94 @@
+/** @file\r
+  Build FV related hobs for platform.\r
+\r
+  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "PiPei.h"\r
+#include "Platform.h"\r
+#include <Library/DebugLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+\r
+/**\r
+  Publish PEI & DXE (Decompressed) Memory based FVs to let PEI\r
+  and DXE know about them.\r
+\r
+  @retval EFI_SUCCESS   Platform PEI FVs were initialized successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+PeiFvInitialization (\r
+  VOID\r
+  )\r
+{\r
+  BOOLEAN SecureS3Needed;\r
+\r
+  DEBUG ((DEBUG_INFO, "Platform PEI Firmware Volume Initialization\n"));\r
+\r
+  //\r
+  // Create a memory allocation HOB for the PEI FV.\r
+  //\r
+  // Allocate as ACPI NVS is S3 is supported\r
+  //\r
+  BuildMemoryAllocationHob (\r
+    PcdGet32 (PcdOvmfPeiMemFvBase),\r
+    PcdGet32 (PcdOvmfPeiMemFvSize),\r
+    mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData\r
+    );\r
+\r
+  //\r
+  // Let DXE know about the DXE FV\r
+  //\r
+  BuildFvHob (PcdGet32 (PcdOvmfDxeMemFvBase), PcdGet32 (PcdOvmfDxeMemFvSize));\r
+\r
+  SecureS3Needed = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire);\r
+\r
+  //\r
+  // Create a memory allocation HOB for the DXE FV.\r
+  //\r
+  // If "secure" S3 is needed, then SEC will decompress both PEI and DXE\r
+  // firmware volumes at S3 resume too, hence we need to keep away the OS from\r
+  // DXEFV as well. Otherwise we only need to keep away DXE itself from the\r
+  // DXEFV area.\r
+  //\r
+  BuildMemoryAllocationHob (\r
+    PcdGet32 (PcdOvmfDxeMemFvBase),\r
+    PcdGet32 (PcdOvmfDxeMemFvSize),\r
+    SecureS3Needed ? EfiACPIMemoryNVS : EfiBootServicesData\r
+    );\r
+\r
+  //\r
+  // Additionally, said decompression will use temporary memory above the end\r
+  // of DXEFV, so let's keep away the OS from there too.\r
+  //\r
+  if (SecureS3Needed) {\r
+    UINT32 DxeMemFvEnd;\r
+\r
+    DxeMemFvEnd = PcdGet32 (PcdOvmfDxeMemFvBase) +\r
+                  PcdGet32 (PcdOvmfDxeMemFvSize);\r
+    BuildMemoryAllocationHob (\r
+      DxeMemFvEnd,\r
+      PcdGet32 (PcdOvmfDecompressionScratchEnd) - DxeMemFvEnd,\r
+      EfiACPIMemoryNVS\r
+      );\r
+  }\r
+\r
+  //\r
+  // Let PEI know about the DXE FV so it can find the DXE Core\r
+  //\r
+  PeiServicesInstallFvInfoPpi (\r
+    NULL,\r
+    (VOID *)(UINTN) PcdGet32 (PcdOvmfDxeMemFvBase),\r
+    PcdGet32 (PcdOvmfDxeMemFvSize),\r
+    NULL,\r
+    NULL\r
+    );\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
diff --git a/OvmfPkg/Bhyve/PlatformPei/MemDetect.c b/OvmfPkg/Bhyve/PlatformPei/MemDetect.c
new file mode 100644 (file)
index 0000000..1b556be
--- /dev/null
@@ -0,0 +1,627 @@
+/**@file\r
+  Memory Detection for Virtual Machines.\r
+\r
+  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+Module Name:\r
+\r
+  MemDetect.c\r
+\r
+**/\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <IndustryStandard/E820.h>\r
+#include <IndustryStandard/Q35MchIch9.h>\r
+#include <PiPei.h>\r
+\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/PciLib.h>\r
+#include <Library/PeimEntryPoint.h>\r
+#include <Library/ResourcePublicationLib.h>\r
+#include <Library/MtrrLib.h>\r
+\r
+#include "Platform.h"\r
+#include "Cmos.h"\r
+\r
+UINT8 mPhysMemAddressWidth;\r
+\r
+STATIC UINT32 mS3AcpiReservedMemoryBase;\r
+STATIC UINT32 mS3AcpiReservedMemorySize;\r
+\r
+STATIC UINT16 mQ35TsegMbytes;\r
+\r
+BOOLEAN mQ35SmramAtDefaultSmbase = FALSE;\r
+\r
+VOID\r
+Q35TsegMbytesInitialization (\r
+  VOID\r
+  )\r
+{\r
+  UINT16        ExtendedTsegMbytes;\r
+  RETURN_STATUS PcdStatus;\r
+\r
+  if (mHostBridgeDevId != INTEL_Q35_MCH_DEVICE_ID) {\r
+    DEBUG ((\r
+      DEBUG_ERROR,\r
+      "%a: no TSEG (SMRAM) on host bridge DID=0x%04x; "\r
+      "only DID=0x%04x (Q35) is supported\n",\r
+      __FUNCTION__,\r
+      mHostBridgeDevId,\r
+      INTEL_Q35_MCH_DEVICE_ID\r
+      ));\r
+    ASSERT (FALSE);\r
+    CpuDeadLoop ();\r
+  }\r
+\r
+  //\r
+  // Check if QEMU offers an extended TSEG.\r
+  //\r
+  // This can be seen from writing MCH_EXT_TSEG_MB_QUERY to the MCH_EXT_TSEG_MB\r
+  // register, and reading back the register.\r
+  //\r
+  // On a QEMU machine type that does not offer an extended TSEG, the initial\r
+  // write overwrites whatever value a malicious guest OS may have placed in\r
+  // the (unimplemented) register, before entering S3 or rebooting.\r
+  // Subsequently, the read returns MCH_EXT_TSEG_MB_QUERY unchanged.\r
+  //\r
+  // On a QEMU machine type that offers an extended TSEG, the initial write\r
+  // triggers an update to the register. Subsequently, the value read back\r
+  // (which is guaranteed to differ from MCH_EXT_TSEG_MB_QUERY) tells us the\r
+  // number of megabytes.\r
+  //\r
+  PciWrite16 (DRAMC_REGISTER_Q35 (MCH_EXT_TSEG_MB), MCH_EXT_TSEG_MB_QUERY);\r
+  ExtendedTsegMbytes = PciRead16 (DRAMC_REGISTER_Q35 (MCH_EXT_TSEG_MB));\r
+  if (ExtendedTsegMbytes == MCH_EXT_TSEG_MB_QUERY) {\r
+    mQ35TsegMbytes = PcdGet16 (PcdQ35TsegMbytes);\r
+    return;\r
+  }\r
+\r
+  DEBUG ((\r
+    DEBUG_INFO,\r
+    "%a: QEMU offers an extended TSEG (%d MB)\n",\r
+    __FUNCTION__,\r
+    ExtendedTsegMbytes\r
+    ));\r
+  PcdStatus = PcdSet16S (PcdQ35TsegMbytes, ExtendedTsegMbytes);\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
+  mQ35TsegMbytes = ExtendedTsegMbytes;\r
+}\r
+\r
+\r
+UINT32\r
+GetSystemMemorySizeBelow4gb (\r
+  VOID\r
+  )\r
+{\r
+  UINT8 Cmos0x34;\r
+  UINT8 Cmos0x35;\r
+\r
+  //\r
+  // CMOS 0x34/0x35 specifies the system memory above 16 MB.\r
+  // * CMOS(0x35) is the high byte\r
+  // * CMOS(0x34) is the low byte\r
+  // * The size is specified in 64kb chunks\r
+  // * Since this is memory above 16MB, the 16MB must be added\r
+  //   into the calculation to get the total memory size.\r
+  //\r
+\r
+  Cmos0x34 = (UINT8) CmosRead8 (0x34);\r
+  Cmos0x35 = (UINT8) CmosRead8 (0x35);\r
+\r
+  return (UINT32) (((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);\r
+}\r
+\r
+\r
+STATIC\r
+UINT64\r
+GetSystemMemorySizeAbove4gb (\r
+  )\r
+{\r
+  UINT32 Size;\r
+  UINTN  CmosIndex;\r
+\r
+  //\r
+  // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.\r
+  // * CMOS(0x5d) is the most significant size byte\r
+  // * CMOS(0x5c) is the middle size byte\r
+  // * CMOS(0x5b) is the least significant size byte\r
+  // * The size is specified in 64kb chunks\r
+  //\r
+\r
+  Size = 0;\r
+  for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {\r
+    Size = (UINT32) (Size << 8) + (UINT32) CmosRead8 (CmosIndex);\r
+  }\r
+\r
+  return LShiftU64 (Size, 16);\r
+}\r
+\r
+\r
+/**\r
+  Return the highest address that DXE could possibly use, plus one.\r
+**/\r
+STATIC\r
+UINT64\r
+GetFirstNonAddress (\r
+  VOID\r
+  )\r
+{\r
+  UINT64               FirstNonAddress;\r
+  UINT64               Pci64Base, Pci64Size;\r
+  RETURN_STATUS        PcdStatus;\r
+\r
+  FirstNonAddress = BASE_4GB + GetSystemMemorySizeAbove4gb ();\r
+\r
+  //\r
+  // If DXE is 32-bit, then we're done; PciBusDxe will degrade 64-bit MMIO\r
+  // resources to 32-bit anyway. See DegradeResource() in\r
+  // "PciResourceSupport.c".\r
+  //\r
+#ifdef MDE_CPU_IA32\r
+  if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
+    return FirstNonAddress;\r
+  }\r
+#endif\r
+\r
+  //\r
+  // Otherwise, in order to calculate the highest address plus one, we must\r
+  // consider the 64-bit PCI host aperture too. Fetch the default size.\r
+  //\r
+  Pci64Size = PcdGet64 (PcdPciMmio64Size);\r
+\r
+  if (Pci64Size == 0) {\r
+    if (mBootMode != BOOT_ON_S3_RESUME) {\r
+      DEBUG ((DEBUG_INFO, "%a: disabling 64-bit PCI host aperture\n",\r
+        __FUNCTION__));\r
+      PcdStatus = PcdSet64S (PcdPciMmio64Size, 0);\r
+      ASSERT_RETURN_ERROR (PcdStatus);\r
+    }\r
+\r
+    //\r
+    // There's nothing more to do; the amount of memory above 4GB fully\r
+    // determines the highest address plus one. The memory hotplug area (see\r
+    // below) plays no role for the firmware in this case.\r
+    //\r
+    return FirstNonAddress;\r
+  }\r
+\r
+  //\r
+  // SeaBIOS aligns both boundaries of the 64-bit PCI host aperture to 1GB, so\r
+  // that the host can map it with 1GB hugepages. Follow suit.\r
+  //\r
+  Pci64Base = ALIGN_VALUE (FirstNonAddress, (UINT64)SIZE_1GB);\r
+  Pci64Size = ALIGN_VALUE (Pci64Size, (UINT64)SIZE_1GB);\r
+\r
+  //\r
+  // The 64-bit PCI host aperture should also be "naturally" aligned. The\r
+  // alignment is determined by rounding the size of the aperture down to the\r
+  // next smaller or equal power of two. That is, align the aperture by the\r
+  // largest BAR size that can fit into it.\r
+  //\r
+  Pci64Base = ALIGN_VALUE (Pci64Base, GetPowerOfTwo64 (Pci64Size));\r
+\r
+  if (mBootMode != BOOT_ON_S3_RESUME) {\r
+    //\r
+    // The core PciHostBridgeDxe driver will automatically add this range to\r
+    // the GCD memory space map through our PciHostBridgeLib instance; here we\r
+    // only need to set the PCDs.\r
+    //\r
+    PcdStatus = PcdSet64S (PcdPciMmio64Base, Pci64Base);\r
+    ASSERT_RETURN_ERROR (PcdStatus);\r
+    PcdStatus = PcdSet64S (PcdPciMmio64Size, Pci64Size);\r
+    ASSERT_RETURN_ERROR (PcdStatus);\r
+\r
+    DEBUG ((DEBUG_INFO, "%a: Pci64Base=0x%Lx Pci64Size=0x%Lx\n",\r
+      __FUNCTION__, Pci64Base, Pci64Size));\r
+  }\r
+\r
+  //\r
+  // The useful address space ends with the 64-bit PCI host aperture.\r
+  //\r
+  FirstNonAddress = Pci64Base + Pci64Size;\r
+  return FirstNonAddress;\r
+}\r
+\r
+\r
+/**\r
+  Initialize the mPhysMemAddressWidth variable, based on guest RAM size.\r
+**/\r
+VOID\r
+AddressWidthInitialization (\r
+  VOID\r
+  )\r
+{\r
+  UINT64 FirstNonAddress;\r
+\r
+  //\r
+  // As guest-physical memory size grows, the permanent PEI RAM requirements\r
+  // are dominated by the identity-mapping page tables built by the DXE IPL.\r
+  // The DXL IPL keys off of the physical address bits advertized in the CPU\r
+  // HOB. To conserve memory, we calculate the minimum address width here.\r
+  //\r
+  FirstNonAddress      = GetFirstNonAddress ();\r
+  mPhysMemAddressWidth = (UINT8)HighBitSet64 (FirstNonAddress);\r
+\r
+  //\r
+  // If FirstNonAddress is not an integral power of two, then we need an\r
+  // additional bit.\r
+  //\r
+  if ((FirstNonAddress & (FirstNonAddress - 1)) != 0) {\r
+    ++mPhysMemAddressWidth;\r
+  }\r
+\r
+  //\r
+  // The minimum address width is 36 (covers up to and excluding 64 GB, which\r
+  // is the maximum for Ia32 + PAE). The theoretical architecture maximum for\r
+  // X64 long mode is 52 bits, but the DXE IPL clamps that down to 48 bits. We\r
+  // can simply assert that here, since 48 bits are good enough for 256 TB.\r
+  //\r
+  if (mPhysMemAddressWidth <= 36) {\r
+    mPhysMemAddressWidth = 36;\r
+  }\r
+  ASSERT (mPhysMemAddressWidth <= 48);\r
+}\r
+\r
+\r
+/**\r
+  Calculate the cap for the permanent PEI memory.\r
+**/\r
+STATIC\r
+UINT32\r
+GetPeiMemoryCap (\r
+  VOID\r
+  )\r
+{\r
+  BOOLEAN Page1GSupport;\r
+  UINT32  RegEax;\r
+  UINT32  RegEdx;\r
+  UINT32  Pml4Entries;\r
+  UINT32  PdpEntries;\r
+  UINTN   TotalPages;\r
+\r
+  //\r
+  // If DXE is 32-bit, then just return the traditional 64 MB cap.\r
+  //\r
+#ifdef MDE_CPU_IA32\r
+  if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
+    return SIZE_64MB;\r
+  }\r
+#endif\r
+\r
+  //\r
+  // Dependent on physical address width, PEI memory allocations can be\r
+  // dominated by the page tables built for 64-bit DXE. So we key the cap off\r
+  // of those. The code below is based on CreateIdentityMappingPageTables() in\r
+  // "MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c".\r
+  //\r
+  Page1GSupport = FALSE;\r
+  if (PcdGetBool (PcdUse1GPageTable)) {\r
+    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
+    if (RegEax >= 0x80000001) {\r
+      AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);\r
+      if ((RegEdx & BIT26) != 0) {\r
+        Page1GSupport = TRUE;\r
+      }\r
+    }\r
+  }\r
+\r
+  if (mPhysMemAddressWidth <= 39) {\r
+    Pml4Entries = 1;\r
+    PdpEntries = 1 << (mPhysMemAddressWidth - 30);\r
+    ASSERT (PdpEntries <= 0x200);\r
+  } else {\r
+    Pml4Entries = 1 << (mPhysMemAddressWidth - 39);\r
+    ASSERT (Pml4Entries <= 0x200);\r
+    PdpEntries = 512;\r
+  }\r
+\r
+  TotalPages = Page1GSupport ? Pml4Entries + 1 :\r
+                               (PdpEntries + 1) * Pml4Entries + 1;\r
+  ASSERT (TotalPages <= 0x40201);\r
+\r
+  //\r
+  // Add 64 MB for miscellaneous allocations. Note that for\r
+  // mPhysMemAddressWidth values close to 36, the cap will actually be\r
+  // dominated by this increment.\r
+  //\r
+  return (UINT32)(EFI_PAGES_TO_SIZE (TotalPages) + SIZE_64MB);\r
+}\r
+\r
+\r
+/**\r
+  Publish PEI core memory\r
+\r
+  @return EFI_SUCCESS     The PEIM initialized successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+PublishPeiMemory (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_PHYSICAL_ADDRESS        MemoryBase;\r
+  UINT64                      MemorySize;\r
+  UINT32                      LowerMemorySize;\r
+  UINT32                      PeiMemoryCap;\r
+\r
+  LowerMemorySize = GetSystemMemorySizeBelow4gb ();\r
+  if (FeaturePcdGet (PcdSmmSmramRequire)) {\r
+    //\r
+    // TSEG is chipped from the end of low RAM\r
+    //\r
+    LowerMemorySize -= mQ35TsegMbytes * SIZE_1MB;\r
+  }\r
+\r
+  //\r
+  // If S3 is supported, then the S3 permanent PEI memory is placed next,\r
+  // downwards. Its size is primarily dictated by CpuMpPei. The formula below\r
+  // is an approximation.\r
+  //\r
+  if (mS3Supported) {\r
+    mS3AcpiReservedMemorySize = SIZE_512KB +\r
+      mMaxCpuCount *\r
+      PcdGet32 (PcdCpuApStackSize);\r
+    mS3AcpiReservedMemoryBase = LowerMemorySize - mS3AcpiReservedMemorySize;\r
+    LowerMemorySize = mS3AcpiReservedMemoryBase;\r
+  }\r
+\r
+  if (mBootMode == BOOT_ON_S3_RESUME) {\r
+    MemoryBase = mS3AcpiReservedMemoryBase;\r
+    MemorySize = mS3AcpiReservedMemorySize;\r
+  } else {\r
+    PeiMemoryCap = GetPeiMemoryCap ();\r
+    DEBUG ((DEBUG_INFO, "%a: mPhysMemAddressWidth=%d PeiMemoryCap=%u KB\n",\r
+      __FUNCTION__, mPhysMemAddressWidth, PeiMemoryCap >> 10));\r
+\r
+    //\r
+    // Determine the range of memory to use during PEI\r
+    //\r
+    // Technically we could lay the permanent PEI RAM over SEC's temporary\r
+    // decompression and scratch buffer even if "secure S3" is needed, since\r
+    // their lifetimes don't overlap. However, PeiFvInitialization() will cover\r
+    // RAM up to PcdOvmfDecompressionScratchEnd with an EfiACPIMemoryNVS memory\r
+    // allocation HOB, and other allocations served from the permanent PEI RAM\r
+    // shouldn't overlap with that HOB.\r
+    //\r
+    MemoryBase = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire) ?\r
+      PcdGet32 (PcdOvmfDecompressionScratchEnd) :\r
+      PcdGet32 (PcdOvmfDxeMemFvBase) + PcdGet32 (PcdOvmfDxeMemFvSize);\r
+    MemorySize = LowerMemorySize - MemoryBase;\r
+    if (MemorySize > PeiMemoryCap) {\r
+      MemoryBase = LowerMemorySize - PeiMemoryCap;\r
+      MemorySize = PeiMemoryCap;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Publish this memory to the PEI Core\r
+  //\r
+  Status = PublishSystemMemory(MemoryBase, MemorySize);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r
+\r
+\r
+/**\r
+  Peform Memory Detection for QEMU / KVM\r
+\r
+**/\r
+STATIC\r
+VOID\r
+QemuInitializeRam (\r
+  VOID\r
+  )\r
+{\r
+  UINT64                      LowerMemorySize;\r
+  UINT64                      UpperMemorySize;\r
+  MTRR_SETTINGS               MtrrSettings;\r
+  EFI_STATUS                  Status;\r
+\r
+  DEBUG ((DEBUG_INFO, "%a called\n", __FUNCTION__));\r
+\r
+  //\r
+  // Determine total memory size available\r
+  //\r
+  LowerMemorySize = GetSystemMemorySizeBelow4gb ();\r
+  UpperMemorySize = GetSystemMemorySizeAbove4gb ();\r
+\r
+  if (mBootMode == BOOT_ON_S3_RESUME) {\r
+    //\r
+    // Create the following memory HOB as an exception on the S3 boot path.\r
+    //\r
+    // Normally we'd create memory HOBs only on the normal boot path. However,\r
+    // CpuMpPei specifically needs such a low-memory HOB on the S3 path as\r
+    // well, for "borrowing" a subset of it temporarily, for the AP startup\r
+    // vector.\r
+    //\r
+    // CpuMpPei saves the original contents of the borrowed area in permanent\r
+    // PEI RAM, in a backup buffer allocated with the normal PEI services.\r
+    // CpuMpPei restores the original contents ("returns" the borrowed area) at\r
+    // End-of-PEI. End-of-PEI in turn is emitted by S3Resume2Pei before\r
+    // transferring control to the OS's wakeup vector in the FACS.\r
+    //\r
+    // We expect any other PEIMs that "borrow" memory similarly to CpuMpPei to\r
+    // restore the original contents. Furthermore, we expect all such PEIMs\r
+    // (CpuMpPei included) to claim the borrowed areas by producing memory\r
+    // allocation HOBs, and to honor preexistent memory allocation HOBs when\r
+    // looking for an area to borrow.\r
+    //\r
+    AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);\r
+  } else {\r
+    //\r
+    // Create memory HOBs\r
+    //\r
+    AddMemoryRangeHob (0, BASE_512KB + BASE_128KB);\r
+\r
+    if (FeaturePcdGet (PcdSmmSmramRequire)) {\r
+      UINT32 TsegSize;\r
+\r
+      TsegSize = mQ35TsegMbytes * SIZE_1MB;\r
+      AddMemoryRangeHob (BASE_1MB, LowerMemorySize - TsegSize);\r
+      AddReservedMemoryBaseSizeHob (LowerMemorySize - TsegSize, TsegSize,\r
+        TRUE);\r
+    } else {\r
+      AddMemoryRangeHob (BASE_1MB, LowerMemorySize);\r
+    }\r
+\r
+    if (UpperMemorySize != 0) {\r
+      AddMemoryBaseSizeHob (BASE_4GB, UpperMemorySize);\r
+    }\r
+  }\r
+\r
+  //\r
+  // We'd like to keep the following ranges uncached:\r
+  // - [640 KB, 1 MB)\r
+  // - [LowerMemorySize, 4 GB)\r
+  //\r
+  // Everything else should be WB. Unfortunately, programming the inverse (ie.\r
+  // keeping the default UC, and configuring the complement set of the above as\r
+  // WB) is not reliable in general, because the end of the upper RAM can have\r
+  // practically any alignment, and we may not have enough variable MTRRs to\r
+  // cover it exactly.\r
+  //\r
+  if (IsMtrrSupported ()) {\r
+    MtrrGetAllMtrrs (&MtrrSettings);\r
+\r
+    //\r
+    // MTRRs disabled, fixed MTRRs disabled, default type is uncached\r
+    //\r
+    ASSERT ((MtrrSettings.MtrrDefType & BIT11) == 0);\r
+    ASSERT ((MtrrSettings.MtrrDefType & BIT10) == 0);\r
+    ASSERT ((MtrrSettings.MtrrDefType & 0xFF) == 0);\r
+\r
+    //\r
+    // flip default type to writeback\r
+    //\r
+    SetMem (&MtrrSettings.Fixed, sizeof MtrrSettings.Fixed, 0x06);\r
+    ZeroMem (&MtrrSettings.Variables, sizeof MtrrSettings.Variables);\r
+    MtrrSettings.MtrrDefType |= BIT11 | BIT10 | 6;\r
+    MtrrSetAllMtrrs (&MtrrSettings);\r
+\r
+    //\r
+    // Set memory range from 640KB to 1MB to uncacheable\r
+    //\r
+    Status = MtrrSetMemoryAttribute (BASE_512KB + BASE_128KB,\r
+               BASE_1MB - (BASE_512KB + BASE_128KB), CacheUncacheable);\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    //\r
+    // Set memory range from the "top of lower RAM" (RAM below 4GB) to 4GB as\r
+    // uncacheable\r
+    //\r
+    Status = MtrrSetMemoryAttribute (LowerMemorySize,\r
+               SIZE_4GB - LowerMemorySize, CacheUncacheable);\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+}\r
+\r
+/**\r
+  Publish system RAM and reserve memory regions\r
+\r
+**/\r
+VOID\r
+InitializeRamRegions (\r
+  VOID\r
+  )\r
+{\r
+  QemuInitializeRam ();\r
+\r
+  if (mS3Supported && mBootMode != BOOT_ON_S3_RESUME) {\r
+    //\r
+    // This is the memory range that will be used for PEI on S3 resume\r
+    //\r
+    BuildMemoryAllocationHob (\r
+      mS3AcpiReservedMemoryBase,\r
+      mS3AcpiReservedMemorySize,\r
+      EfiACPIMemoryNVS\r
+      );\r
+\r
+    //\r
+    // Cover the initial RAM area used as stack and temporary PEI heap.\r
+    //\r
+    // This is reserved as ACPI NVS so it can be used on S3 resume.\r
+    //\r
+    BuildMemoryAllocationHob (\r
+      PcdGet32 (PcdOvmfSecPeiTempRamBase),\r
+      PcdGet32 (PcdOvmfSecPeiTempRamSize),\r
+      EfiACPIMemoryNVS\r
+      );\r
+\r
+    //\r
+    // SEC stores its table of GUIDed section handlers here.\r
+    //\r
+    BuildMemoryAllocationHob (\r
+      PcdGet64 (PcdGuidedExtractHandlerTableAddress),\r
+      PcdGet32 (PcdGuidedExtractHandlerTableSize),\r
+      EfiACPIMemoryNVS\r
+      );\r
+\r
+#ifdef MDE_CPU_X64\r
+    //\r
+    // Reserve the initial page tables built by the reset vector code.\r
+    //\r
+    // Since this memory range will be used by the Reset Vector on S3\r
+    // resume, it must be reserved as ACPI NVS.\r
+    //\r
+    BuildMemoryAllocationHob (\r
+      (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdOvmfSecPageTablesBase),\r
+      (UINT64)(UINTN) PcdGet32 (PcdOvmfSecPageTablesSize),\r
+      EfiACPIMemoryNVS\r
+      );\r
+#endif\r
+  }\r
+\r
+  if (mBootMode != BOOT_ON_S3_RESUME) {\r
+    if (!FeaturePcdGet (PcdSmmSmramRequire)) {\r
+      //\r
+      // Reserve the lock box storage area\r
+      //\r
+      // Since this memory range will be used on S3 resume, it must be\r
+      // reserved as ACPI NVS.\r
+      //\r
+      // If S3 is unsupported, then various drivers might still write to the\r
+      // LockBox area. We ought to prevent DXE from serving allocation requests\r
+      // such that they would overlap the LockBox storage.\r
+      //\r
+      ZeroMem (\r
+        (VOID*)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageBase),\r
+        (UINTN) PcdGet32 (PcdOvmfLockBoxStorageSize)\r
+        );\r
+      BuildMemoryAllocationHob (\r
+        (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageBase),\r
+        (UINT64)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageSize),\r
+        mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData\r
+        );\r
+    }\r
+\r
+    if (FeaturePcdGet (PcdSmmSmramRequire)) {\r
+      UINT32 TsegSize;\r
+\r
+      //\r
+      // Make sure the TSEG area that we reported as a reserved memory resource\r
+      // cannot be used for reserved memory allocations.\r
+      //\r
+      TsegSize = mQ35TsegMbytes * SIZE_1MB;\r
+      BuildMemoryAllocationHob (\r
+        GetSystemMemorySizeBelow4gb() - TsegSize,\r
+        TsegSize,\r
+        EfiReservedMemoryType\r
+        );\r
+    }\r
+  }\r
+}\r
diff --git a/OvmfPkg/Bhyve/PlatformPei/Platform.c b/OvmfPkg/Bhyve/PlatformPei/Platform.c
new file mode 100644 (file)
index 0000000..11658d4
--- /dev/null
@@ -0,0 +1,607 @@
+/**@file\r
+  Platform PEI driver\r
+\r
+  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+//\r
+// The package level header files this module uses\r
+//\r
+#include <PiPei.h>\r
+\r
+//\r
+// The Library classes this module consumes\r
+//\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/PciLib.h>\r
+#include <Library/PeimEntryPoint.h>\r
+#include <Library/PeiServicesLib.h>\r
+#include <Library/ResourcePublicationLib.h>\r
+#include <Library/LocalApicLib.h>\r
+#include <Guid/MemoryTypeInformation.h>\r
+#include <Ppi/MasterBootMode.h>\r
+#include <IndustryStandard/Pci22.h>\r
+#include <OvmfPlatforms.h>\r
+\r
+#include "Platform.h"\r
+#include "Cmos.h"\r
+\r
+EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {\r
+  { EfiACPIMemoryNVS,       0x004 },\r
+  { EfiACPIReclaimMemory,   0x008 },\r
+  { EfiReservedMemoryType,  0x004 },\r
+  { EfiRuntimeServicesData, 0x024 },\r
+  { EfiRuntimeServicesCode, 0x030 },\r
+  { EfiBootServicesCode,    0x180 },\r
+  { EfiBootServicesData,    0xF00 },\r
+  { EfiMaxMemoryType,       0x000 }\r
+};\r
+\r
+\r
+EFI_PEI_PPI_DESCRIPTOR   mPpiBootMode[] = {\r
+  {\r
+    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
+    &gEfiPeiMasterBootModePpiGuid,\r
+    NULL\r
+  }\r
+};\r
+\r
+\r
+UINT16 mHostBridgeDevId;\r
+\r
+EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION;\r
+\r
+BOOLEAN mS3Supported = FALSE;\r
+\r
+UINT32 mMaxCpuCount;\r
+\r
+VOID\r
+AddIoMemoryBaseSizeHob (\r
+  EFI_PHYSICAL_ADDRESS        MemoryBase,\r
+  UINT64                      MemorySize\r
+  )\r
+{\r
+  BuildResourceDescriptorHob (\r
+    EFI_RESOURCE_MEMORY_MAPPED_IO,\r
+      EFI_RESOURCE_ATTRIBUTE_PRESENT     |\r
+      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
+      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
+      EFI_RESOURCE_ATTRIBUTE_TESTED,\r
+    MemoryBase,\r
+    MemorySize\r
+    );\r
+}\r
+\r
+VOID\r
+AddReservedMemoryBaseSizeHob (\r
+  EFI_PHYSICAL_ADDRESS        MemoryBase,\r
+  UINT64                      MemorySize,\r
+  BOOLEAN                     Cacheable\r
+  )\r
+{\r
+  BuildResourceDescriptorHob (\r
+    EFI_RESOURCE_MEMORY_RESERVED,\r
+      EFI_RESOURCE_ATTRIBUTE_PRESENT     |\r
+      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
+      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
+      (Cacheable ?\r
+       EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
+       EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
+       EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE :\r
+       0\r
+       ) |\r
+      EFI_RESOURCE_ATTRIBUTE_TESTED,\r
+    MemoryBase,\r
+    MemorySize\r
+    );\r
+}\r
+\r
+VOID\r
+AddIoMemoryRangeHob (\r
+  EFI_PHYSICAL_ADDRESS        MemoryBase,\r
+  EFI_PHYSICAL_ADDRESS        MemoryLimit\r
+  )\r
+{\r
+  AddIoMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));\r
+}\r
+\r
+\r
+VOID\r
+AddMemoryBaseSizeHob (\r
+  EFI_PHYSICAL_ADDRESS        MemoryBase,\r
+  UINT64                      MemorySize\r
+  )\r
+{\r
+  BuildResourceDescriptorHob (\r
+    EFI_RESOURCE_SYSTEM_MEMORY,\r
+      EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
+      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
+      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
+      EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
+      EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
+      EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |\r
+      EFI_RESOURCE_ATTRIBUTE_TESTED,\r
+    MemoryBase,\r
+    MemorySize\r
+    );\r
+}\r
+\r
+\r
+VOID\r
+AddMemoryRangeHob (\r
+  EFI_PHYSICAL_ADDRESS        MemoryBase,\r
+  EFI_PHYSICAL_ADDRESS        MemoryLimit\r
+  )\r
+{\r
+  AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));\r
+}\r
+\r
+\r
+VOID\r
+MemMapInitialization (\r
+  VOID\r
+  )\r
+{\r
+  UINT64        PciIoBase;\r
+  UINT64        PciIoSize;\r
+  RETURN_STATUS PcdStatus;\r
+\r
+  PciIoBase = 0xC000;\r
+  PciIoSize = 0x4000;\r
+\r
+  //\r
+  // Create Memory Type Information HOB\r
+  //\r
+  BuildGuidDataHob (\r
+    &gEfiMemoryTypeInformationGuid,\r
+    mDefaultMemoryTypeInformation,\r
+    sizeof(mDefaultMemoryTypeInformation)\r
+    );\r
+\r
+  //\r
+  // Video memory + Legacy BIOS region\r
+  //\r
+  AddIoMemoryRangeHob (0x0A0000, BASE_1MB);\r
+\r
+  if (TRUE) {\r
+    UINT32  TopOfLowRam;\r
+    UINT64  PciExBarBase;\r
+    UINT32  PciBase;\r
+    UINT32  PciSize;\r
+\r
+    TopOfLowRam = GetSystemMemorySizeBelow4gb ();\r
+    PciExBarBase = 0;\r
+    if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {\r
+      //\r
+      // The MMCONFIG area is expected to fall between the top of low RAM and\r
+      // the base of the 32-bit PCI host aperture.\r
+      //\r
+      PciExBarBase = FixedPcdGet64 (PcdPciExpressBaseAddress);\r
+      ASSERT (TopOfLowRam <= PciExBarBase);\r
+      ASSERT (PciExBarBase <= MAX_UINT32 - SIZE_256MB);\r
+      PciBase = (UINT32)(PciExBarBase + SIZE_256MB);\r
+    } else {\r
+      PciBase = (TopOfLowRam < BASE_2GB) ? BASE_2GB : TopOfLowRam;\r
+    }\r
+\r
+    //\r
+    // address       purpose   size\r
+    // ------------  --------  -------------------------\r
+    // max(top, 2g)  PCI MMIO  0xFC000000 - max(top, 2g)\r
+    // 0xFC000000    gap                           44 MB\r
+    // 0xFEC00000    IO-APIC                        4 KB\r
+    // 0xFEC01000    gap                         1020 KB\r
+    // 0xFED00000    HPET                           1 KB\r
+    // 0xFED00400    gap                          111 KB\r
+    // 0xFED1C000    gap (PIIX4) / RCRB (ICH9)     16 KB\r
+    // 0xFED20000    gap                          896 KB\r
+    // 0xFEE00000    LAPIC                          1 MB\r
+    //\r
+    PciSize = 0xFC000000 - PciBase;\r
+    AddIoMemoryBaseSizeHob (PciBase, PciSize);\r
+    PcdStatus = PcdSet64S (PcdPciMmio32Base, PciBase);\r
+    ASSERT_RETURN_ERROR (PcdStatus);\r
+    PcdStatus = PcdSet64S (PcdPciMmio32Size, PciSize);\r
+    ASSERT_RETURN_ERROR (PcdStatus);\r
+\r
+    AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);\r
+    AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);\r
+    if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {\r
+      AddIoMemoryBaseSizeHob (ICH9_ROOT_COMPLEX_BASE, SIZE_16KB);\r
+      //\r
+      // Note: there should be an\r
+      //\r
+      //   AddIoMemoryBaseSizeHob (PciExBarBase, SIZE_256MB);\r
+      //\r
+      // call below, just like the one above for RCBA. However, Linux insists\r
+      // that the MMCONFIG area be marked in the E820 or UEFI memory map as\r
+      // "reserved memory" -- Linux does not content itself with a simple gap\r
+      // in the memory map wherever the MCFG ACPI table points to.\r
+      //\r
+      // This appears to be a safety measure. The PCI Firmware Specification\r
+      // (rev 3.1) says in 4.1.2. "MCFG Table Description": "The resources can\r
+      // *optionally* be returned in [...] EFIGetMemoryMap as reserved memory\r
+      // [...]". (Emphasis added here.)\r
+      //\r
+      // Normally we add memory resource descriptor HOBs in\r
+      // QemuInitializeRam(), and pre-allocate from those with memory\r
+      // allocation HOBs in InitializeRamRegions(). However, the MMCONFIG area\r
+      // is most definitely not RAM; so, as an exception, cover it with\r
+      // uncacheable reserved memory right here.\r
+      //\r
+      AddReservedMemoryBaseSizeHob (PciExBarBase, SIZE_256MB, FALSE);\r
+      BuildMemoryAllocationHob (PciExBarBase, SIZE_256MB,\r
+        EfiReservedMemoryType);\r
+    }\r
+    AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress), SIZE_1MB);\r
+\r
+    //\r
+    // On Q35, the IO Port space is available for PCI resource allocations from\r
+    // 0x6000 up.\r
+    //\r
+    if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {\r
+      PciIoBase = 0x6000;\r
+      PciIoSize = 0xA000;\r
+      ASSERT ((ICH9_PMBASE_VALUE & 0xF000) < PciIoBase);\r
+    }\r
+  }\r
+\r
+  //\r
+  // Add PCI IO Port space available for PCI resource allocations.\r
+  //\r
+  BuildResourceDescriptorHob (\r
+    EFI_RESOURCE_IO,\r
+    EFI_RESOURCE_ATTRIBUTE_PRESENT     |\r
+    EFI_RESOURCE_ATTRIBUTE_INITIALIZED,\r
+    PciIoBase,\r
+    PciIoSize\r
+    );\r
+  PcdStatus = PcdSet64S (PcdPciIoBase, PciIoBase);\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
+  PcdStatus = PcdSet64S (PcdPciIoSize, PciIoSize);\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
+}\r
+\r
+VOID\r
+NoexecDxeInitialization (\r
+  VOID\r
+  )\r
+{\r
+}\r
+\r
+VOID\r
+PciExBarInitialization (\r
+  VOID\r
+  )\r
+{\r
+  union {\r
+    UINT64 Uint64;\r
+    UINT32 Uint32[2];\r
+  } PciExBarBase;\r
+\r
+  //\r
+  // We only support the 256MB size for the MMCONFIG area:\r
+  // 256 buses * 32 devices * 8 functions * 4096 bytes config space.\r
+  //\r
+  // The masks used below enforce the Q35 requirements that the MMCONFIG area\r
+  // be (a) correctly aligned -- here at 256 MB --, (b) located under 64 GB.\r
+  //\r
+  // Note that (b) also ensures that the minimum address width we have\r
+  // determined in AddressWidthInitialization(), i.e., 36 bits, will suffice\r
+  // for DXE's page tables to cover the MMCONFIG area.\r
+  //\r
+  PciExBarBase.Uint64 = FixedPcdGet64 (PcdPciExpressBaseAddress);\r
+  ASSERT ((PciExBarBase.Uint32[1] & MCH_PCIEXBAR_HIGHMASK) == 0);\r
+  ASSERT ((PciExBarBase.Uint32[0] & MCH_PCIEXBAR_LOWMASK) == 0);\r
+\r
+  //\r
+  // Clear the PCIEXBAREN bit first, before programming the high register.\r
+  //\r
+  PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW), 0);\r
+\r
+  //\r
+  // Program the high register. Then program the low register, setting the\r
+  // MMCONFIG area size and enabling decoding at once.\r
+  //\r
+  PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_HIGH), PciExBarBase.Uint32[1]);\r
+  PciWrite32 (\r
+    DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW),\r
+    PciExBarBase.Uint32[0] | MCH_PCIEXBAR_BUS_FF | MCH_PCIEXBAR_EN\r
+    );\r
+}\r
+\r
+VOID\r
+MiscInitialization (\r
+  VOID\r
+  )\r
+{\r
+  UINTN         PmCmd;\r
+  UINTN         Pmba;\r
+  UINT32        PmbaAndVal;\r
+  UINT32        PmbaOrVal;\r
+  UINTN         AcpiCtlReg;\r
+  UINT8         AcpiEnBit;\r
+  RETURN_STATUS PcdStatus;\r
+\r
+  //\r
+  // Disable A20 Mask\r
+  //\r
+  IoOr8 (0x92, BIT1);\r
+\r
+  //\r
+  // Build the CPU HOB with guest RAM size dependent address width and 16-bits\r
+  // of IO space. (Side note: unlike other HOBs, the CPU HOB is needed during\r
+  // S3 resume as well, so we build it unconditionally.)\r
+  //\r
+  BuildCpuHob (mPhysMemAddressWidth, 16);\r
+\r
+  //\r
+  // Determine platform type and save Host Bridge DID to PCD\r
+  //\r
+  switch (mHostBridgeDevId) {\r
+    case 0x1275: // BHYVE\r
+    case INTEL_82441_DEVICE_ID:\r
+      PmCmd      = POWER_MGMT_REGISTER_PIIX4 (PCI_COMMAND_OFFSET);\r
+      Pmba       = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);\r
+      PmbaAndVal = ~(UINT32)PIIX4_PMBA_MASK;\r
+      PmbaOrVal  = PIIX4_PMBA_VALUE;\r
+      AcpiCtlReg = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMREGMISC);\r
+      AcpiEnBit  = PIIX4_PMREGMISC_PMIOSE;\r
+      break;\r
+    case INTEL_Q35_MCH_DEVICE_ID:\r
+      PmCmd      = POWER_MGMT_REGISTER_Q35 (PCI_COMMAND_OFFSET);\r
+      Pmba       = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);\r
+      PmbaAndVal = ~(UINT32)ICH9_PMBASE_MASK;\r
+      PmbaOrVal  = ICH9_PMBASE_VALUE;\r
+      AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL);\r
+      AcpiEnBit  = ICH9_ACPI_CNTL_ACPI_EN;\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
+  PcdStatus = PcdSet16S (PcdOvmfHostBridgePciDevId, mHostBridgeDevId);\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
+\r
+  //\r
+  // If the appropriate IOspace enable bit is set, assume the ACPI PMBA\r
+  // has been configured (e.g., by Xen) and skip the setup here.\r
+  // This matches the logic in AcpiTimerLibConstructor ().\r
+  //\r
+  if ((PciRead8 (AcpiCtlReg) & AcpiEnBit) == 0) {\r
+    //\r
+    // The PEI phase should be exited with fully accessibe ACPI PM IO space:\r
+    // 1. set PMBA\r
+    //\r
+    PciAndThenOr32 (Pmba, PmbaAndVal, PmbaOrVal);\r
+\r
+    //\r
+    // 2. set PCICMD/IOSE\r
+    //\r
+    PciOr8 (PmCmd, EFI_PCI_COMMAND_IO_SPACE);\r
+\r
+    //\r
+    // 3. set ACPI PM IO enable bit (PMREGMISC:PMIOSE or ACPI_CNTL:ACPI_EN)\r
+    //\r
+    PciOr8 (AcpiCtlReg, AcpiEnBit);\r
+  }\r
+\r
+  if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {\r
+    //\r
+    // Set Root Complex Register Block BAR\r
+    //\r
+    PciWrite32 (\r
+      POWER_MGMT_REGISTER_Q35 (ICH9_RCBA),\r
+      ICH9_ROOT_COMPLEX_BASE | ICH9_RCBA_EN\r
+      );\r
+\r
+    //\r
+    // Set PCI Express Register Range Base Address\r
+    //\r
+    PciExBarInitialization ();\r
+  }\r
+}\r
+\r
+\r
+VOID\r
+BootModeInitialization (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+\r
+  if (CmosRead8 (0xF) == 0xFE) {\r
+    mBootMode = BOOT_ON_S3_RESUME;\r
+  }\r
+  CmosWrite8 (0xF, 0x00);\r
+\r
+  Status = PeiServicesSetBootMode (mBootMode);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = PeiServicesInstallPpi (mPpiBootMode);\r
+  ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
+\r
+VOID\r
+ReserveEmuVariableNvStore (\r
+  )\r
+{\r
+  EFI_PHYSICAL_ADDRESS VariableStore;\r
+  RETURN_STATUS        PcdStatus;\r
+\r
+  //\r
+  // Allocate storage for NV variables early on so it will be\r
+  // at a consistent address.  Since VM memory is preserved\r
+  // across reboots, this allows the NV variable storage to survive\r
+  // a VM reboot.\r
+  //\r
+  VariableStore =\r
+    (EFI_PHYSICAL_ADDRESS)(UINTN)\r
+      AllocateRuntimePages (\r
+        EFI_SIZE_TO_PAGES (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize))\r
+        );\r
+  DEBUG ((DEBUG_INFO,\r
+          "Reserved variable store memory: 0x%lX; size: %dkb\n",\r
+          VariableStore,\r
+          (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / 1024\r
+        ));\r
+  PcdStatus = PcdSet64S (PcdEmuVariableNvStoreReserved, VariableStore);\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
+}\r
+\r
+\r
+VOID\r
+DebugDumpCmos (\r
+  VOID\r
+  )\r
+{\r
+  UINT32 Loop;\r
+\r
+  DEBUG ((DEBUG_INFO, "CMOS:\n"));\r
+\r
+  for (Loop = 0; Loop < 0x80; Loop++) {\r
+    if ((Loop % 0x10) == 0) {\r
+      DEBUG ((DEBUG_INFO, "%02x:", Loop));\r
+    }\r
+    DEBUG ((DEBUG_INFO, " %02x", CmosRead8 (Loop)));\r
+    if ((Loop % 0x10) == 0xf) {\r
+      DEBUG ((DEBUG_INFO, "\n"));\r
+    }\r
+  }\r
+}\r
+\r
+\r
+VOID\r
+S3Verification (\r
+  VOID\r
+  )\r
+{\r
+#if defined (MDE_CPU_X64)\r
+  if (FeaturePcdGet (PcdSmmSmramRequire) && mS3Supported) {\r
+    DEBUG ((DEBUG_ERROR,\r
+      "%a: S3Resume2Pei doesn't support X64 PEI + SMM yet.\n", __FUNCTION__));\r
+    DEBUG ((DEBUG_ERROR,\r
+      "%a: Please disable S3 on the QEMU command line (see the README),\n",\r
+      __FUNCTION__));\r
+    DEBUG ((DEBUG_ERROR,\r
+      "%a: or build OVMF with \"OvmfPkgIa32X64.dsc\".\n", __FUNCTION__));\r
+    ASSERT (FALSE);\r
+    CpuDeadLoop ();\r
+  }\r
+#endif\r
+}\r
+\r
+\r
+/**\r
+  Fetch the number of boot CPUs from QEMU and expose it to UefiCpuPkg modules.\r
+  Set the mMaxCpuCount variable.\r
+**/\r
+VOID\r
+MaxCpuCountInitialization (\r
+  VOID\r
+  )\r
+{\r
+  UINT16        ProcessorCount = 0;\r
+  RETURN_STATUS PcdStatus;\r
+\r
+  //\r
+  // If the fw_cfg key or fw_cfg entirely is unavailable, load mMaxCpuCount\r
+  // from the PCD default. No change to PCDs.\r
+  //\r
+  if (ProcessorCount == 0) {\r
+    mMaxCpuCount = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);\r
+    return;\r
+  }\r
+  //\r
+  // Otherwise, set mMaxCpuCount to the value reported by QEMU.\r
+  //\r
+  mMaxCpuCount = ProcessorCount;\r
+  //\r
+  // Additionally, tell UefiCpuPkg modules (a) the exact number of VCPUs, (b)\r
+  // to wait, in the initial AP bringup, exactly as long as it takes for all of\r
+  // the APs to report in. For this, we set the longest representable timeout\r
+  // (approx. 71 minutes).\r
+  //\r
+  PcdStatus = PcdSet32S (PcdCpuMaxLogicalProcessorNumber, ProcessorCount);\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
+  PcdStatus = PcdSet32S (PcdCpuApInitTimeOutInMicroSeconds, MAX_UINT32);\r
+  ASSERT_RETURN_ERROR (PcdStatus);\r
+  DEBUG ((DEBUG_INFO, "%a: QEMU reports %d processor(s)\n", __FUNCTION__,\r
+    ProcessorCount));\r
+}\r
+\r
+\r
+/**\r
+  Perform Platform PEI initialization.\r
+\r
+  @param  FileHandle      Handle of the file being invoked.\r
+  @param  PeiServices     Describes the list of possible PEI Services.\r
+\r
+  @return EFI_SUCCESS     The PEIM initialized successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializePlatform (\r
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,\r
+  IN CONST EFI_PEI_SERVICES     **PeiServices\r
+  )\r
+{\r
+  DEBUG ((DEBUG_INFO, "Platform PEIM Loaded\n"));\r
+\r
+  //\r
+  // Initialize Local APIC Timer hardware and disable Local APIC Timer\r
+  // interrupts before initializing the Debug Agent and the debug timer is\r
+  // enabled.\r
+  //\r
+  InitializeApicTimer (0, MAX_UINT32, TRUE, 5);\r
+  DisableApicTimerInterrupt ();\r
+\r
+  DebugDumpCmos ();\r
+\r
+  BootModeInitialization ();\r
+  AddressWidthInitialization ();\r
+  MaxCpuCountInitialization ();\r
+\r
+  //\r
+  // Query Host Bridge DID\r
+  //\r
+  mHostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);\r
+\r
+  if (FeaturePcdGet (PcdSmmSmramRequire)) {\r
+    Q35TsegMbytesInitialization ();\r
+  }\r
+\r
+  PublishPeiMemory ();\r
+\r
+  InitializeRamRegions ();\r
+\r
+  if (mBootMode != BOOT_ON_S3_RESUME) {\r
+    if (!FeaturePcdGet (PcdSmmSmramRequire)) {\r
+      ReserveEmuVariableNvStore ();\r
+    }\r
+    PeiFvInitialization ();\r
+    MemMapInitialization ();\r
+    NoexecDxeInitialization ();\r
+  }\r
+\r
+  InstallClearCacheCallback ();\r
+  AmdSevInitialize ();\r
+  MiscInitialization ();\r
+  InstallFeatureControlCallback ();\r
+\r
+  return EFI_SUCCESS;\r
+}\r
diff --git a/OvmfPkg/Bhyve/PlatformPei/Platform.h b/OvmfPkg/Bhyve/PlatformPei/Platform.h
new file mode 100644 (file)
index 0000000..8239ca0
--- /dev/null
@@ -0,0 +1,137 @@
+/** @file\r
+  Platform PEI module include file.\r
+\r
+  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef _PLATFORM_PEI_H_INCLUDED_\r
+#define _PLATFORM_PEI_H_INCLUDED_\r
+\r
+#include <IndustryStandard/E820.h>\r
+\r
+VOID\r
+AddIoMemoryBaseSizeHob (\r
+  EFI_PHYSICAL_ADDRESS        MemoryBase,\r
+  UINT64                      MemorySize\r
+  );\r
+\r
+VOID\r
+AddIoMemoryRangeHob (\r
+  EFI_PHYSICAL_ADDRESS        MemoryBase,\r
+  EFI_PHYSICAL_ADDRESS        MemoryLimit\r
+  );\r
+\r
+VOID\r
+AddMemoryBaseSizeHob (\r
+  EFI_PHYSICAL_ADDRESS        MemoryBase,\r
+  UINT64                      MemorySize\r
+  );\r
+\r
+VOID\r
+AddMemoryRangeHob (\r
+  EFI_PHYSICAL_ADDRESS        MemoryBase,\r
+  EFI_PHYSICAL_ADDRESS        MemoryLimit\r
+  );\r
+\r
+VOID\r
+AddReservedMemoryBaseSizeHob (\r
+  EFI_PHYSICAL_ADDRESS        MemoryBase,\r
+  UINT64                      MemorySize,\r
+  BOOLEAN                     Cacheable\r
+  );\r
+\r
+VOID\r
+AddressWidthInitialization (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+Q35TsegMbytesInitialization (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+Q35SmramAtDefaultSmbaseInitialization (\r
+  VOID\r
+  );\r
+\r
+EFI_STATUS\r
+PublishPeiMemory (\r
+  VOID\r
+  );\r
+\r
+UINT32\r
+GetSystemMemorySizeBelow4gb (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+QemuUc32BaseInitialization (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+InitializeRamRegions (\r
+  VOID\r
+  );\r
+\r
+EFI_STATUS\r
+PeiFvInitialization (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+MemTypeInfoInitialization (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+InstallFeatureControlCallback (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+InstallClearCacheCallback (\r
+  VOID\r
+  );\r
+\r
+EFI_STATUS\r
+InitializeXen (\r
+  VOID\r
+  );\r
+\r
+BOOLEAN\r
+XenDetect (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+AmdSevInitialize (\r
+  VOID\r
+  );\r
+\r
+extern BOOLEAN mXen;\r
+\r
+VOID\r
+XenPublishRamRegions (\r
+  VOID\r
+  );\r
+\r
+extern EFI_BOOT_MODE mBootMode;\r
+\r
+extern BOOLEAN mS3Supported;\r
+\r
+extern UINT8 mPhysMemAddressWidth;\r
+\r
+extern UINT32 mMaxCpuCount;\r
+\r
+extern UINT16 mHostBridgeDevId;\r
+\r
+extern BOOLEAN mQ35SmramAtDefaultSmbase;\r
+\r
+extern UINT32 mQemuUc32Base;\r
+\r
+#endif // _PLATFORM_PEI_H_INCLUDED_\r
diff --git a/OvmfPkg/Bhyve/PlatformPei/PlatformPei.inf b/OvmfPkg/Bhyve/PlatformPei/PlatformPei.inf
new file mode 100644 (file)
index 0000000..7288cff
--- /dev/null
@@ -0,0 +1,113 @@
+## @file\r
+#  Platform PEI driver\r
+#\r
+#  This module provides platform specific function to detect boot mode.\r
+#\r
+#  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+#  Copyright (c) 2006 - 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                      = PlatformPei\r
+  FILE_GUID                      = aa89d903-345b-4ab2-9abf-030b5efb5d50\r
+  MODULE_TYPE                    = PEIM\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = InitializePlatform\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
+  AmdSev.c\r
+  ClearCache.c\r
+  Cmos.c\r
+  Cmos.h\r
+  FeatureControl.c\r
+  Fv.c\r
+  MemDetect.c\r
+  Platform.c\r
+  Platform.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+  UefiCpuPkg/UefiCpuPkg.dec\r
+  OvmfPkg/OvmfPkg.dec\r
+\r
+[Guids]\r
+  gEfiMemoryTypeInformationGuid\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  CacheMaintenanceLib\r
+  DebugLib\r
+  HobLib\r
+  IoLib\r
+  PciLib\r
+  ResourcePublicationLib\r
+  PeiServicesLib\r
+  PeiServicesTablePointerLib\r
+  PeimEntryPoint\r
+  MtrrLib\r
+  MemEncryptSevLib\r
+  PcdLib\r
+  LocalApicLib\r
+\r
+[Pcd]\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoSize\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Base\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Size\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Base\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Size\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecompressionScratchEnd\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes\r
+  gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPteMemoryEncryptionAddressOrMask\r
+  gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy\r
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress\r
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber\r
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds\r
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize\r
+\r
+[FixedPcd]\r
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress\r
+\r
+[FeaturePcd]\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire\r
+\r
+[Ppis]\r
+  gEfiPeiMasterBootModePpiGuid\r
+  gEfiPeiMpServicesPpiGuid\r
+\r
+[Depex]\r
+  TRUE\r
+\r
diff --git a/OvmfPkg/Bhyve/SmbiosPlatformDxe/Bhyve.c b/OvmfPkg/Bhyve/SmbiosPlatformDxe/Bhyve.c
new file mode 100644 (file)
index 0000000..6ca976d
--- /dev/null
@@ -0,0 +1,43 @@
+/*\r
+ * Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+ * Copyright (c) 2014, Pluribus Networks, Inc.\r
+ *\r
+ * SPDX-License-Identifier: BSD-2-Clause-Patent\r
+ */\r
+\r
+#include "SmbiosPlatformDxe.h"\r
+\r
+#define BHYVE_SMBIOS_PHYSICAL_ADDRESS       0x000F0000\r
+#define BHYVE_SMBIOS_PHYSICAL_END           0x000FFFFF\r
+\r
+/**\r
+  Locates the bhyve SMBIOS data if it exists\r
+\r
+  @return SMBIOS_TABLE_ENTRY_POINT   Address of bhyve SMBIOS data\r
+\r
+**/\r
+SMBIOS_TABLE_ENTRY_POINT *\r
+GetBhyveSmbiosTables (\r
+  VOID\r
+  )\r
+{\r
+  UINT8                     *BhyveSmbiosPtr;\r
+  SMBIOS_TABLE_ENTRY_POINT  *BhyveSmbiosEntryPointStructure;\r
+\r
+  for (BhyveSmbiosPtr = (UINT8*)(UINTN) BHYVE_SMBIOS_PHYSICAL_ADDRESS;\r
+       BhyveSmbiosPtr < (UINT8*)(UINTN) BHYVE_SMBIOS_PHYSICAL_END;\r
+       BhyveSmbiosPtr += 0x10) {\r
+\r
+    BhyveSmbiosEntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *) BhyveSmbiosPtr;\r
+\r
+    if (!AsciiStrnCmp ((CHAR8 *) BhyveSmbiosEntryPointStructure->AnchorString, "_SM_", 4) &&\r
+        !AsciiStrnCmp ((CHAR8 *) BhyveSmbiosEntryPointStructure->IntermediateAnchorString, "_DMI_", 5) &&\r
+        IsEntryPointStructureValid (BhyveSmbiosEntryPointStructure)) {\r
+\r
+      return BhyveSmbiosEntryPointStructure;\r
+\r
+    }\r
+  }\r
+\r
+  return NULL;\r
+}\r
diff --git a/OvmfPkg/Bhyve/SmbiosPlatformDxe/SmbiosPlatformDxe.c b/OvmfPkg/Bhyve/SmbiosPlatformDxe/SmbiosPlatformDxe.c
new file mode 100644 (file)
index 0000000..59f5d77
--- /dev/null
@@ -0,0 +1,245 @@
+/** @file\r
+  This driver installs SMBIOS information for OVMF\r
+\r
+  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+  Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>\r
+  Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "SmbiosPlatformDxe.h"\r
+\r
+#define TYPE0_STRINGS \\r
+  "EFI Development Kit II / OVMF\0"     /* Vendor */ \\r
+  "0.0.0\0"                             /* BiosVersion */ \\r
+  "02/06/2015\0"                        /* BiosReleaseDate */\r
+//\r
+// Type definition and contents of the default Type 0 SMBIOS table.\r
+//\r
+#pragma pack(1)\r
+typedef struct {\r
+  SMBIOS_TABLE_TYPE0 Base;\r
+  UINT8              Strings[sizeof(TYPE0_STRINGS)];\r
+} OVMF_TYPE0;\r
+#pragma pack()\r
+\r
+STATIC CONST OVMF_TYPE0 mOvmfDefaultType0 = {\r
+  {\r
+    // SMBIOS_STRUCTURE Hdr\r
+    {\r
+      EFI_SMBIOS_TYPE_BIOS_INFORMATION, // UINT8 Type\r
+      sizeof (SMBIOS_TABLE_TYPE0),      // UINT8 Length\r
+    },\r
+    1,     // SMBIOS_TABLE_STRING       Vendor\r
+    2,     // SMBIOS_TABLE_STRING       BiosVersion\r
+    0xE800,// UINT16                    BiosSegment\r
+    3,     // SMBIOS_TABLE_STRING       BiosReleaseDate\r
+    0,     // UINT8                     BiosSize\r
+    {      // MISC_BIOS_CHARACTERISTICS BiosCharacteristics\r
+      0,     // Reserved                                      :2\r
+      0,     // Unknown                                       :1\r
+      1,     // BiosCharacteristicsNotSupported               :1\r
+             // Remaining BiosCharacteristics bits left unset :60\r
+    },\r
+    {      // BIOSCharacteristicsExtensionBytes[2]\r
+      0,     // BiosReserved\r
+      0x1C   // SystemReserved = VirtualMachineSupported |\r
+             //                  UefiSpecificationSupported |\r
+             //                  TargetContentDistributionEnabled\r
+    },\r
+    0,     // UINT8                     SystemBiosMajorRelease\r
+    0,     // UINT8                     SystemBiosMinorRelease\r
+    0xFF,  // UINT8                     EmbeddedControllerFirmwareMajorRelease\r
+    0xFF   // UINT8                     EmbeddedControllerFirmwareMinorRelease\r
+  },\r
+  // Text strings (unformatted area)\r
+  TYPE0_STRINGS\r
+};\r
+\r
+\r
+/**\r
+  Validates the SMBIOS entry point structure\r
+\r
+  @param  EntryPointStructure  SMBIOS entry point structure\r
+\r
+  @retval TRUE   The entry point structure is valid\r
+  @retval FALSE  The entry point structure is not valid\r
+\r
+**/\r
+BOOLEAN\r
+IsEntryPointStructureValid (\r
+  IN SMBIOS_TABLE_ENTRY_POINT  *EntryPointStructure\r
+  )\r
+{\r
+  UINTN                     Index;\r
+  UINT8                     Length;\r
+  UINT8                     Checksum;\r
+  UINT8                     *BytePtr;\r
+\r
+  BytePtr = (UINT8*) EntryPointStructure;\r
+  Length = EntryPointStructure->EntryPointLength;\r
+  Checksum = 0;\r
+\r
+  for (Index = 0; Index < Length; Index++) {\r
+    Checksum = Checksum + (UINT8) BytePtr[Index];\r
+  }\r
+\r
+  if (Checksum != 0) {\r
+    return FALSE;\r
+  } else {\r
+    return TRUE;\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  Get SMBIOS record length.\r
+\r
+  @param  SmbiosTable   SMBIOS pointer.\r
+\r
+**/\r
+UINTN\r
+SmbiosTableLength (\r
+  IN SMBIOS_STRUCTURE_POINTER SmbiosTable\r
+  )\r
+{\r
+  CHAR8  *AChar;\r
+  UINTN  Length;\r
+\r
+  AChar = (CHAR8 *)(SmbiosTable.Raw + SmbiosTable.Hdr->Length);\r
+\r
+  //\r
+  // Each structure shall be terminated by a double-null (SMBIOS spec.7.1)\r
+  //\r
+  while ((*AChar != 0) || (*(AChar + 1) != 0)) {\r
+    AChar ++;\r
+  }\r
+  Length = ((UINTN)AChar - (UINTN)SmbiosTable.Raw + 2);\r
+\r
+  return Length;\r
+}\r
+\r
+\r
+/**\r
+  Install all structures from the given SMBIOS structures block\r
+\r
+  @param  Smbios               SMBIOS protocol\r
+  @param  TableAddress         SMBIOS tables starting address\r
+\r
+**/\r
+EFI_STATUS\r
+InstallAllStructures (\r
+  IN EFI_SMBIOS_PROTOCOL       *Smbios,\r
+  IN UINT8                     *TableAddress\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  SMBIOS_STRUCTURE_POINTER  SmbiosTable;\r
+  EFI_SMBIOS_HANDLE         SmbiosHandle;\r
+  BOOLEAN                   NeedSmbiosType0;\r
+\r
+  SmbiosTable.Raw = TableAddress;\r
+  if (SmbiosTable.Raw == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  NeedSmbiosType0 = TRUE;\r
+\r
+  while (SmbiosTable.Hdr->Type != 127) {\r
+    //\r
+    // Log the SMBIOS data for this structure\r
+    //\r
+    SmbiosHandle = SmbiosTable.Hdr->Handle;\r
+    Status = Smbios->Add (\r
+                       Smbios,\r
+                       NULL,\r
+                       &SmbiosHandle,\r
+                       (EFI_SMBIOS_TABLE_HEADER*) SmbiosTable.Raw\r
+                       );\r
+    ASSERT_EFI_ERROR (Status);\r
+\r
+    if (SmbiosTable.Hdr->Type == 0) {\r
+      NeedSmbiosType0 = FALSE;\r
+    }\r
+\r
+    //\r
+    // Get the next structure address\r
+    //\r
+    SmbiosTable.Raw = (UINT8 *)(SmbiosTable.Raw + SmbiosTableLength (SmbiosTable));\r
+  }\r
+\r
+  if (NeedSmbiosType0) {\r
+    //\r
+    // Add OVMF default Type 0 (BIOS Information) table\r
+    //\r
+    SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r
+    Status = Smbios->Add (\r
+                       Smbios,\r
+                       NULL,\r
+                       &SmbiosHandle,\r
+                       (EFI_SMBIOS_TABLE_HEADER*) &mOvmfDefaultType0\r
+                       );\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Installs SMBIOS information for OVMF\r
+\r
+  @param ImageHandle     Module's image handle\r
+  @param SystemTable     Pointer of EFI_SYSTEM_TABLE\r
+\r
+  @retval EFI_SUCCESS    Smbios data successfully installed\r
+  @retval Other          Smbios data was not installed\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmbiosTablePublishEntry (\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  EFI_SMBIOS_PROTOCOL       *Smbios;\r
+  SMBIOS_TABLE_ENTRY_POINT  *EntryPointStructure;\r
+  UINT8                     *SmbiosTables = NULL;\r
+\r
+  //\r
+  // Find the SMBIOS protocol\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiSmbiosProtocolGuid,\r
+                  NULL,\r
+                  (VOID**)&Smbios\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Add bhyve SMBIOS data\r
+  //\r
+  EntryPointStructure = GetBhyveSmbiosTables ();\r
+  if (EntryPointStructure != NULL) {\r
+    SmbiosTables = (UINT8*)(UINTN)EntryPointStructure->TableAddress;\r
+  }\r
+\r
+  if (SmbiosTables != NULL) {\r
+    Status = InstallAllStructures (Smbios, SmbiosTables);\r
+\r
+    //\r
+    // Free SmbiosTables if allocated by Qemu (i.e., NOT by Xen):\r
+    //\r
+    if (EntryPointStructure == NULL) {\r
+      FreePool (SmbiosTables);\r
+    }\r
+  }\r
+\r
+  return Status;\r
+}\r
diff --git a/OvmfPkg/Bhyve/SmbiosPlatformDxe/SmbiosPlatformDxe.h b/OvmfPkg/Bhyve/SmbiosPlatformDxe/SmbiosPlatformDxe.h
new file mode 100644 (file)
index 0000000..1971827
--- /dev/null
@@ -0,0 +1,52 @@
+/** @file\r
+  This driver installs SMBIOS information for OVMF\r
+\r
+  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+  Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>\r
+  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef _SMBIOS_PLATFORM_DXE_H_\r
+#define _SMBIOS_PLATFORM_DXE_H_\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Protocol/Smbios.h>\r
+#include <IndustryStandard/SmBios.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+\r
+\r
+/**\r
+  Locates the bhyve SMBIOS data if it exists\r
+\r
+  @return SMBIOS_TABLE_ENTRY_POINT   Address of bhyve SMBIOS data\r
+\r
+**/\r
+SMBIOS_TABLE_ENTRY_POINT *\r
+GetBhyveSmbiosTables (\r
+  VOID\r
+  );\r
+\r
+\r
+/**\r
+  Validates the SMBIOS entry point structure\r
+\r
+  @param  EntryPointStructure  SMBIOS entry point structure\r
+\r
+  @retval TRUE   The entry point structure is valid\r
+  @retval FALSE  The entry point structure is not valid\r
+\r
+**/\r
+BOOLEAN\r
+IsEntryPointStructureValid (\r
+  IN SMBIOS_TABLE_ENTRY_POINT  *EntryPointStructure\r
+  );\r
+\r
+#endif\r
diff --git a/OvmfPkg/Bhyve/SmbiosPlatformDxe/SmbiosPlatformDxe.inf b/OvmfPkg/Bhyve/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
new file mode 100644 (file)
index 0000000..a4cc6e7
--- /dev/null
@@ -0,0 +1,55 @@
+## @file\r
+#  This driver installs SMBIOS information for bhyve\r
+#\r
+#  Copyright (c) 2020, Rebecca Cran <rebecca@bsdio.com>\r
+#  Copyright (c) 2011, Bei Guan <gbtju85@gmail.com>\r
+#  Copyright (c) 2011 - 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                      = SmbiosPlatformDxe\r
+  FILE_GUID                      = e2d8a63c-c239-484f-bb21-2917843cc382\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+\r
+  ENTRY_POINT                    = SmbiosTablePublishEntry\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 EBC ARM AARCH64\r
+#\r
+\r
+[Sources]\r
+  SmbiosPlatformDxe.h\r
+  SmbiosPlatformDxe.c\r
+  Bhyve.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  OvmfPkg/OvmfPkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiBootServicesTableLib\r
+  BaseMemoryLib\r
+  BaseLib\r
+  UefiDriverEntryPoint\r
+  DebugLib\r
+  HobLib\r
+  MemoryAllocationLib\r
+  PcdLib\r
+\r
+[Pcd]\r
+  gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated\r
+\r
+[Protocols]\r
+  gEfiSmbiosProtocolGuid                      # PROTOCOL ALWAYS_CONSUMED\r
+\r
+[Depex]\r
+  gEfiSmbiosProtocolGuid\r
+\r
diff --git a/OvmfPkg/Bhyve/VarStore.fdf.inc b/OvmfPkg/Bhyve/VarStore.fdf.inc
new file mode 100644 (file)
index 0000000..a1e524e
--- /dev/null
@@ -0,0 +1,115 @@
+## @file\r
+#  FDF include file with Layout Regions that define an empty variable store.\r
+#\r
+#  Copyright (C) 2014, Red Hat, Inc.\r
+#  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)\r
+0x00000000|0x0000e000\r
+!endif\r
+!if $(FD_SIZE_IN_KB) == 4096\r
+0x00000000|0x00040000\r
+!endif\r
+#NV_VARIABLE_STORE\r
+DATA = {\r
+  ## This is the EFI_FIRMWARE_VOLUME_HEADER\r
+  # ZeroVector []\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+  # FileSystemGuid: gEfiSystemNvDataFvGuid         =\r
+  #   { 0xFFF12B8D, 0x7696, 0x4C8B,\r
+  #     { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}\r
+  0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,\r
+  0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,\r
+!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)\r
+  # FvLength: 0x20000\r
+  0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+!endif\r
+!if $(FD_SIZE_IN_KB) == 4096\r
+  # FvLength: 0x84000\r
+  0x00, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+!endif\r
+  # Signature "_FVH"       # Attributes\r
+  0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,\r
+  # HeaderLength\r
+  0x48, 0x00,\r
+!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)\r
+  # CheckSum\r
+  0x19, 0xF9,\r
+!endif\r
+!if $(FD_SIZE_IN_KB) == 4096\r
+  # CheckSum\r
+  0xAF, 0xB8,\r
+!endif\r
+  # ExtHeaderOffset #Reserved #Revision\r
+  0x00, 0x00, 0x00, 0x02,\r
+!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)\r
+  # Blockmap[0]: 0x20 Blocks * 0x1000 Bytes / Block\r
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\r
+!endif\r
+!if $(FD_SIZE_IN_KB) == 4096\r
+  # Blockmap[0]: 0x84 Blocks * 0x1000 Bytes / Block\r
+  0x84, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\r
+!endif\r
+  # Blockmap[1]: End\r
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
+  ## This is the VARIABLE_STORE_HEADER\r
+  # It is compatible with SECURE_BOOT_ENABLE == FALSE as well.\r
+  # Signature: gEfiAuthenticatedVariableGuid =\r
+  #   { 0xaaf32c78, 0x947b, 0x439a,\r
+  #     { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }}\r
+  0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,\r
+  0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,\r
+!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)\r
+  # Size: 0xe000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) -\r
+  #         0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0xdfb8\r
+  # This can speed up the Variable Dispatch a bit.\r
+  0xB8, 0xDF, 0x00, 0x00,\r
+!endif\r
+!if $(FD_SIZE_IN_KB) == 4096\r
+  # Size: 0x40000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) -\r
+  #          0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x3ffb8\r
+  # This can speed up the Variable Dispatch a bit.\r
+  0xB8, 0xFF, 0x03, 0x00,\r
+!endif\r
+  # FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32\r
+  0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+}\r
+\r
+!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)\r
+0x0000e000|0x00001000\r
+!endif\r
+!if $(FD_SIZE_IN_KB) == 4096\r
+0x00040000|0x00001000\r
+!endif\r
+#NV_EVENT_LOG\r
+\r
+!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)\r
+0x0000f000|0x00001000\r
+!endif\r
+!if $(FD_SIZE_IN_KB) == 4096\r
+0x00041000|0x00001000\r
+!endif\r
+#NV_FTW_WORKING\r
+DATA = {\r
+  # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid         =\r
+  #  { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95 }}\r
+  0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,\r
+  0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95,\r
+  # Crc:UINT32            #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved\r
+  0x2c, 0xaf, 0x2c, 0x64, 0xFE, 0xFF, 0xFF, 0xFF,\r
+  # WriteQueueSize: UINT64\r
+  0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
+}\r
+\r
+!if ($(FD_SIZE_IN_KB) == 1024) || ($(FD_SIZE_IN_KB) == 2048)\r
+0x00010000|0x00010000\r
+!endif\r
+!if $(FD_SIZE_IN_KB) == 4096\r
+0x00042000|0x00042000\r
+!endif\r
+#NV_FTW_SPARE\r