public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests
@ 2016-12-08 15:33 Anthony PERARD
  2016-12-08 15:33 ` [PATCH RFC 01/14] OvmfPkg: Create platform XenOvmf Anthony PERARD
                   ` (14 more replies)
  0 siblings, 15 replies; 37+ messages in thread
From: Anthony PERARD @ 2016-12-08 15:33 UTC (permalink / raw)
  To: edk2-devel, xen-devel; +Cc: Anthony PERARD

Hi,

I've started to create a Xen specifig plaform, in OvmfPkg/XenOvmf.dsc
with the goal to make it work on both Xen HVM and Xen PVHv2

The first few patches only create the platform and duplicate some code from
OvmfPkg and the later patches (from OvmfPkg/XenPlatformPei: Add xen PVH
specific code) makes OVMF boot in a Xen PVH guest, and can boot a Linux.

== Part 1: XenOvmf.dsc

- OvmfPkg: Create platform XenOvmf
which for now remove virtio drivers and some SMM

- OvmfPkg/XenOvmf: Update debug IO port for Xen

- OvmfPkg/XenOvmf.dsc: Introduce XenResetVector
Just for one change, enable cache in CR0 as on Xen, OVMF run from RAM, that
disabling cache can make OVMF very slow.

- OvmfPkg: Introduce XenPlatformPei
remove some QEMU/KVM specific code from PlatformPei.

- OvmfPkg/Library: add XenPciHostBridgeLib
same with PciHostBridgeLib

== Part 2: PVH enabled

- OvmfPkg/XenPlatformPei: Add xen PVH specific code
To figure out the memory size from E820

- OvmfPkg/XenResetVector: Add new entry point for Xen PVH
which is in 32bits

- OvmfPkg/PlatformBootManagerLib: Workaround missing PCI bus on Xen PVH
to avoid the Unknown Host Bridge Device ID error

- OvmfPkg/ResetSystemLib: Add missing dependency on PciLib
- UefiCpuPkg/BaseXApicX2ApicLib: Fix initialisation on my system and ...
- OvmfPkg/XenOvmf: Adding XenTimerLocalApic
to replace the ACPI timer

- OvmfPkg/PlatformBootManagerLib: Use a Xen console for ConOut/ConIn
- OvmfPkg: Introduce XenIoPvhDxe to initialize Grant Tables
- XenOvmf: Use a different RTC
which does always return the same value

== to build and boot

To build, simply run OvmfPkg/build.sh -p OvmfPkg/XenOvmf.dsc

To run, I currently use a loader, base on hvmloader which does some setup, read
the e820 and copy ovmf to the right place to start it.

The loader is avaible in branch `ovmf-pvhloader' from
https://xenbits.xen.org/git-http/people/aperard/xen-unstable.git

And the guest I'm using:
builder = 'hvm'
memory = 512
name = "pvh-ovmf"
kernel = 'pvh-ovmf-loader'
ramdisk='OVMF.fd'
extra='ovmf=1'
disk = [ 'file:iso/archlinux-2016.10.01-dual.iso,hdc:cdrom,r', ]
device_model_version = 'none'
serial = 'pty'

Anthony PERARD (14):
  OvmfPkg: Create platform XenOvmf
  OvmfPkg/XenOvmf: Update debug IO port for Xen
  OvmfPkg/XenOvmf.dsc: Introduce XenResetVector
  OvmfPkg: Introduce XenPlatformPei
  OvmfPkg/Library: add XenPciHostBridgeLib
  OvmfPkg/XenPlatformPei: Add xen PVH specific code
  OvmfPkg/XenResetVector: Add new entry point for Xen PVH
  OvmfPkg/PlatformBootManagerLib: Workaround missing PCI bus on Xen PVH
  OvmfPkg/ResetSystemLib: Add missing dependency on PciLib
  UefiCpuPkg/BaseXApicX2ApicLib: Fix initialisation on my system and ...
  OvmfPkg/XenOvmf: Adding XenTimerLocalApic
  OvmfPkg/PlatformBootManagerLib: Use a Xen console for ConOut/ConIn
  OvmfPkg: Introduce XenIoPvhDxe to initialize Grant Tables
  XenOvmf: Use a different RTC

 .../Library/PlatformBootManagerLib/BdsPlatform.c   |  35 +
 .../PlatformBootManagerLib.inf                     |   2 +
 OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf  |   1 +
 .../Library/XenPciHostBridgeLib/XenPciHostBridge.h |  75 ++
 .../XenPciHostBridgeLib/XenPciHostBridgeLib.c      | 291 ++++++++
 .../XenPciHostBridgeLib/XenPciHostBridgeLib.inf    |  58 ++
 OvmfPkg/Library/XenPciHostBridgeLib/XenSupport.c   | 456 ++++++++++++
 OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c                  | 263 +++++++
 OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf                |  45 ++
 OvmfPkg/XenOvmf.dsc                                | 809 +++++++++++++++++++++
 OvmfPkg/XenOvmf.fdf                                | 506 +++++++++++++
 OvmfPkg/XenPlatformPei/Cmos.c                      |  64 ++
 OvmfPkg/XenPlatformPei/Cmos.h                      |  56 ++
 OvmfPkg/XenPlatformPei/Fv.c                        | 100 +++
 OvmfPkg/XenPlatformPei/MemDetect.c                 | 520 +++++++++++++
 OvmfPkg/XenPlatformPei/Platform.c                  | 541 ++++++++++++++
 OvmfPkg/XenPlatformPei/Platform.h                  | 114 +++
 OvmfPkg/XenPlatformPei/Xen.c                       | 231 ++++++
 OvmfPkg/XenPlatformPei/Xen.h                       |  45 ++
 OvmfPkg/XenPlatformPei/XenPlatformPei.inf          | 110 +++
 OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm     | 133 ++++
 OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm    |  79 ++
 OvmfPkg/XenResetVector/Ia32/PageTables64.asm       |  93 +++
 OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm         |  23 +
 OvmfPkg/XenResetVector/XenResetVector.inf          |  37 +
 OvmfPkg/XenResetVector/XenResetVector.nasmb        |  67 ++
 OvmfPkg/XenTimerLocalApic/Timer.h                  | 191 +++++
 OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.c      | 386 ++++++++++
 OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.inf    |  51 ++
 UefiCpuPkg/Include/Library/LocalApicLib.h          |  40 +
 .../BaseXApicX2ApicLib/BaseXApicX2ApicLib.c        |  10 +-
 31 files changed, 5427 insertions(+), 5 deletions(-)
 create mode 100644 OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridge.h
 create mode 100644 OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridgeLib.c
 create mode 100644 OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridgeLib.inf
 create mode 100644 OvmfPkg/Library/XenPciHostBridgeLib/XenSupport.c
 create mode 100644 OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c
 create mode 100644 OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
 create mode 100644 OvmfPkg/XenOvmf.dsc
 create mode 100644 OvmfPkg/XenOvmf.fdf
 create mode 100644 OvmfPkg/XenPlatformPei/Cmos.c
 create mode 100644 OvmfPkg/XenPlatformPei/Cmos.h
 create mode 100644 OvmfPkg/XenPlatformPei/Fv.c
 create mode 100644 OvmfPkg/XenPlatformPei/MemDetect.c
 create mode 100644 OvmfPkg/XenPlatformPei/Platform.c
 create mode 100644 OvmfPkg/XenPlatformPei/Platform.h
 create mode 100644 OvmfPkg/XenPlatformPei/Xen.c
 create mode 100644 OvmfPkg/XenPlatformPei/Xen.h
 create mode 100644 OvmfPkg/XenPlatformPei/XenPlatformPei.inf
 create mode 100644 OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
 create mode 100644 OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
 create mode 100644 OvmfPkg/XenResetVector/Ia32/PageTables64.asm
 create mode 100644 OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
 create mode 100644 OvmfPkg/XenResetVector/XenResetVector.inf
 create mode 100644 OvmfPkg/XenResetVector/XenResetVector.nasmb
 create mode 100644 OvmfPkg/XenTimerLocalApic/Timer.h
 create mode 100644 OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.c
 create mode 100644 OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.inf

-- 
Anthony PERARD



^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH RFC 01/14] OvmfPkg: Create platform XenOvmf
  2016-12-08 15:33 [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
@ 2016-12-08 15:33 ` Anthony PERARD
  2017-01-04 19:14   ` Laszlo Ersek
  2016-12-08 15:33 ` [PATCH RFC 02/14] OvmfPkg/XenOvmf: Update debug IO port for Xen Anthony PERARD
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Anthony PERARD @ 2016-12-08 15:33 UTC (permalink / raw)
  To: edk2-devel, xen-devel; +Cc: Anthony PERARD

This is a copy of OvmfX64, removing VirtIO and some SMM.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 OvmfPkg/XenOvmf.dsc | 793 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 OvmfPkg/XenOvmf.fdf | 504 +++++++++++++++++++++++++++++++++
 2 files changed, 1297 insertions(+)
 create mode 100644 OvmfPkg/XenOvmf.dsc
 create mode 100644 OvmfPkg/XenOvmf.fdf

diff --git a/OvmfPkg/XenOvmf.dsc b/OvmfPkg/XenOvmf.dsc
new file mode 100644
index 0000000..e452eb3
--- /dev/null
+++ b/OvmfPkg/XenOvmf.dsc
@@ -0,0 +1,793 @@
+## @file
+#  EFI/Framework Open Virtual Machine Firmware (OVMF) platform
+#
+#  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+#  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  PLATFORM_NAME                  = Ovmf
+  PLATFORM_GUID                  = e3aa4fbe-9459-482d-bd40-d3f3b5f89d6e
+  PLATFORM_VERSION               = 0.1
+  DSC_SPECIFICATION              = 0x00010005
+  OUTPUT_DIRECTORY               = Build/XenOvmf
+  SUPPORTED_ARCHITECTURES        = X64
+  BUILD_TARGETS                  = NOOPT|DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+  FLASH_DEFINITION               = OvmfPkg/XenOvmf.fdf
+
+  #
+  # Defines for default states.  These can be changed on the command line.
+  # -D FLAG=VALUE
+  #
+  DEFINE SECURE_BOOT_ENABLE      = FALSE
+  DEFINE NETWORK_IP6_ENABLE      = FALSE
+  DEFINE HTTP_BOOT_ENABLE        = FALSE
+  DEFINE SMM_REQUIRE             = FALSE
+
+[BuildOptions]
+  GCC:*_UNIXGCC_*_CC_FLAGS             = -DMDEPKG_NDEBUG
+  GCC:RELEASE_*_*_CC_FLAGS             = -DMDEPKG_NDEBUG
+  INTEL:RELEASE_*_*_CC_FLAGS           = /D MDEPKG_NDEBUG
+  MSFT:RELEASE_*_*_CC_FLAGS            = /D MDEPKG_NDEBUG
+  GCC:*_*_*_CC_FLAGS                   = -mno-mmx -mno-sse
+!ifdef $(SOURCE_DEBUG_ENABLE)
+  MSFT:*_*_X64_GENFW_FLAGS  = --keepexceptiontable
+  GCC:*_*_X64_GENFW_FLAGS   = --keepexceptiontable
+  INTEL:*_*_X64_GENFW_FLAGS = --keepexceptiontable
+!endif
+
+  #
+  # Disable deprecated APIs.
+  #
+  MSFT:*_*_*_CC_FLAGS = /D DISABLE_NEW_DEPRECATED_INTERFACES
+  INTEL:*_*_*_CC_FLAGS = /D DISABLE_NEW_DEPRECATED_INTERFACES
+  GCC:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
+
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
+# Force PE/COFF sections to be aligned at 4KB boundaries to support page level
+# protection of DXE_SMM_DRIVER/SMM_CORE modules
+[BuildOptions.common.EDKII.DXE_SMM_DRIVER, BuildOptions.common.EDKII.SMM_CORE]
+  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
+################################################################################
+#
+# SKU Identification section - list of all SKU IDs supported by this Platform.
+#
+################################################################################
+[SkuIds]
+  0|DEFAULT
+
+################################################################################
+#
+# Library Class section - list of all Library Classes needed by this Platform.
+#
+################################################################################
+[LibraryClasses]
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
+  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
+  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+  PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+  SerialPortLib|PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf
+  MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
+  NvVarsFileLib|OvmfPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
+  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+  UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
+  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+  IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
+  UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
+  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+  SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
+  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
+  LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
+!if $(SMM_REQUIRE) == FALSE
+  LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
+!endif
+  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+  FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
+
+!ifdef $(SOURCE_DEBUG_ENABLE)
+  PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
+  DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf
+!else
+  PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+!endif
+
+  ResetSystemLib|OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
+  LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+  AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
+!if $(NETWORK_IP6_ENABLE) == TRUE
+  TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf
+!endif
+!else
+  TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+  AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
+!endif
+  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+
+!if $(HTTP_BOOT_ENABLE) == TRUE
+  HttpLib|MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.inf
+!endif
+
+  S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
+  SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
+  OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
+  XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
+
+[LibraryClasses.common]
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+!endif
+
+[LibraryClasses.common.SEC]
+  TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
+  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf
+!ifdef $(SOURCE_DEBUG_ENABLE)
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+!endif
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
+
+[LibraryClasses.common.PEI_CORE]
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+
+[LibraryClasses.common.PEIM]
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+!ifdef $(SOURCE_DEBUG_ENABLE)
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
+!endif
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
+  MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
+
+[LibraryClasses.common.DXE_CORE]
+  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+!ifdef $(SOURCE_DEBUG_ENABLE)
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+!endif
+  PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+
+[LibraryClasses.common.UEFI_DRIVER]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+  PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+
+[LibraryClasses.common.DXE_DRIVER]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+  IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
+  UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
+  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
+  PlatformBootManagerLib|OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+  QemuBootOrderLib|OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
+  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
+!if $(SMM_REQUIRE) == TRUE
+  LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf
+!else
+  LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf
+!endif
+!ifdef $(SOURCE_DEBUG_ENABLE)
+  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
+!endif
+  PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+  MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
+
+[LibraryClasses.common.UEFI_APPLICATION]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+!ifdef $(DEBUG_ON_SERIAL_PORT)
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!else
+  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
+!endif
+  PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform.
+#
+################################################################################
+[PcdsFeatureFlag]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdHiiOsRuntimeSupport|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportUefiDecompress|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  gUefiOvmfPkgTokenSpaceGuid.PcdSecureBootEnable|TRUE
+!endif
+!if $(SMM_REQUIRE) == TRUE
+  gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire|TRUE
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmEnableBspElection|FALSE
+!endif
+
+[PcdsFixedAtBuild]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxFvSupported|6
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeimPerFv|32
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
+
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+
+  # DEBUG_INIT      0x00000001  // Initialization
+  # DEBUG_WARN      0x00000002  // Warnings
+  # DEBUG_LOAD      0x00000004  // Load events
+  # DEBUG_FS        0x00000008  // EFI File system
+  # DEBUG_POOL      0x00000010  // Alloc & Free (pool)
+  # DEBUG_PAGE      0x00000020  // Alloc & Free (page)
+  # DEBUG_INFO      0x00000040  // Informational debug messages
+  # DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers
+  # DEBUG_VARIABLE  0x00000100  // Variable
+  # DEBUG_BM        0x00000400  // Boot Manager
+  # DEBUG_BLKIO     0x00001000  // BlkIo Driver
+  # DEBUG_NET       0x00004000  // SNP Driver
+  # DEBUG_UNDI      0x00010000  // UNDI Driver
+  # DEBUG_LOADFILE  0x00020000  // LoadFile
+  # DEBUG_EVENT     0x00080000  // Event messages
+  # DEBUG_GCD       0x00100000  // Global Coherency Database changes
+  # DEBUG_CACHE     0x00200000  // Memory range cachability changes
+  # DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
+  #                             // significantly impact boot performance
+  # DEBUG_ERROR     0x80000000  // Error
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
+
+!ifdef $(SOURCE_DEBUG_ENABLE)
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
+!endif
+
+  # This PCD is used to set the base address of the PCI express hierarchy. It
+  # is only consulted when OVMF runs on Q35. In that case it is programmed into
+  # the PCIEXBAR register.
+  #
+  # On Q35 machine types that QEMU intends to support in the long term, QEMU
+  # never lets the RAM below 4 GB exceed 2 GB.
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0x80000000
+
+!ifdef $(SOURCE_DEBUG_ENABLE)
+  gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|0x2
+!endif
+
+!ifndef $(USE_OLD_SHELL)
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }
+!endif
+
+!if $(SMM_REQUIRE) == TRUE
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x01
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|100000
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize|0x4000
+!endif
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x00
+!endif
+
+  # IRQs 5, 9, 10, 11 are level-triggered
+  gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel|0x0E20
+
+  # Point to the MdeModulePkg/Application/UiApp/UiApp.inf
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+
+################################################################################
+#
+# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsDynamicDefault]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable|FALSE
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId|0
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase|0x0
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoSize|0x0
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Base|0x0
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Size|0x0
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Base|0x0
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Size|0x800000000
+
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|0
+
+  # Set video resolution for text setup.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
+  gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
+
+  # Noexec settings for DXE.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPropertiesTableEnable|FALSE
+
+  # UefiCpuPkg PCDs related to initial AP bringup and general AP management.
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform.
+#
+################################################################################
+[Components]
+  OvmfPkg/ResetVector/ResetVector.inf
+
+  #
+  # SEC Phase modules
+  #
+  OvmfPkg/Sec/SecMain.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+  }
+
+  #
+  # PEI Phase modules
+  #
+  MdeModulePkg/Core/Pei/PeiMain.inf
+  MdeModulePkg/Universal/PCD/Pei/Pcd.inf  {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+
+  OvmfPkg/PlatformPei/PlatformPei.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+!if $(SMM_REQUIRE) == TRUE
+      LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
+!endif
+  }
+!if $(SMM_REQUIRE) == TRUE
+  OvmfPkg/SmmAccess/SmmAccessPei.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+!endif
+  UefiCpuPkg/CpuMpPei/CpuMpPei.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  }
+
+  #
+  # DXE Phase modules
+  #
+  MdeModulePkg/Core/Dxe/DxeMain.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  }
+
+  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf  {
+   <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
+    <LibraryClasses>
+      NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
+	}
+!else
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+!endif
+
+  MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
+  PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
+  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+  UefiCpuPkg/CpuDxe/CpuDxe.inf
+  PcAtChipsetPkg/8254TimerDxe/8254Timer.inf
+  OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf
+  OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
+  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
+    <LibraryClasses>
+      PciHostBridgeLib|OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
+  }
+  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+  MdeModulePkg/Universal/Metronome/Metronome.inf
+  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+  MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
+  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf {
+    <LibraryClasses>
+!ifdef $(CSM_ENABLE)
+      NULL|OvmfPkg/Csm/CsmSupportLib/CsmSupportLib.inf
+      NULL|IntelFrameworkModulePkg/Library/LegacyBootManagerLib/LegacyBootManagerLib.inf
+!endif
+  }
+  MdeModulePkg/Logo/LogoDxe.inf
+  MdeModulePkg/Application/UiApp/UiApp.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
+      NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
+      NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
+!ifdef $(CSM_ENABLE)
+      NULL|IntelFrameworkModulePkg/Library/LegacyBootManagerLib/LegacyBootManagerLib.inf
+      NULL|IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUiLib.inf
+!endif
+  }
+  OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
+  OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
+  OvmfPkg/XenBusDxe/XenBusDxe.inf
+  OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf {
+    <LibraryClasses>
+      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+  MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
+  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
+  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+  FatPkg/EnhancedFatDxe/Fat.inf
+  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+  OvmfPkg/SataControllerDxe/SataControllerDxe.inf
+  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+
+  OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
+
+  #
+  # ISA Support
+  #
+  PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.inf
+  IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf
+  IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf
+  IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf
+  IntelFrameworkModulePkg/Bus/Isa/IsaFloppyDxe/IsaFloppyDxe.inf
+
+  #
+  # SMBIOS Support
+  #
+  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf {
+    <LibraryClasses>
+      NULL|OvmfPkg/Library/SmbiosVersionLib/DetectSmbiosVersionLib.inf
+  }
+  OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+
+  #
+  # ACPI Support
+  #
+  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+  OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
+  OvmfPkg/AcpiTables/AcpiTables.inf
+  MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+  MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
+
+  #
+  # Network Support
+  #
+  MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
+  MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
+  MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
+  MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
+  MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
+  MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
+  MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
+  MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
+  MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+!if $(NETWORK_IP6_ENABLE) == TRUE
+  NetworkPkg/Ip6Dxe/Ip6Dxe.inf
+  NetworkPkg/TcpDxe/TcpDxe.inf
+  NetworkPkg/Udp6Dxe/Udp6Dxe.inf
+  NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
+  NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
+  NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  NetworkPkg/IScsiDxe/IScsiDxe.inf
+!else
+  MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+!endif
+!else
+  MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
+  MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
+  MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+!endif
+!if $(HTTP_BOOT_ENABLE) == TRUE
+  NetworkPkg/DnsDxe/DnsDxe.inf
+  NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf
+  NetworkPkg/HttpDxe/HttpDxe.inf
+  NetworkPkg/HttpBootDxe/HttpBootDxe.inf
+!endif
+
+  #
+  # Usb Support
+  #
+  MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
+  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+  MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
+  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+!ifdef $(CSM_ENABLE)
+  IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  }
+  IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf
+  OvmfPkg/Csm/Csm16/Csm16.inf
+!endif
+
+!ifndef $(USE_OLD_SHELL)
+  ShellPkg/Application/Shell/Shell.inf {
+    <LibraryClasses>
+      ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+!if $(NETWORK_IP6_ENABLE) == TRUE
+      NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
+!endif
+      NULL|ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf
+      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+      ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+      FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+#      SafeBlockIoLib|ShellPkg/Library/SafeBlockIoLib/SafeBlockIoLib.inf
+#      SafeOpenProtocolLib|ShellPkg/Library/SafeOpenProtocolLib/SafeOpenProtocolLib.inf
+      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
+  }
+!endif
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+!endif
+
+  OvmfPkg/PlatformDxe/Platform.inf
+
+!if $(SMM_REQUIRE) == TRUE
+  OvmfPkg/SmmAccess/SmmAccess2Dxe.inf
+  OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
+  UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf
+
+  #
+  # SMM Initial Program Load (a DXE_RUNTIME_DRIVER)
+  #
+  MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
+
+  #
+  # SMM_CORE
+  #
+  MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
+
+  #
+  # Privileged drivers (DXE_SMM_DRIVER modules)
+  #
+  UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
+  MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf {
+    <LibraryClasses>
+      LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf
+  }
+  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf {
+    <LibraryClasses>
+      SmmCpuPlatformHookLib|UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf
+      SmmCpuFeaturesLib|OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
+  }
+
+  #
+  # Variable driver stack (SMM)
+  #
+  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+  }
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+
+!else
+
+  #
+  # Variable driver stack (non-SMM)
+  #
+  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+  OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf {
+    <LibraryClasses>
+      PlatformFvbLib|OvmfPkg/Library/EmuVariableFvbLib/EmuVariableFvbLib.inf
+  }
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+  }
+!endif
diff --git a/OvmfPkg/XenOvmf.fdf b/OvmfPkg/XenOvmf.fdf
new file mode 100644
index 0000000..d01454e
--- /dev/null
+++ b/OvmfPkg/XenOvmf.fdf
@@ -0,0 +1,504 @@
+## @file
+#  Open Virtual Machine Firmware: FDF
+#
+#  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+#  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+################################################################################
+
+[Defines]
+!include OvmfPkg.fdf.inc
+
+#
+# Build the variable store and the firmware code as one unified flash device
+# image.
+#
+[FD.OVMF]
+BaseAddress   = $(FW_BASE_ADDRESS)
+Size          = $(FW_SIZE)
+ErasePolarity = 1
+BlockSize     = $(BLOCK_SIZE)
+NumBlocks     = $(FW_BLOCKS)
+
+!include VarStore.fdf.inc
+
+$(VARS_SIZE)|$(FVMAIN_SIZE)
+FV = FVMAIN_COMPACT
+
+$(SECFV_OFFSET)|$(SECFV_SIZE)
+FV = SECFV
+
+#
+# Build the variable store and the firmware code as separate flash device
+# images.
+#
+[FD.OVMF_VARS]
+BaseAddress   = $(FW_BASE_ADDRESS)
+Size          = $(VARS_SIZE)
+ErasePolarity = 1
+BlockSize     = $(BLOCK_SIZE)
+NumBlocks     = $(VARS_BLOCKS)
+
+!include VarStore.fdf.inc
+
+[FD.OVMF_CODE]
+BaseAddress   = $(CODE_BASE_ADDRESS)
+Size          = $(CODE_SIZE)
+ErasePolarity = 1
+BlockSize     = $(BLOCK_SIZE)
+NumBlocks     = $(CODE_BLOCKS)
+
+0x00000000|$(FVMAIN_SIZE)
+FV = FVMAIN_COMPACT
+
+$(FVMAIN_SIZE)|$(SECFV_SIZE)
+FV = SECFV
+
+################################################################################
+
+[FD.MEMFD]
+BaseAddress   = $(MEMFD_BASE_ADDRESS)
+Size          = 0xB00000
+ErasePolarity = 1
+BlockSize     = 0x10000
+NumBlocks     = 0xB0
+
+0x000000|0x006000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
+
+0x006000|0x001000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize
+
+0x007000|0x001000
+gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+
+0x010000|0x008000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
+
+0x020000|0x0E0000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
+FV = PEIFV
+
+0x100000|0xA00000
+gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
+FV = DXEFV
+
+################################################################################
+
+[FV.SECFV]
+FvNameGuid         = 763BED0D-DE9F-48F5-81F1-3E90E1B1A015
+BlockSize          = 0x1000
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+#
+# SEC Phase modules
+#
+# The code in this FV handles the initial firmware startup, and
+# decompresses the PEI and DXE FVs which handles the rest of the boot sequence.
+#
+INF  OvmfPkg/Sec/SecMain.inf
+
+INF  RuleOverride=RESET_VECTOR OvmfPkg/ResetVector/ResetVector.inf
+
+################################################################################
+[FV.PEIFV]
+FvNameGuid         = 6938079B-B503-4E3D-9D24-B28337A25806
+BlockSize          = 0x10000
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+APRIORI PEI {
+  INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+}
+
+#
+#  PEI Phase modules
+#
+INF  MdeModulePkg/Core/Pei/PeiMain.inf
+INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+INF  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+INF  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+INF  OvmfPkg/PlatformPei/PlatformPei.inf
+INF  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+INF  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
+!if $(SMM_REQUIRE) == TRUE
+INF  OvmfPkg/SmmAccess/SmmAccessPei.inf
+!endif
+INF  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+
+################################################################################
+
+[FV.DXEFV]
+FvNameGuid         = 7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1
+BlockSize          = 0x10000
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+APRIORI DXE {
+  INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+  INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+!if $(SMM_REQUIRE) == FALSE
+  INF  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+!endif
+}
+
+#
+# DXE Phase modules
+#
+INF  MdeModulePkg/Core/Dxe/DxeMain.inf
+
+INF  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+INF  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+
+INF  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+INF  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+INF  MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
+INF  PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
+INF  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+INF  UefiCpuPkg/CpuDxe/CpuDxe.inf
+INF  PcAtChipsetPkg/8254TimerDxe/8254Timer.inf
+INF  OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf
+INF  OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
+INF  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+INF  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+INF  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
+INF  MdeModulePkg/Universal/Metronome/Metronome.inf
+INF  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+
+INF  OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
+INF  OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
+INF  OvmfPkg/XenBusDxe/XenBusDxe.inf
+INF  OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  INF  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+!endif
+
+INF  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+INF  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+INF  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+INF  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+INF  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+INF  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+INF  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+INF  MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
+INF  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+INF  MdeModulePkg/Application/UiApp/UiApp.inf
+INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+INF  MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
+INF  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+INF  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+INF  MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
+INF  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+INF  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+INF  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+INF  OvmfPkg/SataControllerDxe/SataControllerDxe.inf
+INF  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+INF  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+INF  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+INF  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+INF  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+INF  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
+
+INF  PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.inf
+INF  IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf
+
+!ifndef $(SOURCE_DEBUG_ENABLE)
+INF  IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf
+!endif
+
+INF  IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf
+INF  IntelFrameworkModulePkg/Bus/Isa/IsaFloppyDxe/IsaFloppyDxe.inf
+
+INF  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+INF  OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+
+INF  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+INF  OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
+INF  RuleOverride=ACPITABLE OvmfPkg/AcpiTables/AcpiTables.inf
+INF  MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
+INF  MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
+
+INF  FatPkg/EnhancedFatDxe/Fat.inf
+
+!ifndef $(USE_OLD_SHELL)
+INF  ShellPkg/Application/Shell/Shell.inf
+!else
+INF  RuleOverride = BINARY EdkShellBinPkg/FullShell/FullShell.inf
+!endif
+
+INF MdeModulePkg/Logo/LogoDxe.inf
+
+#
+# Network modules
+#
+!if $(E1000_ENABLE)
+  FILE DRIVER = 5D695E11-9B3F-4b83-B25F-4A8D5D69BE07 {
+    SECTION PE32 = Intel3.5/EFIX64/E3507X2.EFI
+  }
+!endif
+  INF  MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
+  INF  MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
+  INF  MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
+  INF  MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
+  INF  MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
+  INF  MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
+  INF  MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
+  INF  MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
+  INF  MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
+!if $(NETWORK_IP6_ENABLE) == TRUE
+  INF  NetworkPkg/Ip6Dxe/Ip6Dxe.inf
+  INF  NetworkPkg/TcpDxe/TcpDxe.inf
+  INF  NetworkPkg/Udp6Dxe/Udp6Dxe.inf
+  INF  NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
+  INF  NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
+  INF  NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  INF  NetworkPkg/IScsiDxe/IScsiDxe.inf
+!else
+  INF  MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+!endif
+!else
+  INF  MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
+  INF  MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
+  INF  MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
+!endif
+!if $(HTTP_BOOT_ENABLE) == TRUE
+  INF  NetworkPkg/DnsDxe/DnsDxe.inf
+  INF  NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf
+  INF  NetworkPkg/HttpDxe/HttpDxe.inf
+  INF  NetworkPkg/HttpBootDxe/HttpBootDxe.inf
+!endif
+
+#
+# Usb Support
+#
+INF  MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
+INF  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+INF  MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
+INF  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+INF  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+INF  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+!ifdef $(CSM_ENABLE)
+INF  IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf
+INF  IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf
+INF  RuleOverride=CSM OvmfPkg/Csm/Csm16/Csm16.inf
+!endif
+
+INF  OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
+INF  OvmfPkg/PlatformDxe/Platform.inf
+
+!if $(SMM_REQUIRE) == TRUE
+INF  OvmfPkg/SmmAccess/SmmAccess2Dxe.inf
+INF  OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
+INF  UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf
+INF  MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
+INF  MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
+INF  UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
+INF  MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
+INF  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+
+#
+# Variable driver stack (SMM)
+#
+INF  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf
+INF  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf
+INF  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
+INF  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+
+!else
+
+#
+# Variable driver stack (non-SMM)
+#
+INF  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
+INF  OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf
+INF  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+INF  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+!endif
+
+################################################################################
+
+[FV.FVMAIN_COMPACT]
+FvNameGuid         = 48DB5E17-707C-472D-91CD-1613E7EF51B0
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+   SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+     #
+     # These firmware volumes will have files placed in them uncompressed,
+     # and then both firmware volumes will be compressed in a single
+     # compression operation in order to achieve better overall compression.
+     #
+     SECTION FV_IMAGE = PEIFV
+     SECTION FV_IMAGE = DXEFV
+   }
+ }
+
+!include DecomprScratchEnd.fdf.inc
+
+################################################################################
+
+[Rule.Common.SEC]
+  FILE SEC = $(NAMED_GUID) {
+    PE32     PE32           $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING ="$(MODULE_NAME)" Optional
+    VERSION  STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.PEI_CORE]
+  FILE PEI_CORE = $(NAMED_GUID) {
+    PE32     PE32   Align=Auto    $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING ="$(MODULE_NAME)" Optional
+    VERSION  STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.PEIM]
+  FILE PEIM = $(NAMED_GUID) {
+     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+     PE32      PE32   Align=Auto         $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI       STRING="$(MODULE_NAME)" Optional
+     VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_CORE]
+  FILE DXE_CORE = $(NAMED_GUID) {
+    PE32     PE32           $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.DXE_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+    RAW ACPI  Optional               |.acpi
+    RAW ASL   Optional               |.aml
+  }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional      |.depex
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION.BINARY]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.USER_DEFINED.ACPITABLE]
+  FILE FREEFORM = $(NAMED_GUID) {
+    RAW ACPI               |.acpi
+    RAW ASL                |.aml
+  }
+
+[Rule.Common.USER_DEFINED.CSM]
+  FILE FREEFORM = $(NAMED_GUID) {
+    RAW BIN                |.bin
+  }
+
+[Rule.Common.SEC.RESET_VECTOR]
+  FILE RAW = $(NAMED_GUID) {
+    RAW BIN   Align = 16   |.bin
+  }
-- 
Anthony PERARD



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH RFC 02/14] OvmfPkg/XenOvmf: Update debug IO port for Xen
  2016-12-08 15:33 [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
  2016-12-08 15:33 ` [PATCH RFC 01/14] OvmfPkg: Create platform XenOvmf Anthony PERARD
@ 2016-12-08 15:33 ` Anthony PERARD
  2017-01-04 19:23   ` Laszlo Ersek
  2016-12-08 15:33 ` [PATCH RFC 03/14] OvmfPkg/XenOvmf.dsc: Introduce XenResetVector Anthony PERARD
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Anthony PERARD @ 2016-12-08 15:33 UTC (permalink / raw)
  To: edk2-devel, xen-devel; +Cc: Anthony PERARD

This is a debug IO port that will output directly to the Xen Hypervisor
console.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 OvmfPkg/XenOvmf.dsc | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/OvmfPkg/XenOvmf.dsc b/OvmfPkg/XenOvmf.dsc
index e452eb3..5b3550d 100644
--- a/OvmfPkg/XenOvmf.dsc
+++ b/OvmfPkg/XenOvmf.dsc
@@ -421,6 +421,9 @@
   # Point to the MdeModulePkg/Application/UiApp/UiApp.inf
   gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
 
+  ## This flag is used to control the destination port for PlatformDebugLibIoPort
+  gUefiOvmfPkgTokenSpaceGuid.PcdDebugIoPort|0xe9
+
 ################################################################################
 #
 # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
-- 
Anthony PERARD



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH RFC 03/14] OvmfPkg/XenOvmf.dsc: Introduce XenResetVector
  2016-12-08 15:33 [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
  2016-12-08 15:33 ` [PATCH RFC 01/14] OvmfPkg: Create platform XenOvmf Anthony PERARD
  2016-12-08 15:33 ` [PATCH RFC 02/14] OvmfPkg/XenOvmf: Update debug IO port for Xen Anthony PERARD
@ 2016-12-08 15:33 ` Anthony PERARD
  2017-01-04 19:49   ` Laszlo Ersek
  2016-12-08 15:33 ` [PATCH RFC 04/14] OvmfPkg: Introduce XenPlatformPei Anthony PERARD
                   ` (11 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Anthony PERARD @ 2016-12-08 15:33 UTC (permalink / raw)
  To: edk2-devel, xen-devel; +Cc: Anthony PERARD

Copy of OvmfPkg/ResetVector, with one changes:
  - default_cr0: enable cache

Xen copy the OVMF code to RAM, there is no need for cache. Also, it
makes OVMF slow to start on AMD.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 OvmfPkg/XenOvmf.dsc                            |   2 +-
 OvmfPkg/XenOvmf.fdf                            |   2 +-
 OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm | 133 +++++++++++++++++++++++++
 OvmfPkg/XenResetVector/Ia32/PageTables64.asm   |  93 +++++++++++++++++
 OvmfPkg/XenResetVector/XenResetVector.inf      |  37 +++++++
 OvmfPkg/XenResetVector/XenResetVector.nasmb    |  66 ++++++++++++
 6 files changed, 331 insertions(+), 2 deletions(-)
 create mode 100644 OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
 create mode 100644 OvmfPkg/XenResetVector/Ia32/PageTables64.asm
 create mode 100644 OvmfPkg/XenResetVector/XenResetVector.inf
 create mode 100644 OvmfPkg/XenResetVector/XenResetVector.nasmb

diff --git a/OvmfPkg/XenOvmf.dsc b/OvmfPkg/XenOvmf.dsc
index 5b3550d..0a7ea21 100644
--- a/OvmfPkg/XenOvmf.dsc
+++ b/OvmfPkg/XenOvmf.dsc
@@ -471,7 +471,7 @@
 #
 ################################################################################
 [Components]
-  OvmfPkg/ResetVector/ResetVector.inf
+  OvmfPkg/XenResetVector/XenResetVector.inf
 
   #
   # SEC Phase modules
diff --git a/OvmfPkg/XenOvmf.fdf b/OvmfPkg/XenOvmf.fdf
index d01454e..f4609b0 100644
--- a/OvmfPkg/XenOvmf.fdf
+++ b/OvmfPkg/XenOvmf.fdf
@@ -123,7 +123,7 @@ READ_LOCK_STATUS   = TRUE
 #
 INF  OvmfPkg/Sec/SecMain.inf
 
-INF  RuleOverride=RESET_VECTOR OvmfPkg/ResetVector/ResetVector.inf
+INF  RuleOverride=RESET_VECTOR OvmfPkg/XenResetVector/XenResetVector.inf
 
 ################################################################################
 [FV.PEIFV]
diff --git a/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm b/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
new file mode 100644
index 0000000..d746427
--- /dev/null
+++ b/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
@@ -0,0 +1,133 @@
+;------------------------------------------------------------------------------
+; @file
+; Transition from 16 bit real mode into 32 bit flat protected mode
+;
+; Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution.  The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;------------------------------------------------------------------------------
+
+%define SEC_DEFAULT_CR0  0x00000023
+%define SEC_DEFAULT_CR4  0x640
+
+BITS    16
+
+;
+; Modified:  EAX, EBX
+;
+TransitionFromReal16To32BitFlat:
+
+    debugShowPostCode POSTCODE_16BIT_MODE
+
+    cli
+
+    mov     bx, 0xf000
+    mov     ds, bx
+
+    mov     bx, ADDR16_OF(gdtr)
+
+o32 lgdt    [cs:bx]
+
+    mov     eax, SEC_DEFAULT_CR0
+    mov     cr0, eax
+
+    jmp     LINEAR_CODE_SEL:dword ADDR_OF(jumpTo32BitAndLandHere)
+BITS    32
+jumpTo32BitAndLandHere:
+
+    mov     eax, SEC_DEFAULT_CR4
+    mov     cr4, eax
+
+    debugShowPostCode POSTCODE_32BIT_MODE
+
+    mov     ax, LINEAR_SEL
+    mov     ds, ax
+    mov     es, ax
+    mov     fs, ax
+    mov     gs, ax
+    mov     ss, ax
+
+    OneTimeCallRet TransitionFromReal16To32BitFlat
+
+ALIGN   2
+
+gdtr:
+    dw      GDT_END - GDT_BASE - 1   ; GDT limit
+    dd      ADDR_OF(GDT_BASE)
+
+ALIGN   16
+
+;
+; Macros for GDT entries
+;
+
+%define  PRESENT_FLAG(p) (p << 7)
+%define  DPL(dpl) (dpl << 5)
+%define  SYSTEM_FLAG(s) (s << 4)
+%define  DESC_TYPE(t) (t)
+
+; Type: data, expand-up, writable, accessed
+%define  DATA32_TYPE 3
+
+; Type: execute, readable, expand-up, accessed
+%define  CODE32_TYPE 0xb
+
+; Type: execute, readable, expand-up, accessed
+%define  CODE64_TYPE 0xb
+
+%define  GRANULARITY_FLAG(g) (g << 7)
+%define  DEFAULT_SIZE32(d) (d << 6)
+%define  CODE64_FLAG(l) (l << 5)
+%define  UPPER_LIMIT(l) (l)
+
+;
+; The Global Descriptor Table (GDT)
+;
+
+GDT_BASE:
+; null descriptor
+NULL_SEL            equ $-GDT_BASE
+    DW      0            ; limit 15:0
+    DW      0            ; base 15:0
+    DB      0            ; base 23:16
+    DB      0            ; sys flag, dpl, type
+    DB      0            ; limit 19:16, flags
+    DB      0            ; base 31:24
+
+; linear data segment descriptor
+LINEAR_SEL          equ $-GDT_BASE
+    DW      0xffff       ; limit 15:0
+    DW      0            ; base 15:0
+    DB      0            ; base 23:16
+    DB      PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(DATA32_TYPE)
+    DB      GRANULARITY_FLAG(1)|DEFAULT_SIZE32(1)|CODE64_FLAG(0)|UPPER_LIMIT(0xf)
+    DB      0            ; base 31:24
+
+; linear code segment descriptor
+LINEAR_CODE_SEL     equ $-GDT_BASE
+    DW      0xffff       ; limit 15:0
+    DW      0            ; base 15:0
+    DB      0            ; base 23:16
+    DB      PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(CODE32_TYPE)
+    DB      GRANULARITY_FLAG(1)|DEFAULT_SIZE32(1)|CODE64_FLAG(0)|UPPER_LIMIT(0xf)
+    DB      0            ; base 31:24
+
+%ifdef ARCH_X64
+; linear code (64-bit) segment descriptor
+LINEAR_CODE64_SEL   equ $-GDT_BASE
+    DW      0xffff       ; limit 15:0
+    DW      0            ; base 15:0
+    DB      0            ; base 23:16
+    DB      PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(CODE64_TYPE)
+    DB      GRANULARITY_FLAG(1)|DEFAULT_SIZE32(0)|CODE64_FLAG(1)|UPPER_LIMIT(0xf)
+    DB      0            ; base 31:24
+%endif
+
+GDT_END:
+
diff --git a/OvmfPkg/XenResetVector/Ia32/PageTables64.asm b/OvmfPkg/XenResetVector/Ia32/PageTables64.asm
new file mode 100644
index 0000000..b5a4cf8
--- /dev/null
+++ b/OvmfPkg/XenResetVector/Ia32/PageTables64.asm
@@ -0,0 +1,93 @@
+;------------------------------------------------------------------------------
+; @file
+; Sets the CR3 register for 64-bit paging
+;
+; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution.  The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;------------------------------------------------------------------------------
+
+BITS    32
+
+%define PAGE_PRESENT            0x01
+%define PAGE_READ_WRITE         0x02
+%define PAGE_USER_SUPERVISOR    0x04
+%define PAGE_WRITE_THROUGH      0x08
+%define PAGE_CACHE_DISABLE     0x010
+%define PAGE_ACCESSED          0x020
+%define PAGE_DIRTY             0x040
+%define PAGE_PAT               0x080
+%define PAGE_GLOBAL           0x0100
+%define PAGE_2M_MBO            0x080
+%define PAGE_2M_PAT          0x01000
+
+%define PAGE_2M_PDE_ATTR (PAGE_2M_MBO + \
+                          PAGE_ACCESSED + \
+                          PAGE_DIRTY + \
+                          PAGE_READ_WRITE + \
+                          PAGE_PRESENT)
+
+%define PAGE_PDP_ATTR (PAGE_ACCESSED + \
+                       PAGE_READ_WRITE + \
+                       PAGE_PRESENT)
+
+
+;
+; Modified:  EAX, ECX
+;
+SetCr3ForPageTables64:
+
+    ;
+    ; For OVMF, build some initial page tables at 0x800000-0x806000.
+    ;
+    ; This range should match with PcdOvmfSecPageTablesBase and
+    ; PcdOvmfSecPageTablesSize which are declared in the FDF files.
+    ;
+    ; At the end of PEI, the pages tables will be rebuilt into a
+    ; more permanent location by DxeIpl.
+    ;
+
+    mov     ecx, 6 * 0x1000 / 4
+    xor     eax, eax
+clearPageTablesMemoryLoop:
+    mov     dword[ecx * 4 + 0x800000 - 4], eax
+    loop    clearPageTablesMemoryLoop
+
+    ;
+    ; Top level Page Directory Pointers (1 * 512GB entry)
+    ;
+    mov     dword[0x800000], 0x801000 + PAGE_PDP_ATTR
+
+    ;
+    ; Next level Page Directory Pointers (4 * 1GB entries => 4GB)
+    ;
+    mov     dword[0x801000], 0x802000 + PAGE_PDP_ATTR
+    mov     dword[0x801008], 0x803000 + PAGE_PDP_ATTR
+    mov     dword[0x801010], 0x804000 + PAGE_PDP_ATTR
+    mov     dword[0x801018], 0x805000 + PAGE_PDP_ATTR
+
+    ;
+    ; Page Table Entries (2048 * 2MB entries => 4GB)
+    ;
+    mov     ecx, 0x800
+pageTableEntriesLoop:
+    mov     eax, ecx
+    dec     eax
+    shl     eax, 21
+    add     eax, PAGE_2M_PDE_ATTR
+    mov     [ecx * 8 + 0x802000 - 8], eax
+    loop    pageTableEntriesLoop
+
+    ;
+    ; Set CR3 now that the paging structures are available
+    ;
+    mov     eax, 0x800000
+    mov     cr3, eax
+
+    OneTimeCallRet SetCr3ForPageTables64
diff --git a/OvmfPkg/XenResetVector/XenResetVector.inf b/OvmfPkg/XenResetVector/XenResetVector.inf
new file mode 100644
index 0000000..ebfab12
--- /dev/null
+++ b/OvmfPkg/XenResetVector/XenResetVector.inf
@@ -0,0 +1,37 @@
+## @file
+#  Reset Vector
+#
+#  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = XenResetVector
+  FILE_GUID                      = 1BA0062E-C779-4582-8566-336AE8F78F09
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.1
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  XenResetVector.nasmb
+
+[Packages]
+  MdePkg/MdePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+
+[BuildOptions]
+   *_*_IA32_NASMB_FLAGS = -I$(WORKSPACE)/UefiCpuPkg/ResetVector/Vtf0/
+   *_*_X64_NASMB_FLAGS = -I$(WORKSPACE)/UefiCpuPkg/ResetVector/Vtf0/
diff --git a/OvmfPkg/XenResetVector/XenResetVector.nasmb b/OvmfPkg/XenResetVector/XenResetVector.nasmb
new file mode 100644
index 0000000..31ac06a
--- /dev/null
+++ b/OvmfPkg/XenResetVector/XenResetVector.nasmb
@@ -0,0 +1,66 @@
+;------------------------------------------------------------------------------
+; @file
+; This file includes all other code files to assemble the reset vector code
+;
+; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution.  The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;------------------------------------------------------------------------------
+
+;
+; If neither ARCH_IA32 nor ARCH_X64 are defined, then try to include
+; Base.h to use the C pre-processor to determine the architecture.
+;
+%ifndef ARCH_IA32
+  %ifndef ARCH_X64
+    #include <Base.h>
+    #if defined (MDE_CPU_IA32)
+      %define ARCH_IA32
+    #elif defined (MDE_CPU_X64)
+      %define ARCH_X64
+    #endif
+  %endif
+%endif
+
+%ifdef ARCH_IA32
+  %ifdef ARCH_X64
+    %error "Only one of ARCH_IA32 or ARCH_X64 can be defined."
+  %endif
+%elifdef ARCH_X64
+%else
+  %error "Either ARCH_IA32 or ARCH_X64 must be defined."
+%endif
+
+%include "CommonMacros.inc"
+
+%include "PostCodes.inc"
+
+%ifdef DEBUG_PORT80
+  %include "Port80Debug.asm"
+%elifdef DEBUG_SERIAL
+  %include "SerialDebug.asm"
+%else
+  %include "DebugDisabled.asm"
+%endif
+
+%include "Ia32/SearchForBfvBase.asm"
+%include "Ia32/SearchForSecEntry.asm"
+
+%ifdef ARCH_X64
+%include "Ia32/Flat32ToFlat64.asm"
+%include "Ia32/PageTables64.asm"
+%endif
+
+%include "Ia16/Real16ToFlat32.asm"
+%include "Ia16/Init16.asm"
+
+%include "Main.asm"
+
+%include "Ia16/ResetVectorVtf0.asm"
+
-- 
Anthony PERARD



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH RFC 04/14] OvmfPkg: Introduce XenPlatformPei
  2016-12-08 15:33 [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
                   ` (2 preceding siblings ...)
  2016-12-08 15:33 ` [PATCH RFC 03/14] OvmfPkg/XenOvmf.dsc: Introduce XenResetVector Anthony PERARD
@ 2016-12-08 15:33 ` Anthony PERARD
  2017-01-05  9:59   ` Laszlo Ersek
  2016-12-08 15:33 ` [PATCH RFC 05/14] OvmfPkg/Library: add XenPciHostBridgeLib Anthony PERARD
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Anthony PERARD @ 2016-12-08 15:33 UTC (permalink / raw)
  To: edk2-devel, xen-devel; +Cc: Anthony PERARD

A copy of OvmfPkg/PlatformPei without some of QEMU specific
initialization, Xen does not support QemuFwCfg.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 OvmfPkg/XenOvmf.dsc                       |   2 +-
 OvmfPkg/XenOvmf.fdf                       |   2 +-
 OvmfPkg/XenPlatformPei/Cmos.c             |  64 ++++
 OvmfPkg/XenPlatformPei/Cmos.h             |  56 ++++
 OvmfPkg/XenPlatformPei/Fv.c               | 100 ++++++
 OvmfPkg/XenPlatformPei/MemDetect.c        | 449 +++++++++++++++++++++++++
 OvmfPkg/XenPlatformPei/Platform.c         | 536 ++++++++++++++++++++++++++++++
 OvmfPkg/XenPlatformPei/Platform.h         | 104 ++++++
 OvmfPkg/XenPlatformPei/Xen.c              | 231 +++++++++++++
 OvmfPkg/XenPlatformPei/Xen.h              |  45 +++
 OvmfPkg/XenPlatformPei/XenPlatformPei.inf | 110 ++++++
 11 files changed, 1697 insertions(+), 2 deletions(-)
 create mode 100644 OvmfPkg/XenPlatformPei/Cmos.c
 create mode 100644 OvmfPkg/XenPlatformPei/Cmos.h
 create mode 100644 OvmfPkg/XenPlatformPei/Fv.c
 create mode 100644 OvmfPkg/XenPlatformPei/MemDetect.c
 create mode 100644 OvmfPkg/XenPlatformPei/Platform.c
 create mode 100644 OvmfPkg/XenPlatformPei/Platform.h
 create mode 100644 OvmfPkg/XenPlatformPei/Xen.c
 create mode 100644 OvmfPkg/XenPlatformPei/Xen.h
 create mode 100644 OvmfPkg/XenPlatformPei/XenPlatformPei.inf

diff --git a/OvmfPkg/XenOvmf.dsc b/OvmfPkg/XenOvmf.dsc
index 0a7ea21..ef32c33 100644
--- a/OvmfPkg/XenOvmf.dsc
+++ b/OvmfPkg/XenOvmf.dsc
@@ -496,7 +496,7 @@
       PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
   }
 
-  OvmfPkg/PlatformPei/PlatformPei.inf {
+  OvmfPkg/XenPlatformPei/XenPlatformPei.inf {
     <LibraryClasses>
       PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
   }
diff --git a/OvmfPkg/XenOvmf.fdf b/OvmfPkg/XenOvmf.fdf
index f4609b0..c211f61 100644
--- a/OvmfPkg/XenOvmf.fdf
+++ b/OvmfPkg/XenOvmf.fdf
@@ -157,7 +157,7 @@ INF  MdeModulePkg/Core/Pei/PeiMain.inf
 INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
 INF  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
 INF  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
-INF  OvmfPkg/PlatformPei/PlatformPei.inf
+INF  OvmfPkg/XenPlatformPei/XenPlatformPei.inf
 INF  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
 INF  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
 !if $(SMM_REQUIRE) == TRUE
diff --git a/OvmfPkg/XenPlatformPei/Cmos.c b/OvmfPkg/XenPlatformPei/Cmos.c
new file mode 100644
index 0000000..48ed2cb
--- /dev/null
+++ b/OvmfPkg/XenPlatformPei/Cmos.c
@@ -0,0 +1,64 @@
+/** @file
+  PC/AT CMOS access routines
+
+  Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include "Cmos.h"
+#include "Library/IoLib.h"
+
+/**
+  Reads 8-bits of CMOS data.
+
+  Reads the 8-bits of CMOS data at the location specified by Index.
+  The 8-bit read value is returned.
+
+  @param  Index  The CMOS location to read.
+
+  @return The value read.
+
+**/
+UINT8
+EFIAPI
+CmosRead8 (
+  IN      UINTN                     Index
+  )
+{
+  IoWrite8 (0x70, (UINT8) Index);
+  return IoRead8 (0x71);
+}
+
+
+/**
+  Writes 8-bits of CMOS data.
+
+  Writes 8-bits of CMOS data to the location specified by Index
+  with the value specified by Value and returns Value.
+
+  @param  Index  The CMOS location to write.
+  @param  Value  The value to write to CMOS.
+
+  @return The value written to CMOS.
+
+**/
+UINT8
+EFIAPI
+CmosWrite8 (
+  IN      UINTN                     Index,
+  IN      UINT8                     Value
+  )
+{
+  IoWrite8 (0x70, (UINT8) Index);
+  IoWrite8 (0x71, Value);
+  return Value;
+}
+
diff --git a/OvmfPkg/XenPlatformPei/Cmos.h b/OvmfPkg/XenPlatformPei/Cmos.h
new file mode 100644
index 0000000..949f884
--- /dev/null
+++ b/OvmfPkg/XenPlatformPei/Cmos.h
@@ -0,0 +1,56 @@
+/** @file
+  PC/AT CMOS access routines
+
+  Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __CMOS_H__
+#define __CMOS_H__
+
+/**
+  Reads 8-bits of CMOS data.
+
+  Reads the 8-bits of CMOS data at the location specified by Index.
+  The 8-bit read value is returned.
+
+  @param  Index  The CMOS location to read.
+
+  @return The value read.
+
+**/
+UINT8
+EFIAPI
+CmosRead8 (
+  IN      UINTN                     Index
+  );
+
+/**
+  Writes 8-bits of CMOS data.
+
+  Writes 8-bits of CMOS data to the location specified by Index
+  with the value specified by Value and returns Value.
+
+  @param  Index  The CMOS location to write.
+  @param  Value  The value to write to CMOS.
+
+  @return The value written to CMOS.
+
+**/
+UINT8
+EFIAPI
+CmosWrite8 (
+  IN      UINTN                     Index,
+  IN      UINT8                     Value
+  );
+
+
+#endif
+
diff --git a/OvmfPkg/XenPlatformPei/Fv.c b/OvmfPkg/XenPlatformPei/Fv.c
new file mode 100644
index 0000000..248c585
--- /dev/null
+++ b/OvmfPkg/XenPlatformPei/Fv.c
@@ -0,0 +1,100 @@
+/** @file
+  Build FV related hobs for platform.
+
+  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "PiPei.h"
+#include "Platform.h"
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+
+
+/**
+  Publish PEI & DXE (Decompressed) Memory based FVs to let PEI
+  and DXE know about them.
+
+  @retval EFI_SUCCESS   Platform PEI FVs were initialized successfully.
+
+**/
+EFI_STATUS
+PeiFvInitialization (
+  VOID
+  )
+{
+  BOOLEAN SecureS3Needed;
+
+  DEBUG ((EFI_D_INFO, "Platform PEI Firmware Volume Initialization\n"));
+
+  //
+  // Create a memory allocation HOB for the PEI FV.
+  //
+  // Allocate as ACPI NVS is S3 is supported
+  //
+  BuildMemoryAllocationHob (
+    PcdGet32 (PcdOvmfPeiMemFvBase),
+    PcdGet32 (PcdOvmfPeiMemFvSize),
+    mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
+    );
+
+  //
+  // Let DXE know about the DXE FV
+  //
+  BuildFvHob (PcdGet32 (PcdOvmfDxeMemFvBase), PcdGet32 (PcdOvmfDxeMemFvSize));
+
+  SecureS3Needed = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire);
+
+  //
+  // Create a memory allocation HOB for the DXE FV.
+  //
+  // If "secure" S3 is needed, then SEC will decompress both PEI and DXE
+  // firmware volumes at S3 resume too, hence we need to keep away the OS from
+  // DXEFV as well. Otherwise we only need to keep away DXE itself from the
+  // DXEFV area.
+  //
+  BuildMemoryAllocationHob (
+    PcdGet32 (PcdOvmfDxeMemFvBase),
+    PcdGet32 (PcdOvmfDxeMemFvSize),
+    SecureS3Needed ? EfiACPIMemoryNVS : EfiBootServicesData
+    );
+
+  //
+  // Additionally, said decompression will use temporary memory above the end
+  // of DXEFV, so let's keep away the OS from there too.
+  //
+  if (SecureS3Needed) {
+    UINT32 DxeMemFvEnd;
+
+    DxeMemFvEnd = PcdGet32 (PcdOvmfDxeMemFvBase) +
+                  PcdGet32 (PcdOvmfDxeMemFvSize);
+    BuildMemoryAllocationHob (
+      DxeMemFvEnd,
+      PcdGet32 (PcdOvmfDecompressionScratchEnd) - DxeMemFvEnd,
+      EfiACPIMemoryNVS
+      );
+  }
+
+  //
+  // Let PEI know about the DXE FV so it can find the DXE Core
+  //
+  PeiServicesInstallFvInfoPpi (
+    NULL,
+    (VOID *)(UINTN) PcdGet32 (PcdOvmfDxeMemFvBase),
+    PcdGet32 (PcdOvmfDxeMemFvSize),
+    NULL,
+    NULL
+    );
+
+  return EFI_SUCCESS;
+}
+
diff --git a/OvmfPkg/XenPlatformPei/MemDetect.c b/OvmfPkg/XenPlatformPei/MemDetect.c
new file mode 100644
index 0000000..4ecdf5e
--- /dev/null
+++ b/OvmfPkg/XenPlatformPei/MemDetect.c
@@ -0,0 +1,449 @@
+/**@file
+  Memory Detection for Virtual Machines.
+
+  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+  MemDetect.c
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/ResourcePublicationLib.h>
+#include <Library/MtrrLib.h>
+#include <Library/QemuFwCfgLib.h>
+
+#include "Platform.h"
+#include "Cmos.h"
+
+UINT8 mPhysMemAddressWidth;
+
+STATIC UINT32 mS3AcpiReservedMemoryBase;
+STATIC UINT32 mS3AcpiReservedMemorySize;
+
+UINT32
+GetSystemMemorySizeBelow4gb (
+  VOID
+  )
+{
+  UINT8 Cmos0x34;
+  UINT8 Cmos0x35;
+
+  //
+  // CMOS 0x34/0x35 specifies the system memory above 16 MB.
+  // * CMOS(0x35) is the high byte
+  // * CMOS(0x34) is the low byte
+  // * The size is specified in 64kb chunks
+  // * Since this is memory above 16MB, the 16MB must be added
+  //   into the calculation to get the total memory size.
+  //
+
+  Cmos0x34 = (UINT8) CmosRead8 (0x34);
+  Cmos0x35 = (UINT8) CmosRead8 (0x35);
+
+  return (UINT32) (((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);
+}
+
+
+STATIC
+UINT64
+GetSystemMemorySizeAbove4gb (
+  )
+{
+  UINT32 Size;
+  UINTN  CmosIndex;
+
+  //
+  // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
+  // * CMOS(0x5d) is the most significant size byte
+  // * CMOS(0x5c) is the middle size byte
+  // * CMOS(0x5b) is the least significant size byte
+  // * The size is specified in 64kb chunks
+  //
+
+  Size = 0;
+  for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {
+    Size = (UINT32) (Size << 8) + (UINT32) CmosRead8 (CmosIndex);
+  }
+
+  return LShiftU64 (Size, 16);
+}
+
+
+/**
+  Return the highest address that DXE could possibly use, plus one.
+**/
+STATIC
+UINT64
+GetFirstNonAddress (
+  VOID
+  )
+{
+  UINT64               FirstNonAddress;
+  UINT64               Pci64Base, Pci64Size;
+  RETURN_STATUS        PcdStatus;
+
+  FirstNonAddress = BASE_4GB + GetSystemMemorySizeAbove4gb ();
+
+  //
+  // If DXE is 32-bit, then we're done; PciBusDxe will degrade 64-bit MMIO
+  // resources to 32-bit anyway. See DegradeResource() in
+  // "PciResourceSupport.c".
+  //
+#ifdef MDE_CPU_IA32
+  if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
+    return FirstNonAddress;
+  }
+#endif
+
+  //
+  // Otherwise, in order to calculate the highest address plus one, we must
+  // consider the 64-bit PCI host aperture too. Fetch the default size.
+  //
+  Pci64Size = PcdGet64 (PcdPciMmio64Size);
+
+  if (Pci64Size == 0) {
+    if (mBootMode != BOOT_ON_S3_RESUME) {
+      DEBUG ((EFI_D_INFO, "%a: disabling 64-bit PCI host aperture\n",
+        __FUNCTION__));
+      PcdStatus = PcdSet64S (PcdPciMmio64Size, 0);
+      ASSERT_RETURN_ERROR (PcdStatus);
+    }
+
+    //
+    // There's nothing more to do; the amount of memory above 4GB fully
+    // determines the highest address plus one. The memory hotplug area (see
+    // below) plays no role for the firmware in this case.
+    //
+    return FirstNonAddress;
+  }
+
+  //
+  // SeaBIOS aligns both boundaries of the 64-bit PCI host aperture to 1GB, so
+  // that the host can map it with 1GB hugepages. Follow suit.
+  //
+  Pci64Base = ALIGN_VALUE (FirstNonAddress, (UINT64)SIZE_1GB);
+  Pci64Size = ALIGN_VALUE (Pci64Size, (UINT64)SIZE_1GB);
+
+  //
+  // The 64-bit PCI host aperture should also be "naturally" aligned. The
+  // alignment is determined by rounding the size of the aperture down to the
+  // next smaller or equal power of two. That is, align the aperture by the
+  // largest BAR size that can fit into it.
+  //
+  Pci64Base = ALIGN_VALUE (Pci64Base, GetPowerOfTwo64 (Pci64Size));
+
+  if (mBootMode != BOOT_ON_S3_RESUME) {
+    //
+    // The core PciHostBridgeDxe driver will automatically add this range to
+    // the GCD memory space map through our PciHostBridgeLib instance; here we
+    // only need to set the PCDs.
+    //
+    PcdStatus = PcdSet64S (PcdPciMmio64Base, Pci64Base);
+    ASSERT_RETURN_ERROR (PcdStatus);
+    PcdStatus = PcdSet64S (PcdPciMmio64Size, Pci64Size);
+    ASSERT_RETURN_ERROR (PcdStatus);
+
+    DEBUG ((EFI_D_INFO, "%a: Pci64Base=0x%Lx Pci64Size=0x%Lx\n",
+      __FUNCTION__, Pci64Base, Pci64Size));
+  }
+
+  //
+  // The useful address space ends with the 64-bit PCI host aperture.
+  //
+  FirstNonAddress = Pci64Base + Pci64Size;
+  return FirstNonAddress;
+}
+
+
+/**
+  Initialize the mPhysMemAddressWidth variable, based on guest RAM size.
+**/
+VOID
+AddressWidthInitialization (
+  VOID
+  )
+{
+  UINT64 FirstNonAddress;
+
+  //
+  // As guest-physical memory size grows, the permanent PEI RAM requirements
+  // are dominated by the identity-mapping page tables built by the DXE IPL.
+  // The DXL IPL keys off of the physical address bits advertized in the CPU
+  // HOB. To conserve memory, we calculate the minimum address width here.
+  //
+  FirstNonAddress      = GetFirstNonAddress ();
+  mPhysMemAddressWidth = (UINT8)HighBitSet64 (FirstNonAddress);
+
+  //
+  // If FirstNonAddress is not an integral power of two, then we need an
+  // additional bit.
+  //
+  if ((FirstNonAddress & (FirstNonAddress - 1)) != 0) {
+    ++mPhysMemAddressWidth;
+  }
+
+  //
+  // The minimum address width is 36 (covers up to and excluding 64 GB, which
+  // is the maximum for Ia32 + PAE). The theoretical architecture maximum for
+  // X64 long mode is 52 bits, but the DXE IPL clamps that down to 48 bits. We
+  // can simply assert that here, since 48 bits are good enough for 256 TB.
+  //
+  if (mPhysMemAddressWidth <= 36) {
+    mPhysMemAddressWidth = 36;
+  }
+  ASSERT (mPhysMemAddressWidth <= 48);
+}
+
+
+/**
+  Calculate the cap for the permanent PEI memory.
+**/
+STATIC
+UINT32
+GetPeiMemoryCap (
+  VOID
+  )
+{
+  BOOLEAN Page1GSupport;
+  UINT32  RegEax;
+  UINT32  RegEdx;
+  UINT32  Pml4Entries;
+  UINT32  PdpEntries;
+  UINTN   TotalPages;
+
+  //
+  // If DXE is 32-bit, then just return the traditional 64 MB cap.
+  //
+#ifdef MDE_CPU_IA32
+  if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
+    return SIZE_64MB;
+  }
+#endif
+
+  //
+  // Dependent on physical address width, PEI memory allocations can be
+  // dominated by the page tables built for 64-bit DXE. So we key the cap off
+  // of those. The code below is based on CreateIdentityMappingPageTables() in
+  // "MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c".
+  //
+  Page1GSupport = FALSE;
+  if (PcdGetBool (PcdUse1GPageTable)) {
+    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+    if (RegEax >= 0x80000001) {
+      AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
+      if ((RegEdx & BIT26) != 0) {
+        Page1GSupport = TRUE;
+      }
+    }
+  }
+
+  if (mPhysMemAddressWidth <= 39) {
+    Pml4Entries = 1;
+    PdpEntries = 1 << (mPhysMemAddressWidth - 30);
+    ASSERT (PdpEntries <= 0x200);
+  } else {
+    Pml4Entries = 1 << (mPhysMemAddressWidth - 39);
+    ASSERT (Pml4Entries <= 0x200);
+    PdpEntries = 512;
+  }
+
+  TotalPages = Page1GSupport ? Pml4Entries + 1 :
+                               (PdpEntries + 1) * Pml4Entries + 1;
+  ASSERT (TotalPages <= 0x40201);
+
+  //
+  // Add 64 MB for miscellaneous allocations. Note that for
+  // mPhysMemAddressWidth values close to 36, the cap will actually be
+  // dominated by this increment.
+  //
+  return (UINT32)(EFI_PAGES_TO_SIZE (TotalPages) + SIZE_64MB);
+}
+
+
+/**
+  Publish PEI core memory
+
+  @return EFI_SUCCESS     The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+PublishPeiMemory (
+  VOID
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_PHYSICAL_ADDRESS        MemoryBase;
+  UINT64                      MemorySize;
+  UINT32                      LowerMemorySize;
+  UINT32                      PeiMemoryCap;
+
+  LowerMemorySize = GetSystemMemorySizeBelow4gb ();
+
+  //
+  // If S3 is supported, then the S3 permanent PEI memory is placed next,
+  // downwards. Its size is primarily dictated by CpuMpPei. The formula below
+  // is an approximation.
+  //
+  if (mS3Supported) {
+    mS3AcpiReservedMemorySize = SIZE_512KB +
+      PcdGet32 (PcdCpuMaxLogicalProcessorNumber) *
+      PcdGet32 (PcdCpuApStackSize);
+    mS3AcpiReservedMemoryBase = LowerMemorySize - mS3AcpiReservedMemorySize;
+    LowerMemorySize = mS3AcpiReservedMemoryBase;
+  }
+
+  if (mBootMode == BOOT_ON_S3_RESUME) {
+    MemoryBase = mS3AcpiReservedMemoryBase;
+    MemorySize = mS3AcpiReservedMemorySize;
+  } else {
+    PeiMemoryCap = GetPeiMemoryCap ();
+    DEBUG ((EFI_D_INFO, "%a: mPhysMemAddressWidth=%d PeiMemoryCap=%u KB\n",
+      __FUNCTION__, mPhysMemAddressWidth, PeiMemoryCap >> 10));
+
+    //
+    // Determine the range of memory to use during PEI
+    //
+    // Technically we could lay the permanent PEI RAM over SEC's temporary
+    // decompression and scratch buffer even if "secure S3" is needed, since
+    // their lifetimes don't overlap. However, PeiFvInitialization() will cover
+    // RAM up to PcdOvmfDecompressionScratchEnd with an EfiACPIMemoryNVS memory
+    // allocation HOB, and other allocations served from the permanent PEI RAM
+    // shouldn't overlap with that HOB.
+    //
+    MemoryBase = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire) ?
+      PcdGet32 (PcdOvmfDecompressionScratchEnd) :
+      PcdGet32 (PcdOvmfDxeMemFvBase) + PcdGet32 (PcdOvmfDxeMemFvSize);
+    MemorySize = LowerMemorySize - MemoryBase;
+    if (MemorySize > PeiMemoryCap) {
+      MemoryBase = LowerMemorySize - PeiMemoryCap;
+      MemorySize = PeiMemoryCap;
+    }
+  }
+
+  //
+  // Publish this memory to the PEI Core
+  //
+  Status = PublishSystemMemory(MemoryBase, MemorySize);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+
+/**
+  Publish system RAM and reserve memory regions
+
+**/
+VOID
+InitializeRamRegions (
+  VOID
+  )
+{
+  XenPublishRamRegions ();
+
+  if (mS3Supported && mBootMode != BOOT_ON_S3_RESUME) {
+    //
+    // This is the memory range that will be used for PEI on S3 resume
+    //
+    BuildMemoryAllocationHob (
+      mS3AcpiReservedMemoryBase,
+      mS3AcpiReservedMemorySize,
+      EfiACPIMemoryNVS
+      );
+
+    //
+    // Cover the initial RAM area used as stack and temporary PEI heap.
+    //
+    // This is reserved as ACPI NVS so it can be used on S3 resume.
+    //
+    BuildMemoryAllocationHob (
+      PcdGet32 (PcdOvmfSecPeiTempRamBase),
+      PcdGet32 (PcdOvmfSecPeiTempRamSize),
+      EfiACPIMemoryNVS
+      );
+
+    //
+    // SEC stores its table of GUIDed section handlers here.
+    //
+    BuildMemoryAllocationHob (
+      PcdGet64 (PcdGuidedExtractHandlerTableAddress),
+      PcdGet32 (PcdGuidedExtractHandlerTableSize),
+      EfiACPIMemoryNVS
+      );
+
+#ifdef MDE_CPU_X64
+    //
+    // Reserve the initial page tables built by the reset vector code.
+    //
+    // Since this memory range will be used by the Reset Vector on S3
+    // resume, it must be reserved as ACPI NVS.
+    //
+    BuildMemoryAllocationHob (
+      (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdOvmfSecPageTablesBase),
+      (UINT64)(UINTN) PcdGet32 (PcdOvmfSecPageTablesSize),
+      EfiACPIMemoryNVS
+      );
+#endif
+  }
+
+  if (mBootMode != BOOT_ON_S3_RESUME) {
+    if (!FeaturePcdGet (PcdSmmSmramRequire)) {
+      //
+      // Reserve the lock box storage area
+      //
+      // Since this memory range will be used on S3 resume, it must be
+      // reserved as ACPI NVS.
+      //
+      // If S3 is unsupported, then various drivers might still write to the
+      // LockBox area. We ought to prevent DXE from serving allocation requests
+      // such that they would overlap the LockBox storage.
+      //
+      ZeroMem (
+        (VOID*)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageBase),
+        (UINTN) PcdGet32 (PcdOvmfLockBoxStorageSize)
+        );
+      BuildMemoryAllocationHob (
+        (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageBase),
+        (UINT64)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageSize),
+        mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
+        );
+    }
+
+    if (FeaturePcdGet (PcdSmmSmramRequire)) {
+      UINT32 TsegSize;
+
+      //
+      // Make sure the TSEG area that we reported as a reserved memory resource
+      // cannot be used for reserved memory allocations.
+      //
+      TsegSize = FixedPcdGet8 (PcdQ35TsegMbytes) * SIZE_1MB;
+      BuildMemoryAllocationHob (
+        GetSystemMemorySizeBelow4gb() - TsegSize,
+        TsegSize,
+        EfiReservedMemoryType
+        );
+    }
+  }
+}
diff --git a/OvmfPkg/XenPlatformPei/Platform.c b/OvmfPkg/XenPlatformPei/Platform.c
new file mode 100644
index 0000000..bf78878
--- /dev/null
+++ b/OvmfPkg/XenPlatformPei/Platform.c
@@ -0,0 +1,536 @@
+/**@file
+  Platform PEI driver
+
+  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/QemuFwCfgLib.h>
+#include <Library/ResourcePublicationLib.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Ppi/MasterBootMode.h>
+#include <IndustryStandard/Pci22.h>
+#include <OvmfPlatforms.h>
+
+#include "Platform.h"
+#include "Cmos.h"
+
+EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
+  { EfiACPIMemoryNVS,       0x004 },
+  { EfiACPIReclaimMemory,   0x008 },
+  { EfiReservedMemoryType,  0x004 },
+  { EfiRuntimeServicesData, 0x024 },
+  { EfiRuntimeServicesCode, 0x030 },
+  { EfiBootServicesCode,    0x180 },
+  { EfiBootServicesData,    0xF00 },
+  { EfiMaxMemoryType,       0x000 }
+};
+
+
+EFI_PEI_PPI_DESCRIPTOR   mPpiBootMode[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+    &gEfiPeiMasterBootModePpiGuid,
+    NULL
+  }
+};
+
+
+UINT16 mHostBridgeDevId;
+
+EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION;
+
+BOOLEAN mS3Supported = FALSE;
+
+
+VOID
+AddIoMemoryBaseSizeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  UINT64                      MemorySize
+  )
+{
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_MEMORY_MAPPED_IO,
+      EFI_RESOURCE_ATTRIBUTE_PRESENT     |
+      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_TESTED,
+    MemoryBase,
+    MemorySize
+    );
+}
+
+VOID
+AddReservedMemoryBaseSizeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  UINT64                      MemorySize,
+  BOOLEAN                     Cacheable
+  )
+{
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_MEMORY_RESERVED,
+      EFI_RESOURCE_ATTRIBUTE_PRESENT     |
+      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+      (Cacheable ?
+       EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+       EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+       EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE :
+       0
+       ) |
+      EFI_RESOURCE_ATTRIBUTE_TESTED,
+    MemoryBase,
+    MemorySize
+    );
+}
+
+VOID
+AddIoMemoryRangeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  EFI_PHYSICAL_ADDRESS        MemoryLimit
+  )
+{
+  AddIoMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
+}
+
+
+VOID
+AddMemoryBaseSizeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  UINT64                      MemorySize
+  )
+{
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_SYSTEM_MEMORY,
+      EFI_RESOURCE_ATTRIBUTE_PRESENT |
+      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+      EFI_RESOURCE_ATTRIBUTE_TESTED,
+    MemoryBase,
+    MemorySize
+    );
+}
+
+
+VOID
+AddMemoryRangeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  EFI_PHYSICAL_ADDRESS        MemoryLimit
+  )
+{
+  AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
+}
+
+
+VOID
+MemMapInitialization (
+  VOID
+  )
+{
+  UINT64        PciIoBase;
+  UINT64        PciIoSize;
+  RETURN_STATUS PcdStatus;
+
+  PciIoBase = 0xC000;
+  PciIoSize = 0x4000;
+
+  //
+  // Create Memory Type Information HOB
+  //
+  BuildGuidDataHob (
+    &gEfiMemoryTypeInformationGuid,
+    mDefaultMemoryTypeInformation,
+    sizeof(mDefaultMemoryTypeInformation)
+    );
+
+  //
+  // Video memory + Legacy BIOS region
+  //
+  AddIoMemoryRangeHob (0x0A0000, BASE_1MB);
+
+  if (!mXen) {
+    UINT32  TopOfLowRam;
+    UINT64  PciExBarBase;
+    UINT32  PciBase;
+    UINT32  PciSize;
+
+    TopOfLowRam = GetSystemMemorySizeBelow4gb ();
+    PciExBarBase = 0;
+    if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
+      //
+      // The MMCONFIG area is expected to fall between the top of low RAM and
+      // the base of the 32-bit PCI host aperture.
+      //
+      PciExBarBase = FixedPcdGet64 (PcdPciExpressBaseAddress);
+      ASSERT (TopOfLowRam <= PciExBarBase);
+      ASSERT (PciExBarBase <= MAX_UINT32 - SIZE_256MB);
+      PciBase = (UINT32)(PciExBarBase + SIZE_256MB);
+    } else {
+      PciBase = (TopOfLowRam < BASE_2GB) ? BASE_2GB : TopOfLowRam;
+    }
+
+    //
+    // address       purpose   size
+    // ------------  --------  -------------------------
+    // max(top, 2g)  PCI MMIO  0xFC000000 - max(top, 2g)
+    // 0xFC000000    gap                           44 MB
+    // 0xFEC00000    IO-APIC                        4 KB
+    // 0xFEC01000    gap                         1020 KB
+    // 0xFED00000    HPET                           1 KB
+    // 0xFED00400    gap                          111 KB
+    // 0xFED1C000    gap (PIIX4) / RCRB (ICH9)     16 KB
+    // 0xFED20000    gap                          896 KB
+    // 0xFEE00000    LAPIC                          1 MB
+    //
+    PciSize = 0xFC000000 - PciBase;
+    AddIoMemoryBaseSizeHob (PciBase, PciSize);
+    PcdStatus = PcdSet64S (PcdPciMmio32Base, PciBase);
+    ASSERT_RETURN_ERROR (PcdStatus);
+    PcdStatus = PcdSet64S (PcdPciMmio32Size, PciSize);
+    ASSERT_RETURN_ERROR (PcdStatus);
+
+    AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);
+    AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);
+    if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
+      AddIoMemoryBaseSizeHob (ICH9_ROOT_COMPLEX_BASE, SIZE_16KB);
+      //
+      // Note: there should be an
+      //
+      //   AddIoMemoryBaseSizeHob (PciExBarBase, SIZE_256MB);
+      //
+      // call below, just like the one above for RCBA. However, Linux insists
+      // that the MMCONFIG area be marked in the E820 or UEFI memory map as
+      // "reserved memory" -- Linux does not content itself with a simple gap
+      // in the memory map wherever the MCFG ACPI table points to.
+      //
+      // This appears to be a safety measure. The PCI Firmware Specification
+      // (rev 3.1) says in 4.1.2. "MCFG Table Description": "The resources can
+      // *optionally* be returned in [...] EFIGetMemoryMap as reserved memory
+      // [...]". (Emphasis added here.)
+      //
+      // Normally we add memory resource descriptor HOBs in
+      // QemuInitializeRam(), and pre-allocate from those with memory
+      // allocation HOBs in InitializeRamRegions(). However, the MMCONFIG area
+      // is most definitely not RAM; so, as an exception, cover it with
+      // uncacheable reserved memory right here.
+      //
+      AddReservedMemoryBaseSizeHob (PciExBarBase, SIZE_256MB, FALSE);
+      BuildMemoryAllocationHob (PciExBarBase, SIZE_256MB,
+        EfiReservedMemoryType);
+    }
+    AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress), SIZE_1MB);
+
+    //
+    // On Q35, the IO Port space is available for PCI resource allocations from
+    // 0x6000 up.
+    //
+    if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
+      PciIoBase = 0x6000;
+      PciIoSize = 0xA000;
+      ASSERT ((ICH9_PMBASE_VALUE & 0xF000) < PciIoBase);
+    }
+  }
+
+  //
+  // Add PCI IO Port space available for PCI resource allocations.
+  //
+  BuildResourceDescriptorHob (
+    EFI_RESOURCE_IO,
+    EFI_RESOURCE_ATTRIBUTE_PRESENT     |
+    EFI_RESOURCE_ATTRIBUTE_INITIALIZED,
+    PciIoBase,
+    PciIoSize
+    );
+  PcdStatus = PcdSet64S (PcdPciIoBase, PciIoBase);
+  ASSERT_RETURN_ERROR (PcdStatus);
+  PcdStatus = PcdSet64S (PcdPciIoSize, PciIoSize);
+  ASSERT_RETURN_ERROR (PcdStatus);
+}
+
+VOID
+PciExBarInitialization (
+  VOID
+  )
+{
+  union {
+    UINT64 Uint64;
+    UINT32 Uint32[2];
+  } PciExBarBase;
+
+  //
+  // We only support the 256MB size for the MMCONFIG area:
+  // 256 buses * 32 devices * 8 functions * 4096 bytes config space.
+  //
+  // The masks used below enforce the Q35 requirements that the MMCONFIG area
+  // be (a) correctly aligned -- here at 256 MB --, (b) located under 64 GB.
+  //
+  // Note that (b) also ensures that the minimum address width we have
+  // determined in AddressWidthInitialization(), i.e., 36 bits, will suffice
+  // for DXE's page tables to cover the MMCONFIG area.
+  //
+  PciExBarBase.Uint64 = FixedPcdGet64 (PcdPciExpressBaseAddress);
+  ASSERT ((PciExBarBase.Uint32[1] & MCH_PCIEXBAR_HIGHMASK) == 0);
+  ASSERT ((PciExBarBase.Uint32[0] & MCH_PCIEXBAR_LOWMASK) == 0);
+
+  //
+  // Clear the PCIEXBAREN bit first, before programming the high register.
+  //
+  PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW), 0);
+
+  //
+  // Program the high register. Then program the low register, setting the
+  // MMCONFIG area size and enabling decoding at once.
+  //
+  PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_HIGH), PciExBarBase.Uint32[1]);
+  PciWrite32 (
+    DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW),
+    PciExBarBase.Uint32[0] | MCH_PCIEXBAR_BUS_FF | MCH_PCIEXBAR_EN
+    );
+}
+
+VOID
+MiscInitialization (
+  VOID
+  )
+{
+  UINTN         PmCmd;
+  UINTN         Pmba;
+  UINT32        PmbaAndVal;
+  UINT32        PmbaOrVal;
+  UINTN         AcpiCtlReg;
+  UINT8         AcpiEnBit;
+  RETURN_STATUS PcdStatus;
+
+  //
+  // Disable A20 Mask
+  //
+  IoOr8 (0x92, BIT1);
+
+  //
+  // Build the CPU HOB with guest RAM size dependent address width and 16-bits
+  // of IO space. (Side note: unlike other HOBs, the CPU HOB is needed during
+  // S3 resume as well, so we build it unconditionally.)
+  //
+  BuildCpuHob (mPhysMemAddressWidth, 16);
+
+  //
+  // Determine platform type and save Host Bridge DID to PCD
+  //
+  switch (mHostBridgeDevId) {
+    case INTEL_82441_DEVICE_ID:
+      PmCmd      = POWER_MGMT_REGISTER_PIIX4 (PCI_COMMAND_OFFSET);
+      Pmba       = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);
+      PmbaAndVal = ~(UINT32)PIIX4_PMBA_MASK;
+      PmbaOrVal  = PIIX4_PMBA_VALUE;
+      AcpiCtlReg = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMREGMISC);
+      AcpiEnBit  = PIIX4_PMREGMISC_PMIOSE;
+      break;
+    case INTEL_Q35_MCH_DEVICE_ID:
+      PmCmd      = POWER_MGMT_REGISTER_Q35 (PCI_COMMAND_OFFSET);
+      Pmba       = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);
+      PmbaAndVal = ~(UINT32)ICH9_PMBASE_MASK;
+      PmbaOrVal  = ICH9_PMBASE_VALUE;
+      AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL);
+      AcpiEnBit  = ICH9_ACPI_CNTL_ACPI_EN;
+      break;
+    default:
+      DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
+        __FUNCTION__, mHostBridgeDevId));
+      ASSERT (FALSE);
+      return;
+  }
+  PcdStatus = PcdSet16S (PcdOvmfHostBridgePciDevId, mHostBridgeDevId);
+  ASSERT_RETURN_ERROR (PcdStatus);
+
+  //
+  // If the appropriate IOspace enable bit is set, assume the ACPI PMBA
+  // has been configured (e.g., by Xen) and skip the setup here.
+  // This matches the logic in AcpiTimerLibConstructor ().
+  //
+  if ((PciRead8 (AcpiCtlReg) & AcpiEnBit) == 0) {
+    //
+    // The PEI phase should be exited with fully accessibe ACPI PM IO space:
+    // 1. set PMBA
+    //
+    PciAndThenOr32 (Pmba, PmbaAndVal, PmbaOrVal);
+
+    //
+    // 2. set PCICMD/IOSE
+    //
+    PciOr8 (PmCmd, EFI_PCI_COMMAND_IO_SPACE);
+
+    //
+    // 3. set ACPI PM IO enable bit (PMREGMISC:PMIOSE or ACPI_CNTL:ACPI_EN)
+    //
+    PciOr8 (AcpiCtlReg, AcpiEnBit);
+  }
+
+  if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
+    //
+    // Set Root Complex Register Block BAR
+    //
+    PciWrite32 (
+      POWER_MGMT_REGISTER_Q35 (ICH9_RCBA),
+      ICH9_ROOT_COMPLEX_BASE | ICH9_RCBA_EN
+      );
+
+    //
+    // Set PCI Express Register Range Base Address
+    //
+    PciExBarInitialization ();
+  }
+}
+
+
+VOID
+BootModeInitialization (
+  VOID
+  )
+{
+  EFI_STATUS    Status;
+
+  if (CmosRead8 (0xF) == 0xFE) {
+    mBootMode = BOOT_ON_S3_RESUME;
+  }
+  CmosWrite8 (0xF, 0x00);
+
+  Status = PeiServicesSetBootMode (mBootMode);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = PeiServicesInstallPpi (mPpiBootMode);
+  ASSERT_EFI_ERROR (Status);
+}
+
+
+VOID
+ReserveEmuVariableNvStore (
+  )
+{
+  EFI_PHYSICAL_ADDRESS VariableStore;
+  RETURN_STATUS        PcdStatus;
+
+  //
+  // Allocate storage for NV variables early on so it will be
+  // at a consistent address.  Since VM memory is preserved
+  // across reboots, this allows the NV variable storage to survive
+  // a VM reboot.
+  //
+  VariableStore =
+    (EFI_PHYSICAL_ADDRESS)(UINTN)
+      AllocateAlignedRuntimePages (
+        EFI_SIZE_TO_PAGES (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)),
+        PcdGet32 (PcdFlashNvStorageFtwSpareSize)
+        );
+  DEBUG ((EFI_D_INFO,
+          "Reserved variable store memory: 0x%lX; size: %dkb\n",
+          VariableStore,
+          (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / 1024
+        ));
+  PcdStatus = PcdSet64S (PcdEmuVariableNvStoreReserved, VariableStore);
+  ASSERT_RETURN_ERROR (PcdStatus);
+}
+
+
+VOID
+DebugDumpCmos (
+  VOID
+  )
+{
+  UINT32 Loop;
+
+  DEBUG ((EFI_D_INFO, "CMOS:\n"));
+
+  for (Loop = 0; Loop < 0x80; Loop++) {
+    if ((Loop % 0x10) == 0) {
+      DEBUG ((EFI_D_INFO, "%02x:", Loop));
+    }
+    DEBUG ((EFI_D_INFO, " %02x", CmosRead8 (Loop)));
+    if ((Loop % 0x10) == 0xf) {
+      DEBUG ((EFI_D_INFO, "\n"));
+    }
+  }
+}
+
+
+
+/**
+  Perform Platform PEI initialization.
+
+  @param  FileHandle      Handle of the file being invoked.
+  @param  PeiServices     Describes the list of possible PEI Services.
+
+  @return EFI_SUCCESS     The PEIM initialized successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeXenPlatform (
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES     **PeiServices
+  )
+{
+  DEBUG ((EFI_D_ERROR, "Platform PEIM Loaded\n"));
+
+  DebugDumpCmos ();
+
+  XenDetect ();
+
+  BootModeInitialization ();
+  AddressWidthInitialization ();
+
+  PublishPeiMemory ();
+
+  InitializeRamRegions ();
+
+  if (mXen) {
+    DEBUG ((EFI_D_INFO, "Xen was detected\n"));
+    InitializeXen ();
+  } else {
+    DEBUG ((EFI_D_ERROR, "not running on Xen\n"));
+    CpuDeadLoop ();
+  }
+
+  //
+  // Query Host Bridge DID
+  //
+  mHostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);
+
+  if (mBootMode != BOOT_ON_S3_RESUME) {
+    ReserveEmuVariableNvStore ();
+    PeiFvInitialization ();
+    MemMapInitialization ();
+  }
+
+  MiscInitialization ();
+
+  return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/XenPlatformPei/Platform.h b/OvmfPkg/XenPlatformPei/Platform.h
new file mode 100644
index 0000000..eda765b
--- /dev/null
+++ b/OvmfPkg/XenPlatformPei/Platform.h
@@ -0,0 +1,104 @@
+/** @file
+  Platform PEI module include file.
+
+  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PLATFORM_PEI_H_INCLUDED_
+#define _PLATFORM_PEI_H_INCLUDED_
+
+#include <IndustryStandard/E820.h>
+
+VOID
+AddIoMemoryBaseSizeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  UINT64                      MemorySize
+  );
+
+VOID
+AddIoMemoryRangeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  EFI_PHYSICAL_ADDRESS        MemoryLimit
+  );
+
+VOID
+AddMemoryBaseSizeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  UINT64                      MemorySize
+  );
+
+VOID
+AddMemoryRangeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  EFI_PHYSICAL_ADDRESS        MemoryLimit
+  );
+
+VOID
+AddReservedMemoryBaseSizeHob (
+  EFI_PHYSICAL_ADDRESS        MemoryBase,
+  UINT64                      MemorySize,
+  BOOLEAN                     Cacheable
+  );
+
+VOID
+AddressWidthInitialization (
+  VOID
+  );
+
+EFI_STATUS
+PublishPeiMemory (
+  VOID
+  );
+
+UINT32
+GetSystemMemorySizeBelow4gb (
+  VOID
+  );
+
+VOID
+InitializeRamRegions (
+  VOID
+  );
+
+EFI_STATUS
+PeiFvInitialization (
+  VOID
+  );
+
+VOID
+InstallFeatureControlCallback (
+  VOID
+  );
+
+EFI_STATUS
+InitializeXen (
+  VOID
+  );
+
+BOOLEAN
+XenDetect (
+  VOID
+  );
+
+extern BOOLEAN mXen;
+
+VOID
+XenPublishRamRegions (
+  VOID
+  );
+
+extern EFI_BOOT_MODE mBootMode;
+
+extern BOOLEAN mS3Supported;
+
+extern UINT8 mPhysMemAddressWidth;
+
+#endif // _PLATFORM_PEI_H_INCLUDED_
diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
new file mode 100644
index 0000000..ab38f97
--- /dev/null
+++ b/OvmfPkg/XenPlatformPei/Xen.c
@@ -0,0 +1,231 @@
+/**@file
+  Xen Platform PEI support
+
+  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+//
+// The package level header files this module uses
+//
+#include <PiPei.h>
+
+//
+// The Library classes this module consumes
+//
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Guid/XenInfo.h>
+#include <IndustryStandard/E820.h>
+#include <Library/ResourcePublicationLib.h>
+#include <Library/MtrrLib.h>
+
+#include "Platform.h"
+#include "Xen.h"
+
+BOOLEAN mXen = FALSE;
+
+STATIC UINT32 mXenLeaf = 0;
+
+EFI_XEN_INFO mXenInfo;
+
+/**
+  Returns E820 map provided by Xen
+
+  @param Entries      Pointer to E820 map
+  @param Count        Number of entries
+
+  @return EFI_STATUS
+**/
+EFI_STATUS
+XenGetE820Map (
+  EFI_E820_ENTRY64 **Entries,
+  UINT32 *Count
+  )
+{
+  EFI_XEN_OVMF_INFO *Info =
+    (EFI_XEN_OVMF_INFO *)(UINTN) OVMF_INFO_PHYSICAL_ADDRESS;
+
+  if (AsciiStrCmp ((CHAR8 *) Info->Signature, "XenHVMOVMF")) {
+    return EFI_NOT_FOUND;
+  }
+
+  ASSERT (Info->E820 < MAX_ADDRESS);
+  *Entries = (EFI_E820_ENTRY64 *)(UINTN) Info->E820;
+  *Count = Info->E820EntriesCount;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Connects to the Hypervisor.
+ 
+  @param  XenLeaf     CPUID index used to connect.
+
+  @return EFI_STATUS
+
+**/
+EFI_STATUS
+XenConnect (
+  UINT32 XenLeaf
+  )
+{
+  UINT32 Index;
+  UINT32 TransferReg;
+  UINT32 TransferPages;
+  UINT32 XenVersion;
+
+  AsmCpuid (XenLeaf + 2, &TransferPages, &TransferReg, NULL, NULL);
+  mXenInfo.HyperPages = AllocatePages (TransferPages);
+  if (!mXenInfo.HyperPages) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  for (Index = 0; Index < TransferPages; Index++) {
+    AsmWriteMsr64 (TransferReg,
+                   (UINTN) mXenInfo.HyperPages +
+                   (Index << EFI_PAGE_SHIFT) + Index);
+  }
+
+  AsmCpuid (XenLeaf + 1, &XenVersion, NULL, NULL, NULL);
+  DEBUG ((EFI_D_ERROR, "Detected Xen version %d.%d\n",
+          XenVersion >> 16, XenVersion & 0xFFFF));
+  mXenInfo.VersionMajor = (UINT16)(XenVersion >> 16);
+  mXenInfo.VersionMinor = (UINT16)(XenVersion & 0xFFFF);
+
+  /* TBD: Locate hvm_info and reserve it away. */
+  mXenInfo.HvmInfo = NULL;
+
+  BuildGuidDataHob (
+    &gEfiXenInfoGuid,
+    &mXenInfo,
+    sizeof(mXenInfo)
+    );
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Figures out if we are running inside Xen HVM.
+
+  @retval TRUE   Xen was detected
+  @retval FALSE  Xen was not detected
+
+**/
+BOOLEAN
+XenDetect (
+  VOID
+  )
+{
+  UINT8 Signature[13];
+
+  if (mXenLeaf != 0) {
+    return TRUE;
+  }
+
+  Signature[12] = '\0';
+  for (mXenLeaf = 0x40000000; mXenLeaf < 0x40010000; mXenLeaf += 0x100) {
+    AsmCpuid (mXenLeaf,
+              NULL,
+              (UINT32 *) &Signature[0],
+              (UINT32 *) &Signature[4],
+              (UINT32 *) &Signature[8]);
+
+    if (!AsciiStrCmp ((CHAR8 *) Signature, "XenVMMXenVMM")) {
+      mXen = TRUE;
+      return TRUE;
+    }
+  }
+
+  mXenLeaf = 0;
+  return FALSE;
+}
+
+
+VOID
+XenPublishRamRegions (
+  VOID
+  )
+{
+  EFI_E820_ENTRY64  *E820Map;
+  UINT32            E820EntriesCount;
+  EFI_STATUS        Status;
+
+  if (!mXen) {
+    return;
+  }
+
+  DEBUG ((EFI_D_INFO, "Using memory map provided by Xen\n"));
+
+  //
+  // Parse RAM in E820 map
+  //
+  E820EntriesCount = 0;
+  Status = XenGetE820Map (&E820Map, &E820EntriesCount);
+
+  ASSERT_EFI_ERROR (Status);
+
+  if (E820EntriesCount > 0) {
+    EFI_E820_ENTRY64 *Entry;
+    UINT32 Loop;
+
+    for (Loop = 0; Loop < E820EntriesCount; Loop++) {
+      Entry = E820Map + Loop;
+
+      //
+      // Only care about RAM
+      //
+      if (Entry->Type != EfiAcpiAddressRangeMemory) {
+        continue;
+      }
+
+      AddMemoryBaseSizeHob (Entry->BaseAddr, Entry->Length);
+
+      MtrrSetMemoryAttribute (Entry->BaseAddr, Entry->Length, CacheWriteBack);
+    }
+  }
+}
+
+
+/**
+  Perform Xen PEI initialization.
+
+  @return EFI_SUCCESS     Xen initialized successfully
+  @return EFI_NOT_FOUND   Not running under Xen
+
+**/
+EFI_STATUS
+InitializeXen (
+  VOID
+  )
+{
+  RETURN_STATUS PcdStatus;
+
+  if (mXenLeaf == 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  XenConnect (mXenLeaf);
+
+  //
+  // Reserve away HVMLOADER reserved memory [0xFC000000,0xFD000000).
+  // This needs to match HVMLOADER RESERVED_MEMBASE/RESERVED_MEMSIZE.
+  //
+  AddReservedMemoryBaseSizeHob (0xFC000000, 0x1000000, FALSE);
+
+  PcdStatus = PcdSetBoolS (PcdPciDisableBusEnumeration, TRUE);
+  ASSERT_RETURN_ERROR (PcdStatus);
+
+  return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/XenPlatformPei/Xen.h b/OvmfPkg/XenPlatformPei/Xen.h
new file mode 100644
index 0000000..2a8a32b
--- /dev/null
+++ b/OvmfPkg/XenPlatformPei/Xen.h
@@ -0,0 +1,45 @@
+/** @file
+  Ovmf info structure passed by Xen
+
+Copyright (c) 2013, Citrix Systems UK Ltd.<BR>
+
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __XEN_H__
+#define __XEN_H__
+
+#include <PiPei.h>
+
+// Physical address of OVMF info
+#define OVMF_INFO_PHYSICAL_ADDRESS 0x00001000
+
+// This structure must match the definition on Xen side
+#pragma pack(1)
+typedef struct {
+  CHAR8 Signature[14]; // XenHVMOVMF\0
+  UINT8 Length;        // Length of this structure
+  UINT8 Checksum;      // Set such that the sum over bytes 0..length == 0
+  //
+  // Physical address of an array of TablesCount elements.
+  //
+  // Each element contains the physical address of a BIOS table.
+  //
+  EFI_PHYSICAL_ADDRESS Tables;
+  UINT32 TablesCount;
+  //
+  // Physical address of the E820 table, contains E820EntriesCount entries.
+  //
+  EFI_PHYSICAL_ADDRESS E820;
+  UINT32 E820EntriesCount;
+} EFI_XEN_OVMF_INFO;
+#pragma pack()
+
+#endif /* __XEN_H__ */
diff --git a/OvmfPkg/XenPlatformPei/XenPlatformPei.inf b/OvmfPkg/XenPlatformPei/XenPlatformPei.inf
new file mode 100644
index 0000000..dfa7d85
--- /dev/null
+++ b/OvmfPkg/XenPlatformPei/XenPlatformPei.inf
@@ -0,0 +1,110 @@
+## @file
+#  Platform PEI driver
+#
+#  This module provides platform specific function to detect boot mode.
+#  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = XenPlatformPei
+  FILE_GUID                      = f112a6ee-993a-4f0b-8295-e52029d9b4ba
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InitializeXenPlatform
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+
+[Sources]
+  Cmos.c
+  Fv.c
+  MemDetect.c
+  Platform.c
+  Xen.c
+
+[Packages]
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[Guids]
+  gEfiMemoryTypeInformationGuid
+  gEfiXenInfoGuid
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  HobLib
+  IoLib
+  PciLib
+  PeiResourcePublicationLib
+  PeiServicesLib
+  PeiServicesTablePointerLib
+  PeimEntryPoint
+  MtrrLib
+  PcdLib
+
+[Pcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Base
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Size
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Base
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Size
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecompressionScratchEnd
+  gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes
+  gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
+  gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPropertiesTableEnable
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
+
+[FixedPcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+[FeaturePcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire
+
+[Ppis]
+  gEfiPeiMasterBootModePpiGuid
+  gEfiPeiMpServicesPpiGuid
+
+[Depex]
+  TRUE
+
-- 
Anthony PERARD



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH RFC 05/14] OvmfPkg/Library: add XenPciHostBridgeLib
  2016-12-08 15:33 [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
                   ` (3 preceding siblings ...)
  2016-12-08 15:33 ` [PATCH RFC 04/14] OvmfPkg: Introduce XenPlatformPei Anthony PERARD
@ 2016-12-08 15:33 ` Anthony PERARD
  2017-01-05 10:15   ` Laszlo Ersek
  2016-12-08 15:33 ` [PATCH RFC 06/14] OvmfPkg/XenPlatformPei: Add xen PVH specific code Anthony PERARD
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Anthony PERARD @ 2016-12-08 15:33 UTC (permalink / raw)
  To: edk2-devel, xen-devel; +Cc: Anthony PERARD

A copy of OvmfPkg/Library/PciHostBridgeLib

Removing support for pci bus enumeration, I think, and only use scan of
already enumerated pci bus.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 .../Library/XenPciHostBridgeLib/XenPciHostBridge.h |  75 ++++
 .../XenPciHostBridgeLib/XenPciHostBridgeLib.c      | 291 +++++++++++++
 .../XenPciHostBridgeLib/XenPciHostBridgeLib.inf    |  58 +++
 OvmfPkg/Library/XenPciHostBridgeLib/XenSupport.c   | 456 +++++++++++++++++++++
 4 files changed, 880 insertions(+)
 create mode 100644 OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridge.h
 create mode 100644 OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridgeLib.c
 create mode 100644 OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridgeLib.inf
 create mode 100644 OvmfPkg/Library/XenPciHostBridgeLib/XenSupport.c

diff --git a/OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridge.h b/OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridge.h
new file mode 100644
index 0000000..c23d40c
--- /dev/null
+++ b/OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridge.h
@@ -0,0 +1,75 @@
+/** @file
+  Header file of OVMF instance of PciHostBridgeLib.
+
+  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+  This program and the accompanying materials are licensed and made available
+  under the terms and conditions of the BSD License which accompanies this
+  distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php.
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
+  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+PCI_ROOT_BRIDGE *
+ScanForRootBridges (
+  UINTN      *NumberOfRootBridges
+);
+
+/**
+  Initialize a PCI_ROOT_BRIDGE structure.
+
+  @param[in]  Supports         Supported attributes.
+
+  @param[in]  Attributes       Initial attributes.
+
+  @param[in]  AllocAttributes  Allocation attributes.
+
+  @param[in]  RootBusNumber    The bus number to store in RootBus.
+
+  @param[in]  MaxSubBusNumber  The inclusive maximum bus number that can be
+                               assigned to any subordinate bus found behind any
+                               PCI bridge hanging off this root bus.
+
+                               The caller is repsonsible for ensuring that
+                               RootBusNumber <= MaxSubBusNumber. If
+                               RootBusNumber equals MaxSubBusNumber, then the
+                               root bus has no room for subordinate buses.
+
+  @param[in]  Io               IO aperture.
+
+  @param[in]  Mem              MMIO aperture.
+
+  @param[in]  MemAbove4G       MMIO aperture above 4G.
+
+  @param[in]  PMem             Prefetchable MMIO aperture.
+
+  @param[in]  PMemAbove4G      Prefetchable MMIO aperture above 4G.
+
+  @param[out] RootBus          The PCI_ROOT_BRIDGE structure (allocated by the
+                               caller) that should be filled in by this
+                               function.
+
+  @retval EFI_SUCCESS           Initialization successful. A device path
+                                consisting of an ACPI device path node, with
+                                UID = RootBusNumber, has been allocated and
+                                linked into RootBus.
+
+  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
+**/
+EFI_STATUS
+InitRootBridge (
+  IN  UINT64                   Supports,
+  IN  UINT64                   Attributes,
+  IN  UINT64                   AllocAttributes,
+  IN  UINT8                    RootBusNumber,
+  IN  UINT8                    MaxSubBusNumber,
+  IN  PCI_ROOT_BRIDGE_APERTURE *Io,
+  IN  PCI_ROOT_BRIDGE_APERTURE *Mem,
+  IN  PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,
+  IN  PCI_ROOT_BRIDGE_APERTURE *PMem,
+  IN  PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G,
+  OUT PCI_ROOT_BRIDGE          *RootBus
+  );
diff --git a/OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridgeLib.c b/OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridgeLib.c
new file mode 100644
index 0000000..efcd830
--- /dev/null
+++ b/OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridgeLib.c
@@ -0,0 +1,291 @@
+/** @file
+  OVMF's instance of the PCI Host Bridge Library.
+
+  Copyright (C) 2016, Red Hat, Inc.
+  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+  This program and the accompanying materials are licensed and made available
+  under the terms and conditions of the BSD License which accompanies this
+  distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php.
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
+  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <PiDxe.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Q35MchIch9.h>
+
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Protocol/PciRootBridgeIo.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PciHostBridgeLib.h>
+#include <Library/PciLib.h>
+#include <Library/QemuFwCfgLib.h>
+#include "XenPciHostBridge.h"
+
+
+#pragma pack(1)
+typedef struct {
+  ACPI_HID_DEVICE_PATH     AcpiDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
+} OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH;
+#pragma pack ()
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {
+  L"Mem", L"I/O", L"Bus"
+};
+
+
+STATIC
+CONST
+OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate = {
+  {
+    {
+      ACPI_DEVICE_PATH,
+      ACPI_DP,
+      {
+        (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
+        (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
+      }
+    },
+    EISA_PNP_ID(0x0A03), // HID
+    0                    // UID
+  },
+
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      END_DEVICE_PATH_LENGTH,
+      0
+    }
+  }
+};
+
+/**
+  Initialize a PCI_ROOT_BRIDGE structure.
+
+  @param[in]  Supports         Supported attributes.
+
+  @param[in]  Attributes       Initial attributes.
+
+  @param[in]  AllocAttributes  Allocation attributes.
+
+  @param[in]  RootBusNumber    The bus number to store in RootBus.
+
+  @param[in]  MaxSubBusNumber  The inclusive maximum bus number that can be
+                               assigned to any subordinate bus found behind any
+                               PCI bridge hanging off this root bus.
+
+                               The caller is repsonsible for ensuring that
+                               RootBusNumber <= MaxSubBusNumber. If
+                               RootBusNumber equals MaxSubBusNumber, then the
+                               root bus has no room for subordinate buses.
+
+  @param[in]  Io               IO aperture.
+
+  @param[in]  Mem              MMIO aperture.
+
+  @param[in]  MemAbove4G       MMIO aperture above 4G.
+
+  @param[in]  PMem             Prefetchable MMIO aperture.
+
+  @param[in]  PMemAbove4G      Prefetchable MMIO aperture above 4G.
+
+  @param[out] RootBus          The PCI_ROOT_BRIDGE structure (allocated by the
+                               caller) that should be filled in by this
+                               function.
+
+  @retval EFI_SUCCESS           Initialization successful. A device path
+                                consisting of an ACPI device path node, with
+                                UID = RootBusNumber, has been allocated and
+                                linked into RootBus.
+
+  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
+**/
+EFI_STATUS
+InitRootBridge (
+  IN  UINT64                   Supports,
+  IN  UINT64                   Attributes,
+  IN  UINT64                   AllocAttributes,
+  IN  UINT8                    RootBusNumber,
+  IN  UINT8                    MaxSubBusNumber,
+  IN  PCI_ROOT_BRIDGE_APERTURE *Io,
+  IN  PCI_ROOT_BRIDGE_APERTURE *Mem,
+  IN  PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,
+  IN  PCI_ROOT_BRIDGE_APERTURE *PMem,
+  IN  PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G,
+  OUT PCI_ROOT_BRIDGE          *RootBus
+  )
+{
+  OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath;
+
+  //
+  // Be safe if other fields are added to PCI_ROOT_BRIDGE later.
+  //
+  ZeroMem (RootBus, sizeof *RootBus);
+
+  RootBus->Segment = 0;
+
+  RootBus->Supports   = Supports;
+  RootBus->Attributes = Attributes;
+
+  RootBus->DmaAbove4G = FALSE;
+
+  RootBus->AllocationAttributes = AllocAttributes;
+  RootBus->Bus.Base  = RootBusNumber;
+  RootBus->Bus.Limit = MaxSubBusNumber;
+  CopyMem (&RootBus->Io, Io, sizeof (*Io));
+  CopyMem (&RootBus->Mem, Mem, sizeof (*Mem));
+  CopyMem (&RootBus->MemAbove4G, MemAbove4G, sizeof (*MemAbove4G));
+  CopyMem (&RootBus->PMem, PMem, sizeof (*PMem));
+  CopyMem (&RootBus->PMemAbove4G, PMemAbove4G, sizeof (*PMemAbove4G));
+
+  RootBus->NoExtendedConfigSpace = (PcdGet16 (PcdOvmfHostBridgePciDevId) !=
+                                    INTEL_Q35_MCH_DEVICE_ID);
+
+  DevicePath = AllocateCopyPool (sizeof mRootBridgeDevicePathTemplate,
+                 &mRootBridgeDevicePathTemplate);
+  if (DevicePath == NULL) {
+    DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES));
+    return EFI_OUT_OF_RESOURCES;
+  }
+  DevicePath->AcpiDevicePath.UID = RootBusNumber;
+  RootBus->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;
+
+  DEBUG ((EFI_D_INFO,
+    "%a: populated root bus %d, with room for %d subordinate bus(es)\n",
+    __FUNCTION__, RootBusNumber, MaxSubBusNumber - RootBusNumber));
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Uninitialize a PCI_ROOT_BRIDGE structure set up with InitRootBridge().
+
+  param[in] RootBus  The PCI_ROOT_BRIDGE structure, allocated by the caller and
+                     initialized with InitRootBridge(), that should be
+                     uninitialized. This function doesn't free RootBus.
+**/
+STATIC
+VOID
+UninitRootBridge (
+  IN PCI_ROOT_BRIDGE *RootBus
+  )
+{
+  FreePool (RootBus->DevicePath);
+}
+
+
+/**
+  Return all the root bridge instances in an array.
+
+  @param Count  Return the count of root bridge instances.
+
+  @return All the root bridge instances in an array.
+          The array should be passed into PciHostBridgeFreeRootBridges()
+          when it's not used.
+**/
+PCI_ROOT_BRIDGE *
+EFIAPI
+PciHostBridgeGetRootBridges (
+  UINTN *Count
+  )
+{
+  ASSERT (PcdGetBool (PcdPciDisableBusEnumeration));
+  return ScanForRootBridges (Count);
+}
+
+
+/**
+  Free the root bridge instances array returned from
+  PciHostBridgeGetRootBridges().
+
+  @param  The root bridge instances array.
+  @param  The count of the array.
+**/
+VOID
+EFIAPI
+PciHostBridgeFreeRootBridges (
+  PCI_ROOT_BRIDGE *Bridges,
+  UINTN           Count
+  )
+{
+  if (Bridges == NULL && Count == 0) {
+    return;
+  }
+  ASSERT (Bridges != NULL && Count > 0);
+
+  do {
+    --Count;
+    UninitRootBridge (&Bridges[Count]);
+  } while (Count > 0);
+
+  FreePool (Bridges);
+}
+
+
+/**
+  Inform the platform that the resource conflict happens.
+
+  @param HostBridgeHandle Handle of the Host Bridge.
+  @param Configuration    Pointer to PCI I/O and PCI memory resource
+                          descriptors. The Configuration contains the resources
+                          for all the root bridges. The resource for each root
+                          bridge is terminated with END descriptor and an
+                          additional END is appended indicating the end of the
+                          entire resources. The resource descriptor field
+                          values follow the description in
+                          EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+                          .SubmitResources().
+**/
+VOID
+EFIAPI
+PciHostBridgeResourceConflict (
+  EFI_HANDLE                        HostBridgeHandle,
+  VOID                              *Configuration
+  )
+{
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
+  UINTN                             RootBridgeIndex;
+  DEBUG ((EFI_D_ERROR, "PciHostBridge: Resource conflict happens!\n"));
+
+  RootBridgeIndex = 0;
+  Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
+  while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+    DEBUG ((EFI_D_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++));
+    for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
+      ASSERT (Descriptor->ResType <
+              ARRAY_SIZE (mPciHostBridgeLibAcpiAddressSpaceTypeStr)
+              );
+      DEBUG ((EFI_D_ERROR, " %s: Length/Alignment = 0x%lx / 0x%lx\n",
+              mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType],
+              Descriptor->AddrLen, Descriptor->AddrRangeMax
+              ));
+      if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
+        DEBUG ((EFI_D_ERROR, "     Granularity/SpecificFlag = %ld / %02x%s\n",
+                Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag,
+                ((Descriptor->SpecificFlag &
+                  EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE
+                  ) != 0) ? L" (Prefetchable)" : L""
+                ));
+      }
+    }
+    //
+    // Skip the END descriptor for root bridge
+    //
+    ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR);
+    Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)(
+                   (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1
+                   );
+  }
+}
diff --git a/OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridgeLib.inf b/OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridgeLib.inf
new file mode 100644
index 0000000..3b8f003
--- /dev/null
+++ b/OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridgeLib.inf
@@ -0,0 +1,58 @@
+## @file
+#  OVMF's instance of the PCI Host Bridge Library.
+#
+#  Copyright (C) 2016, Red Hat, Inc.
+#  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+#  This program and the accompanying materials are licensed and made available
+#  under the terms and conditions of the BSD License which accompanies this
+#  distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
+#  IMPLIED.
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = XenPciHostBridgeLib
+  FILE_GUID                      = 9F2BC05E-51EA-4AED-9A3E-7699641734E8
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PciHostBridgeLib
+
+#
+# The following information is for reference only and not required by the build
+# tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+
+[Sources]
+  XenPciHostBridgeLib.c
+  XenSupport.c
+  XenPciHostBridge.h
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  DevicePathLib
+  MemoryAllocationLib
+  PciLib
+
+[Pcd]
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoSize
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Base
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Size
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Base
+  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Size
+  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
+  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
diff --git a/OvmfPkg/Library/XenPciHostBridgeLib/XenSupport.c b/OvmfPkg/Library/XenPciHostBridgeLib/XenSupport.c
new file mode 100644
index 0000000..a45945f
--- /dev/null
+++ b/OvmfPkg/Library/XenPciHostBridgeLib/XenSupport.c
@@ -0,0 +1,456 @@
+/** @file
+  Scan the entire PCI bus for root bridges to support OVMF above Xen.
+
+  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+  This program and the accompanying materials are licensed and made available
+  under the terms and conditions of the BSD License which accompanies this
+  distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php.
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
+  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <PiDxe.h>
+
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Q35MchIch9.h>
+
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Protocol/PciRootBridgeIo.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PciHostBridgeLib.h>
+#include <Library/PciLib.h>
+#include "XenPciHostBridge.h"
+
+STATIC
+VOID
+PcatPciRootBridgeBarExisted (
+  IN  UINTN                          Address,
+  OUT UINT32                         *OriginalValue,
+  OUT UINT32                         *Value
+  )
+{
+  //
+  // Preserve the original value
+  //
+  *OriginalValue = PciRead32 (Address);
+
+  //
+  // Disable timer interrupt while the BAR is probed
+  //
+  DisableInterrupts ();
+
+  PciWrite32 (Address, 0xFFFFFFFF);
+  *Value = PciRead32 (Address);
+  PciWrite32 (Address, *OriginalValue);
+
+  //
+  // Enable interrupt
+  //
+  EnableInterrupts ();
+}
+
+STATIC
+VOID
+PcatPciRootBridgeParseBars (
+  IN UINT16                         Command,
+  IN UINTN                          Bus,
+  IN UINTN                          Device,
+  IN UINTN                          Function,
+  IN UINTN                          BarOffsetBase,
+  IN UINTN                          BarOffsetEnd,
+  IN PCI_ROOT_BRIDGE_APERTURE       *Io,
+  IN PCI_ROOT_BRIDGE_APERTURE       *Mem,
+  IN PCI_ROOT_BRIDGE_APERTURE       *MemAbove4G,
+  IN PCI_ROOT_BRIDGE_APERTURE       *PMem,
+  IN PCI_ROOT_BRIDGE_APERTURE       *PMemAbove4G
+
+)
+{
+  UINT32                            OriginalValue;
+  UINT32                            Value;
+  UINT32                            OriginalUpperValue;
+  UINT32                            UpperValue;
+  UINT64                            Mask;
+  UINTN                             Offset;
+  UINT64                            Base;
+  UINT64                            Length;
+  UINT64                            Limit;
+  PCI_ROOT_BRIDGE_APERTURE          *MemAperture;
+
+  for (Offset = BarOffsetBase; Offset < BarOffsetEnd; Offset += sizeof (UINT32)) {
+    PcatPciRootBridgeBarExisted (
+      PCI_LIB_ADDRESS (Bus, Device, Function, Offset),
+      &OriginalValue, &Value
+    );
+    if (Value == 0) {
+      continue;
+    }
+    if ((Value & BIT0) == BIT0) {
+      //
+      // IO Bar
+      //
+      if (Command & EFI_PCI_COMMAND_IO_SPACE) {
+        Mask = 0xfffffffc;
+        Base = OriginalValue & Mask;
+        Length = ((~(Value & Mask)) & Mask) + 0x04;
+        if (!(Value & 0xFFFF0000)) {
+          Length &= 0x0000FFFF;
+        }
+        Limit = Base + Length - 1;
+
+        if (Base < Limit) {
+          if (Io->Base > Base) {
+            Io->Base = Base;
+          }
+          if (Io->Limit < Limit) {
+            Io->Limit = Limit;
+          }
+        }
+      }
+    } else {
+      //
+      // Mem Bar
+      //
+      if (Command & EFI_PCI_COMMAND_MEMORY_SPACE) {
+
+        Mask = 0xfffffff0;
+        Base = OriginalValue & Mask;
+        Length = Value & Mask;
+
+        if ((Value & (BIT1 | BIT2)) == 0) {
+          //
+          // 32bit
+          //
+          Length = ((~Length) + 1) & 0xffffffff;
+
+          if ((Value & BIT3) == BIT3) {
+            MemAperture = PMem;
+          } else {
+            MemAperture = Mem;
+          }
+        } else {
+          //
+          // 64bit
+          //
+          Offset += 4;
+          PcatPciRootBridgeBarExisted (
+            PCI_LIB_ADDRESS (Bus, Device, Function, Offset),
+            &OriginalUpperValue,
+            &UpperValue
+          );
+
+          Base = Base | LShiftU64 ((UINT64) OriginalUpperValue, 32);
+          Length = Length | LShiftU64 ((UINT64) UpperValue, 32);
+          Length = (~Length) + 1;
+
+          if ((Value & BIT3) == BIT3) {
+            MemAperture = PMemAbove4G;
+          } else {
+            MemAperture = MemAbove4G;
+          }
+        }
+
+        Limit = Base + Length - 1;
+        if (Base < Limit) {
+          if (MemAperture->Base > Base) {
+            MemAperture->Base = Base;
+          }
+          if (MemAperture->Limit < Limit) {
+            MemAperture->Limit = Limit;
+          }
+        }
+      }
+    }
+  }
+}
+
+PCI_ROOT_BRIDGE *
+ScanForRootBridges (
+  UINTN      *NumberOfRootBridges
+  )
+{
+  UINTN      PrimaryBus;
+  UINTN      SubBus;
+  UINT8      Device;
+  UINT8      Function;
+  UINTN      NumberOfDevices;
+  UINTN      Address;
+  PCI_TYPE01 Pci;
+  UINT64     Attributes;
+  UINT64     Base;
+  UINT64     Limit;
+  UINT64     Value;
+  PCI_ROOT_BRIDGE_APERTURE Io, Mem, MemAbove4G, PMem, PMemAbove4G, *MemAperture;
+  PCI_ROOT_BRIDGE *RootBridges;
+  UINTN      BarOffsetEnd;
+
+
+  *NumberOfRootBridges = 0;
+  RootBridges = NULL;
+
+  //
+  // After scanning all the PCI devices on the PCI root bridge's primary bus,
+  // update the Primary Bus Number for the next PCI root bridge to be this PCI
+  // root bridge's subordinate bus number + 1.
+  //
+  for (PrimaryBus = 0; PrimaryBus <= PCI_MAX_BUS; PrimaryBus = SubBus + 1) {
+    SubBus = PrimaryBus;
+    Attributes = 0;
+    Io.Base = Mem.Base = MemAbove4G.Base = PMem.Base = PMemAbove4G.Base = MAX_UINT64;
+    Io.Limit = Mem.Limit = MemAbove4G.Limit = PMem.Limit = PMemAbove4G.Limit = 0;
+    //
+    // Scan all the PCI devices on the primary bus of the PCI root bridge
+    //
+    for (Device = 0, NumberOfDevices = 0; Device <= PCI_MAX_DEVICE; Device++) {
+
+      for (Function = 0; Function <= PCI_MAX_FUNC; Function++) {
+
+        //
+        // Compute the PCI configuration address of the PCI device to probe
+        //
+        Address = PCI_LIB_ADDRESS (PrimaryBus, Device, Function, 0);
+
+        //
+        // Read the Vendor ID from the PCI Configuration Header
+        //
+        if (PciRead16 (Address) == MAX_UINT16) {
+          if (Function == 0) {
+            //
+            // If the PCI Configuration Read fails, or a PCI device does not
+            // exist, then skip this entire PCI device
+            //
+            break;
+          } else {
+            //
+            // If PCI function != 0, VendorId == 0xFFFF, we continue to search
+            // PCI function.
+            //
+            continue;
+          }
+        }
+
+        //
+        // Read the entire PCI Configuration Header
+        //
+        PciReadBuffer (Address, sizeof (Pci), &Pci);
+
+        //
+        // Increment the number of PCI device found on the primary bus of the
+        // PCI root bridge
+        //
+        NumberOfDevices++;
+
+        //
+        // Look for devices with the VGA Palette Snoop enabled in the COMMAND
+        // register of the PCI Config Header
+        //
+        if ((Pci.Hdr.Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) != 0) {
+          Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;
+          Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
+        }
+
+        BarOffsetEnd = 0;
+
+        //
+        // PCI-PCI Bridge
+        //
+        if (IS_PCI_BRIDGE (&Pci)) {
+          //
+          // Get the Bus range that the PPB is decoding
+          //
+          if (Pci.Bridge.SubordinateBus > SubBus) {
+            //
+            // If the suborinate bus number of the PCI-PCI bridge is greater
+            // than the PCI root bridge's current subordinate bus number,
+            // then update the PCI root bridge's subordinate bus number
+            //
+            SubBus = Pci.Bridge.SubordinateBus;
+          }
+
+          //
+          // Get the I/O range that the PPB is decoding
+          //
+          Value = Pci.Bridge.IoBase & 0x0f;
+          Base = ((UINT32) Pci.Bridge.IoBase & 0xf0) << 8;
+          Limit = (((UINT32) Pci.Bridge.IoLimit & 0xf0) << 8) | 0x0fff;
+          if (Value == BIT0) {
+            Base |= ((UINT32) Pci.Bridge.IoBaseUpper16 << 16);
+            Limit |= ((UINT32) Pci.Bridge.IoLimitUpper16 << 16);
+          }
+          if (Base < Limit) {
+            if (Io.Base > Base) {
+              Io.Base = Base;
+            }
+            if (Io.Limit < Limit) {
+              Io.Limit = Limit;
+            }
+          }
+
+          //
+          // Get the Memory range that the PPB is decoding
+          //
+          Base = ((UINT32) Pci.Bridge.MemoryBase & 0xfff0) << 16;
+          Limit = (((UINT32) Pci.Bridge.MemoryLimit & 0xfff0) << 16) | 0xfffff;
+          if (Base < Limit) {
+            if (Mem.Base > Base) {
+              Mem.Base = Base;
+            }
+            if (Mem.Limit < Limit) {
+              Mem.Limit = Limit;
+            }
+          }
+
+          //
+          // Get the Prefetchable Memory range that the PPB is decoding
+          //
+          Value = Pci.Bridge.PrefetchableMemoryBase & 0x0f;
+          Base = ((UINT32) Pci.Bridge.PrefetchableMemoryBase & 0xfff0) << 16;
+          Limit = (((UINT32) Pci.Bridge.PrefetchableMemoryLimit & 0xfff0)
+                   << 16) | 0xfffff;
+          MemAperture = &PMem;
+          if (Value == BIT0) {
+            Base |= LShiftU64 (Pci.Bridge.PrefetchableBaseUpper32, 32);
+            Limit |= LShiftU64 (Pci.Bridge.PrefetchableLimitUpper32, 32);
+            MemAperture = &PMemAbove4G;
+          }
+          if (Base < Limit) {
+            if (MemAperture->Base > Base) {
+              MemAperture->Base = Base;
+            }
+            if (MemAperture->Limit < Limit) {
+              MemAperture->Limit = Limit;
+            }
+          }
+
+          //
+          // Look at the PPB Configuration for legacy decoding attributes
+          //
+          if ((Pci.Bridge.BridgeControl & EFI_PCI_BRIDGE_CONTROL_ISA)
+              == EFI_PCI_BRIDGE_CONTROL_ISA) {
+            Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO;
+            Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO_16;
+            Attributes |= EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO;
+          }
+          if ((Pci.Bridge.BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA)
+              == EFI_PCI_BRIDGE_CONTROL_VGA) {
+            Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;
+            Attributes |= EFI_PCI_ATTRIBUTE_VGA_MEMORY;
+            Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO;
+            if ((Pci.Bridge.BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA_16)
+                != 0) {
+              Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
+              Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO_16;
+            }
+          }
+
+          BarOffsetEnd = OFFSET_OF (PCI_TYPE01, Bridge.Bar[2]);
+        } else {
+          //
+          // Parse the BARs of the PCI device to get what I/O Ranges, Memory
+          // Ranges, and Prefetchable Memory Ranges the device is decoding
+          //
+          if ((Pci.Hdr.HeaderType & HEADER_LAYOUT_CODE) == HEADER_TYPE_DEVICE) {
+            BarOffsetEnd = OFFSET_OF (PCI_TYPE00, Device.Bar[6]);
+          }
+        }
+
+        PcatPciRootBridgeParseBars (
+          Pci.Hdr.Command,
+          PrimaryBus,
+          Device,
+          Function,
+          OFFSET_OF (PCI_TYPE00, Device.Bar),
+          BarOffsetEnd,
+          &Io,
+          &Mem, &MemAbove4G,
+          &PMem, &PMemAbove4G
+        );
+
+        //
+        // See if the PCI device is an IDE controller
+        //
+        if (IS_CLASS2 (&Pci, PCI_CLASS_MASS_STORAGE,
+                       PCI_CLASS_MASS_STORAGE_IDE)) {
+          if (Pci.Hdr.ClassCode[0] & 0x80) {
+            Attributes |= EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO;
+            Attributes |= EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO;
+          }
+          if (Pci.Hdr.ClassCode[0] & 0x01) {
+            Attributes |= EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO;
+          }
+          if (Pci.Hdr.ClassCode[0] & 0x04) {
+            Attributes |= EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO;
+          }
+        }
+
+        //
+        // See if the PCI device is a legacy VGA controller or
+        // a standard VGA controller
+        //
+        if (IS_CLASS2 (&Pci, PCI_CLASS_OLD, PCI_CLASS_OLD_VGA) ||
+            IS_CLASS2 (&Pci, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA)
+            ) {
+          Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;
+          Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
+          Attributes |= EFI_PCI_ATTRIBUTE_VGA_MEMORY;
+          Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO;
+          Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO_16;
+        }
+
+        //
+        // See if the PCI Device is a PCI - ISA or PCI - EISA
+        // or ISA_POSITIVIE_DECODE Bridge device
+        //
+        if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) {
+          if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA ||
+              Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_EISA ||
+              Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE) {
+            Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO;
+            Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO_16;
+            Attributes |= EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO;
+          }
+        }
+
+        //
+        // If this device is not a multi function device, then skip the rest
+        // of this PCI device
+        //
+        if (Function == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {
+          break;
+        }
+      }
+    }
+
+    //
+    // If at least one PCI device was found on the primary bus of this PCI
+    // root bridge, then the PCI root bridge exists.
+    //
+    if (NumberOfDevices > 0) {
+      RootBridges = ReallocatePool (
+        (*NumberOfRootBridges) * sizeof (PCI_ROOT_BRIDGE),
+        (*NumberOfRootBridges + 1) * sizeof (PCI_ROOT_BRIDGE),
+        RootBridges
+      );
+      ASSERT (RootBridges != NULL);
+      InitRootBridge (
+        Attributes, Attributes, 0,
+        (UINT8) PrimaryBus, (UINT8) SubBus,
+        &Io, &Mem, &MemAbove4G, &PMem, &PMemAbove4G,
+        &RootBridges[*NumberOfRootBridges]
+      );
+      RootBridges[*NumberOfRootBridges].ResourceAssigned = TRUE;
+      //
+      // Increment the index for the next PCI Root Bridge
+      //
+      (*NumberOfRootBridges)++;
+    }
+  }
+
+  return RootBridges;
+}
-- 
Anthony PERARD



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH RFC 06/14] OvmfPkg/XenPlatformPei: Add xen PVH specific code
  2016-12-08 15:33 [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
                   ` (4 preceding siblings ...)
  2016-12-08 15:33 ` [PATCH RFC 05/14] OvmfPkg/Library: add XenPciHostBridgeLib Anthony PERARD
@ 2016-12-08 15:33 ` Anthony PERARD
  2017-01-05 10:30   ` Laszlo Ersek
  2016-12-08 15:33 ` [PATCH RFC 07/14] OvmfPkg/XenResetVector: Add new entry point for Xen PVH Anthony PERARD
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Anthony PERARD @ 2016-12-08 15:33 UTC (permalink / raw)
  To: edk2-devel, xen-devel; +Cc: Anthony PERARD

- learn about memory size from the E820
- ignore error if host bridge devid is 0xffff, PVH does not have PCI and
  reading from unexisting device return -1.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 OvmfPkg/XenPlatformPei/MemDetect.c | 71 ++++++++++++++++++++++++++++++++++++++
 OvmfPkg/XenPlatformPei/Platform.c  |  5 +++
 OvmfPkg/XenPlatformPei/Platform.h  | 10 ++++++
 3 files changed, 86 insertions(+)

diff --git a/OvmfPkg/XenPlatformPei/MemDetect.c b/OvmfPkg/XenPlatformPei/MemDetect.c
index 4ecdf5e..0d80775 100644
--- a/OvmfPkg/XenPlatformPei/MemDetect.c
+++ b/OvmfPkg/XenPlatformPei/MemDetect.c
@@ -42,6 +42,70 @@ UINT8 mPhysMemAddressWidth;
 STATIC UINT32 mS3AcpiReservedMemoryBase;
 STATIC UINT32 mS3AcpiReservedMemorySize;
 
+STATIC UINT32 mXenLowerMemorySize = 0;
+STATIC UINT64 mXenHighMemorySize = 0;
+
+VOID
+XenReadMemorySizes (
+  VOID
+  )
+{
+  EFI_E820_ENTRY64  *E820Map;
+  UINT32            E820EntriesCount;
+  EFI_STATUS Status;
+
+  Status = XenGetE820Map (&E820Map, &E820EntriesCount);
+  ASSERT_EFI_ERROR (Status);
+
+  mXenLowerMemorySize = 0;
+  mXenHighMemorySize = 0;
+
+  if (E820EntriesCount > 0) {
+    EFI_E820_ENTRY64 *Entry;
+    UINT32 Loop;
+
+    for (Loop = 0; Loop < E820EntriesCount; Loop++) {
+      Entry = E820Map + Loop;
+
+      //
+      // Only care about RAM
+      //
+      if (Entry->Type != EfiAcpiAddressRangeMemory) {
+        continue;
+      }
+
+      if ((Entry->BaseAddr + Entry->Length) <= SIZE_16MB) {
+        continue;
+      }
+
+      if (Entry->BaseAddr < SIZE_16MB) {
+        UINT64 bottom = Entry->BaseAddr;
+        UINT64 size = Entry->Length;
+        size -= SIZE_16MB - bottom;
+        bottom = SIZE_16MB;
+        mXenLowerMemorySize += size;
+        continue;
+      }
+      if (Entry->BaseAddr <= SIZE_4GB) {
+        UINT64 size = Entry->Length;
+        mXenLowerMemorySize += size;
+        continue;
+      }
+
+      if (Entry->BaseAddr == SIZE_4GB) {
+        mXenHighMemorySize = Entry->Length;
+        continue;
+      }
+
+      DEBUG ((EFI_D_INFO, "%a: ignored XenE820 entry (0x%llx, 0x%llx)\n",
+              __FUNCTION__,
+              Entry->BaseAddr,
+              Entry->Length));
+    }
+    mXenLowerMemorySize += SIZE_16MB;
+  }
+}
+
 UINT32
 GetSystemMemorySizeBelow4gb (
   VOID
@@ -50,6 +114,9 @@ GetSystemMemorySizeBelow4gb (
   UINT8 Cmos0x34;
   UINT8 Cmos0x35;
 
+  if (mXen && mXenLowerMemorySize)
+    return mXenLowerMemorySize;
+
   //
   // CMOS 0x34/0x35 specifies the system memory above 16 MB.
   // * CMOS(0x35) is the high byte
@@ -74,6 +141,10 @@ GetSystemMemorySizeAbove4gb (
   UINT32 Size;
   UINTN  CmosIndex;
 
+  // if lower memory is specified that way, return also high memory
+  if (mXen && mXenLowerMemorySize)
+    return mXenHighMemorySize;
+
   //
   // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
   // * CMOS(0x5d) is the most significant size byte
diff --git a/OvmfPkg/XenPlatformPei/Platform.c b/OvmfPkg/XenPlatformPei/Platform.c
index bf78878..9fc713c 100644
--- a/OvmfPkg/XenPlatformPei/Platform.c
+++ b/OvmfPkg/XenPlatformPei/Platform.c
@@ -362,6 +362,10 @@ MiscInitialization (
       AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL);
       AcpiEnBit  = ICH9_ACPI_CNTL_ACPI_EN;
       break;
+    case 0xffff:
+      // xen PVH, ignore
+      PcdStatus = PcdSet16S (PcdOvmfHostBridgePciDevId, mHostBridgeDevId);
+      return;
     default:
       DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
         __FUNCTION__, mHostBridgeDevId));
@@ -503,6 +507,7 @@ InitializeXenPlatform (
   DebugDumpCmos ();
 
   XenDetect ();
+  XenReadMemorySizes ();
 
   BootModeInitialization ();
   AddressWidthInitialization ();
diff --git a/OvmfPkg/XenPlatformPei/Platform.h b/OvmfPkg/XenPlatformPei/Platform.h
index eda765b..2948853 100644
--- a/OvmfPkg/XenPlatformPei/Platform.h
+++ b/OvmfPkg/XenPlatformPei/Platform.h
@@ -101,4 +101,14 @@ extern BOOLEAN mS3Supported;
 
 extern UINT8 mPhysMemAddressWidth;
 
+EFI_STATUS
+XenGetE820Map (
+  EFI_E820_ENTRY64 **Entries,
+  UINT32 *Count
+  );
+VOID
+XenReadMemorySizes (
+  VOID
+  );
+
 #endif // _PLATFORM_PEI_H_INCLUDED_
-- 
Anthony PERARD



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH RFC 07/14] OvmfPkg/XenResetVector: Add new entry point for Xen PVH
  2016-12-08 15:33 [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
                   ` (5 preceding siblings ...)
  2016-12-08 15:33 ` [PATCH RFC 06/14] OvmfPkg/XenPlatformPei: Add xen PVH specific code Anthony PERARD
@ 2016-12-08 15:33 ` Anthony PERARD
  2017-01-05 10:36   ` Laszlo Ersek
  2016-12-08 15:33 ` [PATCH RFC 08/14] OvmfPkg/PlatformBootManagerLib: Workaround missing PCI bus on " Anthony PERARD
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Anthony PERARD @ 2016-12-08 15:33 UTC (permalink / raw)
  To: edk2-devel, xen-devel; +Cc: Anthony PERARD

This one enter directly in 32bits

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm | 79 +++++++++++++++++++++++++
 OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm      | 23 +++++++
 OvmfPkg/XenResetVector/XenResetVector.nasmb     |  1 +
 3 files changed, 103 insertions(+)
 create mode 100644 OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
 create mode 100644 OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm

diff --git a/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
new file mode 100644
index 0000000..70436d8
--- /dev/null
+++ b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
@@ -0,0 +1,79 @@
+;------------------------------------------------------------------------------
+; @file
+; First code executed by processor after resetting.
+;
+; Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution.  The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;------------------------------------------------------------------------------
+
+BITS    16
+
+ALIGN   16
+
+;
+; Pad the image size to 4k when page tables are in VTF0
+;
+; If the VTF0 image has page tables built in, then we need to make
+; sure the end of VTF0 is 4k above where the page tables end.
+;
+; This is required so the page tables will be 4k aligned when VTF0 is
+; located just below 0x100000000 (4GB) in the firmware device.
+;
+%ifdef ALIGN_TOP_TO_4K_FOR_PAGING
+    TIMES (0x1000 - ($ - EndOfPageTables) - (fourGigabytes - xenPVHEntryPoint)) DB 0
+%endif
+
+BITS    32
+xenPVHEntryPoint:
+; this is probably 0xffffffd0
+  jmp xenPVHMain
+
+BITS    16
+ALIGN   16
+
+applicationProcessorEntryPoint:
+;
+; Application Processors entry point
+;
+; GenFv generates code aligned on a 4k boundary which will jump to this
+; location.  (0xffffffe0)  This allows the Local APIC Startup IPI to be
+; used to wake up the application processors.
+;
+    jmp     EarlyApInitReal16
+
+ALIGN   8
+
+    DD      0
+
+;
+; The VTF signature
+;
+; VTF-0 means that the VTF (Volume Top File) code does not require
+; any fixups.
+;
+vtfSignature:
+    DB      'V', 'T', 'F', 0
+
+ALIGN   16
+
+resetVector:
+;
+; Reset Vector
+;
+; This is where the processor will begin execution
+;
+    nop
+    nop
+    jmp     EarlyBspInitReal16
+
+ALIGN   16
+
+fourGigabytes:
+
diff --git a/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
new file mode 100644
index 0000000..eb12f6c
--- /dev/null
+++ b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
@@ -0,0 +1,23 @@
+BITS 32
+
+xenPVHMain:
+  mov di, 'BP'
+
+  cli
+  mov ebx, ADDR_OF(gdtr)
+  lgdt [ebx]
+  mov eax, SEC_DEFAULT_CR0
+  mov cr0, eax
+  jmp LINEAR_CODE_SEL:ADDR_OF(jmpHerePVH)
+jmpHerePVH:
+  mov eax, SEC_DEFAULT_CR4
+  mov cr4, eax
+
+  mov     ax, LINEAR_SEL
+  mov     ds, ax
+  mov     es, ax
+  mov     fs, ax
+  mov     gs, ax
+  mov     ss, ax
+
+  OneTimeCallRet TransitionFromReal16To32BitFlat
diff --git a/OvmfPkg/XenResetVector/XenResetVector.nasmb b/OvmfPkg/XenResetVector/XenResetVector.nasmb
index 31ac06a..f9812fd 100644
--- a/OvmfPkg/XenResetVector/XenResetVector.nasmb
+++ b/OvmfPkg/XenResetVector/XenResetVector.nasmb
@@ -61,6 +61,7 @@
 %include "Ia16/Init16.asm"
 
 %include "Main.asm"
+%include "Ia32/XenPVHMain.asm"
 
 %include "Ia16/ResetVectorVtf0.asm"
 
-- 
Anthony PERARD



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH RFC 08/14] OvmfPkg/PlatformBootManagerLib: Workaround missing PCI bus on Xen PVH
  2016-12-08 15:33 [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
                   ` (6 preceding siblings ...)
  2016-12-08 15:33 ` [PATCH RFC 07/14] OvmfPkg/XenResetVector: Add new entry point for Xen PVH Anthony PERARD
@ 2016-12-08 15:33 ` Anthony PERARD
  2017-01-05 10:38   ` Laszlo Ersek
  2016-12-08 15:33 ` [PATCH RFC 09/14] OvmfPkg/ResetSystemLib: Add missing dependency on PciLib Anthony PERARD
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Anthony PERARD @ 2016-12-08 15:33 UTC (permalink / raw)
  To: edk2-devel, xen-devel; +Cc: Anthony PERARD

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
index cc35630..bd64cc3 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
+++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
@@ -1152,6 +1152,8 @@ PciAcpiInitialization (
       PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6a), 0x0b); // G
       PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), 0x0b); // H
       break;
+    case 0xffff:
+      return;
     default:
       DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
         __FUNCTION__, mHostBridgeDevId));
-- 
Anthony PERARD



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH RFC 09/14] OvmfPkg/ResetSystemLib: Add missing dependency on PciLib
  2016-12-08 15:33 [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
                   ` (7 preceding siblings ...)
  2016-12-08 15:33 ` [PATCH RFC 08/14] OvmfPkg/PlatformBootManagerLib: Workaround missing PCI bus on " Anthony PERARD
@ 2016-12-08 15:33 ` Anthony PERARD
  2017-01-05 10:46   ` Laszlo Ersek
  2016-12-08 15:33 ` [PATCH RFC 10/14] UefiCpuPkg/BaseXApicX2ApicLib: Fix initialisation on my system and Anthony PERARD
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Anthony PERARD @ 2016-12-08 15:33 UTC (permalink / raw)
  To: edk2-devel, xen-devel; +Cc: Anthony PERARD

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf | 1 +
 1 file changed, 1 insertion(+)

diff --git a/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf b/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
index ecd462b..2e0ed48 100644
--- a/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
+++ b/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
@@ -36,4 +36,5 @@
 [LibraryClasses]
   DebugLib
   IoLib
+  PciLib
   TimerLib
-- 
Anthony PERARD



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH RFC 10/14] UefiCpuPkg/BaseXApicX2ApicLib: Fix initialisation on my system and ...
  2016-12-08 15:33 [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
                   ` (8 preceding siblings ...)
  2016-12-08 15:33 ` [PATCH RFC 09/14] OvmfPkg/ResetSystemLib: Add missing dependency on PciLib Anthony PERARD
@ 2016-12-08 15:33 ` Anthony PERARD
  2016-12-09  6:48   ` Kinney, Michael D
  2016-12-08 15:33 ` [PATCH RFC 11/14] OvmfPkg/XenOvmf: Adding XenTimerLocalApic Anthony PERARD
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Anthony PERARD @ 2016-12-08 15:33 UTC (permalink / raw)
  To: edk2-devel, xen-devel; +Cc: Anthony PERARD

declare more exported function, ReadLocalApicReg and WriteLocalApicReg.

On my system (running OVMF inside a Xen PVH guest), writing the
interrupt information (to XAPIC_LVT_TIMER_OFFSET) would also reset the
init-count register, thus disabling the timer.
---
 UefiCpuPkg/Include/Library/LocalApicLib.h          | 40 ++++++++++++++++++++++
 .../BaseXApicX2ApicLib/BaseXApicX2ApicLib.c        | 10 +++---
 2 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/UefiCpuPkg/Include/Library/LocalApicLib.h b/UefiCpuPkg/Include/Library/LocalApicLib.h
index fc980bc..ab621f2 100644
--- a/UefiCpuPkg/Include/Library/LocalApicLib.h
+++ b/UefiCpuPkg/Include/Library/LocalApicLib.h
@@ -48,6 +48,46 @@ SetLocalApicBaseAddress (
   );
 
 /**
+  Read from a local APIC register.
+
+  This function reads from a local APIC register either in xAPIC or x2APIC mode.
+  It is required that in xAPIC mode wider registers (64-bit or 256-bit) must be
+  accessed using multiple 32-bit loads or stores, so this function only performs
+  32-bit read.
+
+  @param  MmioOffset  The MMIO offset of the local APIC register in xAPIC mode.
+                      It must be 16-byte aligned.
+
+  @return 32-bit      Value read from the register.
+**/
+UINT32
+EFIAPI
+ReadLocalApicReg (
+  IN UINTN  MmioOffset
+  );
+
+/**
+  Write to a local APIC register.
+
+  This function writes to a local APIC register either in xAPIC or x2APIC mode.
+  It is required that in xAPIC mode wider registers (64-bit or 256-bit) must be
+  accessed using multiple 32-bit loads or stores, so this function only performs
+  32-bit write.
+
+  if the register index is invalid or unsupported in current APIC mode, then ASSERT.
+
+  @param  MmioOffset  The MMIO offset of the local APIC register in xAPIC mode.
+                      It must be 16-byte aligned.
+  @param  Value       Value to be written to the register.
+**/
+VOID
+EFIAPI
+WriteLocalApicReg (
+  IN UINTN  MmioOffset,
+  IN UINT32 Value
+  );
+
+/**
   Get the current local APIC mode.
 
   If local APIC is disabled, then ASSERT.
diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
index e690d2a..f84a40a 100644
--- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
+++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
@@ -820,11 +820,6 @@ InitializeApicTimer (
   //
   InitializeLocalApicSoftwareEnable (TRUE);
 
-  //
-  // Program init-count register.
-  //
-  WriteLocalApicReg (XAPIC_TIMER_INIT_COUNT_OFFSET, InitCount);
-
   if (DivideValue != 0) {
     ASSERT (DivideValue <= 128);
     ASSERT (DivideValue == GetPowerOfTwo32((UINT32)DivideValue));
@@ -848,6 +843,11 @@ InitializeApicTimer (
   LvtTimer.Bits.Mask = 0;
   LvtTimer.Bits.Vector = Vector;
   WriteLocalApicReg (XAPIC_LVT_TIMER_OFFSET, LvtTimer.Uint32);
+
+  //
+  // Program init-count register.
+  //
+  WriteLocalApicReg (XAPIC_TIMER_INIT_COUNT_OFFSET, InitCount);
 }
 
 /**
-- 
Anthony PERARD



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH RFC 11/14] OvmfPkg/XenOvmf: Adding XenTimerLocalApic
  2016-12-08 15:33 [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
                   ` (9 preceding siblings ...)
  2016-12-08 15:33 ` [PATCH RFC 10/14] UefiCpuPkg/BaseXApicX2ApicLib: Fix initialisation on my system and Anthony PERARD
@ 2016-12-08 15:33 ` Anthony PERARD
  2017-01-05 11:26   ` Laszlo Ersek
  2016-12-08 15:33 ` [PATCH RFC 12/14] OvmfPkg/PlatformBootManagerLib: Use a Xen console for ConOut/ConIn Anthony PERARD
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Anthony PERARD @ 2016-12-08 15:33 UTC (permalink / raw)
  To: edk2-devel, xen-devel; +Cc: Anthony PERARD

And replacing the ACPI Timer by this one based on the local APIC.

ACPI Timer does not work in a PVH guest, but local APIC works on both
PVH and HVM.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 OvmfPkg/XenOvmf.dsc                             |  18 +-
 OvmfPkg/XenOvmf.fdf                             |   2 +-
 OvmfPkg/XenTimerLocalApic/Timer.h               | 191 ++++++++++++
 OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.c   | 386 ++++++++++++++++++++++++
 OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.inf |  51 ++++
 5 files changed, 640 insertions(+), 8 deletions(-)
 create mode 100644 OvmfPkg/XenTimerLocalApic/Timer.h
 create mode 100644 OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.c
 create mode 100644 OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.inf

diff --git a/OvmfPkg/XenOvmf.dsc b/OvmfPkg/XenOvmf.dsc
index ef32c33..31a2185 100644
--- a/OvmfPkg/XenOvmf.dsc
+++ b/OvmfPkg/XenOvmf.dsc
@@ -81,7 +81,7 @@
 ################################################################################
 [LibraryClasses]
   PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
-  TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
+  TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
   PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
   BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
   BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
@@ -175,7 +175,7 @@
 !endif
 
 [LibraryClasses.common.SEC]
-  TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
+  TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
   QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf
 !ifdef $(DEBUG_ON_SERIAL_PORT)
   DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
@@ -251,7 +251,7 @@
 
 [LibraryClasses.common.DXE_RUNTIME_DRIVER]
   PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
-  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+  TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
   HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
   DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
   MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
@@ -269,7 +269,7 @@
 
 [LibraryClasses.common.UEFI_DRIVER]
   PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
-  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+  TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
   HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
   DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
   MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
@@ -284,7 +284,7 @@
 
 [LibraryClasses.common.DXE_DRIVER]
   PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
-  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+  TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
   HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
   MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
   ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
@@ -314,7 +314,7 @@
 
 [LibraryClasses.common.UEFI_APPLICATION]
   PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
-  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
+  TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
   HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
   MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
   ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
@@ -546,7 +546,11 @@
 !endif
 
   MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
-  PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
+  OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.inf
+  #{
+  #<LibraryClasses>
+    #LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
+  #}
   UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
   UefiCpuPkg/CpuDxe/CpuDxe.inf
   PcAtChipsetPkg/8254TimerDxe/8254Timer.inf
diff --git a/OvmfPkg/XenOvmf.fdf b/OvmfPkg/XenOvmf.fdf
index c211f61..f6876d7 100644
--- a/OvmfPkg/XenOvmf.fdf
+++ b/OvmfPkg/XenOvmf.fdf
@@ -207,7 +207,7 @@ INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
 INF  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
 INF  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
 INF  MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
-INF  PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
+INF  OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.inf
 INF  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
 INF  UefiCpuPkg/CpuDxe/CpuDxe.inf
 INF  PcAtChipsetPkg/8254TimerDxe/8254Timer.inf
diff --git a/OvmfPkg/XenTimerLocalApic/Timer.h b/OvmfPkg/XenTimerLocalApic/Timer.h
new file mode 100644
index 0000000..8d6f37c
--- /dev/null
+++ b/OvmfPkg/XenTimerLocalApic/Timer.h
@@ -0,0 +1,191 @@
+/** @file
+  Private data structures
+
+Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#ifndef _TIMER_H_
+#define _TIMER_H_
+
+#include <PiDxe.h>
+
+#include <Protocol/Cpu.h>
+#include <Protocol/Legacy8259.h>
+#include <Protocol/Timer.h>
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+
+//
+// The PCAT 8253/8254 has an input clock at 1.193182 MHz and Timer 0 is
+// initialized as a 16 bit free running counter that generates an interrupt(IRQ0)
+// each time the counter rolls over.
+//
+//   65536 counts
+// ---------------- * 1,000,000 uS/S = 54925.4 uS = 549254 * 100 ns
+//   1,193,182 Hz
+//
+
+//
+// The maximum tick duration for 8254 timer
+//
+#define MAX_TIMER_TICK_DURATION     549254
+//
+// The default timer tick duration is set to 10 ms = 100000 100 ns units
+//
+#define DEFAULT_TIMER_TICK_DURATION 100000
+#define TIMER_CONTROL_PORT          0x43
+#define TIMER0_COUNT_PORT           0x40
+
+//
+// Function Prototypes
+//
+/**
+  Initialize the Timer Architectural Protocol driver
+
+  @param ImageHandle     ImageHandle of the loaded driver
+  @param SystemTable     Pointer to the System Table
+
+  @retval EFI_SUCCESS            Timer Architectural Protocol created
+  @retval EFI_OUT_OF_RESOURCES   Not enough resources available to initialize driver.
+  @retval EFI_DEVICE_ERROR       A device error occured attempting to initialize the driver.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverInitialize (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+;
+
+/**
+
+  This function adjusts the period of timer interrupts to the value specified
+  by TimerPeriod.  If the timer period is updated, then the selected timer
+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
+  If an error occurs while attempting to update the timer period, then the
+  timer hardware will be put back in its state prior to this call, and
+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
+  is disabled.  This is not the same as disabling the CPU's interrupts.
+  Instead, it must either turn off the timer hardware, or it must adjust the
+  interrupt controller so that a CPU interrupt is not generated when the timer
+  interrupt fires.
+
+
+  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param NotifyFunction  The rate to program the timer interrupt in 100 nS units.  If
+                         the timer hardware is not programmable, then EFI_UNSUPPORTED is
+                         returned.  If the timer is programmable, then the timer period
+                         will be rounded up to the nearest timer period that is supported
+                         by the timer hardware.  If TimerPeriod is set to 0, then the
+                         timer interrupts will be disabled.
+
+  @retval        EFI_SUCCESS       The timer period was changed.
+  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.
+  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverRegisterHandler (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This,
+  IN EFI_TIMER_NOTIFY         NotifyFunction
+  )
+;
+
+/**
+
+  This function adjusts the period of timer interrupts to the value specified
+  by TimerPeriod.  If the timer period is updated, then the selected timer
+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
+  If an error occurs while attempting to update the timer period, then the
+  timer hardware will be put back in its state prior to this call, and
+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
+  is disabled.  This is not the same as disabling the CPU's interrupts.
+  Instead, it must either turn off the timer hardware, or it must adjust the
+  interrupt controller so that a CPU interrupt is not generated when the timer
+  interrupt fires.
+
+
+  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param TimerPeriod     The rate to program the timer interrupt in 100 nS units.  If
+                         the timer hardware is not programmable, then EFI_UNSUPPORTED is
+                         returned.  If the timer is programmable, then the timer period
+                         will be rounded up to the nearest timer period that is supported
+                         by the timer hardware.  If TimerPeriod is set to 0, then the
+                         timer interrupts will be disabled.
+
+  @retval        EFI_SUCCESS       The timer period was changed.
+  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.
+  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverSetTimerPeriod (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This,
+  IN UINT64                   TimerPeriod
+  )
+;
+
+/**
+
+  This function retrieves the period of timer interrupts in 100 ns units,
+  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod
+  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is
+  returned, then the timer is currently disabled.
+
+
+  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param TimerPeriod     A pointer to the timer period to retrieve in 100 ns units.  If
+                         0 is returned, then the timer is currently disabled.
+
+  @retval EFI_SUCCESS            The timer period was returned in TimerPeriod.
+  @retval EFI_INVALID_PARAMETER  TimerPeriod is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGetTimerPeriod (
+  IN EFI_TIMER_ARCH_PROTOCOL   *This,
+  OUT UINT64                   *TimerPeriod
+  )
+;
+
+/**
+
+  This function generates a soft timer interrupt. If the platform does not support soft
+  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.
+  If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
+  service, then a soft timer interrupt will be generated. If the timer interrupt is
+  enabled when this service is called, then the registered handler will be invoked. The
+  registered handler should not be able to distinguish a hardware-generated timer
+  interrupt from a software-generated timer interrupt.
+
+
+  @param This              The EFI_TIMER_ARCH_PROTOCOL instance.
+
+  @retval EFI_SUCCESS       The soft timer interrupt was generated.
+  @retval EFI_UNSUPPORTED   The platform does not support the generation of soft timer interrupts.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGenerateSoftInterrupt (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This
+  )
+;
+
+#endif
diff --git a/OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.c b/OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.c
new file mode 100644
index 0000000..7f3a8f0
--- /dev/null
+++ b/OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.c
@@ -0,0 +1,386 @@
+/** @file
+  Timer Architectural Protocol as defined in the DXE CIS
+
+Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution.  The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Register/LocalApic.h>
+#include <Library/LocalApicLib.h>
+#include <Library/PcdLib.h>
+#include "Timer.h"
+
+//
+// The handle onto which the Timer Architectural Protocol will be installed
+//
+EFI_HANDLE                mTimerHandle = NULL;
+
+//
+// The Timer Architectural Protocol that this driver produces
+//
+EFI_TIMER_ARCH_PROTOCOL   mTimer = {
+  TimerDriverRegisterHandler,
+  TimerDriverSetTimerPeriod,
+  TimerDriverGetTimerPeriod,
+  TimerDriverGenerateSoftInterrupt
+};
+
+//
+// Pointer to the CPU Architectural Protocol instance
+//
+EFI_CPU_ARCH_PROTOCOL     *mCpu;
+
+//
+// The notification function to call on every timer interrupt.
+// A bug in the compiler prevents us from initializing this here.
+//
+EFI_TIMER_NOTIFY mTimerNotifyFunction;
+
+//
+// The current period of the timer interrupt
+//
+volatile UINT64           mTimerPeriod = 0;
+
+//
+// Worker Functions
+//
+/**
+  8254 Timer #0 Interrupt Handler.
+
+  @param InterruptType    The type of interrupt that occured
+  @param SystemContext    A pointer to the system context when the interrupt occured
+**/
+VOID
+EFIAPI
+TimerInterruptHandler (
+  IN EFI_EXCEPTION_TYPE   InterruptType,
+  IN EFI_SYSTEM_CONTEXT   SystemContext
+  )
+{
+  EFI_TPL OriginalTPL;
+
+  OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+
+  /* mLegacy8259->EndOfInterrupt (mLegacy8259, Efi8259Irq0); */
+
+  if (mTimerNotifyFunction != NULL) {
+    //
+    // @bug : This does not handle missed timer interrupts
+    //
+    mTimerNotifyFunction (mTimerPeriod);
+  }
+  SendApicEoi();
+
+  gBS->RestoreTPL (OriginalTPL);
+}
+
+/**
+
+  This function registers the handler NotifyFunction so it is called every time
+  the timer interrupt fires.  It also passes the amount of time since the last
+  handler call to the NotifyFunction.  If NotifyFunction is NULL, then the
+  handler is unregistered.  If the handler is registered, then EFI_SUCCESS is
+  returned.  If the CPU does not support registering a timer interrupt handler,
+  then EFI_UNSUPPORTED is returned.  If an attempt is made to register a handler
+  when a handler is already registered, then EFI_ALREADY_STARTED is returned.
+  If an attempt is made to unregister a handler when a handler is not registered,
+  then EFI_INVALID_PARAMETER is returned.  If an error occurs attempting to
+  register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR
+  is returned.
+
+
+  @param This             The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param NotifyFunction   The function to call when a timer interrupt fires.  This
+                          function executes at TPL_HIGH_LEVEL.  The DXE Core will
+                          register a handler for the timer interrupt, so it can know
+                          how much time has passed.  This information is used to
+                          signal timer based events.  NULL will unregister the handler.
+
+  @retval        EFI_SUCCESS            The timer handler was registered.
+  @retval        EFI_UNSUPPORTED        The platform does not support timer interrupts.
+  @retval        EFI_ALREADY_STARTED    NotifyFunction is not NULL, and a handler is already
+                                        registered.
+  @retval        EFI_INVALID_PARAMETER  NotifyFunction is NULL, and a handler was not
+                                        previously registered.
+  @retval        EFI_DEVICE_ERROR       The timer handler could not be registered.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverRegisterHandler (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This,
+  IN EFI_TIMER_NOTIFY         NotifyFunction
+  )
+{
+  //
+  // Check for invalid parameters
+  //
+  DEBUG((EFI_D_ERROR, "%a %d\n", __FUNCTION__, __LINE__));
+  if (NotifyFunction == NULL && mTimerNotifyFunction == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (NotifyFunction != NULL && mTimerNotifyFunction != NULL) {
+    return EFI_ALREADY_STARTED;
+  }
+  DEBUG((EFI_D_ERROR, "%a %d\n", __FUNCTION__, __LINE__));
+
+  mTimerNotifyFunction = NotifyFunction;
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  This function adjusts the period of timer interrupts to the value specified
+  by TimerPeriod.  If the timer period is updated, then the selected timer
+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
+  If an error occurs while attempting to update the timer period, then the
+  timer hardware will be put back in its state prior to this call, and
+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
+  is disabled.  This is not the same as disabling the CPU's interrupts.
+  Instead, it must either turn off the timer hardware, or it must adjust the
+  interrupt controller so that a CPU interrupt is not generated when the timer
+  interrupt fires.
+
+
+  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param TimerPeriod     The rate to program the timer interrupt in 100 nS units.  If
+                         the timer hardware is not programmable, then EFI_UNSUPPORTED is
+                         returned.  If the timer is programmable, then the timer period
+                         will be rounded up to the nearest timer period that is supported
+                         by the timer hardware.  If TimerPeriod is set to 0, then the
+                         timer interrupts will be disabled.
+
+  @retval        EFI_SUCCESS       The timer period was changed.
+  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.
+  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverSetTimerPeriod (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This,
+  IN UINT64                   TimerPeriod
+  )
+{
+  UINT64  TimerCount;
+  UINT32  TimerFrequency;
+  UINTN   DivideValue;
+
+  GetApicTimerState(&DivideValue, NULL, NULL);
+
+  // XXX rework comment, copy from other lib
+  //
+  //  The basic clock is 1.19318 MHz or 0.119318 ticks per 100 ns.
+  //  TimerPeriod * 0.119318 = 8254 timer divisor. Using integer arithmetic
+  //  TimerCount = (TimerPeriod * 119318)/1000000.
+  //
+  //  Round up to next highest integer. This guarantees that the timer is
+  //  equal to or slightly longer than the requested time.
+  //  TimerCount = ((TimerPeriod * 119318) + 500000)/1000000
+  //
+  // Note that a TimerCount of 0 is equivalent to a count of 65,536
+  //
+  if (TimerPeriod == 0) {
+    //
+    // Disable timer interrupt for a TimerPeriod of 0
+    //
+    DisableApicTimerInterrupt();
+  } else {
+    TimerFrequency = PcdGet32(PcdFSBClock) / DivideValue;
+
+    DEBUG((EFI_D_ERROR, "%a %d, fsbclock %d, freq %d\n",
+           __FUNCTION__, __LINE__,
+           PcdGet32(PcdFSBClock),
+           TimerFrequency));
+
+    //
+    // Convert TimerPeriod into local apic counts
+    //
+
+    TimerCount = DivU64x32 (MultU64x32 (TimerFrequency,
+                                        (UINT32) TimerPeriod) + 500000,
+                            1000000);
+
+    DEBUG((EFI_D_ERROR, "%a %d, new init val: %d\n", __FUNCTION__, __LINE__, TimerCount));
+
+    //
+    // Program the timer with the new count value
+    //
+    WriteLocalApicReg (XAPIC_TIMER_INIT_COUNT_OFFSET, TimerCount);
+
+    //
+    // Enable timer interrupt
+    //
+    EnableApicTimerInterrupt();
+  }
+  //
+  // Save the new timer period
+  //
+  mTimerPeriod = TimerPeriod;
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  This function retrieves the period of timer interrupts in 100 ns units,
+  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod
+  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is
+  returned, then the timer is currently disabled.
+
+
+  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param TimerPeriod     A pointer to the timer period to retrieve in 100 ns units.  If
+                         0 is returned, then the timer is currently disabled.
+
+  @retval EFI_SUCCESS            The timer period was returned in TimerPeriod.
+  @retval EFI_INVALID_PARAMETER  TimerPeriod is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGetTimerPeriod (
+  IN EFI_TIMER_ARCH_PROTOCOL   *This,
+  OUT UINT64                   *TimerPeriod
+  )
+{
+  if (TimerPeriod == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *TimerPeriod = mTimerPeriod;
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  This function generates a soft timer interrupt. If the platform does not support soft
+  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.
+  If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
+  service, then a soft timer interrupt will be generated. If the timer interrupt is
+  enabled when this service is called, then the registered handler will be invoked. The
+  registered handler should not be able to distinguish a hardware-generated timer
+  interrupt from a software-generated timer interrupt.
+
+
+  @param This              The EFI_TIMER_ARCH_PROTOCOL instance.
+
+  @retval EFI_SUCCESS       The soft timer interrupt was generated.
+  @retval EFI_UNSUPPORTED   The platform does not support the generation of soft timer interrupts.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGenerateSoftInterrupt (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This
+  )
+{
+  EFI_TPL     OriginalTPL;
+
+  if (GetApicTimerInterruptState()) {
+    //
+    // Invoke the registered handler
+    //
+    OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+
+    DisableApicTimerInterrupt();
+    if (mTimerNotifyFunction != NULL) {
+      //
+      // @bug : This does not handle missed timer interrupts
+      //
+      mTimerNotifyFunction (mTimerPeriod);
+    }
+
+    gBS->RestoreTPL (OriginalTPL);
+  } else {
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Initialize the Timer Architectural Protocol driver
+
+  @param ImageHandle     ImageHandle of the loaded driver
+  @param SystemTable     Pointer to the System Table
+
+  @retval EFI_SUCCESS            Timer Architectural Protocol created
+  @retval EFI_OUT_OF_RESOURCES   Not enough resources available to initialize driver.
+  @retval EFI_DEVICE_ERROR       A device error occured attempting to initialize the driver.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverInitialize (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      TimerVector;
+
+  //
+  // Initialize the pointer to our notify function.
+  //
+  mTimerNotifyFunction = NULL;
+
+  //
+  // Make sure the Timer Architectural Protocol is not already installed in the system
+  //
+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiTimerArchProtocolGuid);
+
+  //
+  // Find the CPU architectural protocol.
+  //
+  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **) &mCpu);
+  ASSERT_EFI_ERROR (Status);
+
+
+  //
+  // Force the timer to be disabled
+  //
+  DisableApicTimerInterrupt();
+
+  //
+  // Get the interrupt vector number corresponding to IRQ0 from the 8259 driver
+  //
+  TimerVector = 32;
+  InitializeApicTimer(2, 0, 1, TimerVector);
+
+  //
+  // Install interrupt handler for 8254 Timer #0 (ISA IRQ0)
+  //
+  Status = mCpu->RegisterInterruptHandler (mCpu, TimerVector, TimerInterruptHandler);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Force the timer to be enabled at its default period
+  //
+  Status = TimerDriverSetTimerPeriod (&mTimer, DEFAULT_TIMER_TICK_DURATION);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Install the Timer Architectural Protocol onto a new handle
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mTimerHandle,
+                  &gEfiTimerArchProtocolGuid, &mTimer,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
diff --git a/OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.inf b/OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.inf
new file mode 100644
index 0000000..43e137c
--- /dev/null
+++ b/OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.inf
@@ -0,0 +1,51 @@
+## @file
+# 8254 timer driver that provides Timer Arch protocol.
+#
+# Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution.  The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = ApicTimer
+  FILE_GUID                      = 52fe8196-f9de-4d07-b22f-51f77a0e7c41
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = TimerDriverInitialize
+
+[Packages]
+  MdePkg/MdePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  UefiCpuPkg/UefiCpuPkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[LibraryClasses]
+  UefiBootServicesTableLib
+  BaseLib
+  DebugLib
+  UefiDriverEntryPoint
+  IoLib
+  LocalApicLib
+
+[Sources]
+  Timer.h
+  XenTimerLocalApic.c
+
+[Protocols]
+  gEfiCpuArchProtocolGuid       ## CONSUMES
+  gEfiTimerArchProtocolGuid     ## PRODUCES
+[Pcd.IA32, Pcd.X64]
+  gEfiMdePkgTokenSpaceGuid.PcdFSBClock  ## CONSUMES
+
+[Depex]
+  gEfiCpuArchProtocolGuid# AND gEfiLegacy8259ProtocolGuid
+#[UserExtensions.TianoCore."ExtraFiles"]
+  #TimerExtra.uni
-- 
Anthony PERARD



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH RFC 12/14] OvmfPkg/PlatformBootManagerLib: Use a Xen console for ConOut/ConIn
  2016-12-08 15:33 [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
                   ` (10 preceding siblings ...)
  2016-12-08 15:33 ` [PATCH RFC 11/14] OvmfPkg/XenOvmf: Adding XenTimerLocalApic Anthony PERARD
@ 2016-12-08 15:33 ` Anthony PERARD
  2017-01-05 16:38   ` Laszlo Ersek
  2016-12-08 15:33 ` [PATCH RFC 13/14] OvmfPkg: Introduce XenIoPvhDxe to initialize Grant Tables Anthony PERARD
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Anthony PERARD @ 2016-12-08 15:33 UTC (permalink / raw)
  To: edk2-devel, xen-devel; +Cc: Anthony PERARD

and add OvmfPkg/XenConsoleIo/XenConsoleIo to XenOvmf platform.

It actually look for gEfiSerialIoProtocolGuid.
---
 .../Library/PlatformBootManagerLib/BdsPlatform.c   | 33 ++++++++++++++++++++++
 .../PlatformBootManagerLib.inf                     |  2 ++
 OvmfPkg/XenOvmf.dsc                                |  4 +++
 OvmfPkg/XenOvmf.fdf                                |  1 +
 4 files changed, 40 insertions(+)

diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
index bd64cc3..b8972f7 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
+++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
@@ -904,6 +904,31 @@ DetectAndPreparePlatformPciDevicePaths (
   return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath);
 }
 
+#include <Protocol/SerialIo.h>
+EFI_STATUS
+EFIAPI
+add_serial (
+  IN EFI_HANDLE  DeviceHandle,
+  IN VOID        *Instance,
+  IN VOID        *Context
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath = NULL;
+
+  DevicePath = DevicePathFromHandle(DeviceHandle);
+  if (DevicePath == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
+  DEBUG((EFI_D_ERROR, "%a %d: full path: %s\n", __FUNCTION__, __LINE__,
+         ConvertDevicePathToText(DevicePath, TRUE, FALSE)
+         ));
+  EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
+  EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
+  EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
+  return EFI_SUCCESS;
+}
 
 VOID
 PlatformInitializeConsole (
@@ -931,6 +956,14 @@ Arguments:
   GetEfiGlobalVariable2 (EFI_CON_OUT_VARIABLE_NAME, (VOID **) &VarConout, NULL);
   GetEfiGlobalVariable2 (EFI_CON_IN_VARIABLE_NAME, (VOID **) &VarConin, NULL);
 
+  // do xen console
+  //VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
+  VisitAllInstancesOfProtocol (
+           &gEfiSerialIoProtocolGuid,
+           add_serial,
+           (VOID*)NULL
+           );
+
   if (VarConout == NULL || VarConin == NULL) {
     //
     // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
index 4a6bece..74ab6b1 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+++ b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
@@ -73,6 +73,8 @@
   gEfiLoadedImageProtocolGuid                   # PROTOCOL SOMETIMES_PRODUCED
   gEfiFirmwareVolume2ProtocolGuid               # PROTOCOL SOMETIMES_CONSUMED
 
+  gEfiSerialIoProtocolGuid
+
 [Guids]
   gEfiXenInfoGuid
   gEfiEndOfDxeEventGroupGuid
diff --git a/OvmfPkg/XenOvmf.dsc b/OvmfPkg/XenOvmf.dsc
index 31a2185..8bce996 100644
--- a/OvmfPkg/XenOvmf.dsc
+++ b/OvmfPkg/XenOvmf.dsc
@@ -590,6 +590,10 @@
   OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
   OvmfPkg/XenBusDxe/XenBusDxe.inf
   OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+  OvmfPkg/XenConsoleIo/XenConsoleIo.inf {
+    <LibraryClasses>
+      SerialPortLib|OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
+  }
   MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
   MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
   MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
diff --git a/OvmfPkg/XenOvmf.fdf b/OvmfPkg/XenOvmf.fdf
index f6876d7..a40d186 100644
--- a/OvmfPkg/XenOvmf.fdf
+++ b/OvmfPkg/XenOvmf.fdf
@@ -223,6 +223,7 @@ INF  OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
 INF  OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
 INF  OvmfPkg/XenBusDxe/XenBusDxe.inf
 INF  OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
+INF  OvmfPkg/XenConsoleIo/XenConsoleIo.inf
 
 !if $(SECURE_BOOT_ENABLE) == TRUE
   INF  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
-- 
Anthony PERARD



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH RFC 13/14] OvmfPkg: Introduce XenIoPvhDxe to initialize Grant Tables
  2016-12-08 15:33 [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
                   ` (11 preceding siblings ...)
  2016-12-08 15:33 ` [PATCH RFC 12/14] OvmfPkg/PlatformBootManagerLib: Use a Xen console for ConOut/ConIn Anthony PERARD
@ 2016-12-08 15:33 ` Anthony PERARD
  2017-01-05 16:58   ` Laszlo Ersek
  2016-12-08 15:33 ` [PATCH RFC 14/14] XenOvmf: Use a different RTC Anthony PERARD
  2017-01-04 19:52 ` [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests Laszlo Ersek
  14 siblings, 1 reply; 37+ messages in thread
From: Anthony PERARD @ 2016-12-08 15:33 UTC (permalink / raw)
  To: edk2-devel, xen-devel; +Cc: Anthony PERARD

This "device" use XenIoMmioLib to reserve some space to be use by grant
tables. It's use 0xfc000000, which might not be a good choice...

There is probably a better way that using a device for this.
---
 OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c   | 263 ++++++++++++++++++++++++++++++++++++
 OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf |  45 ++++++
 OvmfPkg/XenOvmf.dsc                 |   2 +
 OvmfPkg/XenOvmf.fdf                 |   1 +
 4 files changed, 311 insertions(+)
 create mode 100644 OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c
 create mode 100644 OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf

diff --git a/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c b/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c
new file mode 100644
index 0000000..12e076f
--- /dev/null
+++ b/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c
@@ -0,0 +1,263 @@
+/** @file
+
+  XXX
+
+  XXX
+
+  This program and the accompanying materials are licensed and made available
+  under the terms and conditions of the BSD License which accompanies this
+  distribution. The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
+  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/XenIoMmioLib.h>
+
+/* #include <Protocol/XenIo.h> */
+STATIC BOOLEAN mXenIoInitialized = FALSE;
+
+/**
+
+  Device probe function for this driver.
+
+  The DXE core calls this function for any given device in order to see if the
+  driver can drive the device.
+
+  @param[in]  This                The EFI_DRIVER_BINDING_PROTOCOL object
+                                  incorporating this driver (independently of
+                                  any device).
+
+  @param[in] DeviceHandle         The device to probe.
+
+  @param[in] RemainingDevicePath  Relevant only for bus drivers, ignored.
+
+
+  @retval EFI_SUCCESS      The driver supports the device being probed.
+
+  @retval EFI_UNSUPPORTED  The driver does not support the device being probed.
+
+  @return                  Error codes from the OpenProtocol() boot service or
+                           the PciIo protocol.
+
+**/
+#if 1
+STATIC
+EFI_STATUS
+EFIAPI
+XenIoPvhDeviceBindingSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL *This,
+  IN EFI_HANDLE                  DeviceHandle,
+  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
+  )
+{
+
+  // XXX check if running Xen PVH
+  //
+
+  if (mXenIoInitialized) {
+    return EFI_ALREADY_STARTED;
+  }
+
+  DEBUG((EFI_D_INFO, "%a %d\n", __FUNCTION__, __LINE__));
+  return EFI_SUCCESS;
+}
+#endif
+
+/**
+
+  After we've pronounced support for a specific device in
+  DriverBindingSupported(), we start managing said device (passed in by the
+  Driver Execution Environment) with the following service.
+
+  See DriverBindingSupported() for specification references.
+
+  @param[in]  This                The EFI_DRIVER_BINDING_PROTOCOL object
+                                  incorporating this driver (independently of
+                                  any device).
+
+  @param[in] DeviceHandle         The supported device to drive.
+
+  @param[in] RemainingDevicePath  Relevant only for bus drivers, ignored.
+
+
+  @retval EFI_SUCCESS           The device was started.
+
+  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
+
+  @return                       Error codes from the OpenProtocol() boot
+                                service, the PciIo protocol or the
+                                InstallProtocolInterface() boot service.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+XenIoPvhDeviceBindingStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL *This,
+  IN EFI_HANDLE                  DeviceHandle,
+  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
+  )
+{
+  EFI_STATUS                        Status;
+  EFI_HANDLE Handle = NULL;
+
+  /* Status = XenIoMmioInstall(&Handle, (UINTN)AllocateReservedPages(4)); */
+  Status = XenIoMmioInstall(&Handle, (UINTN)0xfc000000);
+
+  if (!EFI_ERROR (Status)) {
+    mXenIoInitialized = TRUE;
+    return EFI_SUCCESS;
+  }
+
+  return Status;
+}
+
+#if 1
+/**
+
+  Stop driving the XenIo PCI device
+
+  @param[in] This               The EFI_DRIVER_BINDING_PROTOCOL object
+                                incorporating this driver (independently of any
+                                device).
+
+  @param[in] DeviceHandle       Stop driving this device.
+
+  @param[in] NumberOfChildren   Since this function belongs to a device driver
+                                only (as opposed to a bus driver), the caller
+                                environment sets NumberOfChildren to zero, and
+                                we ignore it.
+
+  @param[in] ChildHandleBuffer  Ignored (corresponding to NumberOfChildren).
+
+  @retval EFI_SUCCESS           Driver instance has been stopped and the PCI
+                                configuration attributes have been restored.
+
+  @return                       Error codes from the OpenProtocol() or
+                                CloseProtocol(), UninstallProtocolInterface()
+                                boot services.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+XenIoPvhDeviceBindingStop (
+  IN EFI_DRIVER_BINDING_PROTOCOL *This,
+  IN EFI_HANDLE                  DeviceHandle,
+  IN UINTN                       NumberOfChildren,
+  IN EFI_HANDLE                  *ChildHandleBuffer
+  )
+{
+  /* return XenIoMmioUninstall(Handle); */
+  return EFI_SUCCESS;
+}
+
+
+//
+// The static object that groups the Supported() (ie. probe), Start() and
+// Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata
+// C, 10.1 EFI Driver Binding Protocol.
+//
+STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {
+  &XenIoPvhDeviceBindingSupported,
+  &XenIoPvhDeviceBindingStart,
+  &XenIoPvhDeviceBindingStop,
+  0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers
+  NULL, // ImageHandle, to be overwritten by
+        // EfiLibInstallDriverBindingComponentName2() in XenIoPvhDeviceEntryPoint()
+  NULL  // DriverBindingHandle, ditto
+};
+
+
+//
+// The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and
+// EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's name
+// in English, for display on standard console devices. This is recommended for
+// UEFI drivers that follow the UEFI Driver Model. Refer to the Driver Writer's
+// Guide for UEFI 2.3.1 v1.01, 11 UEFI Driver and Controller Names.
+//
+STATIC
+EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {
+  { "eng;en", L"XenIo PVH Driver" },
+  { NULL,     NULL                }
+};
+
+STATIC
+EFI_COMPONENT_NAME_PROTOCOL gComponentName;
+
+EFI_STATUS
+EFIAPI
+XenIoPvhGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
+  IN  CHAR8                       *Language,
+  OUT CHAR16                      **DriverName
+  )
+{
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           mDriverNameTable,
+           DriverName,
+           (BOOLEAN)(This == &gComponentName) // Iso639Language
+           );
+}
+
+EFI_STATUS
+EFIAPI
+XenIoPvhGetDeviceName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
+  IN  EFI_HANDLE                  DeviceHandle,
+  IN  EFI_HANDLE                  ChildHandle,
+  IN  CHAR8                       *Language,
+  OUT CHAR16                      **ControllerName
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+STATIC
+EFI_COMPONENT_NAME_PROTOCOL gComponentName = {
+  &XenIoPvhGetDriverName,
+  &XenIoPvhGetDeviceName,
+  "eng" // SupportedLanguages, ISO 639-2 language codes
+};
+
+STATIC
+EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)     &XenIoPvhGetDriverName,
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) &XenIoPvhGetDeviceName,
+  "en" // SupportedLanguages, RFC 4646 language codes
+};
+
+#endif
+
+//
+// Entry point of this driver.
+//
+EFI_STATUS
+EFIAPI
+XenIoPvhDeviceEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  /* DEBUG((EFI_D_ERROR, "%a %d\n", __FUNCTION__, __LINE__)); */
+  /* return XenIoPvhDeviceBindingStart(ImageHandle); */
+
+  return EfiLibInstallDriverBindingComponentName2 (
+           ImageHandle,
+           SystemTable,
+           &gDriverBinding,
+           ImageHandle,
+           &gComponentName,
+           &gComponentName2
+           );
+}
diff --git a/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf b/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
new file mode 100644
index 0000000..dbdfd6e
--- /dev/null
+++ b/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
@@ -0,0 +1,45 @@
+## @file
+#  XXX
+#
+#  Copyright (C) XXX
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION               = 0x00010005
+  BASE_NAME                 = XenIoPvhDxe
+  FILE_GUID                 = 7a567cc4-0e75-4d7a-a305-c3db109b53ad
+  MODULE_TYPE               = UEFI_DRIVER
+  VERSION_STRING            = 1.0
+  ENTRY_POINT               = XenIoPvhDeviceEntryPoint
+
+[Packages]
+  MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
+
+[Sources]
+  XenIoPvhDxe.c
+
+[LibraryClasses]
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  MemoryAllocationLib
+  BaseMemoryLib
+  BaseLib
+  UefiLib
+  DebugLib
+  XenIoMmioLib
+
+[Protocols]
+  gEfiDriverBindingProtocolGuid
+  gEfiComponentName2ProtocolGuid
+  gEfiComponentNameProtocolGuid
+  gXenIoProtocolGuid
diff --git a/OvmfPkg/XenOvmf.dsc b/OvmfPkg/XenOvmf.dsc
index 8bce996..a7a884e 100644
--- a/OvmfPkg/XenOvmf.dsc
+++ b/OvmfPkg/XenOvmf.dsc
@@ -168,6 +168,7 @@
   SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
   OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
   XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
+  XenIoMmioLib|OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.inf
 
 [LibraryClasses.common]
 !if $(SECURE_BOOT_ENABLE) == TRUE
@@ -587,6 +588,7 @@
 !endif
   }
   OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
+  OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
   OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
   OvmfPkg/XenBusDxe/XenBusDxe.inf
   OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
diff --git a/OvmfPkg/XenOvmf.fdf b/OvmfPkg/XenOvmf.fdf
index a40d186..a500ab6 100644
--- a/OvmfPkg/XenOvmf.fdf
+++ b/OvmfPkg/XenOvmf.fdf
@@ -220,6 +220,7 @@ INF  MdeModulePkg/Universal/Metronome/Metronome.inf
 INF  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
 
 INF  OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
+INF  OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
 INF  OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
 INF  OvmfPkg/XenBusDxe/XenBusDxe.inf
 INF  OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
-- 
Anthony PERARD



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH RFC 14/14] XenOvmf: Use a different RTC
  2016-12-08 15:33 [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
                   ` (12 preceding siblings ...)
  2016-12-08 15:33 ` [PATCH RFC 13/14] OvmfPkg: Introduce XenIoPvhDxe to initialize Grant Tables Anthony PERARD
@ 2016-12-08 15:33 ` Anthony PERARD
  2017-01-05 17:02   ` Laszlo Ersek
  2017-01-04 19:52 ` [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests Laszlo Ersek
  14 siblings, 1 reply; 37+ messages in thread
From: Anthony PERARD @ 2016-12-08 15:33 UTC (permalink / raw)
  To: edk2-devel, xen-devel; +Cc: Anthony PERARD

---
 OvmfPkg/XenOvmf.dsc | 5 ++++-
 OvmfPkg/XenOvmf.fdf | 2 +-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/OvmfPkg/XenOvmf.dsc b/OvmfPkg/XenOvmf.dsc
index a7a884e..345157b 100644
--- a/OvmfPkg/XenOvmf.dsc
+++ b/OvmfPkg/XenOvmf.dsc
@@ -567,7 +567,10 @@
   }
   MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
   MdeModulePkg/Universal/Metronome/Metronome.inf
-  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf {
+    <LibraryClasses>
+      RealTimeClockLib|ArmVirtPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf
+  }
   MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
   MdeModulePkg/Universal/BdsDxe/BdsDxe.inf {
     <LibraryClasses>
diff --git a/OvmfPkg/XenOvmf.fdf b/OvmfPkg/XenOvmf.fdf
index a500ab6..65db2ba 100644
--- a/OvmfPkg/XenOvmf.fdf
+++ b/OvmfPkg/XenOvmf.fdf
@@ -217,7 +217,7 @@ INF  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
 INF  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
 INF  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
 INF  MdeModulePkg/Universal/Metronome/Metronome.inf
-INF  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
+INF  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
 
 INF  OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
 INF  OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
-- 
Anthony PERARD



^ permalink raw reply related	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 10/14] UefiCpuPkg/BaseXApicX2ApicLib: Fix initialisation on my system and ...
  2016-12-08 15:33 ` [PATCH RFC 10/14] UefiCpuPkg/BaseXApicX2ApicLib: Fix initialisation on my system and Anthony PERARD
@ 2016-12-09  6:48   ` Kinney, Michael D
  2016-12-12 12:38     ` Anthony PERARD
       [not found]     ` <58dbbeb0-f600-ef3f-7f8c-5c110b0aa809@citrix.com>
  0 siblings, 2 replies; 37+ messages in thread
From: Kinney, Michael D @ 2016-12-09  6:48 UTC (permalink / raw)
  To: Anthony PERARD, edk2-devel@lists.01.org,
	xen-devel@lists.xenproject.org, Kinney, Michael D

Hi Anthony,

Can you provide more details on why you want to expose internal APIs
in the library class?

What is the specific issue?  Is the Local APIC in your environment 
not behaving the same as real HW?

Thanks,

Mike



> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Anthony PERARD
> Sent: Thursday, December 8, 2016 7:34 AM
> To: edk2-devel@lists.01.org; xen-devel@lists.xenproject.org
> Cc: Anthony PERARD <anthony.perard@citrix.com>
> Subject: [edk2] [PATCH RFC 10/14] UefiCpuPkg/BaseXApicX2ApicLib: Fix initialisation
> on my system and ...
> 
> declare more exported function, ReadLocalApicReg and WriteLocalApicReg.
> 
> On my system (running OVMF inside a Xen PVH guest), writing the
> interrupt information (to XAPIC_LVT_TIMER_OFFSET) would also reset the
> init-count register, thus disabling the timer.
> ---
>  UefiCpuPkg/Include/Library/LocalApicLib.h          | 40 ++++++++++++++++++++++
>  .../BaseXApicX2ApicLib/BaseXApicX2ApicLib.c        | 10 +++---
>  2 files changed, 45 insertions(+), 5 deletions(-)
> 
> diff --git a/UefiCpuPkg/Include/Library/LocalApicLib.h
> b/UefiCpuPkg/Include/Library/LocalApicLib.h
> index fc980bc..ab621f2 100644
> --- a/UefiCpuPkg/Include/Library/LocalApicLib.h
> +++ b/UefiCpuPkg/Include/Library/LocalApicLib.h
> @@ -48,6 +48,46 @@ SetLocalApicBaseAddress (
>    );
> 
>  /**
> +  Read from a local APIC register.
> +
> +  This function reads from a local APIC register either in xAPIC or x2APIC mode.
> +  It is required that in xAPIC mode wider registers (64-bit or 256-bit) must be
> +  accessed using multiple 32-bit loads or stores, so this function only performs
> +  32-bit read.
> +
> +  @param  MmioOffset  The MMIO offset of the local APIC register in xAPIC mode.
> +                      It must be 16-byte aligned.
> +
> +  @return 32-bit      Value read from the register.
> +**/
> +UINT32
> +EFIAPI
> +ReadLocalApicReg (
> +  IN UINTN  MmioOffset
> +  );
> +
> +/**
> +  Write to a local APIC register.
> +
> +  This function writes to a local APIC register either in xAPIC or x2APIC mode.
> +  It is required that in xAPIC mode wider registers (64-bit or 256-bit) must be
> +  accessed using multiple 32-bit loads or stores, so this function only performs
> +  32-bit write.
> +
> +  if the register index is invalid or unsupported in current APIC mode, then ASSERT.
> +
> +  @param  MmioOffset  The MMIO offset of the local APIC register in xAPIC mode.
> +                      It must be 16-byte aligned.
> +  @param  Value       Value to be written to the register.
> +**/
> +VOID
> +EFIAPI
> +WriteLocalApicReg (
> +  IN UINTN  MmioOffset,
> +  IN UINT32 Value
> +  );
> +
> +/**
>    Get the current local APIC mode.
> 
>    If local APIC is disabled, then ASSERT.
> diff --git a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
> b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
> index e690d2a..f84a40a 100644
> --- a/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
> +++ b/UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.c
> @@ -820,11 +820,6 @@ InitializeApicTimer (
>    //
>    InitializeLocalApicSoftwareEnable (TRUE);
> 
> -  //
> -  // Program init-count register.
> -  //
> -  WriteLocalApicReg (XAPIC_TIMER_INIT_COUNT_OFFSET, InitCount);
> -
>    if (DivideValue != 0) {
>      ASSERT (DivideValue <= 128);
>      ASSERT (DivideValue == GetPowerOfTwo32((UINT32)DivideValue));
> @@ -848,6 +843,11 @@ InitializeApicTimer (
>    LvtTimer.Bits.Mask = 0;
>    LvtTimer.Bits.Vector = Vector;
>    WriteLocalApicReg (XAPIC_LVT_TIMER_OFFSET, LvtTimer.Uint32);
> +
> +  //
> +  // Program init-count register.
> +  //
> +  WriteLocalApicReg (XAPIC_TIMER_INIT_COUNT_OFFSET, InitCount);
>  }
> 
>  /**
> --
> Anthony PERARD
> 
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 10/14] UefiCpuPkg/BaseXApicX2ApicLib: Fix initialisation on my system and ...
  2016-12-09  6:48   ` Kinney, Michael D
@ 2016-12-12 12:38     ` Anthony PERARD
       [not found]     ` <58dbbeb0-f600-ef3f-7f8c-5c110b0aa809@citrix.com>
  1 sibling, 0 replies; 37+ messages in thread
From: Anthony PERARD @ 2016-12-12 12:38 UTC (permalink / raw)
  To: Kinney, Michael D; +Cc: edk2-devel@lists.01.org, xen-devel@lists.xenproject.org

On Fri, Dec 09, 2016 at 06:48:47AM +0000, Kinney, Michael D wrote:
> Hi Anthony,
> 
> Can you provide more details on why you want to expose internal APIs
> in the library class?

I think I'm only using WriteLocalApicReg() to change the init counter.
Maybe I can just call InitializeApicTimer() again instead.

-- 
Anthony PERARD


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [Xen-devel] [PATCH RFC 10/14] UefiCpuPkg/BaseXApicX2ApicLib: Fix initialisation on my system and ...
       [not found]     ` <58dbbeb0-f600-ef3f-7f8c-5c110b0aa809@citrix.com>
@ 2016-12-12 12:40       ` Anthony PERARD
  0 siblings, 0 replies; 37+ messages in thread
From: Anthony PERARD @ 2016-12-12 12:40 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: Kinney, Michael D, edk2-devel@lists.01.org,
	xen-devel@lists.xenproject.org

On Fri, Dec 09, 2016 at 10:43:30AM +0000, Andrew Cooper wrote:
> On 09/12/16 06:48, Kinney, Michael D wrote:
> > Hi Anthony,
> >
> > Can you provide more details on why you want to expose internal APIs
> > in the library class?
> >
> > What is the specific issue?  Is the Local APIC in your environment 
> > not behaving the same as real HW?
> 
> Xen's LAPIC emulation should match real hardware (because we might even
> substitute it for real hardware APIC virtualisation support).
> 
> If Xen's LAPIC doesn't behave like real hardware, we should fix that,
> but first we should understand what the correct behaviour should be.

I'll try to find out what the real hardware is doing.

At least, I think there where nothing in the Intel manual about the
initial counter been reset.

-- 
Anthony PERARD


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 01/14] OvmfPkg: Create platform XenOvmf
  2016-12-08 15:33 ` [PATCH RFC 01/14] OvmfPkg: Create platform XenOvmf Anthony PERARD
@ 2017-01-04 19:14   ` Laszlo Ersek
  0 siblings, 0 replies; 37+ messages in thread
From: Laszlo Ersek @ 2017-01-04 19:14 UTC (permalink / raw)
  To: Anthony PERARD, edk2-devel, xen-devel

On 12/08/16 16:33, Anthony PERARD wrote:
> This is a copy of OvmfX64, removing VirtIO and some SMM.

(1) Please provide more details in the commit message:

- changed: PLATFORM_GUID, OUTPUT_DIRECTORY, FLASH_DEFINITION
- removed: VirtioLib class resolution
- removed: DXE_SMM_DRIVER and SMM_CORE lib class resolutions
- removed: DXE_SMM_DRIVER and SMM_CORE FDF rules
- changed: PcdPciDisableBusEnumeration dynamic default flipped to TRUE
- removed: all UEFI_DRIVER modules for virtio devices

> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>  OvmfPkg/XenOvmf.dsc | 793 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  OvmfPkg/XenOvmf.fdf | 504 +++++++++++++++++++++++++++++++++
>  2 files changed, 1297 insertions(+)
>  create mode 100644 OvmfPkg/XenOvmf.dsc
>  create mode 100644 OvmfPkg/XenOvmf.fdf
> 
> diff --git a/OvmfPkg/XenOvmf.dsc b/OvmfPkg/XenOvmf.dsc
> new file mode 100644
> index 0000000..e452eb3
> --- /dev/null
> +++ b/OvmfPkg/XenOvmf.dsc
> @@ -0,0 +1,793 @@
> +## @file
> +#  EFI/Framework Open Virtual Machine Firmware (OVMF) platform
> +#
> +#  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
> +#  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>

(2) You might want to add a Citrix copyright notice here.

The rest looks good to me (I diffed these files against their originals).

Thanks
Laszlo

> +#
> +#  This program and the accompanying materials
> +#  are licensed and made available under the terms and conditions of the BSD License
> +#  which accompanies this distribution. The full text of the license may be found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +#
> +##
> +
> +################################################################################
> +#
> +# Defines Section - statements that will be processed to create a Makefile.
> +#
> +################################################################################
> +[Defines]
> +  PLATFORM_NAME                  = Ovmf
> +  PLATFORM_GUID                  = e3aa4fbe-9459-482d-bd40-d3f3b5f89d6e
> +  PLATFORM_VERSION               = 0.1
> +  DSC_SPECIFICATION              = 0x00010005
> +  OUTPUT_DIRECTORY               = Build/XenOvmf
> +  SUPPORTED_ARCHITECTURES        = X64
> +  BUILD_TARGETS                  = NOOPT|DEBUG|RELEASE
> +  SKUID_IDENTIFIER               = DEFAULT
> +  FLASH_DEFINITION               = OvmfPkg/XenOvmf.fdf
> +
> +  #
> +  # Defines for default states.  These can be changed on the command line.
> +  # -D FLAG=VALUE
> +  #
> +  DEFINE SECURE_BOOT_ENABLE      = FALSE
> +  DEFINE NETWORK_IP6_ENABLE      = FALSE
> +  DEFINE HTTP_BOOT_ENABLE        = FALSE
> +  DEFINE SMM_REQUIRE             = FALSE
> +
> +[BuildOptions]
> +  GCC:*_UNIXGCC_*_CC_FLAGS             = -DMDEPKG_NDEBUG
> +  GCC:RELEASE_*_*_CC_FLAGS             = -DMDEPKG_NDEBUG
> +  INTEL:RELEASE_*_*_CC_FLAGS           = /D MDEPKG_NDEBUG
> +  MSFT:RELEASE_*_*_CC_FLAGS            = /D MDEPKG_NDEBUG
> +  GCC:*_*_*_CC_FLAGS                   = -mno-mmx -mno-sse
> +!ifdef $(SOURCE_DEBUG_ENABLE)
> +  MSFT:*_*_X64_GENFW_FLAGS  = --keepexceptiontable
> +  GCC:*_*_X64_GENFW_FLAGS   = --keepexceptiontable
> +  INTEL:*_*_X64_GENFW_FLAGS = --keepexceptiontable
> +!endif
> +
> +  #
> +  # Disable deprecated APIs.
> +  #
> +  MSFT:*_*_*_CC_FLAGS = /D DISABLE_NEW_DEPRECATED_INTERFACES
> +  INTEL:*_*_*_CC_FLAGS = /D DISABLE_NEW_DEPRECATED_INTERFACES
> +  GCC:*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
> +
> +[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
> +  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
> +
> +# Force PE/COFF sections to be aligned at 4KB boundaries to support page level
> +# protection of DXE_SMM_DRIVER/SMM_CORE modules
> +[BuildOptions.common.EDKII.DXE_SMM_DRIVER, BuildOptions.common.EDKII.SMM_CORE]
> +  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
> +
> +################################################################################
> +#
> +# SKU Identification section - list of all SKU IDs supported by this Platform.
> +#
> +################################################################################
> +[SkuIds]
> +  0|DEFAULT
> +
> +################################################################################
> +#
> +# Library Class section - list of all Library Classes needed by this Platform.
> +#
> +################################################################################
> +[LibraryClasses]
> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +  TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
> +  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
> +  BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
> +  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
> +  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
> +  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
> +  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
> +  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
> +  CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
> +  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
> +  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
> +  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
> +  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
> +  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
> +  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
> +  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
> +  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
> +  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
> +  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
> +  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
> +  PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
> +  PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf
> +  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
> +  PciSegmentLib|MdePkg/Library/BasePciSegmentLibPci/BasePciSegmentLibPci.inf
> +  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
> +  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
> +  SerialPortLib|PcAtChipsetPkg/Library/SerialIoLib/SerialIoLib.inf
> +  MtrrLib|UefiCpuPkg/Library/MtrrLib/MtrrLib.inf
> +  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
> +  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
> +  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
> +  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
> +  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
> +  DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
> +  NvVarsFileLib|OvmfPkg/Library/NvVarsFileLib/NvVarsFileLib.inf
> +  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
> +  UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
> +  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
> +  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
> +  IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
> +  UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
> +  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
> +  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
> +  SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf
> +  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
> +  LoadLinuxLib|OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf
> +!if $(SMM_REQUIRE) == FALSE
> +  LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxBaseLib.inf
> +!endif
> +  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
> +  FrameBufferBltLib|MdeModulePkg/Library/FrameBufferBltLib/FrameBufferBltLib.inf
> +
> +!ifdef $(SOURCE_DEBUG_ENABLE)
> +  PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
> +  DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf
> +!else
> +  PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
> +  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
> +!endif
> +
> +  ResetSystemLib|OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
> +  LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
> +  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
> +
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
> +  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> +  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> +  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
> +  AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
> +!if $(NETWORK_IP6_ENABLE) == TRUE
> +  TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf
> +!endif
> +!else
> +  TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
> +  AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
> +!endif
> +  VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> +
> +!if $(HTTP_BOOT_ENABLE) == TRUE
> +  HttpLib|MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.inf
> +!endif
> +
> +  S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf
> +  SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
> +  OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
> +  XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
> +
> +[LibraryClasses.common]
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> +!endif
> +
> +[LibraryClasses.common.SEC]
> +  TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
> +  QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf
> +!ifdef $(DEBUG_ON_SERIAL_PORT)
> +  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
> +!else
> +  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
> +!endif
> +  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
> +  ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf
> +!ifdef $(SOURCE_DEBUG_ENABLE)
> +  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
> +!endif
> +  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> +  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
> +  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
> +  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
> +  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
> +
> +[LibraryClasses.common.PEI_CORE]
> +  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> +  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
> +  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
> +  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
> +  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
> +  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
> +  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
> +  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
> +!ifdef $(DEBUG_ON_SERIAL_PORT)
> +  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
> +!else
> +  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
> +!endif
> +  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
> +
> +[LibraryClasses.common.PEIM]
> +  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> +  PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
> +  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
> +  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
> +  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
> +  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
> +  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
> +  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
> +!ifdef $(DEBUG_ON_SERIAL_PORT)
> +  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
> +!else
> +  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
> +!endif
> +  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
> +  PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
> +  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
> +!ifdef $(SOURCE_DEBUG_ENABLE)
> +  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
> +!endif
> +  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/PeiCpuExceptionHandlerLib.inf
> +  MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf
> +
> +[LibraryClasses.common.DXE_CORE]
> +  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
> +  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
> +  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
> +  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
> +!ifdef $(DEBUG_ON_SERIAL_PORT)
> +  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
> +!else
> +  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
> +!endif
> +  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
> +!ifdef $(SOURCE_DEBUG_ENABLE)
> +  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
> +!endif
> +  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +
> +[LibraryClasses.common.DXE_RUNTIME_DRIVER]
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
> +  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
> +  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
> +  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> +  ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf
> +!ifdef $(DEBUG_ON_SERIAL_PORT)
> +  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
> +!else
> +  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
> +!endif
> +  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
> +!endif
> +  PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
> +
> +[LibraryClasses.common.UEFI_DRIVER]
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
> +  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
> +  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
> +  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> +  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
> +!ifdef $(DEBUG_ON_SERIAL_PORT)
> +  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
> +!else
> +  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
> +!endif
> +  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
> +  PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
> +
> +[LibraryClasses.common.DXE_DRIVER]
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
> +  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
> +  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> +  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
> +  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
> +!ifdef $(DEBUG_ON_SERIAL_PORT)
> +  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
> +!else
> +  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
> +!endif
> +  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
> +  IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
> +  UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
> +  DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
> +  PlatformBootManagerLib|OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> +  QemuBootOrderLib|OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
> +  CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf
> +!if $(SMM_REQUIRE) == TRUE
> +  LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf
> +!else
> +  LockBoxLib|OvmfPkg/Library/LockBoxLib/LockBoxDxeLib.inf
> +!endif
> +!ifdef $(SOURCE_DEBUG_ENABLE)
> +  DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
> +!endif
> +  PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
> +  MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf
> +
> +[LibraryClasses.common.UEFI_APPLICATION]
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
> +  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
> +  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> +  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
> +!ifdef $(DEBUG_ON_SERIAL_PORT)
> +  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
> +!else
> +  DebugLib|OvmfPkg/Library/PlatformDebugLibIoPort/PlatformDebugLibIoPort.inf
> +!endif
> +  PciLib|OvmfPkg/Library/DxePciLibI440FxQ35/DxePciLibI440FxQ35.inf
> +
> +################################################################################
> +#
> +# Pcd Section - list of all EDK II PCD Entries defined by this Platform.
> +#
> +################################################################################
> +[PcdsFeatureFlag]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdHiiOsRuntimeSupport|FALSE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|FALSE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|TRUE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportUefiDecompress|FALSE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode|FALSE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  gUefiOvmfPkgTokenSpaceGuid.PcdSecureBootEnable|TRUE
> +!endif
> +!if $(SMM_REQUIRE) == TRUE
> +  gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire|TRUE
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmEnableBspElection|FALSE
> +!endif
> +
> +[PcdsFixedAtBuild]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
> +  gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxFvSupported|6
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeimPerFv|32
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000
> +
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0
> +
> +  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
> +
> +  # DEBUG_INIT      0x00000001  // Initialization
> +  # DEBUG_WARN      0x00000002  // Warnings
> +  # DEBUG_LOAD      0x00000004  // Load events
> +  # DEBUG_FS        0x00000008  // EFI File system
> +  # DEBUG_POOL      0x00000010  // Alloc & Free (pool)
> +  # DEBUG_PAGE      0x00000020  // Alloc & Free (page)
> +  # DEBUG_INFO      0x00000040  // Informational debug messages
> +  # DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers
> +  # DEBUG_VARIABLE  0x00000100  // Variable
> +  # DEBUG_BM        0x00000400  // Boot Manager
> +  # DEBUG_BLKIO     0x00001000  // BlkIo Driver
> +  # DEBUG_NET       0x00004000  // SNP Driver
> +  # DEBUG_UNDI      0x00010000  // UNDI Driver
> +  # DEBUG_LOADFILE  0x00020000  // LoadFile
> +  # DEBUG_EVENT     0x00080000  // Event messages
> +  # DEBUG_GCD       0x00100000  // Global Coherency Database changes
> +  # DEBUG_CACHE     0x00200000  // Memory range cachability changes
> +  # DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
> +  #                             // significantly impact boot performance
> +  # DEBUG_ERROR     0x80000000  // Error
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F
> +
> +!ifdef $(SOURCE_DEBUG_ENABLE)
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17
> +!else
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
> +!endif
> +
> +  # This PCD is used to set the base address of the PCI express hierarchy. It
> +  # is only consulted when OVMF runs on Q35. In that case it is programmed into
> +  # the PCIEXBAR register.
> +  #
> +  # On Q35 machine types that QEMU intends to support in the long term, QEMU
> +  # never lets the RAM below 4 GB exceed 2 GB.
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0x80000000
> +
> +!ifdef $(SOURCE_DEBUG_ENABLE)
> +  gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|0x2
> +!endif
> +
> +!ifndef $(USE_OLD_SHELL)
> +  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }
> +!endif
> +
> +!if $(SMM_REQUIRE) == TRUE
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode|0x01
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout|100000
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize|0x4000
> +!endif
> +
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x00
> +!endif
> +
> +  # IRQs 5, 9, 10, 11 are level-triggered
> +  gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel|0x0E20
> +
> +  # Point to the MdeModulePkg/Application/UiApp/UiApp.inf
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
> +
> +################################################################################
> +#
> +# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
> +#
> +################################################################################
> +
> +[PcdsDynamicDefault]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|TRUE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable|FALSE
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId|0
> +  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase|0x0
> +  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoSize|0x0
> +  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Base|0x0
> +  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Size|0x0
> +  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Base|0x0
> +  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Size|0x800000000
> +
> +  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|0
> +
> +  # Set video resolution for text setup.
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480
> +
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0
> +  gUefiOvmfPkgTokenSpaceGuid.PcdQemuSmbiosValidated|FALSE
> +
> +  # Noexec settings for DXE.
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|FALSE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdPropertiesTableEnable|FALSE
> +
> +  # UefiCpuPkg PCDs related to initial AP bringup and general AP management.
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber|64
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds|50000
> +
> +################################################################################
> +#
> +# Components Section - list of all EDK II Modules needed by this Platform.
> +#
> +################################################################################
> +[Components]
> +  OvmfPkg/ResetVector/ResetVector.inf
> +
> +  #
> +  # SEC Phase modules
> +  #
> +  OvmfPkg/Sec/SecMain.inf {
> +    <LibraryClasses>
> +      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
> +  }
> +
> +  #
> +  # PEI Phase modules
> +  #
> +  MdeModulePkg/Core/Pei/PeiMain.inf
> +  MdeModulePkg/Universal/PCD/Pei/Pcd.inf  {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +  }
> +  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
> +  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
> +  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +
> +  OvmfPkg/PlatformPei/PlatformPei.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +!if $(SMM_REQUIRE) == TRUE
> +      LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
> +!endif
> +  }
> +!if $(SMM_REQUIRE) == TRUE
> +  OvmfPkg/SmmAccess/SmmAccessPei.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +!endif
> +  UefiCpuPkg/CpuMpPei/CpuMpPei.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  }
> +
> +  #
> +  # DXE Phase modules
> +  #
> +  MdeModulePkg/Core/Dxe/DxeMain.inf {
> +    <LibraryClasses>
> +      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
> +      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
> +  }
> +
> +  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
> +  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
> +  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf  {
> +   <LibraryClasses>
> +      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +  }
> +
> +  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
> +
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
> +    <LibraryClasses>
> +      NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
> +	}
> +!else
> +  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
> +!endif
> +
> +  MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
> +  PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
> +  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
> +  UefiCpuPkg/CpuDxe/CpuDxe.inf
> +  PcAtChipsetPkg/8254TimerDxe/8254Timer.inf
> +  OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf
> +  OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
> +  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf {
> +    <LibraryClasses>
> +      PciHostBridgeLib|OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf
> +  }
> +  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  }
> +  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
> +  MdeModulePkg/Universal/Metronome/Metronome.inf
> +  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
> +  MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
> +  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf {
> +    <LibraryClasses>
> +!ifdef $(CSM_ENABLE)
> +      NULL|OvmfPkg/Csm/CsmSupportLib/CsmSupportLib.inf
> +      NULL|IntelFrameworkModulePkg/Library/LegacyBootManagerLib/LegacyBootManagerLib.inf
> +!endif
> +  }
> +  MdeModulePkg/Logo/LogoDxe.inf
> +  MdeModulePkg/Application/UiApp/UiApp.inf {
> +    <LibraryClasses>
> +      NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
> +      NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
> +      NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
> +!ifdef $(CSM_ENABLE)
> +      NULL|IntelFrameworkModulePkg/Library/LegacyBootManagerLib/LegacyBootManagerLib.inf
> +      NULL|IntelFrameworkModulePkg/Library/LegacyBootMaintUiLib/LegacyBootMaintUiLib.inf
> +!endif
> +  }
> +  OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
> +  OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
> +  OvmfPkg/XenBusDxe/XenBusDxe.inf
> +  OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
> +  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
> +  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
> +  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
> +  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
> +  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
> +  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  }
> +  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
> +  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf {
> +    <LibraryClasses>
> +      DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
> +      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +  }
> +  MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
> +  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
> +  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
> +  MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
> +  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
> +  FatPkg/EnhancedFatDxe/Fat.inf
> +  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
> +  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
> +  OvmfPkg/SataControllerDxe/SataControllerDxe.inf
> +  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
> +  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
> +  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
> +  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
> +  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
> +  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
> +  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
> +
> +  OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
> +
> +  #
> +  # ISA Support
> +  #
> +  PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.inf
> +  IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf
> +  IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf
> +  IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf
> +  IntelFrameworkModulePkg/Bus/Isa/IsaFloppyDxe/IsaFloppyDxe.inf
> +
> +  #
> +  # SMBIOS Support
> +  #
> +  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf {
> +    <LibraryClasses>
> +      NULL|OvmfPkg/Library/SmbiosVersionLib/DetectSmbiosVersionLib.inf
> +  }
> +  OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
> +
> +  #
> +  # ACPI Support
> +  #
> +  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
> +  OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
> +  OvmfPkg/AcpiTables/AcpiTables.inf
> +  MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
> +  MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
> +
> +  #
> +  # Network Support
> +  #
> +  MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
> +  MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
> +  MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
> +  MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
> +  MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
> +  MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
> +  MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
> +  MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
> +  MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
> +!if $(NETWORK_IP6_ENABLE) == TRUE
> +  NetworkPkg/Ip6Dxe/Ip6Dxe.inf
> +  NetworkPkg/TcpDxe/TcpDxe.inf
> +  NetworkPkg/Udp6Dxe/Udp6Dxe.inf
> +  NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
> +  NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
> +  NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  NetworkPkg/IScsiDxe/IScsiDxe.inf
> +!else
> +  MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
> +!endif
> +!else
> +  MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
> +  MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
> +  MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
> +!endif
> +!if $(HTTP_BOOT_ENABLE) == TRUE
> +  NetworkPkg/DnsDxe/DnsDxe.inf
> +  NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf
> +  NetworkPkg/HttpDxe/HttpDxe.inf
> +  NetworkPkg/HttpBootDxe/HttpBootDxe.inf
> +!endif
> +
> +  #
> +  # Usb Support
> +  #
> +  MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
> +  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
> +  MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
> +
> +!ifdef $(CSM_ENABLE)
> +  IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +  }
> +  IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf
> +  OvmfPkg/Csm/Csm16/Csm16.inf
> +!endif
> +
> +!ifndef $(USE_OLD_SHELL)
> +  ShellPkg/Application/Shell/Shell.inf {
> +    <LibraryClasses>
> +      ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
> +      NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
> +      NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
> +      NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
> +      NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
> +      NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
> +      NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
> +      NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
> +!if $(NETWORK_IP6_ENABLE) == TRUE
> +      NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
> +!endif
> +      NULL|ShellPkg/Library/UefiShellTftpCommandLib/UefiShellTftpCommandLib.inf
> +      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
> +      ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
> +      FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
> +      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
> +#      SafeBlockIoLib|ShellPkg/Library/SafeBlockIoLib/SafeBlockIoLib.inf
> +#      SafeOpenProtocolLib|ShellPkg/Library/SafeOpenProtocolLib/SafeOpenProtocolLib.inf
> +      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
> +
> +    <PcdsFixedAtBuild>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
> +      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
> +      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
> +  }
> +!endif
> +
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
> +!endif
> +
> +  OvmfPkg/PlatformDxe/Platform.inf
> +
> +!if $(SMM_REQUIRE) == TRUE
> +  OvmfPkg/SmmAccess/SmmAccess2Dxe.inf
> +  OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
> +  UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf
> +
> +  #
> +  # SMM Initial Program Load (a DXE_RUNTIME_DRIVER)
> +  #
> +  MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
> +
> +  #
> +  # SMM_CORE
> +  #
> +  MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
> +
> +  #
> +  # Privileged drivers (DXE_SMM_DRIVER modules)
> +  #
> +  UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
> +  MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf {
> +    <LibraryClasses>
> +      LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxSmmLib.inf
> +  }
> +  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf {
> +    <LibraryClasses>
> +      SmmCpuPlatformHookLib|UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLibNull.inf
> +      SmmCpuFeaturesLib|OvmfPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
> +  }
> +
> +  #
> +  # Variable driver stack (SMM)
> +  #
> +  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf
> +  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf
> +  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf {
> +    <LibraryClasses>
> +      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
> +  }
> +  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
> +
> +!else
> +
> +  #
> +  # Variable driver stack (non-SMM)
> +  #
> +  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
> +  OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf {
> +    <LibraryClasses>
> +      PlatformFvbLib|OvmfPkg/Library/EmuVariableFvbLib/EmuVariableFvbLib.inf
> +  }
> +  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
> +  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
> +    <LibraryClasses>
> +      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
> +  }
> +!endif
> diff --git a/OvmfPkg/XenOvmf.fdf b/OvmfPkg/XenOvmf.fdf
> new file mode 100644
> index 0000000..d01454e
> --- /dev/null
> +++ b/OvmfPkg/XenOvmf.fdf
> @@ -0,0 +1,504 @@
> +## @file
> +#  Open Virtual Machine Firmware: FDF
> +#
> +#  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
> +#  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
> +#
> +#  This program and the accompanying materials
> +#  are licensed and made available under the terms and conditions of the BSD License
> +#  which accompanies this distribution. The full text of the license may be found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +#
> +##
> +
> +################################################################################
> +
> +[Defines]
> +!include OvmfPkg.fdf.inc
> +
> +#
> +# Build the variable store and the firmware code as one unified flash device
> +# image.
> +#
> +[FD.OVMF]
> +BaseAddress   = $(FW_BASE_ADDRESS)
> +Size          = $(FW_SIZE)
> +ErasePolarity = 1
> +BlockSize     = $(BLOCK_SIZE)
> +NumBlocks     = $(FW_BLOCKS)
> +
> +!include VarStore.fdf.inc
> +
> +$(VARS_SIZE)|$(FVMAIN_SIZE)
> +FV = FVMAIN_COMPACT
> +
> +$(SECFV_OFFSET)|$(SECFV_SIZE)
> +FV = SECFV
> +
> +#
> +# Build the variable store and the firmware code as separate flash device
> +# images.
> +#
> +[FD.OVMF_VARS]
> +BaseAddress   = $(FW_BASE_ADDRESS)
> +Size          = $(VARS_SIZE)
> +ErasePolarity = 1
> +BlockSize     = $(BLOCK_SIZE)
> +NumBlocks     = $(VARS_BLOCKS)
> +
> +!include VarStore.fdf.inc
> +
> +[FD.OVMF_CODE]
> +BaseAddress   = $(CODE_BASE_ADDRESS)
> +Size          = $(CODE_SIZE)
> +ErasePolarity = 1
> +BlockSize     = $(BLOCK_SIZE)
> +NumBlocks     = $(CODE_BLOCKS)
> +
> +0x00000000|$(FVMAIN_SIZE)
> +FV = FVMAIN_COMPACT
> +
> +$(FVMAIN_SIZE)|$(SECFV_SIZE)
> +FV = SECFV
> +
> +################################################################################
> +
> +[FD.MEMFD]
> +BaseAddress   = $(MEMFD_BASE_ADDRESS)
> +Size          = 0xB00000
> +ErasePolarity = 1
> +BlockSize     = 0x10000
> +NumBlocks     = 0xB0
> +
> +0x000000|0x006000
> +gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
> +
> +0x006000|0x001000
> +gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize
> +
> +0x007000|0x001000
> +gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress|gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
> +
> +0x010000|0x008000
> +gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
> +
> +0x020000|0x0E0000
> +gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
> +FV = PEIFV
> +
> +0x100000|0xA00000
> +gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
> +FV = DXEFV
> +
> +################################################################################
> +
> +[FV.SECFV]
> +FvNameGuid         = 763BED0D-DE9F-48F5-81F1-3E90E1B1A015
> +BlockSize          = 0x1000
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +
> +#
> +# SEC Phase modules
> +#
> +# The code in this FV handles the initial firmware startup, and
> +# decompresses the PEI and DXE FVs which handles the rest of the boot sequence.
> +#
> +INF  OvmfPkg/Sec/SecMain.inf
> +
> +INF  RuleOverride=RESET_VECTOR OvmfPkg/ResetVector/ResetVector.inf
> +
> +################################################################################
> +[FV.PEIFV]
> +FvNameGuid         = 6938079B-B503-4E3D-9D24-B28337A25806
> +BlockSize          = 0x10000
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +
> +APRIORI PEI {
> +  INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
> +}
> +
> +#
> +#  PEI Phase modules
> +#
> +INF  MdeModulePkg/Core/Pei/PeiMain.inf
> +INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
> +INF  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
> +INF  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
> +INF  OvmfPkg/PlatformPei/PlatformPei.inf
> +INF  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
> +INF  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
> +!if $(SMM_REQUIRE) == TRUE
> +INF  OvmfPkg/SmmAccess/SmmAccessPei.inf
> +!endif
> +INF  UefiCpuPkg/CpuMpPei/CpuMpPei.inf
> +
> +################################################################################
> +
> +[FV.DXEFV]
> +FvNameGuid         = 7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1
> +BlockSize          = 0x10000
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +
> +APRIORI DXE {
> +  INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
> +  INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
> +!if $(SMM_REQUIRE) == FALSE
> +  INF  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
> +!endif
> +}
> +
> +#
> +# DXE Phase modules
> +#
> +INF  MdeModulePkg/Core/Dxe/DxeMain.inf
> +
> +INF  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
> +INF  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
> +INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
> +
> +INF  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
> +INF  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
> +INF  MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
> +INF  PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
> +INF  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
> +INF  UefiCpuPkg/CpuDxe/CpuDxe.inf
> +INF  PcAtChipsetPkg/8254TimerDxe/8254Timer.inf
> +INF  OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf
> +INF  OvmfPkg/PciHotPlugInitDxe/PciHotPlugInit.inf
> +INF  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
> +INF  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> +INF  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
> +INF  MdeModulePkg/Universal/Metronome/Metronome.inf
> +INF  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
> +
> +INF  OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
> +INF  OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
> +INF  OvmfPkg/XenBusDxe/XenBusDxe.inf
> +INF  OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
> +
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  INF  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
> +!endif
> +
> +INF  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
> +INF  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
> +INF  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
> +INF  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
> +INF  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
> +INF  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
> +INF  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
> +INF  MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
> +INF  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
> +INF  MdeModulePkg/Application/UiApp/UiApp.inf
> +INF  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
> +INF  MdeModulePkg/Universal/PrintDxe/PrintDxe.inf
> +INF  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
> +INF  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
> +INF  MdeModulePkg/Universal/Disk/RamDiskDxe/RamDiskDxe.inf
> +INF  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
> +INF  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
> +INF  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
> +INF  OvmfPkg/SataControllerDxe/SataControllerDxe.inf
> +INF  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
> +INF  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
> +INF  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
> +INF  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
> +INF  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
> +INF  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
> +INF  MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
> +
> +INF  PcAtChipsetPkg/IsaAcpiDxe/IsaAcpi.inf
> +INF  IntelFrameworkModulePkg/Bus/Isa/IsaBusDxe/IsaBusDxe.inf
> +
> +!ifndef $(SOURCE_DEBUG_ENABLE)
> +INF  IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/IsaSerialDxe.inf
> +!endif
> +
> +INF  IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2keyboardDxe.inf
> +INF  IntelFrameworkModulePkg/Bus/Isa/IsaFloppyDxe/IsaFloppyDxe.inf
> +
> +INF  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
> +INF  OvmfPkg/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
> +
> +INF  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
> +INF  OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
> +INF  RuleOverride=ACPITABLE OvmfPkg/AcpiTables/AcpiTables.inf
> +INF  MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
> +INF  MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf
> +
> +INF  FatPkg/EnhancedFatDxe/Fat.inf
> +
> +!ifndef $(USE_OLD_SHELL)
> +INF  ShellPkg/Application/Shell/Shell.inf
> +!else
> +INF  RuleOverride = BINARY EdkShellBinPkg/FullShell/FullShell.inf
> +!endif
> +
> +INF MdeModulePkg/Logo/LogoDxe.inf
> +
> +#
> +# Network modules
> +#
> +!if $(E1000_ENABLE)
> +  FILE DRIVER = 5D695E11-9B3F-4b83-B25F-4A8D5D69BE07 {
> +    SECTION PE32 = Intel3.5/EFIX64/E3507X2.EFI
> +  }
> +!endif
> +  INF  MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
> +  INF  MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf
> +  INF  MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf
> +  INF  MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf
> +  INF  MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf
> +  INF  MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf
> +  INF  MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf
> +  INF  MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf
> +  INF  MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf
> +!if $(NETWORK_IP6_ENABLE) == TRUE
> +  INF  NetworkPkg/Ip6Dxe/Ip6Dxe.inf
> +  INF  NetworkPkg/TcpDxe/TcpDxe.inf
> +  INF  NetworkPkg/Udp6Dxe/Udp6Dxe.inf
> +  INF  NetworkPkg/Dhcp6Dxe/Dhcp6Dxe.inf
> +  INF  NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
> +  INF  NetworkPkg/UefiPxeBcDxe/UefiPxeBcDxe.inf
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  INF  NetworkPkg/IScsiDxe/IScsiDxe.inf
> +!else
> +  INF  MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
> +!endif
> +!else
> +  INF  MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dxe.inf
> +  INF  MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
> +  INF  MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
> +!endif
> +!if $(HTTP_BOOT_ENABLE) == TRUE
> +  INF  NetworkPkg/DnsDxe/DnsDxe.inf
> +  INF  NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf
> +  INF  NetworkPkg/HttpDxe/HttpDxe.inf
> +  INF  NetworkPkg/HttpBootDxe/HttpBootDxe.inf
> +!endif
> +
> +#
> +# Usb Support
> +#
> +INF  MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf
> +INF  MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
> +INF  MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
> +INF  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
> +INF  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
> +INF  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
> +
> +!ifdef $(CSM_ENABLE)
> +INF  IntelFrameworkModulePkg/Csm/BiosThunk/VideoDxe/VideoDxe.inf
> +INF  IntelFrameworkModulePkg/Csm/LegacyBiosDxe/LegacyBiosDxe.inf
> +INF  RuleOverride=CSM OvmfPkg/Csm/Csm16/Csm16.inf
> +!endif
> +
> +INF  OvmfPkg/QemuVideoDxe/QemuVideoDxe.inf
> +INF  OvmfPkg/PlatformDxe/Platform.inf
> +
> +!if $(SMM_REQUIRE) == TRUE
> +INF  OvmfPkg/SmmAccess/SmmAccess2Dxe.inf
> +INF  OvmfPkg/SmmControl2Dxe/SmmControl2Dxe.inf
> +INF  UefiCpuPkg/CpuS3DataDxe/CpuS3DataDxe.inf
> +INF  MdeModulePkg/Core/PiSmmCore/PiSmmIpl.inf
> +INF  MdeModulePkg/Core/PiSmmCore/PiSmmCore.inf
> +INF  UefiCpuPkg/CpuIo2Smm/CpuIo2Smm.inf
> +INF  MdeModulePkg/Universal/LockBox/SmmLockBox/SmmLockBox.inf
> +INF  UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
> +
> +#
> +# Variable driver stack (SMM)
> +#
> +INF  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesSmm.inf
> +INF  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteSmm.inf
> +INF  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
> +INF  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
> +
> +!else
> +
> +#
> +# Variable driver stack (non-SMM)
> +#
> +INF  OvmfPkg/QemuFlashFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf
> +INF  OvmfPkg/EmuVariableFvbRuntimeDxe/Fvb.inf
> +INF  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
> +INF  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> +!endif
> +
> +################################################################################
> +
> +[FV.FVMAIN_COMPACT]
> +FvNameGuid         = 48DB5E17-707C-472D-91CD-1613E7EF51B0
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +
> +FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
> +   SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
> +     #
> +     # These firmware volumes will have files placed in them uncompressed,
> +     # and then both firmware volumes will be compressed in a single
> +     # compression operation in order to achieve better overall compression.
> +     #
> +     SECTION FV_IMAGE = PEIFV
> +     SECTION FV_IMAGE = DXEFV
> +   }
> + }
> +
> +!include DecomprScratchEnd.fdf.inc
> +
> +################################################################################
> +
> +[Rule.Common.SEC]
> +  FILE SEC = $(NAMED_GUID) {
> +    PE32     PE32           $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI       STRING ="$(MODULE_NAME)" Optional
> +    VERSION  STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.PEI_CORE]
> +  FILE PEI_CORE = $(NAMED_GUID) {
> +    PE32     PE32   Align=Auto    $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI       STRING ="$(MODULE_NAME)" Optional
> +    VERSION  STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.PEIM]
> +  FILE PEIM = $(NAMED_GUID) {
> +     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
> +     PE32      PE32   Align=Auto         $(INF_OUTPUT)/$(MODULE_NAME).efi
> +     UI       STRING="$(MODULE_NAME)" Optional
> +     VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.DXE_CORE]
> +  FILE DXE_CORE = $(NAMED_GUID) {
> +    PE32     PE32           $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI       STRING="$(MODULE_NAME)" Optional
> +    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.DXE_DRIVER]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI       STRING="$(MODULE_NAME)" Optional
> +    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +    RAW ACPI  Optional               |.acpi
> +    RAW ASL   Optional               |.aml
> +  }
> +
> +[Rule.Common.DXE_RUNTIME_DRIVER]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI       STRING="$(MODULE_NAME)" Optional
> +    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.UEFI_DRIVER]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX    DXE_DEPEX Optional      $(INF_OUTPUT)/$(MODULE_NAME).depex
> +    PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI       STRING="$(MODULE_NAME)" Optional
> +    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.UEFI_DRIVER.BINARY]
> +  FILE DRIVER = $(NAMED_GUID) {
> +    DXE_DEPEX DXE_DEPEX Optional      |.depex
> +    PE32      PE32                    |.efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.UEFI_APPLICATION]
> +  FILE APPLICATION = $(NAMED_GUID) {
> +    PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
> +    UI       STRING="$(MODULE_NAME)" Optional
> +    VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.UEFI_APPLICATION.BINARY]
> +  FILE APPLICATION = $(NAMED_GUID) {
> +    PE32      PE32                    |.efi
> +    UI        STRING="$(MODULE_NAME)" Optional
> +    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
> +  }
> +
> +[Rule.Common.USER_DEFINED.ACPITABLE]
> +  FILE FREEFORM = $(NAMED_GUID) {
> +    RAW ACPI               |.acpi
> +    RAW ASL                |.aml
> +  }
> +
> +[Rule.Common.USER_DEFINED.CSM]
> +  FILE FREEFORM = $(NAMED_GUID) {
> +    RAW BIN                |.bin
> +  }
> +
> +[Rule.Common.SEC.RESET_VECTOR]
> +  FILE RAW = $(NAMED_GUID) {
> +    RAW BIN   Align = 16   |.bin
> +  }
> 



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 02/14] OvmfPkg/XenOvmf: Update debug IO port for Xen
  2016-12-08 15:33 ` [PATCH RFC 02/14] OvmfPkg/XenOvmf: Update debug IO port for Xen Anthony PERARD
@ 2017-01-04 19:23   ` Laszlo Ersek
  0 siblings, 0 replies; 37+ messages in thread
From: Laszlo Ersek @ 2017-01-04 19:23 UTC (permalink / raw)
  To: Anthony PERARD, edk2-devel, xen-devel

On 12/08/16 16:33, Anthony PERARD wrote:
> This is a debug IO port that will output directly to the Xen Hypervisor
> console.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>  OvmfPkg/XenOvmf.dsc | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/OvmfPkg/XenOvmf.dsc b/OvmfPkg/XenOvmf.dsc
> index e452eb3..5b3550d 100644
> --- a/OvmfPkg/XenOvmf.dsc
> +++ b/OvmfPkg/XenOvmf.dsc
> @@ -421,6 +421,9 @@
>    # Point to the MdeModulePkg/Application/UiApp/UiApp.inf
>    gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
>  
> +  ## This flag is used to control the destination port for PlatformDebugLibIoPort
> +  gUefiOvmfPkgTokenSpaceGuid.PcdDebugIoPort|0xe9
> +
>  ################################################################################
>  #
>  # Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform
> 

This patch looks good to me:

Reviewed-by: Laszlo Ersek <lersek@redhat.com>

But I ask that in the next posting of the series, please format the
patches with the following settings in effect (specifically, "xfuncname"):

https://github.com/tianocore/tianocore.github.io/wiki/Laszlo's-unkempt-git-guide-for-edk2-contributors-and-maintainers#contrib-05

https://github.com/tianocore/tianocore.github.io/wiki/Laszlo's-unkempt-git-guide-for-edk2-contributors-and-maintainers#contrib-09

They ensure that the @@ hunk header above will explicitly name the the
[PcdsFixedAtBuild] section, which helps quite a bit with reviewing.

Thanks,
Laszlo


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 03/14] OvmfPkg/XenOvmf.dsc: Introduce XenResetVector
  2016-12-08 15:33 ` [PATCH RFC 03/14] OvmfPkg/XenOvmf.dsc: Introduce XenResetVector Anthony PERARD
@ 2017-01-04 19:49   ` Laszlo Ersek
  2017-01-10 15:58     ` Anthony PERARD
  0 siblings, 1 reply; 37+ messages in thread
From: Laszlo Ersek @ 2017-01-04 19:49 UTC (permalink / raw)
  To: Anthony PERARD, edk2-devel, xen-devel

(1) I think the subject line should just say:

  OvmfPkg: Introduce XenResetVector

(2) New files are added in this patch; you might want to tag them with a
Citrix copyright notice.

(3) When formatting the next version of this series for posting, please
pass the "-C --find-copies-harder" options to git-format-patch. Those
will automatically format each patch in the series as a (copy, diff)
pair, whenever appropriate, and that way we can compare the changed
copies more easily against the originals.

On 12/08/16 16:33, Anthony PERARD wrote:
> Copy of OvmfPkg/ResetVector, with one changes:
>   - default_cr0: enable cache

(4) Please mention SEC_DEFAULT_CR0 and the bit that is flipped,
specifically.

> 
> Xen copy the OVMF code to RAM, there is no need for cache. Also, it
> makes OVMF slow to start on AMD.

(5) Wait, is the slow start already an issue (with QEMU/KVM) on AMD?
Because, in the past, we saw that happen: refer to commit 98f378a7be12.

Are you saying 98f378a7be12 was not entirely right for QEMU/KVM
(considering recent AMD processors, I guess?)?

Or that the SEC_DEFAULT_CR0 value is not right on AMD only with Xen?

> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>  OvmfPkg/XenOvmf.dsc                            |   2 +-
>  OvmfPkg/XenOvmf.fdf                            |   2 +-
>  OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm | 133 +++++++++++++++++++++++++
>  OvmfPkg/XenResetVector/Ia32/PageTables64.asm   |  93 +++++++++++++++++
>  OvmfPkg/XenResetVector/XenResetVector.inf      |  37 +++++++
>  OvmfPkg/XenResetVector/XenResetVector.nasmb    |  66 ++++++++++++
>  6 files changed, 331 insertions(+), 2 deletions(-)
>  create mode 100644 OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
>  create mode 100644 OvmfPkg/XenResetVector/Ia32/PageTables64.asm
>  create mode 100644 OvmfPkg/XenResetVector/XenResetVector.inf
>  create mode 100644 OvmfPkg/XenResetVector/XenResetVector.nasmb
> 
> diff --git a/OvmfPkg/XenOvmf.dsc b/OvmfPkg/XenOvmf.dsc
> index 5b3550d..0a7ea21 100644
> --- a/OvmfPkg/XenOvmf.dsc
> +++ b/OvmfPkg/XenOvmf.dsc
> @@ -471,7 +471,7 @@
>  #
>  ################################################################################
>  [Components]
> -  OvmfPkg/ResetVector/ResetVector.inf
> +  OvmfPkg/XenResetVector/XenResetVector.inf
>  
>    #
>    # SEC Phase modules
> diff --git a/OvmfPkg/XenOvmf.fdf b/OvmfPkg/XenOvmf.fdf
> index d01454e..f4609b0 100644
> --- a/OvmfPkg/XenOvmf.fdf
> +++ b/OvmfPkg/XenOvmf.fdf
> @@ -123,7 +123,7 @@ READ_LOCK_STATUS   = TRUE
>  #
>  INF  OvmfPkg/Sec/SecMain.inf
>  
> -INF  RuleOverride=RESET_VECTOR OvmfPkg/ResetVector/ResetVector.inf
> +INF  RuleOverride=RESET_VECTOR OvmfPkg/XenResetVector/XenResetVector.inf
>  
>  ################################################################################
>  [FV.PEIFV]
> diff --git a/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm b/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
> new file mode 100644
> index 0000000..d746427
> --- /dev/null
> +++ b/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
> @@ -0,0 +1,133 @@
> +;------------------------------------------------------------------------------
> +; @file
> +; Transition from 16 bit real mode into 32 bit flat protected mode
> +;
> +; Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
> +; This program and the accompanying materials
> +; are licensed and made available under the terms and conditions of the BSD License
> +; which accompanies this distribution.  The full text of the license may be found at
> +; http://opensource.org/licenses/bsd-license.php
> +;
> +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +;
> +;------------------------------------------------------------------------------
> +
> +%define SEC_DEFAULT_CR0  0x00000023
> +%define SEC_DEFAULT_CR4  0x640
> +
> +BITS    16
> +
> +;
> +; Modified:  EAX, EBX
> +;
> +TransitionFromReal16To32BitFlat:
> +
> +    debugShowPostCode POSTCODE_16BIT_MODE
> +
> +    cli
> +
> +    mov     bx, 0xf000
> +    mov     ds, bx
> +
> +    mov     bx, ADDR16_OF(gdtr)
> +
> +o32 lgdt    [cs:bx]
> +
> +    mov     eax, SEC_DEFAULT_CR0
> +    mov     cr0, eax
> +
> +    jmp     LINEAR_CODE_SEL:dword ADDR_OF(jumpTo32BitAndLandHere)
> +BITS    32
> +jumpTo32BitAndLandHere:
> +
> +    mov     eax, SEC_DEFAULT_CR4
> +    mov     cr4, eax
> +
> +    debugShowPostCode POSTCODE_32BIT_MODE
> +
> +    mov     ax, LINEAR_SEL
> +    mov     ds, ax
> +    mov     es, ax
> +    mov     fs, ax
> +    mov     gs, ax
> +    mov     ss, ax
> +
> +    OneTimeCallRet TransitionFromReal16To32BitFlat
> +
> +ALIGN   2
> +
> +gdtr:
> +    dw      GDT_END - GDT_BASE - 1   ; GDT limit
> +    dd      ADDR_OF(GDT_BASE)
> +
> +ALIGN   16
> +
> +;
> +; Macros for GDT entries
> +;
> +
> +%define  PRESENT_FLAG(p) (p << 7)
> +%define  DPL(dpl) (dpl << 5)
> +%define  SYSTEM_FLAG(s) (s << 4)
> +%define  DESC_TYPE(t) (t)
> +
> +; Type: data, expand-up, writable, accessed
> +%define  DATA32_TYPE 3
> +
> +; Type: execute, readable, expand-up, accessed
> +%define  CODE32_TYPE 0xb
> +
> +; Type: execute, readable, expand-up, accessed
> +%define  CODE64_TYPE 0xb
> +
> +%define  GRANULARITY_FLAG(g) (g << 7)
> +%define  DEFAULT_SIZE32(d) (d << 6)
> +%define  CODE64_FLAG(l) (l << 5)
> +%define  UPPER_LIMIT(l) (l)
> +
> +;
> +; The Global Descriptor Table (GDT)
> +;
> +
> +GDT_BASE:
> +; null descriptor
> +NULL_SEL            equ $-GDT_BASE
> +    DW      0            ; limit 15:0
> +    DW      0            ; base 15:0
> +    DB      0            ; base 23:16
> +    DB      0            ; sys flag, dpl, type
> +    DB      0            ; limit 19:16, flags
> +    DB      0            ; base 31:24
> +
> +; linear data segment descriptor
> +LINEAR_SEL          equ $-GDT_BASE
> +    DW      0xffff       ; limit 15:0
> +    DW      0            ; base 15:0
> +    DB      0            ; base 23:16
> +    DB      PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(DATA32_TYPE)
> +    DB      GRANULARITY_FLAG(1)|DEFAULT_SIZE32(1)|CODE64_FLAG(0)|UPPER_LIMIT(0xf)
> +    DB      0            ; base 31:24
> +
> +; linear code segment descriptor
> +LINEAR_CODE_SEL     equ $-GDT_BASE
> +    DW      0xffff       ; limit 15:0
> +    DW      0            ; base 15:0
> +    DB      0            ; base 23:16
> +    DB      PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(CODE32_TYPE)
> +    DB      GRANULARITY_FLAG(1)|DEFAULT_SIZE32(1)|CODE64_FLAG(0)|UPPER_LIMIT(0xf)
> +    DB      0            ; base 31:24
> +
> +%ifdef ARCH_X64
> +; linear code (64-bit) segment descriptor
> +LINEAR_CODE64_SEL   equ $-GDT_BASE
> +    DW      0xffff       ; limit 15:0
> +    DW      0            ; base 15:0
> +    DB      0            ; base 23:16
> +    DB      PRESENT_FLAG(1)|DPL(0)|SYSTEM_FLAG(1)|DESC_TYPE(CODE64_TYPE)
> +    DB      GRANULARITY_FLAG(1)|DEFAULT_SIZE32(0)|CODE64_FLAG(1)|UPPER_LIMIT(0xf)
> +    DB      0            ; base 31:24
> +%endif
> +
> +GDT_END:
> +
> diff --git a/OvmfPkg/XenResetVector/Ia32/PageTables64.asm b/OvmfPkg/XenResetVector/Ia32/PageTables64.asm
> new file mode 100644
> index 0000000..b5a4cf8
> --- /dev/null
> +++ b/OvmfPkg/XenResetVector/Ia32/PageTables64.asm
> @@ -0,0 +1,93 @@
> +;------------------------------------------------------------------------------
> +; @file
> +; Sets the CR3 register for 64-bit paging
> +;
> +; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
> +; This program and the accompanying materials
> +; are licensed and made available under the terms and conditions of the BSD License
> +; which accompanies this distribution.  The full text of the license may be found at
> +; http://opensource.org/licenses/bsd-license.php
> +;
> +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +;
> +;------------------------------------------------------------------------------
> +
> +BITS    32
> +
> +%define PAGE_PRESENT            0x01
> +%define PAGE_READ_WRITE         0x02
> +%define PAGE_USER_SUPERVISOR    0x04
> +%define PAGE_WRITE_THROUGH      0x08
> +%define PAGE_CACHE_DISABLE     0x010
> +%define PAGE_ACCESSED          0x020
> +%define PAGE_DIRTY             0x040
> +%define PAGE_PAT               0x080
> +%define PAGE_GLOBAL           0x0100
> +%define PAGE_2M_MBO            0x080
> +%define PAGE_2M_PAT          0x01000
> +
> +%define PAGE_2M_PDE_ATTR (PAGE_2M_MBO + \
> +                          PAGE_ACCESSED + \
> +                          PAGE_DIRTY + \
> +                          PAGE_READ_WRITE + \
> +                          PAGE_PRESENT)
> +
> +%define PAGE_PDP_ATTR (PAGE_ACCESSED + \
> +                       PAGE_READ_WRITE + \
> +                       PAGE_PRESENT)
> +
> +
> +;
> +; Modified:  EAX, ECX
> +;
> +SetCr3ForPageTables64:
> +
> +    ;
> +    ; For OVMF, build some initial page tables at 0x800000-0x806000.

(6) Are you intentionally undoing, in the copy, commit 73d66c5871cc? If
so, why?

For now I suspect that you originally created this patch before commit
73d66c5871cc came into existence. If that's the case, then please rebase
(re-copy and customize) this patch to the most recent ResetVector state,
including commit 73d66c5871cc.

> +    ;
> +    ; This range should match with PcdOvmfSecPageTablesBase and
> +    ; PcdOvmfSecPageTablesSize which are declared in the FDF files.
> +    ;
> +    ; At the end of PEI, the pages tables will be rebuilt into a
> +    ; more permanent location by DxeIpl.
> +    ;
> +
> +    mov     ecx, 6 * 0x1000 / 4
> +    xor     eax, eax
> +clearPageTablesMemoryLoop:
> +    mov     dword[ecx * 4 + 0x800000 - 4], eax
> +    loop    clearPageTablesMemoryLoop
> +
> +    ;
> +    ; Top level Page Directory Pointers (1 * 512GB entry)
> +    ;
> +    mov     dword[0x800000], 0x801000 + PAGE_PDP_ATTR
> +
> +    ;
> +    ; Next level Page Directory Pointers (4 * 1GB entries => 4GB)
> +    ;
> +    mov     dword[0x801000], 0x802000 + PAGE_PDP_ATTR
> +    mov     dword[0x801008], 0x803000 + PAGE_PDP_ATTR
> +    mov     dword[0x801010], 0x804000 + PAGE_PDP_ATTR
> +    mov     dword[0x801018], 0x805000 + PAGE_PDP_ATTR
> +
> +    ;
> +    ; Page Table Entries (2048 * 2MB entries => 4GB)
> +    ;
> +    mov     ecx, 0x800
> +pageTableEntriesLoop:
> +    mov     eax, ecx
> +    dec     eax
> +    shl     eax, 21
> +    add     eax, PAGE_2M_PDE_ATTR
> +    mov     [ecx * 8 + 0x802000 - 8], eax
> +    loop    pageTableEntriesLoop
> +
> +    ;
> +    ; Set CR3 now that the paging structures are available
> +    ;
> +    mov     eax, 0x800000
> +    mov     cr3, eax
> +
> +    OneTimeCallRet SetCr3ForPageTables64
> diff --git a/OvmfPkg/XenResetVector/XenResetVector.inf b/OvmfPkg/XenResetVector/XenResetVector.inf
> new file mode 100644
> index 0000000..ebfab12
> --- /dev/null
> +++ b/OvmfPkg/XenResetVector/XenResetVector.inf
> @@ -0,0 +1,37 @@
> +## @file
> +#  Reset Vector
> +#
> +#  Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
> +#
> +#  This program and the accompanying materials
> +#  are licensed and made available under the terms and conditions of the BSD License
> +#  which accompanies this distribution. The full text of the license may be found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = XenResetVector
> +  FILE_GUID                      = 1BA0062E-C779-4582-8566-336AE8F78F09

This FILE_GUID was not changed, but for the reset vector, that's
actually the right thing to do -- this FILE_GUID is special. So it's OK.

Thanks
Laszlo

> +  MODULE_TYPE                    = SEC
> +  VERSION_STRING                 = 1.1
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources]
> +  XenResetVector.nasmb
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  UefiCpuPkg/UefiCpuPkg.dec
> +
> +[BuildOptions]
> +   *_*_IA32_NASMB_FLAGS = -I$(WORKSPACE)/UefiCpuPkg/ResetVector/Vtf0/
> +   *_*_X64_NASMB_FLAGS = -I$(WORKSPACE)/UefiCpuPkg/ResetVector/Vtf0/
> diff --git a/OvmfPkg/XenResetVector/XenResetVector.nasmb b/OvmfPkg/XenResetVector/XenResetVector.nasmb
> new file mode 100644
> index 0000000..31ac06a
> --- /dev/null
> +++ b/OvmfPkg/XenResetVector/XenResetVector.nasmb
> @@ -0,0 +1,66 @@
> +;------------------------------------------------------------------------------
> +; @file
> +; This file includes all other code files to assemble the reset vector code
> +;
> +; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
> +; This program and the accompanying materials
> +; are licensed and made available under the terms and conditions of the BSD License
> +; which accompanies this distribution.  The full text of the license may be found at
> +; http://opensource.org/licenses/bsd-license.php
> +;
> +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +;
> +;------------------------------------------------------------------------------
> +
> +;
> +; If neither ARCH_IA32 nor ARCH_X64 are defined, then try to include
> +; Base.h to use the C pre-processor to determine the architecture.
> +;
> +%ifndef ARCH_IA32
> +  %ifndef ARCH_X64
> +    #include <Base.h>
> +    #if defined (MDE_CPU_IA32)
> +      %define ARCH_IA32
> +    #elif defined (MDE_CPU_X64)
> +      %define ARCH_X64
> +    #endif
> +  %endif
> +%endif
> +
> +%ifdef ARCH_IA32
> +  %ifdef ARCH_X64
> +    %error "Only one of ARCH_IA32 or ARCH_X64 can be defined."
> +  %endif
> +%elifdef ARCH_X64
> +%else
> +  %error "Either ARCH_IA32 or ARCH_X64 must be defined."
> +%endif
> +
> +%include "CommonMacros.inc"
> +
> +%include "PostCodes.inc"
> +
> +%ifdef DEBUG_PORT80
> +  %include "Port80Debug.asm"
> +%elifdef DEBUG_SERIAL
> +  %include "SerialDebug.asm"
> +%else
> +  %include "DebugDisabled.asm"
> +%endif
> +
> +%include "Ia32/SearchForBfvBase.asm"
> +%include "Ia32/SearchForSecEntry.asm"
> +
> +%ifdef ARCH_X64
> +%include "Ia32/Flat32ToFlat64.asm"
> +%include "Ia32/PageTables64.asm"
> +%endif
> +
> +%include "Ia16/Real16ToFlat32.asm"
> +%include "Ia16/Init16.asm"
> +
> +%include "Main.asm"
> +
> +%include "Ia16/ResetVectorVtf0.asm"
> +
> 



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests
  2016-12-08 15:33 [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
                   ` (13 preceding siblings ...)
  2016-12-08 15:33 ` [PATCH RFC 14/14] XenOvmf: Use a different RTC Anthony PERARD
@ 2017-01-04 19:52 ` Laszlo Ersek
  2017-01-10 14:55   ` Anthony PERARD
  14 siblings, 1 reply; 37+ messages in thread
From: Laszlo Ersek @ 2017-01-04 19:52 UTC (permalink / raw)
  To: Anthony PERARD, edk2-devel, xen-devel

On 12/08/16 16:33, Anthony PERARD wrote:
> Hi,
> 
> I've started to create a Xen specifig plaform, in OvmfPkg/XenOvmf.dsc
> with the goal to make it work on both Xen HVM and Xen PVHv2

Does this mean we can ultimately move all Xen roles from the current
platform DSC files to the new Xen DSC file entirely?

If so (which I think I would like), then for each module M that exhibits
all of the following properties:
- M is dynamically customized to Xen vs. QEMU,
- M is replaced by a dedicated module M' in the Xen DSC,
I think we should also remove the Xen-specific code from the original M
(as last step, likely in separate patches).

In addition, Xen platform specific device drivers should be removed as
well from the original DSC files.

What do you think?

> The first few patches only create the platform and duplicate some code from
> OvmfPkg and the later patches (from OvmfPkg/XenPlatformPei: Add xen PVH
> specific code) makes OVMF boot in a Xen PVH guest, and can boot a Linux.
> 
> == Part 1: XenOvmf.dsc
> 
> - OvmfPkg: Create platform XenOvmf
> which for now remove virtio drivers and some SMM
> 
> - OvmfPkg/XenOvmf: Update debug IO port for Xen
> 
> - OvmfPkg/XenOvmf.dsc: Introduce XenResetVector
> Just for one change, enable cache in CR0 as on Xen, OVMF run from RAM, that
> disabling cache can make OVMF very slow.
> 

... I might reply to this email again (the remaining stuff), as I
progress with the review.

Thanks
Laszlo

> - OvmfPkg: Introduce XenPlatformPei
> remove some QEMU/KVM specific code from PlatformPei.
> 
> - OvmfPkg/Library: add XenPciHostBridgeLib
> same with PciHostBridgeLib
> 
> == Part 2: PVH enabled
> 
> - OvmfPkg/XenPlatformPei: Add xen PVH specific code
> To figure out the memory size from E820
> 
> - OvmfPkg/XenResetVector: Add new entry point for Xen PVH
> which is in 32bits
> 
> - OvmfPkg/PlatformBootManagerLib: Workaround missing PCI bus on Xen PVH
> to avoid the Unknown Host Bridge Device ID error
> 
> - OvmfPkg/ResetSystemLib: Add missing dependency on PciLib
> - UefiCpuPkg/BaseXApicX2ApicLib: Fix initialisation on my system and ...
> - OvmfPkg/XenOvmf: Adding XenTimerLocalApic
> to replace the ACPI timer
> 
> - OvmfPkg/PlatformBootManagerLib: Use a Xen console for ConOut/ConIn
> - OvmfPkg: Introduce XenIoPvhDxe to initialize Grant Tables
> - XenOvmf: Use a different RTC
> which does always return the same value
> 
> == to build and boot
> 
> To build, simply run OvmfPkg/build.sh -p OvmfPkg/XenOvmf.dsc
> 
> To run, I currently use a loader, base on hvmloader which does some setup, read
> the e820 and copy ovmf to the right place to start it.
> 
> The loader is avaible in branch `ovmf-pvhloader' from
> https://xenbits.xen.org/git-http/people/aperard/xen-unstable.git
> 
> And the guest I'm using:
> builder = 'hvm'
> memory = 512
> name = "pvh-ovmf"
> kernel = 'pvh-ovmf-loader'
> ramdisk='OVMF.fd'
> extra='ovmf=1'
> disk = [ 'file:iso/archlinux-2016.10.01-dual.iso,hdc:cdrom,r', ]
> device_model_version = 'none'
> serial = 'pty'
> 
> Anthony PERARD (14):
>   OvmfPkg: Create platform XenOvmf
>   OvmfPkg/XenOvmf: Update debug IO port for Xen
>   OvmfPkg/XenOvmf.dsc: Introduce XenResetVector
>   OvmfPkg: Introduce XenPlatformPei
>   OvmfPkg/Library: add XenPciHostBridgeLib
>   OvmfPkg/XenPlatformPei: Add xen PVH specific code
>   OvmfPkg/XenResetVector: Add new entry point for Xen PVH
>   OvmfPkg/PlatformBootManagerLib: Workaround missing PCI bus on Xen PVH
>   OvmfPkg/ResetSystemLib: Add missing dependency on PciLib
>   UefiCpuPkg/BaseXApicX2ApicLib: Fix initialisation on my system and ...
>   OvmfPkg/XenOvmf: Adding XenTimerLocalApic
>   OvmfPkg/PlatformBootManagerLib: Use a Xen console for ConOut/ConIn
>   OvmfPkg: Introduce XenIoPvhDxe to initialize Grant Tables
>   XenOvmf: Use a different RTC
> 
>  .../Library/PlatformBootManagerLib/BdsPlatform.c   |  35 +
>  .../PlatformBootManagerLib.inf                     |   2 +
>  OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf  |   1 +
>  .../Library/XenPciHostBridgeLib/XenPciHostBridge.h |  75 ++
>  .../XenPciHostBridgeLib/XenPciHostBridgeLib.c      | 291 ++++++++
>  .../XenPciHostBridgeLib/XenPciHostBridgeLib.inf    |  58 ++
>  OvmfPkg/Library/XenPciHostBridgeLib/XenSupport.c   | 456 ++++++++++++
>  OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c                  | 263 +++++++
>  OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf                |  45 ++
>  OvmfPkg/XenOvmf.dsc                                | 809 +++++++++++++++++++++
>  OvmfPkg/XenOvmf.fdf                                | 506 +++++++++++++
>  OvmfPkg/XenPlatformPei/Cmos.c                      |  64 ++
>  OvmfPkg/XenPlatformPei/Cmos.h                      |  56 ++
>  OvmfPkg/XenPlatformPei/Fv.c                        | 100 +++
>  OvmfPkg/XenPlatformPei/MemDetect.c                 | 520 +++++++++++++
>  OvmfPkg/XenPlatformPei/Platform.c                  | 541 ++++++++++++++
>  OvmfPkg/XenPlatformPei/Platform.h                  | 114 +++
>  OvmfPkg/XenPlatformPei/Xen.c                       | 231 ++++++
>  OvmfPkg/XenPlatformPei/Xen.h                       |  45 ++
>  OvmfPkg/XenPlatformPei/XenPlatformPei.inf          | 110 +++
>  OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm     | 133 ++++
>  OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm    |  79 ++
>  OvmfPkg/XenResetVector/Ia32/PageTables64.asm       |  93 +++
>  OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm         |  23 +
>  OvmfPkg/XenResetVector/XenResetVector.inf          |  37 +
>  OvmfPkg/XenResetVector/XenResetVector.nasmb        |  67 ++
>  OvmfPkg/XenTimerLocalApic/Timer.h                  | 191 +++++
>  OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.c      | 386 ++++++++++
>  OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.inf    |  51 ++
>  UefiCpuPkg/Include/Library/LocalApicLib.h          |  40 +
>  .../BaseXApicX2ApicLib/BaseXApicX2ApicLib.c        |  10 +-
>  31 files changed, 5427 insertions(+), 5 deletions(-)
>  create mode 100644 OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridge.h
>  create mode 100644 OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridgeLib.c
>  create mode 100644 OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridgeLib.inf
>  create mode 100644 OvmfPkg/Library/XenPciHostBridgeLib/XenSupport.c
>  create mode 100644 OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c
>  create mode 100644 OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
>  create mode 100644 OvmfPkg/XenOvmf.dsc
>  create mode 100644 OvmfPkg/XenOvmf.fdf
>  create mode 100644 OvmfPkg/XenPlatformPei/Cmos.c
>  create mode 100644 OvmfPkg/XenPlatformPei/Cmos.h
>  create mode 100644 OvmfPkg/XenPlatformPei/Fv.c
>  create mode 100644 OvmfPkg/XenPlatformPei/MemDetect.c
>  create mode 100644 OvmfPkg/XenPlatformPei/Platform.c
>  create mode 100644 OvmfPkg/XenPlatformPei/Platform.h
>  create mode 100644 OvmfPkg/XenPlatformPei/Xen.c
>  create mode 100644 OvmfPkg/XenPlatformPei/Xen.h
>  create mode 100644 OvmfPkg/XenPlatformPei/XenPlatformPei.inf
>  create mode 100644 OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
>  create mode 100644 OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
>  create mode 100644 OvmfPkg/XenResetVector/Ia32/PageTables64.asm
>  create mode 100644 OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
>  create mode 100644 OvmfPkg/XenResetVector/XenResetVector.inf
>  create mode 100644 OvmfPkg/XenResetVector/XenResetVector.nasmb
>  create mode 100644 OvmfPkg/XenTimerLocalApic/Timer.h
>  create mode 100644 OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.c
>  create mode 100644 OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.inf
> 



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 04/14] OvmfPkg: Introduce XenPlatformPei
  2016-12-08 15:33 ` [PATCH RFC 04/14] OvmfPkg: Introduce XenPlatformPei Anthony PERARD
@ 2017-01-05  9:59   ` Laszlo Ersek
  2017-01-10 16:08     ` Anthony PERARD
  0 siblings, 1 reply; 37+ messages in thread
From: Laszlo Ersek @ 2017-01-05  9:59 UTC (permalink / raw)
  To: Anthony PERARD, edk2-devel, xen-devel

On 12/08/16 16:33, Anthony PERARD wrote:
> A copy of OvmfPkg/PlatformPei without some of QEMU specific
> initialization, Xen does not support QemuFwCfg.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>  OvmfPkg/XenOvmf.dsc                       |   2 +-
>  OvmfPkg/XenOvmf.fdf                       |   2 +-
>  OvmfPkg/XenPlatformPei/Cmos.c             |  64 ++++
>  OvmfPkg/XenPlatformPei/Cmos.h             |  56 ++++
>  OvmfPkg/XenPlatformPei/Fv.c               | 100 ++++++
>  OvmfPkg/XenPlatformPei/MemDetect.c        | 449 +++++++++++++++++++++++++
>  OvmfPkg/XenPlatformPei/Platform.c         | 536 ++++++++++++++++++++++++++++++
>  OvmfPkg/XenPlatformPei/Platform.h         | 104 ++++++
>  OvmfPkg/XenPlatformPei/Xen.c              | 231 +++++++++++++
>  OvmfPkg/XenPlatformPei/Xen.h              |  45 +++
>  OvmfPkg/XenPlatformPei/XenPlatformPei.inf | 110 ++++++
>  11 files changed, 1697 insertions(+), 2 deletions(-)
>  create mode 100644 OvmfPkg/XenPlatformPei/Cmos.c
>  create mode 100644 OvmfPkg/XenPlatformPei/Cmos.h
>  create mode 100644 OvmfPkg/XenPlatformPei/Fv.c
>  create mode 100644 OvmfPkg/XenPlatformPei/MemDetect.c
>  create mode 100644 OvmfPkg/XenPlatformPei/Platform.c
>  create mode 100644 OvmfPkg/XenPlatformPei/Platform.h
>  create mode 100644 OvmfPkg/XenPlatformPei/Xen.c
>  create mode 100644 OvmfPkg/XenPlatformPei/Xen.h
>  create mode 100644 OvmfPkg/XenPlatformPei/XenPlatformPei.inf

(1) You might want to add Citrix copyright notices to new files.

(2) This module is a good example where the moved Xen functionality
(even for HVM guests) should be possible to remove from the original
PlatformPei module. (In a later, final patch.) Is that right?

(3) In the commit message, please list the removed fw_cfg-dependent
functionality in more detail (all of which is dynamically skipped when
the current PlatformPei module runs on Xen):

- GetFirstNonAddress(): controlling the 64-bit PCI MMIO aperture via the
(experimental) "opt/ovmf/X-PciMmio64Mb" file

- GetFirstNonAddress(): honoring the hotplug DIMM area
("etc/reserved-memory-end") in the placement of the 64-bit PCI MMIO aperture

- NoexecDxeInitialization() is removed, so PcdPropertiesTableEnable and
PcdSetNxForStack are left constant FALSE (not set dynamically from
"opt/ovmf/PcdXxxx")

- MaxCpuCountInitialization(), PublishPeiMemory(): the max CPU count is
not taken from the QemuFwCfgItemSmpCpuCount fw_cfg key;
PcdCpuMaxLogicalProcessorNumber is used intact and
PcdCpuApInitTimeOutInMicroSeconds is never changed or used.

- InitializeXenPlatform(), S3Verification(): S3 is assumed disabled (not
consulting "etc/system-states" via QemuFwCfgS3Enabled()).

- InstallFeatureControlCallback(): the feature control MSR is not set
from "etc/msr_feature_control"

Also removed:
-  SMRAM/TSEG-related low mem size adjusting (PcdSmmSmramRequire is
assumed FALSE) in PublishPeiMemory(),
- QemuInitializeRam() entirely,

(4) I think the removal of PcdSmmSmramRequire is incomplete. IMO this
PCD should either be removed completely (all uses, including the INF
reference), assuming a FALSE value in its place, or the PCD should not
be touched at all. The FeaturePcdGet() call in PublishPeiMemory() --
gating the "TSEG is chipped from the end of low RAM" stuff -- seems to
be singled out for removal for no good reason.

(5) It would be nice to hint at the reason (which is implemented in a
later patch) why a separate module is a good idea here. That is, why the
expected PVH2 functionality is best not added to the current PlatformPei
module.

Thanks
Laszlo

> 
> diff --git a/OvmfPkg/XenOvmf.dsc b/OvmfPkg/XenOvmf.dsc
> index 0a7ea21..ef32c33 100644
> --- a/OvmfPkg/XenOvmf.dsc
> +++ b/OvmfPkg/XenOvmf.dsc
> @@ -496,7 +496,7 @@
>        PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
>    }
>  
> -  OvmfPkg/PlatformPei/PlatformPei.inf {
> +  OvmfPkg/XenPlatformPei/XenPlatformPei.inf {
>      <LibraryClasses>
>        PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
>    }
> diff --git a/OvmfPkg/XenOvmf.fdf b/OvmfPkg/XenOvmf.fdf
> index f4609b0..c211f61 100644
> --- a/OvmfPkg/XenOvmf.fdf
> +++ b/OvmfPkg/XenOvmf.fdf
> @@ -157,7 +157,7 @@ INF  MdeModulePkg/Core/Pei/PeiMain.inf
>  INF  MdeModulePkg/Universal/PCD/Pei/Pcd.inf
>  INF  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
>  INF  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
> -INF  OvmfPkg/PlatformPei/PlatformPei.inf
> +INF  OvmfPkg/XenPlatformPei/XenPlatformPei.inf
>  INF  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
>  INF  UefiCpuPkg/Universal/Acpi/S3Resume2Pei/S3Resume2Pei.inf
>  !if $(SMM_REQUIRE) == TRUE
> diff --git a/OvmfPkg/XenPlatformPei/Cmos.c b/OvmfPkg/XenPlatformPei/Cmos.c
> new file mode 100644
> index 0000000..48ed2cb
> --- /dev/null
> +++ b/OvmfPkg/XenPlatformPei/Cmos.c
> @@ -0,0 +1,64 @@
> +/** @file
> +  PC/AT CMOS access routines
> +
> +  Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
> +  This program and the accompanying materials
> +  are licensed and made available under the terms and conditions of the BSD License
> +  which accompanies this distribution.  The full text of the license may be found at
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +
> +#include "Cmos.h"
> +#include "Library/IoLib.h"
> +
> +/**
> +  Reads 8-bits of CMOS data.
> +
> +  Reads the 8-bits of CMOS data at the location specified by Index.
> +  The 8-bit read value is returned.
> +
> +  @param  Index  The CMOS location to read.
> +
> +  @return The value read.
> +
> +**/
> +UINT8
> +EFIAPI
> +CmosRead8 (
> +  IN      UINTN                     Index
> +  )
> +{
> +  IoWrite8 (0x70, (UINT8) Index);
> +  return IoRead8 (0x71);
> +}
> +
> +
> +/**
> +  Writes 8-bits of CMOS data.
> +
> +  Writes 8-bits of CMOS data to the location specified by Index
> +  with the value specified by Value and returns Value.
> +
> +  @param  Index  The CMOS location to write.
> +  @param  Value  The value to write to CMOS.
> +
> +  @return The value written to CMOS.
> +
> +**/
> +UINT8
> +EFIAPI
> +CmosWrite8 (
> +  IN      UINTN                     Index,
> +  IN      UINT8                     Value
> +  )
> +{
> +  IoWrite8 (0x70, (UINT8) Index);
> +  IoWrite8 (0x71, Value);
> +  return Value;
> +}
> +
> diff --git a/OvmfPkg/XenPlatformPei/Cmos.h b/OvmfPkg/XenPlatformPei/Cmos.h
> new file mode 100644
> index 0000000..949f884
> --- /dev/null
> +++ b/OvmfPkg/XenPlatformPei/Cmos.h
> @@ -0,0 +1,56 @@
> +/** @file
> +  PC/AT CMOS access routines
> +
> +  Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
> +  This program and the accompanying materials
> +  are licensed and made available under the terms and conditions of the BSD License
> +  which accompanies this distribution.  The full text of the license may be found at
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef __CMOS_H__
> +#define __CMOS_H__
> +
> +/**
> +  Reads 8-bits of CMOS data.
> +
> +  Reads the 8-bits of CMOS data at the location specified by Index.
> +  The 8-bit read value is returned.
> +
> +  @param  Index  The CMOS location to read.
> +
> +  @return The value read.
> +
> +**/
> +UINT8
> +EFIAPI
> +CmosRead8 (
> +  IN      UINTN                     Index
> +  );
> +
> +/**
> +  Writes 8-bits of CMOS data.
> +
> +  Writes 8-bits of CMOS data to the location specified by Index
> +  with the value specified by Value and returns Value.
> +
> +  @param  Index  The CMOS location to write.
> +  @param  Value  The value to write to CMOS.
> +
> +  @return The value written to CMOS.
> +
> +**/
> +UINT8
> +EFIAPI
> +CmosWrite8 (
> +  IN      UINTN                     Index,
> +  IN      UINT8                     Value
> +  );
> +
> +
> +#endif
> +
> diff --git a/OvmfPkg/XenPlatformPei/Fv.c b/OvmfPkg/XenPlatformPei/Fv.c
> new file mode 100644
> index 0000000..248c585
> --- /dev/null
> +++ b/OvmfPkg/XenPlatformPei/Fv.c
> @@ -0,0 +1,100 @@
> +/** @file
> +  Build FV related hobs for platform.
> +
> +  Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
> +  This program and the accompanying materials
> +  are licensed and made available under the terms and conditions of the BSD License
> +  which accompanies this distribution.  The full text of the license may be found at
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "PiPei.h"
> +#include "Platform.h"
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PcdLib.h>
> +
> +
> +/**
> +  Publish PEI & DXE (Decompressed) Memory based FVs to let PEI
> +  and DXE know about them.
> +
> +  @retval EFI_SUCCESS   Platform PEI FVs were initialized successfully.
> +
> +**/
> +EFI_STATUS
> +PeiFvInitialization (
> +  VOID
> +  )
> +{
> +  BOOLEAN SecureS3Needed;
> +
> +  DEBUG ((EFI_D_INFO, "Platform PEI Firmware Volume Initialization\n"));
> +
> +  //
> +  // Create a memory allocation HOB for the PEI FV.
> +  //
> +  // Allocate as ACPI NVS is S3 is supported
> +  //
> +  BuildMemoryAllocationHob (
> +    PcdGet32 (PcdOvmfPeiMemFvBase),
> +    PcdGet32 (PcdOvmfPeiMemFvSize),
> +    mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
> +    );
> +
> +  //
> +  // Let DXE know about the DXE FV
> +  //
> +  BuildFvHob (PcdGet32 (PcdOvmfDxeMemFvBase), PcdGet32 (PcdOvmfDxeMemFvSize));
> +
> +  SecureS3Needed = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire);
> +
> +  //
> +  // Create a memory allocation HOB for the DXE FV.
> +  //
> +  // If "secure" S3 is needed, then SEC will decompress both PEI and DXE
> +  // firmware volumes at S3 resume too, hence we need to keep away the OS from
> +  // DXEFV as well. Otherwise we only need to keep away DXE itself from the
> +  // DXEFV area.
> +  //
> +  BuildMemoryAllocationHob (
> +    PcdGet32 (PcdOvmfDxeMemFvBase),
> +    PcdGet32 (PcdOvmfDxeMemFvSize),
> +    SecureS3Needed ? EfiACPIMemoryNVS : EfiBootServicesData
> +    );
> +
> +  //
> +  // Additionally, said decompression will use temporary memory above the end
> +  // of DXEFV, so let's keep away the OS from there too.
> +  //
> +  if (SecureS3Needed) {
> +    UINT32 DxeMemFvEnd;
> +
> +    DxeMemFvEnd = PcdGet32 (PcdOvmfDxeMemFvBase) +
> +                  PcdGet32 (PcdOvmfDxeMemFvSize);
> +    BuildMemoryAllocationHob (
> +      DxeMemFvEnd,
> +      PcdGet32 (PcdOvmfDecompressionScratchEnd) - DxeMemFvEnd,
> +      EfiACPIMemoryNVS
> +      );
> +  }
> +
> +  //
> +  // Let PEI know about the DXE FV so it can find the DXE Core
> +  //
> +  PeiServicesInstallFvInfoPpi (
> +    NULL,
> +    (VOID *)(UINTN) PcdGet32 (PcdOvmfDxeMemFvBase),
> +    PcdGet32 (PcdOvmfDxeMemFvSize),
> +    NULL,
> +    NULL
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git a/OvmfPkg/XenPlatformPei/MemDetect.c b/OvmfPkg/XenPlatformPei/MemDetect.c
> new file mode 100644
> index 0000000..4ecdf5e
> --- /dev/null
> +++ b/OvmfPkg/XenPlatformPei/MemDetect.c
> @@ -0,0 +1,449 @@
> +/**@file
> +  Memory Detection for Virtual Machines.
> +
> +  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
> +  This program and the accompanying materials
> +  are licensed and made available under the terms and conditions of the BSD License
> +  which accompanies this distribution.  The full text of the license may be found at
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +Module Name:
> +
> +  MemDetect.c
> +
> +**/
> +
> +//
> +// The package level header files this module uses
> +//
> +#include <PiPei.h>
> +
> +//
> +// The Library classes this module consumes
> +//
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PeimEntryPoint.h>
> +#include <Library/ResourcePublicationLib.h>
> +#include <Library/MtrrLib.h>
> +#include <Library/QemuFwCfgLib.h>
> +
> +#include "Platform.h"
> +#include "Cmos.h"
> +
> +UINT8 mPhysMemAddressWidth;
> +
> +STATIC UINT32 mS3AcpiReservedMemoryBase;
> +STATIC UINT32 mS3AcpiReservedMemorySize;
> +
> +UINT32
> +GetSystemMemorySizeBelow4gb (
> +  VOID
> +  )
> +{
> +  UINT8 Cmos0x34;
> +  UINT8 Cmos0x35;
> +
> +  //
> +  // CMOS 0x34/0x35 specifies the system memory above 16 MB.
> +  // * CMOS(0x35) is the high byte
> +  // * CMOS(0x34) is the low byte
> +  // * The size is specified in 64kb chunks
> +  // * Since this is memory above 16MB, the 16MB must be added
> +  //   into the calculation to get the total memory size.
> +  //
> +
> +  Cmos0x34 = (UINT8) CmosRead8 (0x34);
> +  Cmos0x35 = (UINT8) CmosRead8 (0x35);
> +
> +  return (UINT32) (((UINTN)((Cmos0x35 << 8) + Cmos0x34) << 16) + SIZE_16MB);
> +}
> +
> +
> +STATIC
> +UINT64
> +GetSystemMemorySizeAbove4gb (
> +  )
> +{
> +  UINT32 Size;
> +  UINTN  CmosIndex;
> +
> +  //
> +  // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
> +  // * CMOS(0x5d) is the most significant size byte
> +  // * CMOS(0x5c) is the middle size byte
> +  // * CMOS(0x5b) is the least significant size byte
> +  // * The size is specified in 64kb chunks
> +  //
> +
> +  Size = 0;
> +  for (CmosIndex = 0x5d; CmosIndex >= 0x5b; CmosIndex--) {
> +    Size = (UINT32) (Size << 8) + (UINT32) CmosRead8 (CmosIndex);
> +  }
> +
> +  return LShiftU64 (Size, 16);
> +}
> +
> +
> +/**
> +  Return the highest address that DXE could possibly use, plus one.
> +**/
> +STATIC
> +UINT64
> +GetFirstNonAddress (
> +  VOID
> +  )
> +{
> +  UINT64               FirstNonAddress;
> +  UINT64               Pci64Base, Pci64Size;
> +  RETURN_STATUS        PcdStatus;
> +
> +  FirstNonAddress = BASE_4GB + GetSystemMemorySizeAbove4gb ();
> +
> +  //
> +  // If DXE is 32-bit, then we're done; PciBusDxe will degrade 64-bit MMIO
> +  // resources to 32-bit anyway. See DegradeResource() in
> +  // "PciResourceSupport.c".
> +  //
> +#ifdef MDE_CPU_IA32
> +  if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
> +    return FirstNonAddress;
> +  }
> +#endif
> +
> +  //
> +  // Otherwise, in order to calculate the highest address plus one, we must
> +  // consider the 64-bit PCI host aperture too. Fetch the default size.
> +  //
> +  Pci64Size = PcdGet64 (PcdPciMmio64Size);
> +
> +  if (Pci64Size == 0) {
> +    if (mBootMode != BOOT_ON_S3_RESUME) {
> +      DEBUG ((EFI_D_INFO, "%a: disabling 64-bit PCI host aperture\n",
> +        __FUNCTION__));
> +      PcdStatus = PcdSet64S (PcdPciMmio64Size, 0);
> +      ASSERT_RETURN_ERROR (PcdStatus);
> +    }
> +
> +    //
> +    // There's nothing more to do; the amount of memory above 4GB fully
> +    // determines the highest address plus one. The memory hotplug area (see
> +    // below) plays no role for the firmware in this case.
> +    //
> +    return FirstNonAddress;
> +  }
> +
> +  //
> +  // SeaBIOS aligns both boundaries of the 64-bit PCI host aperture to 1GB, so
> +  // that the host can map it with 1GB hugepages. Follow suit.
> +  //
> +  Pci64Base = ALIGN_VALUE (FirstNonAddress, (UINT64)SIZE_1GB);
> +  Pci64Size = ALIGN_VALUE (Pci64Size, (UINT64)SIZE_1GB);
> +
> +  //
> +  // The 64-bit PCI host aperture should also be "naturally" aligned. The
> +  // alignment is determined by rounding the size of the aperture down to the
> +  // next smaller or equal power of two. That is, align the aperture by the
> +  // largest BAR size that can fit into it.
> +  //
> +  Pci64Base = ALIGN_VALUE (Pci64Base, GetPowerOfTwo64 (Pci64Size));
> +
> +  if (mBootMode != BOOT_ON_S3_RESUME) {
> +    //
> +    // The core PciHostBridgeDxe driver will automatically add this range to
> +    // the GCD memory space map through our PciHostBridgeLib instance; here we
> +    // only need to set the PCDs.
> +    //
> +    PcdStatus = PcdSet64S (PcdPciMmio64Base, Pci64Base);
> +    ASSERT_RETURN_ERROR (PcdStatus);
> +    PcdStatus = PcdSet64S (PcdPciMmio64Size, Pci64Size);
> +    ASSERT_RETURN_ERROR (PcdStatus);
> +
> +    DEBUG ((EFI_D_INFO, "%a: Pci64Base=0x%Lx Pci64Size=0x%Lx\n",
> +      __FUNCTION__, Pci64Base, Pci64Size));
> +  }
> +
> +  //
> +  // The useful address space ends with the 64-bit PCI host aperture.
> +  //
> +  FirstNonAddress = Pci64Base + Pci64Size;
> +  return FirstNonAddress;
> +}
> +
> +
> +/**
> +  Initialize the mPhysMemAddressWidth variable, based on guest RAM size.
> +**/
> +VOID
> +AddressWidthInitialization (
> +  VOID
> +  )
> +{
> +  UINT64 FirstNonAddress;
> +
> +  //
> +  // As guest-physical memory size grows, the permanent PEI RAM requirements
> +  // are dominated by the identity-mapping page tables built by the DXE IPL.
> +  // The DXL IPL keys off of the physical address bits advertized in the CPU
> +  // HOB. To conserve memory, we calculate the minimum address width here.
> +  //
> +  FirstNonAddress      = GetFirstNonAddress ();
> +  mPhysMemAddressWidth = (UINT8)HighBitSet64 (FirstNonAddress);
> +
> +  //
> +  // If FirstNonAddress is not an integral power of two, then we need an
> +  // additional bit.
> +  //
> +  if ((FirstNonAddress & (FirstNonAddress - 1)) != 0) {
> +    ++mPhysMemAddressWidth;
> +  }
> +
> +  //
> +  // The minimum address width is 36 (covers up to and excluding 64 GB, which
> +  // is the maximum for Ia32 + PAE). The theoretical architecture maximum for
> +  // X64 long mode is 52 bits, but the DXE IPL clamps that down to 48 bits. We
> +  // can simply assert that here, since 48 bits are good enough for 256 TB.
> +  //
> +  if (mPhysMemAddressWidth <= 36) {
> +    mPhysMemAddressWidth = 36;
> +  }
> +  ASSERT (mPhysMemAddressWidth <= 48);
> +}
> +
> +
> +/**
> +  Calculate the cap for the permanent PEI memory.
> +**/
> +STATIC
> +UINT32
> +GetPeiMemoryCap (
> +  VOID
> +  )
> +{
> +  BOOLEAN Page1GSupport;
> +  UINT32  RegEax;
> +  UINT32  RegEdx;
> +  UINT32  Pml4Entries;
> +  UINT32  PdpEntries;
> +  UINTN   TotalPages;
> +
> +  //
> +  // If DXE is 32-bit, then just return the traditional 64 MB cap.
> +  //
> +#ifdef MDE_CPU_IA32
> +  if (!FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {
> +    return SIZE_64MB;
> +  }
> +#endif
> +
> +  //
> +  // Dependent on physical address width, PEI memory allocations can be
> +  // dominated by the page tables built for 64-bit DXE. So we key the cap off
> +  // of those. The code below is based on CreateIdentityMappingPageTables() in
> +  // "MdeModulePkg/Core/DxeIplPeim/X64/VirtualMemory.c".
> +  //
> +  Page1GSupport = FALSE;
> +  if (PcdGetBool (PcdUse1GPageTable)) {
> +    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
> +    if (RegEax >= 0x80000001) {
> +      AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
> +      if ((RegEdx & BIT26) != 0) {
> +        Page1GSupport = TRUE;
> +      }
> +    }
> +  }
> +
> +  if (mPhysMemAddressWidth <= 39) {
> +    Pml4Entries = 1;
> +    PdpEntries = 1 << (mPhysMemAddressWidth - 30);
> +    ASSERT (PdpEntries <= 0x200);
> +  } else {
> +    Pml4Entries = 1 << (mPhysMemAddressWidth - 39);
> +    ASSERT (Pml4Entries <= 0x200);
> +    PdpEntries = 512;
> +  }
> +
> +  TotalPages = Page1GSupport ? Pml4Entries + 1 :
> +                               (PdpEntries + 1) * Pml4Entries + 1;
> +  ASSERT (TotalPages <= 0x40201);
> +
> +  //
> +  // Add 64 MB for miscellaneous allocations. Note that for
> +  // mPhysMemAddressWidth values close to 36, the cap will actually be
> +  // dominated by this increment.
> +  //
> +  return (UINT32)(EFI_PAGES_TO_SIZE (TotalPages) + SIZE_64MB);
> +}
> +
> +
> +/**
> +  Publish PEI core memory
> +
> +  @return EFI_SUCCESS     The PEIM initialized successfully.
> +
> +**/
> +EFI_STATUS
> +PublishPeiMemory (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                  Status;
> +  EFI_PHYSICAL_ADDRESS        MemoryBase;
> +  UINT64                      MemorySize;
> +  UINT32                      LowerMemorySize;
> +  UINT32                      PeiMemoryCap;
> +
> +  LowerMemorySize = GetSystemMemorySizeBelow4gb ();
> +
> +  //
> +  // If S3 is supported, then the S3 permanent PEI memory is placed next,
> +  // downwards. Its size is primarily dictated by CpuMpPei. The formula below
> +  // is an approximation.
> +  //
> +  if (mS3Supported) {
> +    mS3AcpiReservedMemorySize = SIZE_512KB +
> +      PcdGet32 (PcdCpuMaxLogicalProcessorNumber) *
> +      PcdGet32 (PcdCpuApStackSize);
> +    mS3AcpiReservedMemoryBase = LowerMemorySize - mS3AcpiReservedMemorySize;
> +    LowerMemorySize = mS3AcpiReservedMemoryBase;
> +  }
> +
> +  if (mBootMode == BOOT_ON_S3_RESUME) {
> +    MemoryBase = mS3AcpiReservedMemoryBase;
> +    MemorySize = mS3AcpiReservedMemorySize;
> +  } else {
> +    PeiMemoryCap = GetPeiMemoryCap ();
> +    DEBUG ((EFI_D_INFO, "%a: mPhysMemAddressWidth=%d PeiMemoryCap=%u KB\n",
> +      __FUNCTION__, mPhysMemAddressWidth, PeiMemoryCap >> 10));
> +
> +    //
> +    // Determine the range of memory to use during PEI
> +    //
> +    // Technically we could lay the permanent PEI RAM over SEC's temporary
> +    // decompression and scratch buffer even if "secure S3" is needed, since
> +    // their lifetimes don't overlap. However, PeiFvInitialization() will cover
> +    // RAM up to PcdOvmfDecompressionScratchEnd with an EfiACPIMemoryNVS memory
> +    // allocation HOB, and other allocations served from the permanent PEI RAM
> +    // shouldn't overlap with that HOB.
> +    //
> +    MemoryBase = mS3Supported && FeaturePcdGet (PcdSmmSmramRequire) ?
> +      PcdGet32 (PcdOvmfDecompressionScratchEnd) :
> +      PcdGet32 (PcdOvmfDxeMemFvBase) + PcdGet32 (PcdOvmfDxeMemFvSize);
> +    MemorySize = LowerMemorySize - MemoryBase;
> +    if (MemorySize > PeiMemoryCap) {
> +      MemoryBase = LowerMemorySize - PeiMemoryCap;
> +      MemorySize = PeiMemoryCap;
> +    }
> +  }
> +
> +  //
> +  // Publish this memory to the PEI Core
> +  //
> +  Status = PublishSystemMemory(MemoryBase, MemorySize);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Publish system RAM and reserve memory regions
> +
> +**/
> +VOID
> +InitializeRamRegions (
> +  VOID
> +  )
> +{
> +  XenPublishRamRegions ();
> +
> +  if (mS3Supported && mBootMode != BOOT_ON_S3_RESUME) {
> +    //
> +    // This is the memory range that will be used for PEI on S3 resume
> +    //
> +    BuildMemoryAllocationHob (
> +      mS3AcpiReservedMemoryBase,
> +      mS3AcpiReservedMemorySize,
> +      EfiACPIMemoryNVS
> +      );
> +
> +    //
> +    // Cover the initial RAM area used as stack and temporary PEI heap.
> +    //
> +    // This is reserved as ACPI NVS so it can be used on S3 resume.
> +    //
> +    BuildMemoryAllocationHob (
> +      PcdGet32 (PcdOvmfSecPeiTempRamBase),
> +      PcdGet32 (PcdOvmfSecPeiTempRamSize),
> +      EfiACPIMemoryNVS
> +      );
> +
> +    //
> +    // SEC stores its table of GUIDed section handlers here.
> +    //
> +    BuildMemoryAllocationHob (
> +      PcdGet64 (PcdGuidedExtractHandlerTableAddress),
> +      PcdGet32 (PcdGuidedExtractHandlerTableSize),
> +      EfiACPIMemoryNVS
> +      );
> +
> +#ifdef MDE_CPU_X64
> +    //
> +    // Reserve the initial page tables built by the reset vector code.
> +    //
> +    // Since this memory range will be used by the Reset Vector on S3
> +    // resume, it must be reserved as ACPI NVS.
> +    //
> +    BuildMemoryAllocationHob (
> +      (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdOvmfSecPageTablesBase),
> +      (UINT64)(UINTN) PcdGet32 (PcdOvmfSecPageTablesSize),
> +      EfiACPIMemoryNVS
> +      );
> +#endif
> +  }
> +
> +  if (mBootMode != BOOT_ON_S3_RESUME) {
> +    if (!FeaturePcdGet (PcdSmmSmramRequire)) {
> +      //
> +      // Reserve the lock box storage area
> +      //
> +      // Since this memory range will be used on S3 resume, it must be
> +      // reserved as ACPI NVS.
> +      //
> +      // If S3 is unsupported, then various drivers might still write to the
> +      // LockBox area. We ought to prevent DXE from serving allocation requests
> +      // such that they would overlap the LockBox storage.
> +      //
> +      ZeroMem (
> +        (VOID*)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageBase),
> +        (UINTN) PcdGet32 (PcdOvmfLockBoxStorageSize)
> +        );
> +      BuildMemoryAllocationHob (
> +        (EFI_PHYSICAL_ADDRESS)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageBase),
> +        (UINT64)(UINTN) PcdGet32 (PcdOvmfLockBoxStorageSize),
> +        mS3Supported ? EfiACPIMemoryNVS : EfiBootServicesData
> +        );
> +    }
> +
> +    if (FeaturePcdGet (PcdSmmSmramRequire)) {
> +      UINT32 TsegSize;
> +
> +      //
> +      // Make sure the TSEG area that we reported as a reserved memory resource
> +      // cannot be used for reserved memory allocations.
> +      //
> +      TsegSize = FixedPcdGet8 (PcdQ35TsegMbytes) * SIZE_1MB;
> +      BuildMemoryAllocationHob (
> +        GetSystemMemorySizeBelow4gb() - TsegSize,
> +        TsegSize,
> +        EfiReservedMemoryType
> +        );
> +    }
> +  }
> +}
> diff --git a/OvmfPkg/XenPlatformPei/Platform.c b/OvmfPkg/XenPlatformPei/Platform.c
> new file mode 100644
> index 0000000..bf78878
> --- /dev/null
> +++ b/OvmfPkg/XenPlatformPei/Platform.c
> @@ -0,0 +1,536 @@
> +/**@file
> +  Platform PEI driver
> +
> +  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
> +
> +  This program and the accompanying materials
> +  are licensed and made available under the terms and conditions of the BSD License
> +  which accompanies this distribution.  The full text of the license may be found at
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +//
> +// The package level header files this module uses
> +//
> +#include <PiPei.h>
> +
> +//
> +// The Library classes this module consumes
> +//
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/PeimEntryPoint.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/QemuFwCfgLib.h>
> +#include <Library/ResourcePublicationLib.h>
> +#include <Guid/MemoryTypeInformation.h>
> +#include <Ppi/MasterBootMode.h>
> +#include <IndustryStandard/Pci22.h>
> +#include <OvmfPlatforms.h>
> +
> +#include "Platform.h"
> +#include "Cmos.h"
> +
> +EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = {
> +  { EfiACPIMemoryNVS,       0x004 },
> +  { EfiACPIReclaimMemory,   0x008 },
> +  { EfiReservedMemoryType,  0x004 },
> +  { EfiRuntimeServicesData, 0x024 },
> +  { EfiRuntimeServicesCode, 0x030 },
> +  { EfiBootServicesCode,    0x180 },
> +  { EfiBootServicesData,    0xF00 },
> +  { EfiMaxMemoryType,       0x000 }
> +};
> +
> +
> +EFI_PEI_PPI_DESCRIPTOR   mPpiBootMode[] = {
> +  {
> +    EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
> +    &gEfiPeiMasterBootModePpiGuid,
> +    NULL
> +  }
> +};
> +
> +
> +UINT16 mHostBridgeDevId;
> +
> +EFI_BOOT_MODE mBootMode = BOOT_WITH_FULL_CONFIGURATION;
> +
> +BOOLEAN mS3Supported = FALSE;
> +
> +
> +VOID
> +AddIoMemoryBaseSizeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  UINT64                      MemorySize
> +  )
> +{
> +  BuildResourceDescriptorHob (
> +    EFI_RESOURCE_MEMORY_MAPPED_IO,
> +      EFI_RESOURCE_ATTRIBUTE_PRESENT     |
> +      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> +      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_TESTED,
> +    MemoryBase,
> +    MemorySize
> +    );
> +}
> +
> +VOID
> +AddReservedMemoryBaseSizeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  UINT64                      MemorySize,
> +  BOOLEAN                     Cacheable
> +  )
> +{
> +  BuildResourceDescriptorHob (
> +    EFI_RESOURCE_MEMORY_RESERVED,
> +      EFI_RESOURCE_ATTRIBUTE_PRESENT     |
> +      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> +      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> +      (Cacheable ?
> +       EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
> +       EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
> +       EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE :
> +       0
> +       ) |
> +      EFI_RESOURCE_ATTRIBUTE_TESTED,
> +    MemoryBase,
> +    MemorySize
> +    );
> +}
> +
> +VOID
> +AddIoMemoryRangeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  EFI_PHYSICAL_ADDRESS        MemoryLimit
> +  )
> +{
> +  AddIoMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
> +}
> +
> +
> +VOID
> +AddMemoryBaseSizeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  UINT64                      MemorySize
> +  )
> +{
> +  BuildResourceDescriptorHob (
> +    EFI_RESOURCE_SYSTEM_MEMORY,
> +      EFI_RESOURCE_ATTRIBUTE_PRESENT |
> +      EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
> +      EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
> +      EFI_RESOURCE_ATTRIBUTE_TESTED,
> +    MemoryBase,
> +    MemorySize
> +    );
> +}
> +
> +
> +VOID
> +AddMemoryRangeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  EFI_PHYSICAL_ADDRESS        MemoryLimit
> +  )
> +{
> +  AddMemoryBaseSizeHob (MemoryBase, (UINT64)(MemoryLimit - MemoryBase));
> +}
> +
> +
> +VOID
> +MemMapInitialization (
> +  VOID
> +  )
> +{
> +  UINT64        PciIoBase;
> +  UINT64        PciIoSize;
> +  RETURN_STATUS PcdStatus;
> +
> +  PciIoBase = 0xC000;
> +  PciIoSize = 0x4000;
> +
> +  //
> +  // Create Memory Type Information HOB
> +  //
> +  BuildGuidDataHob (
> +    &gEfiMemoryTypeInformationGuid,
> +    mDefaultMemoryTypeInformation,
> +    sizeof(mDefaultMemoryTypeInformation)
> +    );
> +
> +  //
> +  // Video memory + Legacy BIOS region
> +  //
> +  AddIoMemoryRangeHob (0x0A0000, BASE_1MB);
> +
> +  if (!mXen) {
> +    UINT32  TopOfLowRam;
> +    UINT64  PciExBarBase;
> +    UINT32  PciBase;
> +    UINT32  PciSize;
> +
> +    TopOfLowRam = GetSystemMemorySizeBelow4gb ();
> +    PciExBarBase = 0;
> +    if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
> +      //
> +      // The MMCONFIG area is expected to fall between the top of low RAM and
> +      // the base of the 32-bit PCI host aperture.
> +      //
> +      PciExBarBase = FixedPcdGet64 (PcdPciExpressBaseAddress);
> +      ASSERT (TopOfLowRam <= PciExBarBase);
> +      ASSERT (PciExBarBase <= MAX_UINT32 - SIZE_256MB);
> +      PciBase = (UINT32)(PciExBarBase + SIZE_256MB);
> +    } else {
> +      PciBase = (TopOfLowRam < BASE_2GB) ? BASE_2GB : TopOfLowRam;
> +    }
> +
> +    //
> +    // address       purpose   size
> +    // ------------  --------  -------------------------
> +    // max(top, 2g)  PCI MMIO  0xFC000000 - max(top, 2g)
> +    // 0xFC000000    gap                           44 MB
> +    // 0xFEC00000    IO-APIC                        4 KB
> +    // 0xFEC01000    gap                         1020 KB
> +    // 0xFED00000    HPET                           1 KB
> +    // 0xFED00400    gap                          111 KB
> +    // 0xFED1C000    gap (PIIX4) / RCRB (ICH9)     16 KB
> +    // 0xFED20000    gap                          896 KB
> +    // 0xFEE00000    LAPIC                          1 MB
> +    //
> +    PciSize = 0xFC000000 - PciBase;
> +    AddIoMemoryBaseSizeHob (PciBase, PciSize);
> +    PcdStatus = PcdSet64S (PcdPciMmio32Base, PciBase);
> +    ASSERT_RETURN_ERROR (PcdStatus);
> +    PcdStatus = PcdSet64S (PcdPciMmio32Size, PciSize);
> +    ASSERT_RETURN_ERROR (PcdStatus);
> +
> +    AddIoMemoryBaseSizeHob (0xFEC00000, SIZE_4KB);
> +    AddIoMemoryBaseSizeHob (0xFED00000, SIZE_1KB);
> +    if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
> +      AddIoMemoryBaseSizeHob (ICH9_ROOT_COMPLEX_BASE, SIZE_16KB);
> +      //
> +      // Note: there should be an
> +      //
> +      //   AddIoMemoryBaseSizeHob (PciExBarBase, SIZE_256MB);
> +      //
> +      // call below, just like the one above for RCBA. However, Linux insists
> +      // that the MMCONFIG area be marked in the E820 or UEFI memory map as
> +      // "reserved memory" -- Linux does not content itself with a simple gap
> +      // in the memory map wherever the MCFG ACPI table points to.
> +      //
> +      // This appears to be a safety measure. The PCI Firmware Specification
> +      // (rev 3.1) says in 4.1.2. "MCFG Table Description": "The resources can
> +      // *optionally* be returned in [...] EFIGetMemoryMap as reserved memory
> +      // [...]". (Emphasis added here.)
> +      //
> +      // Normally we add memory resource descriptor HOBs in
> +      // QemuInitializeRam(), and pre-allocate from those with memory
> +      // allocation HOBs in InitializeRamRegions(). However, the MMCONFIG area
> +      // is most definitely not RAM; so, as an exception, cover it with
> +      // uncacheable reserved memory right here.
> +      //
> +      AddReservedMemoryBaseSizeHob (PciExBarBase, SIZE_256MB, FALSE);
> +      BuildMemoryAllocationHob (PciExBarBase, SIZE_256MB,
> +        EfiReservedMemoryType);
> +    }
> +    AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress), SIZE_1MB);
> +
> +    //
> +    // On Q35, the IO Port space is available for PCI resource allocations from
> +    // 0x6000 up.
> +    //
> +    if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
> +      PciIoBase = 0x6000;
> +      PciIoSize = 0xA000;
> +      ASSERT ((ICH9_PMBASE_VALUE & 0xF000) < PciIoBase);
> +    }
> +  }
> +
> +  //
> +  // Add PCI IO Port space available for PCI resource allocations.
> +  //
> +  BuildResourceDescriptorHob (
> +    EFI_RESOURCE_IO,
> +    EFI_RESOURCE_ATTRIBUTE_PRESENT     |
> +    EFI_RESOURCE_ATTRIBUTE_INITIALIZED,
> +    PciIoBase,
> +    PciIoSize
> +    );
> +  PcdStatus = PcdSet64S (PcdPciIoBase, PciIoBase);
> +  ASSERT_RETURN_ERROR (PcdStatus);
> +  PcdStatus = PcdSet64S (PcdPciIoSize, PciIoSize);
> +  ASSERT_RETURN_ERROR (PcdStatus);
> +}
> +
> +VOID
> +PciExBarInitialization (
> +  VOID
> +  )
> +{
> +  union {
> +    UINT64 Uint64;
> +    UINT32 Uint32[2];
> +  } PciExBarBase;
> +
> +  //
> +  // We only support the 256MB size for the MMCONFIG area:
> +  // 256 buses * 32 devices * 8 functions * 4096 bytes config space.
> +  //
> +  // The masks used below enforce the Q35 requirements that the MMCONFIG area
> +  // be (a) correctly aligned -- here at 256 MB --, (b) located under 64 GB.
> +  //
> +  // Note that (b) also ensures that the minimum address width we have
> +  // determined in AddressWidthInitialization(), i.e., 36 bits, will suffice
> +  // for DXE's page tables to cover the MMCONFIG area.
> +  //
> +  PciExBarBase.Uint64 = FixedPcdGet64 (PcdPciExpressBaseAddress);
> +  ASSERT ((PciExBarBase.Uint32[1] & MCH_PCIEXBAR_HIGHMASK) == 0);
> +  ASSERT ((PciExBarBase.Uint32[0] & MCH_PCIEXBAR_LOWMASK) == 0);
> +
> +  //
> +  // Clear the PCIEXBAREN bit first, before programming the high register.
> +  //
> +  PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW), 0);
> +
> +  //
> +  // Program the high register. Then program the low register, setting the
> +  // MMCONFIG area size and enabling decoding at once.
> +  //
> +  PciWrite32 (DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_HIGH), PciExBarBase.Uint32[1]);
> +  PciWrite32 (
> +    DRAMC_REGISTER_Q35 (MCH_PCIEXBAR_LOW),
> +    PciExBarBase.Uint32[0] | MCH_PCIEXBAR_BUS_FF | MCH_PCIEXBAR_EN
> +    );
> +}
> +
> +VOID
> +MiscInitialization (
> +  VOID
> +  )
> +{
> +  UINTN         PmCmd;
> +  UINTN         Pmba;
> +  UINT32        PmbaAndVal;
> +  UINT32        PmbaOrVal;
> +  UINTN         AcpiCtlReg;
> +  UINT8         AcpiEnBit;
> +  RETURN_STATUS PcdStatus;
> +
> +  //
> +  // Disable A20 Mask
> +  //
> +  IoOr8 (0x92, BIT1);
> +
> +  //
> +  // Build the CPU HOB with guest RAM size dependent address width and 16-bits
> +  // of IO space. (Side note: unlike other HOBs, the CPU HOB is needed during
> +  // S3 resume as well, so we build it unconditionally.)
> +  //
> +  BuildCpuHob (mPhysMemAddressWidth, 16);
> +
> +  //
> +  // Determine platform type and save Host Bridge DID to PCD
> +  //
> +  switch (mHostBridgeDevId) {
> +    case INTEL_82441_DEVICE_ID:
> +      PmCmd      = POWER_MGMT_REGISTER_PIIX4 (PCI_COMMAND_OFFSET);
> +      Pmba       = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMBA);
> +      PmbaAndVal = ~(UINT32)PIIX4_PMBA_MASK;
> +      PmbaOrVal  = PIIX4_PMBA_VALUE;
> +      AcpiCtlReg = POWER_MGMT_REGISTER_PIIX4 (PIIX4_PMREGMISC);
> +      AcpiEnBit  = PIIX4_PMREGMISC_PMIOSE;
> +      break;
> +    case INTEL_Q35_MCH_DEVICE_ID:
> +      PmCmd      = POWER_MGMT_REGISTER_Q35 (PCI_COMMAND_OFFSET);
> +      Pmba       = POWER_MGMT_REGISTER_Q35 (ICH9_PMBASE);
> +      PmbaAndVal = ~(UINT32)ICH9_PMBASE_MASK;
> +      PmbaOrVal  = ICH9_PMBASE_VALUE;
> +      AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL);
> +      AcpiEnBit  = ICH9_ACPI_CNTL_ACPI_EN;
> +      break;
> +    default:
> +      DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
> +        __FUNCTION__, mHostBridgeDevId));
> +      ASSERT (FALSE);
> +      return;
> +  }
> +  PcdStatus = PcdSet16S (PcdOvmfHostBridgePciDevId, mHostBridgeDevId);
> +  ASSERT_RETURN_ERROR (PcdStatus);
> +
> +  //
> +  // If the appropriate IOspace enable bit is set, assume the ACPI PMBA
> +  // has been configured (e.g., by Xen) and skip the setup here.
> +  // This matches the logic in AcpiTimerLibConstructor ().
> +  //
> +  if ((PciRead8 (AcpiCtlReg) & AcpiEnBit) == 0) {
> +    //
> +    // The PEI phase should be exited with fully accessibe ACPI PM IO space:
> +    // 1. set PMBA
> +    //
> +    PciAndThenOr32 (Pmba, PmbaAndVal, PmbaOrVal);
> +
> +    //
> +    // 2. set PCICMD/IOSE
> +    //
> +    PciOr8 (PmCmd, EFI_PCI_COMMAND_IO_SPACE);
> +
> +    //
> +    // 3. set ACPI PM IO enable bit (PMREGMISC:PMIOSE or ACPI_CNTL:ACPI_EN)
> +    //
> +    PciOr8 (AcpiCtlReg, AcpiEnBit);
> +  }
> +
> +  if (mHostBridgeDevId == INTEL_Q35_MCH_DEVICE_ID) {
> +    //
> +    // Set Root Complex Register Block BAR
> +    //
> +    PciWrite32 (
> +      POWER_MGMT_REGISTER_Q35 (ICH9_RCBA),
> +      ICH9_ROOT_COMPLEX_BASE | ICH9_RCBA_EN
> +      );
> +
> +    //
> +    // Set PCI Express Register Range Base Address
> +    //
> +    PciExBarInitialization ();
> +  }
> +}
> +
> +
> +VOID
> +BootModeInitialization (
> +  VOID
> +  )
> +{
> +  EFI_STATUS    Status;
> +
> +  if (CmosRead8 (0xF) == 0xFE) {
> +    mBootMode = BOOT_ON_S3_RESUME;
> +  }
> +  CmosWrite8 (0xF, 0x00);
> +
> +  Status = PeiServicesSetBootMode (mBootMode);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = PeiServicesInstallPpi (mPpiBootMode);
> +  ASSERT_EFI_ERROR (Status);
> +}
> +
> +
> +VOID
> +ReserveEmuVariableNvStore (
> +  )
> +{
> +  EFI_PHYSICAL_ADDRESS VariableStore;
> +  RETURN_STATUS        PcdStatus;
> +
> +  //
> +  // Allocate storage for NV variables early on so it will be
> +  // at a consistent address.  Since VM memory is preserved
> +  // across reboots, this allows the NV variable storage to survive
> +  // a VM reboot.
> +  //
> +  VariableStore =
> +    (EFI_PHYSICAL_ADDRESS)(UINTN)
> +      AllocateAlignedRuntimePages (
> +        EFI_SIZE_TO_PAGES (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)),
> +        PcdGet32 (PcdFlashNvStorageFtwSpareSize)
> +        );
> +  DEBUG ((EFI_D_INFO,
> +          "Reserved variable store memory: 0x%lX; size: %dkb\n",
> +          VariableStore,
> +          (2 * PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / 1024
> +        ));
> +  PcdStatus = PcdSet64S (PcdEmuVariableNvStoreReserved, VariableStore);
> +  ASSERT_RETURN_ERROR (PcdStatus);
> +}
> +
> +
> +VOID
> +DebugDumpCmos (
> +  VOID
> +  )
> +{
> +  UINT32 Loop;
> +
> +  DEBUG ((EFI_D_INFO, "CMOS:\n"));
> +
> +  for (Loop = 0; Loop < 0x80; Loop++) {
> +    if ((Loop % 0x10) == 0) {
> +      DEBUG ((EFI_D_INFO, "%02x:", Loop));
> +    }
> +    DEBUG ((EFI_D_INFO, " %02x", CmosRead8 (Loop)));
> +    if ((Loop % 0x10) == 0xf) {
> +      DEBUG ((EFI_D_INFO, "\n"));
> +    }
> +  }
> +}
> +
> +
> +
> +/**
> +  Perform Platform PEI initialization.
> +
> +  @param  FileHandle      Handle of the file being invoked.
> +  @param  PeiServices     Describes the list of possible PEI Services.
> +
> +  @return EFI_SUCCESS     The PEIM initialized successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializeXenPlatform (
> +  IN       EFI_PEI_FILE_HANDLE  FileHandle,
> +  IN CONST EFI_PEI_SERVICES     **PeiServices
> +  )
> +{
> +  DEBUG ((EFI_D_ERROR, "Platform PEIM Loaded\n"));
> +
> +  DebugDumpCmos ();
> +
> +  XenDetect ();
> +
> +  BootModeInitialization ();
> +  AddressWidthInitialization ();
> +
> +  PublishPeiMemory ();
> +
> +  InitializeRamRegions ();
> +
> +  if (mXen) {
> +    DEBUG ((EFI_D_INFO, "Xen was detected\n"));
> +    InitializeXen ();
> +  } else {
> +    DEBUG ((EFI_D_ERROR, "not running on Xen\n"));
> +    CpuDeadLoop ();
> +  }
> +
> +  //
> +  // Query Host Bridge DID
> +  //
> +  mHostBridgeDevId = PciRead16 (OVMF_HOSTBRIDGE_DID);
> +
> +  if (mBootMode != BOOT_ON_S3_RESUME) {
> +    ReserveEmuVariableNvStore ();
> +    PeiFvInitialization ();
> +    MemMapInitialization ();
> +  }
> +
> +  MiscInitialization ();
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/OvmfPkg/XenPlatformPei/Platform.h b/OvmfPkg/XenPlatformPei/Platform.h
> new file mode 100644
> index 0000000..eda765b
> --- /dev/null
> +++ b/OvmfPkg/XenPlatformPei/Platform.h
> @@ -0,0 +1,104 @@
> +/** @file
> +  Platform PEI module include file.
> +
> +  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
> +  This program and the accompanying materials
> +  are licensed and made available under the terms and conditions of the BSD License
> +  which accompanies this distribution.  The full text of the license may be found at
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef _PLATFORM_PEI_H_INCLUDED_
> +#define _PLATFORM_PEI_H_INCLUDED_
> +
> +#include <IndustryStandard/E820.h>
> +
> +VOID
> +AddIoMemoryBaseSizeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  UINT64                      MemorySize
> +  );
> +
> +VOID
> +AddIoMemoryRangeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  EFI_PHYSICAL_ADDRESS        MemoryLimit
> +  );
> +
> +VOID
> +AddMemoryBaseSizeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  UINT64                      MemorySize
> +  );
> +
> +VOID
> +AddMemoryRangeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  EFI_PHYSICAL_ADDRESS        MemoryLimit
> +  );
> +
> +VOID
> +AddReservedMemoryBaseSizeHob (
> +  EFI_PHYSICAL_ADDRESS        MemoryBase,
> +  UINT64                      MemorySize,
> +  BOOLEAN                     Cacheable
> +  );
> +
> +VOID
> +AddressWidthInitialization (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +PublishPeiMemory (
> +  VOID
> +  );
> +
> +UINT32
> +GetSystemMemorySizeBelow4gb (
> +  VOID
> +  );
> +
> +VOID
> +InitializeRamRegions (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +PeiFvInitialization (
> +  VOID
> +  );
> +
> +VOID
> +InstallFeatureControlCallback (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +InitializeXen (
> +  VOID
> +  );
> +
> +BOOLEAN
> +XenDetect (
> +  VOID
> +  );
> +
> +extern BOOLEAN mXen;
> +
> +VOID
> +XenPublishRamRegions (
> +  VOID
> +  );
> +
> +extern EFI_BOOT_MODE mBootMode;
> +
> +extern BOOLEAN mS3Supported;
> +
> +extern UINT8 mPhysMemAddressWidth;
> +
> +#endif // _PLATFORM_PEI_H_INCLUDED_
> diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c
> new file mode 100644
> index 0000000..ab38f97
> --- /dev/null
> +++ b/OvmfPkg/XenPlatformPei/Xen.c
> @@ -0,0 +1,231 @@
> +/**@file
> +  Xen Platform PEI support
> +
> +  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
> +
> +  This program and the accompanying materials
> +  are licensed and made available under the terms and conditions of the BSD License
> +  which accompanies this distribution.  The full text of the license may be found at
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +//
> +// The package level header files this module uses
> +//
> +#include <PiPei.h>
> +
> +//
> +// The Library classes this module consumes
> +//
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Guid/XenInfo.h>
> +#include <IndustryStandard/E820.h>
> +#include <Library/ResourcePublicationLib.h>
> +#include <Library/MtrrLib.h>
> +
> +#include "Platform.h"
> +#include "Xen.h"
> +
> +BOOLEAN mXen = FALSE;
> +
> +STATIC UINT32 mXenLeaf = 0;
> +
> +EFI_XEN_INFO mXenInfo;
> +
> +/**
> +  Returns E820 map provided by Xen
> +
> +  @param Entries      Pointer to E820 map
> +  @param Count        Number of entries
> +
> +  @return EFI_STATUS
> +**/
> +EFI_STATUS
> +XenGetE820Map (
> +  EFI_E820_ENTRY64 **Entries,
> +  UINT32 *Count
> +  )
> +{
> +  EFI_XEN_OVMF_INFO *Info =
> +    (EFI_XEN_OVMF_INFO *)(UINTN) OVMF_INFO_PHYSICAL_ADDRESS;
> +
> +  if (AsciiStrCmp ((CHAR8 *) Info->Signature, "XenHVMOVMF")) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  ASSERT (Info->E820 < MAX_ADDRESS);
> +  *Entries = (EFI_E820_ENTRY64 *)(UINTN) Info->E820;
> +  *Count = Info->E820EntriesCount;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Connects to the Hypervisor.
> + 
> +  @param  XenLeaf     CPUID index used to connect.
> +
> +  @return EFI_STATUS
> +
> +**/
> +EFI_STATUS
> +XenConnect (
> +  UINT32 XenLeaf
> +  )
> +{
> +  UINT32 Index;
> +  UINT32 TransferReg;
> +  UINT32 TransferPages;
> +  UINT32 XenVersion;
> +
> +  AsmCpuid (XenLeaf + 2, &TransferPages, &TransferReg, NULL, NULL);
> +  mXenInfo.HyperPages = AllocatePages (TransferPages);
> +  if (!mXenInfo.HyperPages) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  for (Index = 0; Index < TransferPages; Index++) {
> +    AsmWriteMsr64 (TransferReg,
> +                   (UINTN) mXenInfo.HyperPages +
> +                   (Index << EFI_PAGE_SHIFT) + Index);
> +  }
> +
> +  AsmCpuid (XenLeaf + 1, &XenVersion, NULL, NULL, NULL);
> +  DEBUG ((EFI_D_ERROR, "Detected Xen version %d.%d\n",
> +          XenVersion >> 16, XenVersion & 0xFFFF));
> +  mXenInfo.VersionMajor = (UINT16)(XenVersion >> 16);
> +  mXenInfo.VersionMinor = (UINT16)(XenVersion & 0xFFFF);
> +
> +  /* TBD: Locate hvm_info and reserve it away. */
> +  mXenInfo.HvmInfo = NULL;
> +
> +  BuildGuidDataHob (
> +    &gEfiXenInfoGuid,
> +    &mXenInfo,
> +    sizeof(mXenInfo)
> +    );
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Figures out if we are running inside Xen HVM.
> +
> +  @retval TRUE   Xen was detected
> +  @retval FALSE  Xen was not detected
> +
> +**/
> +BOOLEAN
> +XenDetect (
> +  VOID
> +  )
> +{
> +  UINT8 Signature[13];
> +
> +  if (mXenLeaf != 0) {
> +    return TRUE;
> +  }
> +
> +  Signature[12] = '\0';
> +  for (mXenLeaf = 0x40000000; mXenLeaf < 0x40010000; mXenLeaf += 0x100) {
> +    AsmCpuid (mXenLeaf,
> +              NULL,
> +              (UINT32 *) &Signature[0],
> +              (UINT32 *) &Signature[4],
> +              (UINT32 *) &Signature[8]);
> +
> +    if (!AsciiStrCmp ((CHAR8 *) Signature, "XenVMMXenVMM")) {
> +      mXen = TRUE;
> +      return TRUE;
> +    }
> +  }
> +
> +  mXenLeaf = 0;
> +  return FALSE;
> +}
> +
> +
> +VOID
> +XenPublishRamRegions (
> +  VOID
> +  )
> +{
> +  EFI_E820_ENTRY64  *E820Map;
> +  UINT32            E820EntriesCount;
> +  EFI_STATUS        Status;
> +
> +  if (!mXen) {
> +    return;
> +  }
> +
> +  DEBUG ((EFI_D_INFO, "Using memory map provided by Xen\n"));
> +
> +  //
> +  // Parse RAM in E820 map
> +  //
> +  E820EntriesCount = 0;
> +  Status = XenGetE820Map (&E820Map, &E820EntriesCount);
> +
> +  ASSERT_EFI_ERROR (Status);
> +
> +  if (E820EntriesCount > 0) {
> +    EFI_E820_ENTRY64 *Entry;
> +    UINT32 Loop;
> +
> +    for (Loop = 0; Loop < E820EntriesCount; Loop++) {
> +      Entry = E820Map + Loop;
> +
> +      //
> +      // Only care about RAM
> +      //
> +      if (Entry->Type != EfiAcpiAddressRangeMemory) {
> +        continue;
> +      }
> +
> +      AddMemoryBaseSizeHob (Entry->BaseAddr, Entry->Length);
> +
> +      MtrrSetMemoryAttribute (Entry->BaseAddr, Entry->Length, CacheWriteBack);
> +    }
> +  }
> +}
> +
> +
> +/**
> +  Perform Xen PEI initialization.
> +
> +  @return EFI_SUCCESS     Xen initialized successfully
> +  @return EFI_NOT_FOUND   Not running under Xen
> +
> +**/
> +EFI_STATUS
> +InitializeXen (
> +  VOID
> +  )
> +{
> +  RETURN_STATUS PcdStatus;
> +
> +  if (mXenLeaf == 0) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  XenConnect (mXenLeaf);
> +
> +  //
> +  // Reserve away HVMLOADER reserved memory [0xFC000000,0xFD000000).
> +  // This needs to match HVMLOADER RESERVED_MEMBASE/RESERVED_MEMSIZE.
> +  //
> +  AddReservedMemoryBaseSizeHob (0xFC000000, 0x1000000, FALSE);
> +
> +  PcdStatus = PcdSetBoolS (PcdPciDisableBusEnumeration, TRUE);
> +  ASSERT_RETURN_ERROR (PcdStatus);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/OvmfPkg/XenPlatformPei/Xen.h b/OvmfPkg/XenPlatformPei/Xen.h
> new file mode 100644
> index 0000000..2a8a32b
> --- /dev/null
> +++ b/OvmfPkg/XenPlatformPei/Xen.h
> @@ -0,0 +1,45 @@
> +/** @file
> +  Ovmf info structure passed by Xen
> +
> +Copyright (c) 2013, Citrix Systems UK Ltd.<BR>
> +
> +This program and the accompanying materials are licensed and made available under
> +the terms and conditions of the BSD License that accompanies this distribution.
> +The full text of the license may be found at
> +http://opensource.org/licenses/bsd-license.php.
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef __XEN_H__
> +#define __XEN_H__
> +
> +#include <PiPei.h>
> +
> +// Physical address of OVMF info
> +#define OVMF_INFO_PHYSICAL_ADDRESS 0x00001000
> +
> +// This structure must match the definition on Xen side
> +#pragma pack(1)
> +typedef struct {
> +  CHAR8 Signature[14]; // XenHVMOVMF\0
> +  UINT8 Length;        // Length of this structure
> +  UINT8 Checksum;      // Set such that the sum over bytes 0..length == 0
> +  //
> +  // Physical address of an array of TablesCount elements.
> +  //
> +  // Each element contains the physical address of a BIOS table.
> +  //
> +  EFI_PHYSICAL_ADDRESS Tables;
> +  UINT32 TablesCount;
> +  //
> +  // Physical address of the E820 table, contains E820EntriesCount entries.
> +  //
> +  EFI_PHYSICAL_ADDRESS E820;
> +  UINT32 E820EntriesCount;
> +} EFI_XEN_OVMF_INFO;
> +#pragma pack()
> +
> +#endif /* __XEN_H__ */
> diff --git a/OvmfPkg/XenPlatformPei/XenPlatformPei.inf b/OvmfPkg/XenPlatformPei/XenPlatformPei.inf
> new file mode 100644
> index 0000000..dfa7d85
> --- /dev/null
> +++ b/OvmfPkg/XenPlatformPei/XenPlatformPei.inf
> @@ -0,0 +1,110 @@
> +## @file
> +#  Platform PEI driver
> +#
> +#  This module provides platform specific function to detect boot mode.
> +#  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
> +#
> +#  This program and the accompanying materials
> +#  are licensed and made available under the terms and conditions of the BSD License
> +#  which accompanies this distribution. The full text of the license may be found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = XenPlatformPei
> +  FILE_GUID                      = f112a6ee-993a-4f0b-8295-e52029d9b4ba
> +  MODULE_TYPE                    = PEIM
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = InitializeXenPlatform
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
> +#
> +
> +[Sources]
> +  Cmos.c
> +  Fv.c
> +  MemDetect.c
> +  Platform.c
> +  Xen.c
> +
> +[Packages]
> +  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  UefiCpuPkg/UefiCpuPkg.dec
> +  OvmfPkg/OvmfPkg.dec
> +
> +[Guids]
> +  gEfiMemoryTypeInformationGuid
> +  gEfiXenInfoGuid
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  HobLib
> +  IoLib
> +  PciLib
> +  PeiResourcePublicationLib
> +  PeiServicesLib
> +  PeiServicesTablePointerLib
> +  PeimEntryPoint
> +  MtrrLib
> +  PcdLib
> +
> +[Pcd]
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvBase
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfPeiMemFvSize
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvBase
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDxeMemFvSize
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamBase
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPeiTempRamSize
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesBase
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfSecPageTablesSize
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageBase
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfLockBoxStorageSize
> +  gUefiOvmfPkgTokenSpaceGuid.PcdGuidedExtractHandlerTableSize
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
> +  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase
> +  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoSize
> +  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Base
> +  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Size
> +  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Base
> +  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Size
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfDecompressionScratchEnd
> +  gUefiOvmfPkgTokenSpaceGuid.PcdQ35TsegMbytes
> +  gEfiMdePkgTokenSpaceGuid.PcdGuidedExtractHandlerTableAddress
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdPropertiesTableEnable
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiS3Enable
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
> +  gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
> +
> +[FixedPcd]
> +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> +
> +[FeaturePcd]
> +  gUefiOvmfPkgTokenSpaceGuid.PcdSmmSmramRequire
> +
> +[Ppis]
> +  gEfiPeiMasterBootModePpiGuid
> +  gEfiPeiMpServicesPpiGuid
> +
> +[Depex]
> +  TRUE
> +
> 



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 05/14] OvmfPkg/Library: add XenPciHostBridgeLib
  2016-12-08 15:33 ` [PATCH RFC 05/14] OvmfPkg/Library: add XenPciHostBridgeLib Anthony PERARD
@ 2017-01-05 10:15   ` Laszlo Ersek
  0 siblings, 0 replies; 37+ messages in thread
From: Laszlo Ersek @ 2017-01-05 10:15 UTC (permalink / raw)
  To: Anthony PERARD, edk2-devel, xen-devel

On 12/08/16 16:33, Anthony PERARD wrote:
> A copy of OvmfPkg/Library/PciHostBridgeLib
> 
> Removing support for pci bus enumeration, I think, and only use scan of
> already enumerated pci bus.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>  .../Library/XenPciHostBridgeLib/XenPciHostBridge.h |  75 ++++
>  .../XenPciHostBridgeLib/XenPciHostBridgeLib.c      | 291 +++++++++++++
>  .../XenPciHostBridgeLib/XenPciHostBridgeLib.inf    |  58 +++
>  OvmfPkg/Library/XenPciHostBridgeLib/XenSupport.c   | 456 +++++++++++++++++++++
>  4 files changed, 880 insertions(+)
>  create mode 100644 OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridge.h
>  create mode 100644 OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridgeLib.c
>  create mode 100644 OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridgeLib.inf
>  create mode 100644 OvmfPkg/Library/XenPciHostBridgeLib/XenSupport.c

(1) I think the following subject line is more idiomatic:

  OvmfPkg: add XenPciHostBridgeLib

Then, I'll practically repeat my comments for the previous patch:

(2) You might want to add Citrix copyright notices to new files.

(3) The Xen-related code that remains in the original PciHostBridgeLib
instance should be possible to remove later; if that's the case, can you
please write a subsequent patch for that too?

(4) The removed functionality should be named more precisely in the
commit message:

- PciHostBridgeGetRootBridges(): the search for extra PCI root buses
(which come from QEMU's pxb and pxb-pcie devices) is removed (hence the
"etc/extra-pci-roots" fw_cfg file is no longer consulted either, which
is otherwise used to speed up the search).

The Xen-specific ScanForRootBridges() function call is hardwired.

(5) It would be nice to hint at the reason (which is implemented in a
later patch) why a separate module is a good idea here. That is, why the
expected PVH2 functionality is best not added to the current
PciHostBridgeLib instance.

More below:

> diff --git a/OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridge.h b/OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridge.h
> new file mode 100644
> index 0000000..c23d40c
> --- /dev/null
> +++ b/OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridge.h
> @@ -0,0 +1,75 @@
> +/** @file
> +  Header file of OVMF instance of PciHostBridgeLib.
> +
> +  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +
> +  This program and the accompanying materials are licensed and made available
> +  under the terms and conditions of the BSD License which accompanies this
> +  distribution.  The full text of the license may be found at
> +  http://opensource.org/licenses/bsd-license.php.
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
> +  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +PCI_ROOT_BRIDGE *
> +ScanForRootBridges (
> +  UINTN      *NumberOfRootBridges
> +);
> +
> +/**
> +  Initialize a PCI_ROOT_BRIDGE structure.
> +
> +  @param[in]  Supports         Supported attributes.
> +
> +  @param[in]  Attributes       Initial attributes.
> +
> +  @param[in]  AllocAttributes  Allocation attributes.
> +
> +  @param[in]  RootBusNumber    The bus number to store in RootBus.
> +
> +  @param[in]  MaxSubBusNumber  The inclusive maximum bus number that can be
> +                               assigned to any subordinate bus found behind any
> +                               PCI bridge hanging off this root bus.
> +
> +                               The caller is repsonsible for ensuring that
> +                               RootBusNumber <= MaxSubBusNumber. If
> +                               RootBusNumber equals MaxSubBusNumber, then the
> +                               root bus has no room for subordinate buses.
> +
> +  @param[in]  Io               IO aperture.
> +
> +  @param[in]  Mem              MMIO aperture.
> +
> +  @param[in]  MemAbove4G       MMIO aperture above 4G.
> +
> +  @param[in]  PMem             Prefetchable MMIO aperture.
> +
> +  @param[in]  PMemAbove4G      Prefetchable MMIO aperture above 4G.
> +
> +  @param[out] RootBus          The PCI_ROOT_BRIDGE structure (allocated by the
> +                               caller) that should be filled in by this
> +                               function.
> +
> +  @retval EFI_SUCCESS           Initialization successful. A device path
> +                                consisting of an ACPI device path node, with
> +                                UID = RootBusNumber, has been allocated and
> +                                linked into RootBus.
> +
> +  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
> +**/
> +EFI_STATUS
> +InitRootBridge (
> +  IN  UINT64                   Supports,
> +  IN  UINT64                   Attributes,
> +  IN  UINT64                   AllocAttributes,
> +  IN  UINT8                    RootBusNumber,
> +  IN  UINT8                    MaxSubBusNumber,
> +  IN  PCI_ROOT_BRIDGE_APERTURE *Io,
> +  IN  PCI_ROOT_BRIDGE_APERTURE *Mem,
> +  IN  PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,
> +  IN  PCI_ROOT_BRIDGE_APERTURE *PMem,
> +  IN  PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G,
> +  OUT PCI_ROOT_BRIDGE          *RootBus
> +  );
> diff --git a/OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridgeLib.c b/OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridgeLib.c
> new file mode 100644
> index 0000000..efcd830
> --- /dev/null
> +++ b/OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridgeLib.c
> @@ -0,0 +1,291 @@
> +/** @file
> +  OVMF's instance of the PCI Host Bridge Library.
> +
> +  Copyright (C) 2016, Red Hat, Inc.
> +  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +
> +  This program and the accompanying materials are licensed and made available
> +  under the terms and conditions of the BSD License which accompanies this
> +  distribution.  The full text of the license may be found at
> +  http://opensource.org/licenses/bsd-license.php.
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
> +  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +#include <PiDxe.h>
> +
> +#include <IndustryStandard/Pci.h>
> +#include <IndustryStandard/Q35MchIch9.h>
> +
> +#include <Protocol/PciHostBridgeResourceAllocation.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PciHostBridgeLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/QemuFwCfgLib.h>
> +#include "XenPciHostBridge.h"
> +
> +
> +#pragma pack(1)
> +typedef struct {
> +  ACPI_HID_DEVICE_PATH     AcpiDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
> +} OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH;
> +#pragma pack ()
> +
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED
> +CHAR16 *mPciHostBridgeLibAcpiAddressSpaceTypeStr[] = {
> +  L"Mem", L"I/O", L"Bus"
> +};
> +
> +
> +STATIC
> +CONST
> +OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate = {
> +  {
> +    {
> +      ACPI_DEVICE_PATH,
> +      ACPI_DP,
> +      {
> +        (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),
> +        (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)
> +      }
> +    },
> +    EISA_PNP_ID(0x0A03), // HID
> +    0                    // UID
> +  },
> +
> +  {
> +    END_DEVICE_PATH_TYPE,
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    {
> +      END_DEVICE_PATH_LENGTH,
> +      0
> +    }
> +  }
> +};
> +
> +/**
> +  Initialize a PCI_ROOT_BRIDGE structure.
> +
> +  @param[in]  Supports         Supported attributes.
> +
> +  @param[in]  Attributes       Initial attributes.
> +
> +  @param[in]  AllocAttributes  Allocation attributes.
> +
> +  @param[in]  RootBusNumber    The bus number to store in RootBus.
> +
> +  @param[in]  MaxSubBusNumber  The inclusive maximum bus number that can be
> +                               assigned to any subordinate bus found behind any
> +                               PCI bridge hanging off this root bus.
> +
> +                               The caller is repsonsible for ensuring that
> +                               RootBusNumber <= MaxSubBusNumber. If
> +                               RootBusNumber equals MaxSubBusNumber, then the
> +                               root bus has no room for subordinate buses.
> +
> +  @param[in]  Io               IO aperture.
> +
> +  @param[in]  Mem              MMIO aperture.
> +
> +  @param[in]  MemAbove4G       MMIO aperture above 4G.
> +
> +  @param[in]  PMem             Prefetchable MMIO aperture.
> +
> +  @param[in]  PMemAbove4G      Prefetchable MMIO aperture above 4G.
> +
> +  @param[out] RootBus          The PCI_ROOT_BRIDGE structure (allocated by the
> +                               caller) that should be filled in by this
> +                               function.
> +
> +  @retval EFI_SUCCESS           Initialization successful. A device path
> +                                consisting of an ACPI device path node, with
> +                                UID = RootBusNumber, has been allocated and
> +                                linked into RootBus.
> +
> +  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
> +**/
> +EFI_STATUS
> +InitRootBridge (
> +  IN  UINT64                   Supports,
> +  IN  UINT64                   Attributes,
> +  IN  UINT64                   AllocAttributes,
> +  IN  UINT8                    RootBusNumber,
> +  IN  UINT8                    MaxSubBusNumber,
> +  IN  PCI_ROOT_BRIDGE_APERTURE *Io,
> +  IN  PCI_ROOT_BRIDGE_APERTURE *Mem,
> +  IN  PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,
> +  IN  PCI_ROOT_BRIDGE_APERTURE *PMem,
> +  IN  PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G,
> +  OUT PCI_ROOT_BRIDGE          *RootBus
> +  )
> +{
> +  OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath;
> +
> +  //
> +  // Be safe if other fields are added to PCI_ROOT_BRIDGE later.
> +  //
> +  ZeroMem (RootBus, sizeof *RootBus);
> +
> +  RootBus->Segment = 0;
> +
> +  RootBus->Supports   = Supports;
> +  RootBus->Attributes = Attributes;
> +
> +  RootBus->DmaAbove4G = FALSE;
> +
> +  RootBus->AllocationAttributes = AllocAttributes;
> +  RootBus->Bus.Base  = RootBusNumber;
> +  RootBus->Bus.Limit = MaxSubBusNumber;
> +  CopyMem (&RootBus->Io, Io, sizeof (*Io));
> +  CopyMem (&RootBus->Mem, Mem, sizeof (*Mem));
> +  CopyMem (&RootBus->MemAbove4G, MemAbove4G, sizeof (*MemAbove4G));
> +  CopyMem (&RootBus->PMem, PMem, sizeof (*PMem));
> +  CopyMem (&RootBus->PMemAbove4G, PMemAbove4G, sizeof (*PMemAbove4G));
> +
> +  RootBus->NoExtendedConfigSpace = (PcdGet16 (PcdOvmfHostBridgePciDevId) !=
> +                                    INTEL_Q35_MCH_DEVICE_ID);
> +
> +  DevicePath = AllocateCopyPool (sizeof mRootBridgeDevicePathTemplate,
> +                 &mRootBridgeDevicePathTemplate);
> +  if (DevicePath == NULL) {
> +    DEBUG ((EFI_D_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +  DevicePath->AcpiDevicePath.UID = RootBusNumber;
> +  RootBus->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;
> +
> +  DEBUG ((EFI_D_INFO,
> +    "%a: populated root bus %d, with room for %d subordinate bus(es)\n",
> +    __FUNCTION__, RootBusNumber, MaxSubBusNumber - RootBusNumber));
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Uninitialize a PCI_ROOT_BRIDGE structure set up with InitRootBridge().
> +
> +  param[in] RootBus  The PCI_ROOT_BRIDGE structure, allocated by the caller and
> +                     initialized with InitRootBridge(), that should be
> +                     uninitialized. This function doesn't free RootBus.
> +**/
> +STATIC
> +VOID
> +UninitRootBridge (
> +  IN PCI_ROOT_BRIDGE *RootBus
> +  )
> +{
> +  FreePool (RootBus->DevicePath);
> +}
> +
> +
> +/**
> +  Return all the root bridge instances in an array.
> +
> +  @param Count  Return the count of root bridge instances.
> +
> +  @return All the root bridge instances in an array.
> +          The array should be passed into PciHostBridgeFreeRootBridges()
> +          when it's not used.
> +**/
> +PCI_ROOT_BRIDGE *
> +EFIAPI
> +PciHostBridgeGetRootBridges (
> +  UINTN *Count
> +  )
> +{
> +  ASSERT (PcdGetBool (PcdPciDisableBusEnumeration));
> +  return ScanForRootBridges (Count);
> +}
> +
> +
> +/**
> +  Free the root bridge instances array returned from
> +  PciHostBridgeGetRootBridges().
> +
> +  @param  The root bridge instances array.
> +  @param  The count of the array.
> +**/
> +VOID
> +EFIAPI
> +PciHostBridgeFreeRootBridges (
> +  PCI_ROOT_BRIDGE *Bridges,
> +  UINTN           Count
> +  )
> +{
> +  if (Bridges == NULL && Count == 0) {
> +    return;
> +  }
> +  ASSERT (Bridges != NULL && Count > 0);
> +
> +  do {
> +    --Count;
> +    UninitRootBridge (&Bridges[Count]);
> +  } while (Count > 0);
> +
> +  FreePool (Bridges);
> +}
> +
> +
> +/**
> +  Inform the platform that the resource conflict happens.
> +
> +  @param HostBridgeHandle Handle of the Host Bridge.
> +  @param Configuration    Pointer to PCI I/O and PCI memory resource
> +                          descriptors. The Configuration contains the resources
> +                          for all the root bridges. The resource for each root
> +                          bridge is terminated with END descriptor and an
> +                          additional END is appended indicating the end of the
> +                          entire resources. The resource descriptor field
> +                          values follow the description in
> +                          EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
> +                          .SubmitResources().
> +**/
> +VOID
> +EFIAPI
> +PciHostBridgeResourceConflict (
> +  EFI_HANDLE                        HostBridgeHandle,
> +  VOID                              *Configuration
> +  )
> +{
> +  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
> +  UINTN                             RootBridgeIndex;
> +  DEBUG ((EFI_D_ERROR, "PciHostBridge: Resource conflict happens!\n"));
> +
> +  RootBridgeIndex = 0;
> +  Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;
> +  while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
> +    DEBUG ((EFI_D_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++));
> +    for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
> +      ASSERT (Descriptor->ResType <
> +              ARRAY_SIZE (mPciHostBridgeLibAcpiAddressSpaceTypeStr)
> +              );
> +      DEBUG ((EFI_D_ERROR, " %s: Length/Alignment = 0x%lx / 0x%lx\n",
> +              mPciHostBridgeLibAcpiAddressSpaceTypeStr[Descriptor->ResType],
> +              Descriptor->AddrLen, Descriptor->AddrRangeMax
> +              ));
> +      if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
> +        DEBUG ((EFI_D_ERROR, "     Granularity/SpecificFlag = %ld / %02x%s\n",
> +                Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag,
> +                ((Descriptor->SpecificFlag &
> +                  EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE
> +                  ) != 0) ? L" (Prefetchable)" : L""
> +                ));
> +      }
> +    }
> +    //
> +    // Skip the END descriptor for root bridge
> +    //
> +    ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR);
> +    Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)(
> +                   (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1
> +                   );
> +  }
> +}
> diff --git a/OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridgeLib.inf b/OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridgeLib.inf
> new file mode 100644
> index 0000000..3b8f003
> --- /dev/null
> +++ b/OvmfPkg/Library/XenPciHostBridgeLib/XenPciHostBridgeLib.inf
> @@ -0,0 +1,58 @@
> +## @file
> +#  OVMF's instance of the PCI Host Bridge Library.
> +#
> +#  Copyright (C) 2016, Red Hat, Inc.
> +#  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +#
> +#  This program and the accompanying materials are licensed and made available
> +#  under the terms and conditions of the BSD License which accompanies this
> +#  distribution. The full text of the license may be found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
> +#  IMPLIED.
> +#
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = XenPciHostBridgeLib
> +  FILE_GUID                      = 9F2BC05E-51EA-4AED-9A3E-7699641734E8

(6) You forgot to generate a new FILE_GUID with uuidgen.

Thanks
Laszlo

> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PciHostBridgeLib
> +
> +#
> +# The following information is for reference only and not required by the build
> +# tools.
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
> +#
> +
> +[Sources]
> +  XenPciHostBridgeLib.c
> +  XenSupport.c
> +  XenPciHostBridge.h
> +
> +[Packages]
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  OvmfPkg/OvmfPkg.dec
> +
> +[LibraryClasses]
> +  BaseMemoryLib
> +  DebugLib
> +  DevicePathLib
> +  MemoryAllocationLib
> +  PciLib
> +
> +[Pcd]
> +  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoBase
> +  gUefiOvmfPkgTokenSpaceGuid.PcdPciIoSize
> +  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Base
> +  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio32Size
> +  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Base
> +  gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Size
> +  gUefiOvmfPkgTokenSpaceGuid.PcdOvmfHostBridgePciDevId
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
> diff --git a/OvmfPkg/Library/XenPciHostBridgeLib/XenSupport.c b/OvmfPkg/Library/XenPciHostBridgeLib/XenSupport.c
> new file mode 100644
> index 0000000..a45945f
> --- /dev/null
> +++ b/OvmfPkg/Library/XenPciHostBridgeLib/XenSupport.c
> @@ -0,0 +1,456 @@
> +/** @file
> +  Scan the entire PCI bus for root bridges to support OVMF above Xen.
> +
> +  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +
> +  This program and the accompanying materials are licensed and made available
> +  under the terms and conditions of the BSD License which accompanies this
> +  distribution.  The full text of the license may be found at
> +  http://opensource.org/licenses/bsd-license.php.
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
> +  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +#include <PiDxe.h>
> +
> +#include <IndustryStandard/Pci.h>
> +#include <IndustryStandard/Q35MchIch9.h>
> +
> +#include <Protocol/PciHostBridgeResourceAllocation.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PciHostBridgeLib.h>
> +#include <Library/PciLib.h>
> +#include "XenPciHostBridge.h"
> +
> +STATIC
> +VOID
> +PcatPciRootBridgeBarExisted (
> +  IN  UINTN                          Address,
> +  OUT UINT32                         *OriginalValue,
> +  OUT UINT32                         *Value
> +  )
> +{
> +  //
> +  // Preserve the original value
> +  //
> +  *OriginalValue = PciRead32 (Address);
> +
> +  //
> +  // Disable timer interrupt while the BAR is probed
> +  //
> +  DisableInterrupts ();
> +
> +  PciWrite32 (Address, 0xFFFFFFFF);
> +  *Value = PciRead32 (Address);
> +  PciWrite32 (Address, *OriginalValue);
> +
> +  //
> +  // Enable interrupt
> +  //
> +  EnableInterrupts ();
> +}
> +
> +STATIC
> +VOID
> +PcatPciRootBridgeParseBars (
> +  IN UINT16                         Command,
> +  IN UINTN                          Bus,
> +  IN UINTN                          Device,
> +  IN UINTN                          Function,
> +  IN UINTN                          BarOffsetBase,
> +  IN UINTN                          BarOffsetEnd,
> +  IN PCI_ROOT_BRIDGE_APERTURE       *Io,
> +  IN PCI_ROOT_BRIDGE_APERTURE       *Mem,
> +  IN PCI_ROOT_BRIDGE_APERTURE       *MemAbove4G,
> +  IN PCI_ROOT_BRIDGE_APERTURE       *PMem,
> +  IN PCI_ROOT_BRIDGE_APERTURE       *PMemAbove4G
> +
> +)
> +{
> +  UINT32                            OriginalValue;
> +  UINT32                            Value;
> +  UINT32                            OriginalUpperValue;
> +  UINT32                            UpperValue;
> +  UINT64                            Mask;
> +  UINTN                             Offset;
> +  UINT64                            Base;
> +  UINT64                            Length;
> +  UINT64                            Limit;
> +  PCI_ROOT_BRIDGE_APERTURE          *MemAperture;
> +
> +  for (Offset = BarOffsetBase; Offset < BarOffsetEnd; Offset += sizeof (UINT32)) {
> +    PcatPciRootBridgeBarExisted (
> +      PCI_LIB_ADDRESS (Bus, Device, Function, Offset),
> +      &OriginalValue, &Value
> +    );
> +    if (Value == 0) {
> +      continue;
> +    }
> +    if ((Value & BIT0) == BIT0) {
> +      //
> +      // IO Bar
> +      //
> +      if (Command & EFI_PCI_COMMAND_IO_SPACE) {
> +        Mask = 0xfffffffc;
> +        Base = OriginalValue & Mask;
> +        Length = ((~(Value & Mask)) & Mask) + 0x04;
> +        if (!(Value & 0xFFFF0000)) {
> +          Length &= 0x0000FFFF;
> +        }
> +        Limit = Base + Length - 1;
> +
> +        if (Base < Limit) {
> +          if (Io->Base > Base) {
> +            Io->Base = Base;
> +          }
> +          if (Io->Limit < Limit) {
> +            Io->Limit = Limit;
> +          }
> +        }
> +      }
> +    } else {
> +      //
> +      // Mem Bar
> +      //
> +      if (Command & EFI_PCI_COMMAND_MEMORY_SPACE) {
> +
> +        Mask = 0xfffffff0;
> +        Base = OriginalValue & Mask;
> +        Length = Value & Mask;
> +
> +        if ((Value & (BIT1 | BIT2)) == 0) {
> +          //
> +          // 32bit
> +          //
> +          Length = ((~Length) + 1) & 0xffffffff;
> +
> +          if ((Value & BIT3) == BIT3) {
> +            MemAperture = PMem;
> +          } else {
> +            MemAperture = Mem;
> +          }
> +        } else {
> +          //
> +          // 64bit
> +          //
> +          Offset += 4;
> +          PcatPciRootBridgeBarExisted (
> +            PCI_LIB_ADDRESS (Bus, Device, Function, Offset),
> +            &OriginalUpperValue,
> +            &UpperValue
> +          );
> +
> +          Base = Base | LShiftU64 ((UINT64) OriginalUpperValue, 32);
> +          Length = Length | LShiftU64 ((UINT64) UpperValue, 32);
> +          Length = (~Length) + 1;
> +
> +          if ((Value & BIT3) == BIT3) {
> +            MemAperture = PMemAbove4G;
> +          } else {
> +            MemAperture = MemAbove4G;
> +          }
> +        }
> +
> +        Limit = Base + Length - 1;
> +        if (Base < Limit) {
> +          if (MemAperture->Base > Base) {
> +            MemAperture->Base = Base;
> +          }
> +          if (MemAperture->Limit < Limit) {
> +            MemAperture->Limit = Limit;
> +          }
> +        }
> +      }
> +    }
> +  }
> +}
> +
> +PCI_ROOT_BRIDGE *
> +ScanForRootBridges (
> +  UINTN      *NumberOfRootBridges
> +  )
> +{
> +  UINTN      PrimaryBus;
> +  UINTN      SubBus;
> +  UINT8      Device;
> +  UINT8      Function;
> +  UINTN      NumberOfDevices;
> +  UINTN      Address;
> +  PCI_TYPE01 Pci;
> +  UINT64     Attributes;
> +  UINT64     Base;
> +  UINT64     Limit;
> +  UINT64     Value;
> +  PCI_ROOT_BRIDGE_APERTURE Io, Mem, MemAbove4G, PMem, PMemAbove4G, *MemAperture;
> +  PCI_ROOT_BRIDGE *RootBridges;
> +  UINTN      BarOffsetEnd;
> +
> +
> +  *NumberOfRootBridges = 0;
> +  RootBridges = NULL;
> +
> +  //
> +  // After scanning all the PCI devices on the PCI root bridge's primary bus,
> +  // update the Primary Bus Number for the next PCI root bridge to be this PCI
> +  // root bridge's subordinate bus number + 1.
> +  //
> +  for (PrimaryBus = 0; PrimaryBus <= PCI_MAX_BUS; PrimaryBus = SubBus + 1) {
> +    SubBus = PrimaryBus;
> +    Attributes = 0;
> +    Io.Base = Mem.Base = MemAbove4G.Base = PMem.Base = PMemAbove4G.Base = MAX_UINT64;
> +    Io.Limit = Mem.Limit = MemAbove4G.Limit = PMem.Limit = PMemAbove4G.Limit = 0;
> +    //
> +    // Scan all the PCI devices on the primary bus of the PCI root bridge
> +    //
> +    for (Device = 0, NumberOfDevices = 0; Device <= PCI_MAX_DEVICE; Device++) {
> +
> +      for (Function = 0; Function <= PCI_MAX_FUNC; Function++) {
> +
> +        //
> +        // Compute the PCI configuration address of the PCI device to probe
> +        //
> +        Address = PCI_LIB_ADDRESS (PrimaryBus, Device, Function, 0);
> +
> +        //
> +        // Read the Vendor ID from the PCI Configuration Header
> +        //
> +        if (PciRead16 (Address) == MAX_UINT16) {
> +          if (Function == 0) {
> +            //
> +            // If the PCI Configuration Read fails, or a PCI device does not
> +            // exist, then skip this entire PCI device
> +            //
> +            break;
> +          } else {
> +            //
> +            // If PCI function != 0, VendorId == 0xFFFF, we continue to search
> +            // PCI function.
> +            //
> +            continue;
> +          }
> +        }
> +
> +        //
> +        // Read the entire PCI Configuration Header
> +        //
> +        PciReadBuffer (Address, sizeof (Pci), &Pci);
> +
> +        //
> +        // Increment the number of PCI device found on the primary bus of the
> +        // PCI root bridge
> +        //
> +        NumberOfDevices++;
> +
> +        //
> +        // Look for devices with the VGA Palette Snoop enabled in the COMMAND
> +        // register of the PCI Config Header
> +        //
> +        if ((Pci.Hdr.Command & EFI_PCI_COMMAND_VGA_PALETTE_SNOOP) != 0) {
> +          Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;
> +          Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
> +        }
> +
> +        BarOffsetEnd = 0;
> +
> +        //
> +        // PCI-PCI Bridge
> +        //
> +        if (IS_PCI_BRIDGE (&Pci)) {
> +          //
> +          // Get the Bus range that the PPB is decoding
> +          //
> +          if (Pci.Bridge.SubordinateBus > SubBus) {
> +            //
> +            // If the suborinate bus number of the PCI-PCI bridge is greater
> +            // than the PCI root bridge's current subordinate bus number,
> +            // then update the PCI root bridge's subordinate bus number
> +            //
> +            SubBus = Pci.Bridge.SubordinateBus;
> +          }
> +
> +          //
> +          // Get the I/O range that the PPB is decoding
> +          //
> +          Value = Pci.Bridge.IoBase & 0x0f;
> +          Base = ((UINT32) Pci.Bridge.IoBase & 0xf0) << 8;
> +          Limit = (((UINT32) Pci.Bridge.IoLimit & 0xf0) << 8) | 0x0fff;
> +          if (Value == BIT0) {
> +            Base |= ((UINT32) Pci.Bridge.IoBaseUpper16 << 16);
> +            Limit |= ((UINT32) Pci.Bridge.IoLimitUpper16 << 16);
> +          }
> +          if (Base < Limit) {
> +            if (Io.Base > Base) {
> +              Io.Base = Base;
> +            }
> +            if (Io.Limit < Limit) {
> +              Io.Limit = Limit;
> +            }
> +          }
> +
> +          //
> +          // Get the Memory range that the PPB is decoding
> +          //
> +          Base = ((UINT32) Pci.Bridge.MemoryBase & 0xfff0) << 16;
> +          Limit = (((UINT32) Pci.Bridge.MemoryLimit & 0xfff0) << 16) | 0xfffff;
> +          if (Base < Limit) {
> +            if (Mem.Base > Base) {
> +              Mem.Base = Base;
> +            }
> +            if (Mem.Limit < Limit) {
> +              Mem.Limit = Limit;
> +            }
> +          }
> +
> +          //
> +          // Get the Prefetchable Memory range that the PPB is decoding
> +          //
> +          Value = Pci.Bridge.PrefetchableMemoryBase & 0x0f;
> +          Base = ((UINT32) Pci.Bridge.PrefetchableMemoryBase & 0xfff0) << 16;
> +          Limit = (((UINT32) Pci.Bridge.PrefetchableMemoryLimit & 0xfff0)
> +                   << 16) | 0xfffff;
> +          MemAperture = &PMem;
> +          if (Value == BIT0) {
> +            Base |= LShiftU64 (Pci.Bridge.PrefetchableBaseUpper32, 32);
> +            Limit |= LShiftU64 (Pci.Bridge.PrefetchableLimitUpper32, 32);
> +            MemAperture = &PMemAbove4G;
> +          }
> +          if (Base < Limit) {
> +            if (MemAperture->Base > Base) {
> +              MemAperture->Base = Base;
> +            }
> +            if (MemAperture->Limit < Limit) {
> +              MemAperture->Limit = Limit;
> +            }
> +          }
> +
> +          //
> +          // Look at the PPB Configuration for legacy decoding attributes
> +          //
> +          if ((Pci.Bridge.BridgeControl & EFI_PCI_BRIDGE_CONTROL_ISA)
> +              == EFI_PCI_BRIDGE_CONTROL_ISA) {
> +            Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO;
> +            Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO_16;
> +            Attributes |= EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO;
> +          }
> +          if ((Pci.Bridge.BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA)
> +              == EFI_PCI_BRIDGE_CONTROL_VGA) {
> +            Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;
> +            Attributes |= EFI_PCI_ATTRIBUTE_VGA_MEMORY;
> +            Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO;
> +            if ((Pci.Bridge.BridgeControl & EFI_PCI_BRIDGE_CONTROL_VGA_16)
> +                != 0) {
> +              Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
> +              Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO_16;
> +            }
> +          }
> +
> +          BarOffsetEnd = OFFSET_OF (PCI_TYPE01, Bridge.Bar[2]);
> +        } else {
> +          //
> +          // Parse the BARs of the PCI device to get what I/O Ranges, Memory
> +          // Ranges, and Prefetchable Memory Ranges the device is decoding
> +          //
> +          if ((Pci.Hdr.HeaderType & HEADER_LAYOUT_CODE) == HEADER_TYPE_DEVICE) {
> +            BarOffsetEnd = OFFSET_OF (PCI_TYPE00, Device.Bar[6]);
> +          }
> +        }
> +
> +        PcatPciRootBridgeParseBars (
> +          Pci.Hdr.Command,
> +          PrimaryBus,
> +          Device,
> +          Function,
> +          OFFSET_OF (PCI_TYPE00, Device.Bar),
> +          BarOffsetEnd,
> +          &Io,
> +          &Mem, &MemAbove4G,
> +          &PMem, &PMemAbove4G
> +        );
> +
> +        //
> +        // See if the PCI device is an IDE controller
> +        //
> +        if (IS_CLASS2 (&Pci, PCI_CLASS_MASS_STORAGE,
> +                       PCI_CLASS_MASS_STORAGE_IDE)) {
> +          if (Pci.Hdr.ClassCode[0] & 0x80) {
> +            Attributes |= EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO;
> +            Attributes |= EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO;
> +          }
> +          if (Pci.Hdr.ClassCode[0] & 0x01) {
> +            Attributes |= EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO;
> +          }
> +          if (Pci.Hdr.ClassCode[0] & 0x04) {
> +            Attributes |= EFI_PCI_ATTRIBUTE_IDE_SECONDARY_IO;
> +          }
> +        }
> +
> +        //
> +        // See if the PCI device is a legacy VGA controller or
> +        // a standard VGA controller
> +        //
> +        if (IS_CLASS2 (&Pci, PCI_CLASS_OLD, PCI_CLASS_OLD_VGA) ||
> +            IS_CLASS2 (&Pci, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA)
> +            ) {
> +          Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO;
> +          Attributes |= EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO_16;
> +          Attributes |= EFI_PCI_ATTRIBUTE_VGA_MEMORY;
> +          Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO;
> +          Attributes |= EFI_PCI_ATTRIBUTE_VGA_IO_16;
> +        }
> +
> +        //
> +        // See if the PCI Device is a PCI - ISA or PCI - EISA
> +        // or ISA_POSITIVIE_DECODE Bridge device
> +        //
> +        if (Pci.Hdr.ClassCode[2] == PCI_CLASS_BRIDGE) {
> +          if (Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA ||
> +              Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_EISA ||
> +              Pci.Hdr.ClassCode[1] == PCI_CLASS_BRIDGE_ISA_PDECODE) {
> +            Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO;
> +            Attributes |= EFI_PCI_ATTRIBUTE_ISA_IO_16;
> +            Attributes |= EFI_PCI_ATTRIBUTE_ISA_MOTHERBOARD_IO;
> +          }
> +        }
> +
> +        //
> +        // If this device is not a multi function device, then skip the rest
> +        // of this PCI device
> +        //
> +        if (Function == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {
> +          break;
> +        }
> +      }
> +    }
> +
> +    //
> +    // If at least one PCI device was found on the primary bus of this PCI
> +    // root bridge, then the PCI root bridge exists.
> +    //
> +    if (NumberOfDevices > 0) {
> +      RootBridges = ReallocatePool (
> +        (*NumberOfRootBridges) * sizeof (PCI_ROOT_BRIDGE),
> +        (*NumberOfRootBridges + 1) * sizeof (PCI_ROOT_BRIDGE),
> +        RootBridges
> +      );
> +      ASSERT (RootBridges != NULL);
> +      InitRootBridge (
> +        Attributes, Attributes, 0,
> +        (UINT8) PrimaryBus, (UINT8) SubBus,
> +        &Io, &Mem, &MemAbove4G, &PMem, &PMemAbove4G,
> +        &RootBridges[*NumberOfRootBridges]
> +      );
> +      RootBridges[*NumberOfRootBridges].ResourceAssigned = TRUE;
> +      //
> +      // Increment the index for the next PCI Root Bridge
> +      //
> +      (*NumberOfRootBridges)++;
> +    }
> +  }
> +
> +  return RootBridges;
> +}
> 



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 06/14] OvmfPkg/XenPlatformPei: Add xen PVH specific code
  2016-12-08 15:33 ` [PATCH RFC 06/14] OvmfPkg/XenPlatformPei: Add xen PVH specific code Anthony PERARD
@ 2017-01-05 10:30   ` Laszlo Ersek
  2017-01-10 16:18     ` Anthony PERARD
  0 siblings, 1 reply; 37+ messages in thread
From: Laszlo Ersek @ 2017-01-05 10:30 UTC (permalink / raw)
  To: Anthony PERARD, edk2-devel, xen-devel

On 12/08/16 16:33, Anthony PERARD wrote:
> - learn about memory size from the E820
> - ignore error if host bridge devid is 0xffff, PVH does not have PCI and
>   reading from unexisting device return -1.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>  OvmfPkg/XenPlatformPei/MemDetect.c | 71 ++++++++++++++++++++++++++++++++++++++
>  OvmfPkg/XenPlatformPei/Platform.c  |  5 +++
>  OvmfPkg/XenPlatformPei/Platform.h  | 10 ++++++
>  3 files changed, 86 insertions(+)
> 
> diff --git a/OvmfPkg/XenPlatformPei/MemDetect.c b/OvmfPkg/XenPlatformPei/MemDetect.c
> index 4ecdf5e..0d80775 100644
> --- a/OvmfPkg/XenPlatformPei/MemDetect.c
> +++ b/OvmfPkg/XenPlatformPei/MemDetect.c
> @@ -42,6 +42,70 @@ UINT8 mPhysMemAddressWidth;
>  STATIC UINT32 mS3AcpiReservedMemoryBase;
>  STATIC UINT32 mS3AcpiReservedMemorySize;
>  
> +STATIC UINT32 mXenLowerMemorySize = 0;
> +STATIC UINT64 mXenHighMemorySize = 0;
> +
> +VOID
> +XenReadMemorySizes (
> +  VOID
> +  )
> +{
> +  EFI_E820_ENTRY64  *E820Map;
> +  UINT32            E820EntriesCount;
> +  EFI_STATUS Status;
> +
> +  Status = XenGetE820Map (&E820Map, &E820EntriesCount);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  mXenLowerMemorySize = 0;
> +  mXenHighMemorySize = 0;
> +
> +  if (E820EntriesCount > 0) {
> +    EFI_E820_ENTRY64 *Entry;
> +    UINT32 Loop;
> +
> +    for (Loop = 0; Loop < E820EntriesCount; Loop++) {
> +      Entry = E820Map + Loop;
> +
> +      //
> +      // Only care about RAM
> +      //
> +      if (Entry->Type != EfiAcpiAddressRangeMemory) {
> +        continue;
> +      }
> +
> +      if ((Entry->BaseAddr + Entry->Length) <= SIZE_16MB) {
> +        continue;
> +      }
> +
> +      if (Entry->BaseAddr < SIZE_16MB) {
> +        UINT64 bottom = Entry->BaseAddr;
> +        UINT64 size = Entry->Length;
> +        size -= SIZE_16MB - bottom;
> +        bottom = SIZE_16MB;
> +        mXenLowerMemorySize += size;
> +        continue;
> +      }
> +      if (Entry->BaseAddr <= SIZE_4GB) {
> +        UINT64 size = Entry->Length;
> +        mXenLowerMemorySize += size;
> +        continue;
> +      }
> +
> +      if (Entry->BaseAddr == SIZE_4GB) {
> +        mXenHighMemorySize = Entry->Length;
> +        continue;
> +      }
> +
> +      DEBUG ((EFI_D_INFO, "%a: ignored XenE820 entry (0x%llx, 0x%llx)\n",
> +              __FUNCTION__,
> +              Entry->BaseAddr,
> +              Entry->Length));
> +    }
> +    mXenLowerMemorySize += SIZE_16MB;
> +  }
> +}
> +
>  UINT32
>  GetSystemMemorySizeBelow4gb (
>    VOID
> @@ -50,6 +114,9 @@ GetSystemMemorySizeBelow4gb (
>    UINT8 Cmos0x34;
>    UINT8 Cmos0x35;
>  
> +  if (mXen && mXenLowerMemorySize)
> +    return mXenLowerMemorySize;
> +
>    //
>    // CMOS 0x34/0x35 specifies the system memory above 16 MB.
>    // * CMOS(0x35) is the high byte
> @@ -74,6 +141,10 @@ GetSystemMemorySizeAbove4gb (
>    UINT32 Size;
>    UINTN  CmosIndex;
>  
> +  // if lower memory is specified that way, return also high memory
> +  if (mXen && mXenLowerMemorySize)
> +    return mXenHighMemorySize;
> +
>    //
>    // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
>    // * CMOS(0x5d) is the most significant size byte
> diff --git a/OvmfPkg/XenPlatformPei/Platform.c b/OvmfPkg/XenPlatformPei/Platform.c
> index bf78878..9fc713c 100644
> --- a/OvmfPkg/XenPlatformPei/Platform.c
> +++ b/OvmfPkg/XenPlatformPei/Platform.c
> @@ -362,6 +362,10 @@ MiscInitialization (
>        AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL);
>        AcpiEnBit  = ICH9_ACPI_CNTL_ACPI_EN;
>        break;
> +    case 0xffff:
> +      // xen PVH, ignore
> +      PcdStatus = PcdSet16S (PcdOvmfHostBridgePciDevId, mHostBridgeDevId);
> +      return;

Can we create a new macro for 0xFFFF in
"OvmfPkg/Include/OvmfPlatforms.h", and use that here?

Normally I would suggest a separate header file under "OvmfPkg/Include",
similar to "Q35MchIch9.h" and "I440FxPiix4.h", and to include that new
file in "OvmfPlatforms.h", but here we only need a single "chipset
identifier", so I guess that can go directly into "OvmfPlatforms.h".

I mainly suggest this because in patch 08/14, the same 0xFFFF case label
is being added to code shared with QEMU, and using a verbose macro there
is much better than a magic number. In turn, we should use the same
macro here, I think.

Looks OK otherwise.

Thanks
Laszlo

>      default:
>        DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
>          __FUNCTION__, mHostBridgeDevId));
> @@ -503,6 +507,7 @@ InitializeXenPlatform (
>    DebugDumpCmos ();
>  
>    XenDetect ();
> +  XenReadMemorySizes ();
>  
>    BootModeInitialization ();
>    AddressWidthInitialization ();
> diff --git a/OvmfPkg/XenPlatformPei/Platform.h b/OvmfPkg/XenPlatformPei/Platform.h
> index eda765b..2948853 100644
> --- a/OvmfPkg/XenPlatformPei/Platform.h
> +++ b/OvmfPkg/XenPlatformPei/Platform.h
> @@ -101,4 +101,14 @@ extern BOOLEAN mS3Supported;
>  
>  extern UINT8 mPhysMemAddressWidth;
>  
> +EFI_STATUS
> +XenGetE820Map (
> +  EFI_E820_ENTRY64 **Entries,
> +  UINT32 *Count
> +  );
> +VOID
> +XenReadMemorySizes (
> +  VOID
> +  );
> +
>  #endif // _PLATFORM_PEI_H_INCLUDED_
> 



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 07/14] OvmfPkg/XenResetVector: Add new entry point for Xen PVH
  2016-12-08 15:33 ` [PATCH RFC 07/14] OvmfPkg/XenResetVector: Add new entry point for Xen PVH Anthony PERARD
@ 2017-01-05 10:36   ` Laszlo Ersek
  0 siblings, 0 replies; 37+ messages in thread
From: Laszlo Ersek @ 2017-01-05 10:36 UTC (permalink / raw)
  To: Anthony PERARD, edk2-devel, xen-devel

On 12/08/16 16:33, Anthony PERARD wrote:
> This one enter directly in 32bits
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>  OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm | 79 +++++++++++++++++++++++++
>  OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm      | 23 +++++++
>  OvmfPkg/XenResetVector/XenResetVector.nasmb     |  1 +
>  3 files changed, 103 insertions(+)
>  create mode 100644 OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
>  create mode 100644 OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm

(1) The new file "XenPVHMain.asm" is missing a license block (incl. a
Citrix copyright notice).

(2) You might want to add a similar (C) to the other new file,
"ResetVectorVtf0.asm", as well.

Thanks
Laszlo

> diff --git a/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
> new file mode 100644
> index 0000000..70436d8
> --- /dev/null
> +++ b/OvmfPkg/XenResetVector/Ia16/ResetVectorVtf0.asm
> @@ -0,0 +1,79 @@
> +;------------------------------------------------------------------------------
> +; @file
> +; First code executed by processor after resetting.
> +;
> +; Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
> +; This program and the accompanying materials
> +; are licensed and made available under the terms and conditions of the BSD License
> +; which accompanies this distribution.  The full text of the license may be found at
> +; http://opensource.org/licenses/bsd-license.php
> +;
> +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +;
> +;------------------------------------------------------------------------------
> +
> +BITS    16
> +
> +ALIGN   16
> +
> +;
> +; Pad the image size to 4k when page tables are in VTF0
> +;
> +; If the VTF0 image has page tables built in, then we need to make
> +; sure the end of VTF0 is 4k above where the page tables end.
> +;
> +; This is required so the page tables will be 4k aligned when VTF0 is
> +; located just below 0x100000000 (4GB) in the firmware device.
> +;
> +%ifdef ALIGN_TOP_TO_4K_FOR_PAGING
> +    TIMES (0x1000 - ($ - EndOfPageTables) - (fourGigabytes - xenPVHEntryPoint)) DB 0
> +%endif
> +
> +BITS    32
> +xenPVHEntryPoint:
> +; this is probably 0xffffffd0
> +  jmp xenPVHMain
> +
> +BITS    16
> +ALIGN   16
> +
> +applicationProcessorEntryPoint:
> +;
> +; Application Processors entry point
> +;
> +; GenFv generates code aligned on a 4k boundary which will jump to this
> +; location.  (0xffffffe0)  This allows the Local APIC Startup IPI to be
> +; used to wake up the application processors.
> +;
> +    jmp     EarlyApInitReal16
> +
> +ALIGN   8
> +
> +    DD      0
> +
> +;
> +; The VTF signature
> +;
> +; VTF-0 means that the VTF (Volume Top File) code does not require
> +; any fixups.
> +;
> +vtfSignature:
> +    DB      'V', 'T', 'F', 0
> +
> +ALIGN   16
> +
> +resetVector:
> +;
> +; Reset Vector
> +;
> +; This is where the processor will begin execution
> +;
> +    nop
> +    nop
> +    jmp     EarlyBspInitReal16
> +
> +ALIGN   16
> +
> +fourGigabytes:
> +
> diff --git a/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
> new file mode 100644
> index 0000000..eb12f6c
> --- /dev/null
> +++ b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
> @@ -0,0 +1,23 @@
> +BITS 32
> +
> +xenPVHMain:
> +  mov di, 'BP'
> +
> +  cli
> +  mov ebx, ADDR_OF(gdtr)
> +  lgdt [ebx]
> +  mov eax, SEC_DEFAULT_CR0
> +  mov cr0, eax
> +  jmp LINEAR_CODE_SEL:ADDR_OF(jmpHerePVH)
> +jmpHerePVH:
> +  mov eax, SEC_DEFAULT_CR4
> +  mov cr4, eax
> +
> +  mov     ax, LINEAR_SEL
> +  mov     ds, ax
> +  mov     es, ax
> +  mov     fs, ax
> +  mov     gs, ax
> +  mov     ss, ax
> +
> +  OneTimeCallRet TransitionFromReal16To32BitFlat
> diff --git a/OvmfPkg/XenResetVector/XenResetVector.nasmb b/OvmfPkg/XenResetVector/XenResetVector.nasmb
> index 31ac06a..f9812fd 100644
> --- a/OvmfPkg/XenResetVector/XenResetVector.nasmb
> +++ b/OvmfPkg/XenResetVector/XenResetVector.nasmb
> @@ -61,6 +61,7 @@
>  %include "Ia16/Init16.asm"
>  
>  %include "Main.asm"
> +%include "Ia32/XenPVHMain.asm"
>  
>  %include "Ia16/ResetVectorVtf0.asm"
>  
> 



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 08/14] OvmfPkg/PlatformBootManagerLib: Workaround missing PCI bus on Xen PVH
  2016-12-08 15:33 ` [PATCH RFC 08/14] OvmfPkg/PlatformBootManagerLib: Workaround missing PCI bus on " Anthony PERARD
@ 2017-01-05 10:38   ` Laszlo Ersek
  0 siblings, 0 replies; 37+ messages in thread
From: Laszlo Ersek @ 2017-01-05 10:38 UTC (permalink / raw)
  To: Anthony PERARD, edk2-devel, xen-devel

On 12/08/16 16:33, Anthony PERARD wrote:
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>  OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
> index cc35630..bd64cc3 100644
> --- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
> +++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
> @@ -1152,6 +1152,8 @@ PciAcpiInitialization (
>        PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6a), 0x0b); // G
>        PciWrite8 (PCI_LIB_ADDRESS (0, 0x1f, 0, 0x6b), 0x0b); // H
>        break;
> +    case 0xffff:
> +      return;
>      default:
>        DEBUG ((EFI_D_ERROR, "%a: Unknown Host Bridge Device ID: 0x%04x\n",
>          __FUNCTION__, mHostBridgeDevId));
> 

Seems okay, but please use a new macro I mentined under patch 06/14. The
new macro name should contain the words XEN and PVH, preferably.

Thanks
Laszlo


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 09/14] OvmfPkg/ResetSystemLib: Add missing dependency on PciLib
  2016-12-08 15:33 ` [PATCH RFC 09/14] OvmfPkg/ResetSystemLib: Add missing dependency on PciLib Anthony PERARD
@ 2017-01-05 10:46   ` Laszlo Ersek
  0 siblings, 0 replies; 37+ messages in thread
From: Laszlo Ersek @ 2017-01-05 10:46 UTC (permalink / raw)
  To: Anthony PERARD, edk2-devel, xen-devel

On 12/08/16 16:33, Anthony PERARD wrote:
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>  OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf b/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
> index ecd462b..2e0ed48 100644
> --- a/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
> +++ b/OvmfPkg/Library/ResetSystemLib/ResetSystemLib.inf
> @@ -36,4 +36,5 @@
>  [LibraryClasses]
>    DebugLib
>    IoLib
> +  PciLib
>    TimerLib
> 

Please also #include <Library/PciLib.h> in "ResetSystemLib.c", for
consistency with the now-modified INF file.

(The lack of the #include directive is currently masked by the fact that
"OvmfPlatforms.h" includes "PciLib.h" too -- it needs PCI_LIB_ADDRESS().)

Also... not sure why, but we include "OvmfPlatforms.h" twice in
"ResetSystemLib.c". Can you please kill the second #include? Can be in
the same patch.

(Hm, it looks like the duplicate #include is my fault, an oversight from
commit 1466b76f9385.)

Thanks!
Laszlo


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 11/14] OvmfPkg/XenOvmf: Adding XenTimerLocalApic
  2016-12-08 15:33 ` [PATCH RFC 11/14] OvmfPkg/XenOvmf: Adding XenTimerLocalApic Anthony PERARD
@ 2017-01-05 11:26   ` Laszlo Ersek
  0 siblings, 0 replies; 37+ messages in thread
From: Laszlo Ersek @ 2017-01-05 11:26 UTC (permalink / raw)
  To: Anthony PERARD, edk2-devel, xen-devel

On 12/08/16 16:33, Anthony PERARD wrote:
> And replacing the ACPI Timer by this one based on the local APIC.
> 
> ACPI Timer does not work in a PVH guest, but local APIC works on both
> PVH and HVM.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> ---
>  OvmfPkg/XenOvmf.dsc                             |  18 +-
>  OvmfPkg/XenOvmf.fdf                             |   2 +-
>  OvmfPkg/XenTimerLocalApic/Timer.h               | 191 ++++++++++++
>  OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.c   | 386 ++++++++++++++++++++++++
>  OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.inf |  51 ++++
>  5 files changed, 640 insertions(+), 8 deletions(-)
>  create mode 100644 OvmfPkg/XenTimerLocalApic/Timer.h
>  create mode 100644 OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.c
>  create mode 100644 OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.inf

comments below:

> diff --git a/OvmfPkg/XenOvmf.dsc b/OvmfPkg/XenOvmf.dsc
> index ef32c33..31a2185 100644
> --- a/OvmfPkg/XenOvmf.dsc
> +++ b/OvmfPkg/XenOvmf.dsc
> @@ -81,7 +81,7 @@
>  ################################################################################
>  [LibraryClasses]
>    PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> -  TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf
> +  TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
>    PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
>    BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
>    BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
> @@ -175,7 +175,7 @@
>  !endif
>  
>  [LibraryClasses.common.SEC]
> -  TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
> +  TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
>    QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf
>  !ifdef $(DEBUG_ON_SERIAL_PORT)
>    DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
> @@ -251,7 +251,7 @@
>  
>  [LibraryClasses.common.DXE_RUNTIME_DRIVER]
>    PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> -  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
> +  TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
>    HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
>    DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
>    MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> @@ -269,7 +269,7 @@
>  
>  [LibraryClasses.common.UEFI_DRIVER]
>    PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> -  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
> +  TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
>    HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
>    DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
>    MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> @@ -284,7 +284,7 @@
>  
>  [LibraryClasses.common.DXE_DRIVER]
>    PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> -  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
> +  TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
>    HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
>    MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
>    ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
> @@ -314,7 +314,7 @@
>  
>  [LibraryClasses.common.UEFI_APPLICATION]
>    PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> -  TimerLib|OvmfPkg/Library/AcpiTimerLib/DxeAcpiTimerLib.inf
> +  TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf
>    HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
>    MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
>    ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf

(1) I suggest to split this patch if possible. In the first half, the
TimerLib class resolutions should be flipped, with the argument given in
the second paragraph of the commit message.

The subject line for the first patch should be something like

  OvmfPkg/XenOvmf: use a TimerLib instance that depends only on the CPU

> @@ -546,7 +546,11 @@
>  !endif
>  
>    MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
> -  PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
> +  OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.inf

(2) The second patch should introduce the new DXE_DRIVER module:

  OvmfPkg/XenOvmf: introduce XenTimerDxe

The commit message should document that
"PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf" is replaced with a
Xen-specific EFI_TIMER_ARCH_PROTOCOL implementation.

(3) The new DXE_DRIVER module should be located under "OvmfPkg/XenTimerDxe".

> +  #{
> +  #<LibraryClasses>
> +    #LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf
> +  #}

(4) Please don't just comment out unnecessary stuff; it's better to
remove those lines.

>    UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
>    UefiCpuPkg/CpuDxe/CpuDxe.inf
>    PcAtChipsetPkg/8254TimerDxe/8254Timer.inf
> diff --git a/OvmfPkg/XenOvmf.fdf b/OvmfPkg/XenOvmf.fdf
> index c211f61..f6876d7 100644
> --- a/OvmfPkg/XenOvmf.fdf
> +++ b/OvmfPkg/XenOvmf.fdf
> @@ -207,7 +207,7 @@ INF  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
>  INF  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
>  INF  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
>  INF  MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
> -INF  PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
> +INF  OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.inf
>  INF  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
>  INF  UefiCpuPkg/CpuDxe/CpuDxe.inf
>  INF  PcAtChipsetPkg/8254TimerDxe/8254Timer.inf
> diff --git a/OvmfPkg/XenTimerLocalApic/Timer.h b/OvmfPkg/XenTimerLocalApic/Timer.h
> new file mode 100644
> index 0000000..8d6f37c
> --- /dev/null
> +++ b/OvmfPkg/XenTimerLocalApic/Timer.h
> @@ -0,0 +1,191 @@
> +/** @file
> +  Private data structures
> +
> +Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD License
> +which accompanies this distribution.  The full text of the license may be found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +**/

(5) You might want to add a Citrix copyright notice to the new files.

> +
> +#ifndef _TIMER_H_
> +#define _TIMER_H_
> +
> +#include <PiDxe.h>
> +
> +#include <Protocol/Cpu.h>
> +#include <Protocol/Legacy8259.h>
> +#include <Protocol/Timer.h>
> +
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +
> +//
> +// The PCAT 8253/8254 has an input clock at 1.193182 MHz and Timer 0 is
> +// initialized as a 16 bit free running counter that generates an interrupt(IRQ0)
> +// each time the counter rolls over.
> +//
> +//   65536 counts
> +// ---------------- * 1,000,000 uS/S = 54925.4 uS = 549254 * 100 ns
> +//   1,193,182 Hz
> +//
> +
> +//
> +// The maximum tick duration for 8254 timer
> +//
> +#define MAX_TIMER_TICK_DURATION     549254
> +//
> +// The default timer tick duration is set to 10 ms = 100000 100 ns units
> +//
> +#define DEFAULT_TIMER_TICK_DURATION 100000
> +#define TIMER_CONTROL_PORT          0x43
> +#define TIMER0_COUNT_PORT           0x40
> +
> +//
> +// Function Prototypes
> +//
> +/**
> +  Initialize the Timer Architectural Protocol driver
> +
> +  @param ImageHandle     ImageHandle of the loaded driver
> +  @param SystemTable     Pointer to the System Table
> +
> +  @retval EFI_SUCCESS            Timer Architectural Protocol created
> +  @retval EFI_OUT_OF_RESOURCES   Not enough resources available to initialize driver.
> +  @retval EFI_DEVICE_ERROR       A device error occured attempting to initialize the driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverInitialize (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +;
> +
> +/**
> +
> +  This function adjusts the period of timer interrupts to the value specified
> +  by TimerPeriod.  If the timer period is updated, then the selected timer
> +  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
> +  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
> +  If an error occurs while attempting to update the timer period, then the
> +  timer hardware will be put back in its state prior to this call, and
> +  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
> +  is disabled.  This is not the same as disabling the CPU's interrupts.
> +  Instead, it must either turn off the timer hardware, or it must adjust the
> +  interrupt controller so that a CPU interrupt is not generated when the timer
> +  interrupt fires.
> +
> +
> +  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param NotifyFunction  The rate to program the timer interrupt in 100 nS units.  If
> +                         the timer hardware is not programmable, then EFI_UNSUPPORTED is
> +                         returned.  If the timer is programmable, then the timer period
> +                         will be rounded up to the nearest timer period that is supported
> +                         by the timer hardware.  If TimerPeriod is set to 0, then the
> +                         timer interrupts will be disabled.
> +
> +  @retval        EFI_SUCCESS       The timer period was changed.
> +  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.
> +  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverRegisterHandler (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This,
> +  IN EFI_TIMER_NOTIFY         NotifyFunction
> +  )
> +;
> +
> +/**
> +
> +  This function adjusts the period of timer interrupts to the value specified
> +  by TimerPeriod.  If the timer period is updated, then the selected timer
> +  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
> +  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
> +  If an error occurs while attempting to update the timer period, then the
> +  timer hardware will be put back in its state prior to this call, and
> +  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
> +  is disabled.  This is not the same as disabling the CPU's interrupts.
> +  Instead, it must either turn off the timer hardware, or it must adjust the
> +  interrupt controller so that a CPU interrupt is not generated when the timer
> +  interrupt fires.
> +
> +
> +  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param TimerPeriod     The rate to program the timer interrupt in 100 nS units.  If
> +                         the timer hardware is not programmable, then EFI_UNSUPPORTED is
> +                         returned.  If the timer is programmable, then the timer period
> +                         will be rounded up to the nearest timer period that is supported
> +                         by the timer hardware.  If TimerPeriod is set to 0, then the
> +                         timer interrupts will be disabled.
> +
> +  @retval        EFI_SUCCESS       The timer period was changed.
> +  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.
> +  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverSetTimerPeriod (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This,
> +  IN UINT64                   TimerPeriod
> +  )
> +;
> +
> +/**
> +
> +  This function retrieves the period of timer interrupts in 100 ns units,
> +  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod
> +  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is
> +  returned, then the timer is currently disabled.
> +
> +
> +  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param TimerPeriod     A pointer to the timer period to retrieve in 100 ns units.  If
> +                         0 is returned, then the timer is currently disabled.
> +
> +  @retval EFI_SUCCESS            The timer period was returned in TimerPeriod.
> +  @retval EFI_INVALID_PARAMETER  TimerPeriod is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverGetTimerPeriod (
> +  IN EFI_TIMER_ARCH_PROTOCOL   *This,
> +  OUT UINT64                   *TimerPeriod
> +  )
> +;
> +
> +/**
> +
> +  This function generates a soft timer interrupt. If the platform does not support soft
> +  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.
> +  If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
> +  service, then a soft timer interrupt will be generated. If the timer interrupt is
> +  enabled when this service is called, then the registered handler will be invoked. The
> +  registered handler should not be able to distinguish a hardware-generated timer
> +  interrupt from a software-generated timer interrupt.
> +
> +
> +  @param This              The EFI_TIMER_ARCH_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS       The soft timer interrupt was generated.
> +  @retval EFI_UNSUPPORTED   The platform does not support the generation of soft timer interrupts.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverGenerateSoftInterrupt (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This
> +  )
> +;
> +
> +#endif
> diff --git a/OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.c b/OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.c
> new file mode 100644
> index 0000000..7f3a8f0
> --- /dev/null
> +++ b/OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.c
> @@ -0,0 +1,386 @@
> +/** @file
> +  Timer Architectural Protocol as defined in the DXE CIS
> +
> +Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD License
> +which accompanies this distribution.  The full text of the license may be found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include <Register/LocalApic.h>
> +#include <Library/LocalApicLib.h>
> +#include <Library/PcdLib.h>
> +#include "Timer.h"
> +
> +//
> +// The handle onto which the Timer Architectural Protocol will be installed
> +//
> +EFI_HANDLE                mTimerHandle = NULL;
> +
> +//
> +// The Timer Architectural Protocol that this driver produces
> +//
> +EFI_TIMER_ARCH_PROTOCOL   mTimer = {
> +  TimerDriverRegisterHandler,
> +  TimerDriverSetTimerPeriod,
> +  TimerDriverGetTimerPeriod,
> +  TimerDriverGenerateSoftInterrupt
> +};
> +
> +//
> +// Pointer to the CPU Architectural Protocol instance
> +//
> +EFI_CPU_ARCH_PROTOCOL     *mCpu;
> +
> +//
> +// The notification function to call on every timer interrupt.
> +// A bug in the compiler prevents us from initializing this here.
> +//
> +EFI_TIMER_NOTIFY mTimerNotifyFunction;
> +
> +//
> +// The current period of the timer interrupt
> +//
> +volatile UINT64           mTimerPeriod = 0;
> +
> +//
> +// Worker Functions
> +//
> +/**
> +  8254 Timer #0 Interrupt Handler.
> +
> +  @param InterruptType    The type of interrupt that occured
> +  @param SystemContext    A pointer to the system context when the interrupt occured
> +**/
> +VOID
> +EFIAPI
> +TimerInterruptHandler (
> +  IN EFI_EXCEPTION_TYPE   InterruptType,
> +  IN EFI_SYSTEM_CONTEXT   SystemContext
> +  )
> +{
> +  EFI_TPL OriginalTPL;
> +
> +  OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
> +
> +  /* mLegacy8259->EndOfInterrupt (mLegacy8259, Efi8259Irq0); */

(6) Please remove this instead.

> +
> +  if (mTimerNotifyFunction != NULL) {
> +    //
> +    // @bug : This does not handle missed timer interrupts
> +    //
> +    mTimerNotifyFunction (mTimerPeriod);
> +  }
> +  SendApicEoi();
> +
> +  gBS->RestoreTPL (OriginalTPL);
> +}
> +
> +/**
> +
> +  This function registers the handler NotifyFunction so it is called every time
> +  the timer interrupt fires.  It also passes the amount of time since the last
> +  handler call to the NotifyFunction.  If NotifyFunction is NULL, then the
> +  handler is unregistered.  If the handler is registered, then EFI_SUCCESS is
> +  returned.  If the CPU does not support registering a timer interrupt handler,
> +  then EFI_UNSUPPORTED is returned.  If an attempt is made to register a handler
> +  when a handler is already registered, then EFI_ALREADY_STARTED is returned.
> +  If an attempt is made to unregister a handler when a handler is not registered,
> +  then EFI_INVALID_PARAMETER is returned.  If an error occurs attempting to
> +  register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR
> +  is returned.
> +
> +
> +  @param This             The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param NotifyFunction   The function to call when a timer interrupt fires.  This
> +                          function executes at TPL_HIGH_LEVEL.  The DXE Core will
> +                          register a handler for the timer interrupt, so it can know
> +                          how much time has passed.  This information is used to
> +                          signal timer based events.  NULL will unregister the handler.
> +
> +  @retval        EFI_SUCCESS            The timer handler was registered.
> +  @retval        EFI_UNSUPPORTED        The platform does not support timer interrupts.
> +  @retval        EFI_ALREADY_STARTED    NotifyFunction is not NULL, and a handler is already
> +                                        registered.
> +  @retval        EFI_INVALID_PARAMETER  NotifyFunction is NULL, and a handler was not
> +                                        previously registered.
> +  @retval        EFI_DEVICE_ERROR       The timer handler could not be registered.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverRegisterHandler (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This,
> +  IN EFI_TIMER_NOTIFY         NotifyFunction
> +  )
> +{
> +  //
> +  // Check for invalid parameters
> +  //
> +  DEBUG((EFI_D_ERROR, "%a %d\n", __FUNCTION__, __LINE__));

(7) This should either be removed, or turned into a DEBUG_VERBOSE message.

> +  if (NotifyFunction == NULL && mTimerNotifyFunction == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (NotifyFunction != NULL && mTimerNotifyFunction != NULL) {
> +    return EFI_ALREADY_STARTED;
> +  }
> +  DEBUG((EFI_D_ERROR, "%a %d\n", __FUNCTION__, __LINE__));

(8) Ditto.

> +
> +  mTimerNotifyFunction = NotifyFunction;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +  This function adjusts the period of timer interrupts to the value specified
> +  by TimerPeriod.  If the timer period is updated, then the selected timer
> +  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
> +  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
> +  If an error occurs while attempting to update the timer period, then the
> +  timer hardware will be put back in its state prior to this call, and
> +  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
> +  is disabled.  This is not the same as disabling the CPU's interrupts.
> +  Instead, it must either turn off the timer hardware, or it must adjust the
> +  interrupt controller so that a CPU interrupt is not generated when the timer
> +  interrupt fires.
> +
> +
> +  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param TimerPeriod     The rate to program the timer interrupt in 100 nS units.  If
> +                         the timer hardware is not programmable, then EFI_UNSUPPORTED is
> +                         returned.  If the timer is programmable, then the timer period
> +                         will be rounded up to the nearest timer period that is supported
> +                         by the timer hardware.  If TimerPeriod is set to 0, then the
> +                         timer interrupts will be disabled.
> +
> +  @retval        EFI_SUCCESS       The timer period was changed.
> +  @retval        EFI_UNSUPPORTED   The platform cannot change the period of the timer interrupt.
> +  @retval        EFI_DEVICE_ERROR  The timer period could not be changed due to a device error.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverSetTimerPeriod (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This,
> +  IN UINT64                   TimerPeriod
> +  )
> +{
> +  UINT64  TimerCount;
> +  UINT32  TimerFrequency;
> +  UINTN   DivideValue;
> +
> +  GetApicTimerState(&DivideValue, NULL, NULL);
> +
> +  // XXX rework comment, copy from other lib

(9) Stale comment?

> +  //
> +  //  The basic clock is 1.19318 MHz or 0.119318 ticks per 100 ns.
> +  //  TimerPeriod * 0.119318 = 8254 timer divisor. Using integer arithmetic
> +  //  TimerCount = (TimerPeriod * 119318)/1000000.
> +  //
> +  //  Round up to next highest integer. This guarantees that the timer is
> +  //  equal to or slightly longer than the requested time.
> +  //  TimerCount = ((TimerPeriod * 119318) + 500000)/1000000
> +  //
> +  // Note that a TimerCount of 0 is equivalent to a count of 65,536
> +  //
> +  if (TimerPeriod == 0) {
> +    //
> +    // Disable timer interrupt for a TimerPeriod of 0
> +    //
> +    DisableApicTimerInterrupt();
> +  } else {
> +    TimerFrequency = PcdGet32(PcdFSBClock) / DivideValue;
> +
> +    DEBUG((EFI_D_ERROR, "%a %d, fsbclock %d, freq %d\n",
> +           __FUNCTION__, __LINE__,
> +           PcdGet32(PcdFSBClock),
> +           TimerFrequency));

(10) Should be logged on DEBUG_VERBOSE or DEBUG_INFO level, I think.

Also, please keep a space between the function / macro name, and the
paren that opens the argument list.

> +
> +    //
> +    // Convert TimerPeriod into local apic counts
> +    //
> +
> +    TimerCount = DivU64x32 (MultU64x32 (TimerFrequency,
> +                                        (UINT32) TimerPeriod) + 500000,
> +                            1000000);
> +
> +    DEBUG((EFI_D_ERROR, "%a %d, new init val: %d\n", __FUNCTION__, __LINE__, TimerCount));

(11) DEBUG_VERBOSE or DEBUG_INFO, and spacing.

> +
> +    //
> +    // Program the timer with the new count value
> +    //
> +    WriteLocalApicReg (XAPIC_TIMER_INIT_COUNT_OFFSET, TimerCount);
> +
> +    //
> +    // Enable timer interrupt
> +    //
> +    EnableApicTimerInterrupt();
> +  }
> +  //
> +  // Save the new timer period
> +  //
> +  mTimerPeriod = TimerPeriod;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +  This function retrieves the period of timer interrupts in 100 ns units,
> +  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod
> +  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is
> +  returned, then the timer is currently disabled.
> +
> +
> +  @param This            The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param TimerPeriod     A pointer to the timer period to retrieve in 100 ns units.  If
> +                         0 is returned, then the timer is currently disabled.
> +
> +  @retval EFI_SUCCESS            The timer period was returned in TimerPeriod.
> +  @retval EFI_INVALID_PARAMETER  TimerPeriod is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverGetTimerPeriod (
> +  IN EFI_TIMER_ARCH_PROTOCOL   *This,
> +  OUT UINT64                   *TimerPeriod
> +  )
> +{
> +  if (TimerPeriod == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *TimerPeriod = mTimerPeriod;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +
> +  This function generates a soft timer interrupt. If the platform does not support soft
> +  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.
> +  If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
> +  service, then a soft timer interrupt will be generated. If the timer interrupt is
> +  enabled when this service is called, then the registered handler will be invoked. The
> +  registered handler should not be able to distinguish a hardware-generated timer
> +  interrupt from a software-generated timer interrupt.
> +
> +
> +  @param This              The EFI_TIMER_ARCH_PROTOCOL instance.
> +
> +  @retval EFI_SUCCESS       The soft timer interrupt was generated.
> +  @retval EFI_UNSUPPORTED   The platform does not support the generation of soft timer interrupts.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverGenerateSoftInterrupt (
> +  IN EFI_TIMER_ARCH_PROTOCOL  *This
> +  )
> +{
> +  EFI_TPL     OriginalTPL;
> +
> +  if (GetApicTimerInterruptState()) {
> +    //
> +    // Invoke the registered handler
> +    //
> +    OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
> +
> +    DisableApicTimerInterrupt();
> +    if (mTimerNotifyFunction != NULL) {
> +      //
> +      // @bug : This does not handle missed timer interrupts
> +      //
> +      mTimerNotifyFunction (mTimerPeriod);
> +    }
> +
> +    gBS->RestoreTPL (OriginalTPL);
> +  } else {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Initialize the Timer Architectural Protocol driver
> +
> +  @param ImageHandle     ImageHandle of the loaded driver
> +  @param SystemTable     Pointer to the System Table
> +
> +  @retval EFI_SUCCESS            Timer Architectural Protocol created
> +  @retval EFI_OUT_OF_RESOURCES   Not enough resources available to initialize driver.
> +  @retval EFI_DEVICE_ERROR       A device error occured attempting to initialize the driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TimerDriverInitialize (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS  Status;
> +  UINT32      TimerVector;
> +
> +  //
> +  // Initialize the pointer to our notify function.
> +  //
> +  mTimerNotifyFunction = NULL;
> +
> +  //
> +  // Make sure the Timer Architectural Protocol is not already installed in the system
> +  //
> +  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiTimerArchProtocolGuid);
> +
> +  //
> +  // Find the CPU architectural protocol.
> +  //
> +  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **) &mCpu);
> +  ASSERT_EFI_ERROR (Status);
> +
> +
> +  //
> +  // Force the timer to be disabled
> +  //
> +  DisableApicTimerInterrupt();
> +
> +  //
> +  // Get the interrupt vector number corresponding to IRQ0 from the 8259 driver
> +  //
> +  TimerVector = 32;
> +  InitializeApicTimer(2, 0, 1, TimerVector);
> +
> +  //
> +  // Install interrupt handler for 8254 Timer #0 (ISA IRQ0)
> +  //
> +  Status = mCpu->RegisterInterruptHandler (mCpu, TimerVector, TimerInterruptHandler);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Force the timer to be enabled at its default period
> +  //
> +  Status = TimerDriverSetTimerPeriod (&mTimer, DEFAULT_TIMER_TICK_DURATION);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Install the Timer Architectural Protocol onto a new handle
> +  //
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &mTimerHandle,
> +                  &gEfiTimerArchProtocolGuid, &mTimer,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> diff --git a/OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.inf b/OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.inf
> new file mode 100644
> index 0000000..43e137c
> --- /dev/null
> +++ b/OvmfPkg/XenTimerLocalApic/XenTimerLocalApic.inf
> @@ -0,0 +1,51 @@
> +## @file
> +# 8254 timer driver that provides Timer Arch protocol.
> +#
> +# Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.<BR>
> +# This program and the accompanying materials
> +# are licensed and made available under the terms and conditions of the BSD License
> +# which accompanies this distribution.  The full text of the license may be found at
> +# http://opensource.org/licenses/bsd-license.php
> +#
> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = ApicTimer
> +  FILE_GUID                      = 52fe8196-f9de-4d07-b22f-51f77a0e7c41
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +
> +  ENTRY_POINT                    = TimerDriverInitialize
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  IntelFrameworkPkg/IntelFrameworkPkg.dec
> +  UefiCpuPkg/UefiCpuPkg.dec
> +  OvmfPkg/OvmfPkg.dec
> +
> +[LibraryClasses]
> +  UefiBootServicesTableLib
> +  BaseLib
> +  DebugLib
> +  UefiDriverEntryPoint
> +  IoLib
> +  LocalApicLib
> +
> +[Sources]
> +  Timer.h
> +  XenTimerLocalApic.c
> +
> +[Protocols]
> +  gEfiCpuArchProtocolGuid       ## CONSUMES
> +  gEfiTimerArchProtocolGuid     ## PRODUCES
> +[Pcd.IA32, Pcd.X64]
> +  gEfiMdePkgTokenSpaceGuid.PcdFSBClock  ## CONSUMES

(12) Any particular reason for not using just [Pcd]?

> +
> +[Depex]
> +  gEfiCpuArchProtocolGuid# AND gEfiLegacy8259ProtocolGuid
> +#[UserExtensions.TianoCore."ExtraFiles"]
> +  #TimerExtra.uni
> 

(13) Since gEfiLegacy8259ProtocolGuid is not consumed, please remove it
from the depex fully, don't just comment it out.

Same for the ExtraFiles section.

Thanks
Laszlo


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 12/14] OvmfPkg/PlatformBootManagerLib: Use a Xen console for ConOut/ConIn
  2016-12-08 15:33 ` [PATCH RFC 12/14] OvmfPkg/PlatformBootManagerLib: Use a Xen console for ConOut/ConIn Anthony PERARD
@ 2017-01-05 16:38   ` Laszlo Ersek
  0 siblings, 0 replies; 37+ messages in thread
From: Laszlo Ersek @ 2017-01-05 16:38 UTC (permalink / raw)
  To: Anthony PERARD, edk2-devel, xen-devel

On 12/08/16 16:33, Anthony PERARD wrote:
> and add OvmfPkg/XenConsoleIo/XenConsoleIo to XenOvmf platform.
> 
> It actually look for gEfiSerialIoProtocolGuid.
> ---
>  .../Library/PlatformBootManagerLib/BdsPlatform.c   | 33 ++++++++++++++++++++++
>  .../PlatformBootManagerLib.inf                     |  2 ++
>  OvmfPkg/XenOvmf.dsc                                |  4 +++
>  OvmfPkg/XenOvmf.fdf                                |  1 +
>  4 files changed, 40 insertions(+)
> 
> diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
> index bd64cc3..b8972f7 100644
> --- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
> +++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
> @@ -904,6 +904,31 @@ DetectAndPreparePlatformPciDevicePaths (
>    return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath);
>  }
>  
> +#include <Protocol/SerialIo.h>
> +EFI_STATUS
> +EFIAPI
> +add_serial (
> +  IN EFI_HANDLE  DeviceHandle,
> +  IN VOID        *Instance,
> +  IN VOID        *Context
> +  )
> +{
> +  EFI_DEVICE_PATH_PROTOCOL  *DevicePath = NULL;
> +
> +  DevicePath = DevicePathFromHandle(DeviceHandle);
> +  if (DevicePath == NULL) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode);
> +  DEBUG((EFI_D_ERROR, "%a %d: full path: %s\n", __FUNCTION__, __LINE__,
> +         ConvertDevicePathToText(DevicePath, TRUE, FALSE)
> +         ));
> +  EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL);
> +  EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL);
> +  EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL);
> +  return EFI_SUCCESS;
> +}
>  
>  VOID
>  PlatformInitializeConsole (
> @@ -931,6 +956,14 @@ Arguments:
>    GetEfiGlobalVariable2 (EFI_CON_OUT_VARIABLE_NAME, (VOID **) &VarConout, NULL);
>    GetEfiGlobalVariable2 (EFI_CON_IN_VARIABLE_NAME, (VOID **) &VarConin, NULL);
>  
> +  // do xen console
> +  //VISIT_PCI_INSTANCE_CALLBACK CallBackFunction
> +  VisitAllInstancesOfProtocol (
> +           &gEfiSerialIoProtocolGuid,
> +           add_serial,
> +           (VOID*)NULL
> +           );
> +
>    if (VarConout == NULL || VarConin == NULL) {
>      //
>      // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut
> diff --git a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> index 4a6bece..74ab6b1 100644
> --- a/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> +++ b/OvmfPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
> @@ -73,6 +73,8 @@
>    gEfiLoadedImageProtocolGuid                   # PROTOCOL SOMETIMES_PRODUCED
>    gEfiFirmwareVolume2ProtocolGuid               # PROTOCOL SOMETIMES_CONSUMED
>  
> +  gEfiSerialIoProtocolGuid
> +
>  [Guids]
>    gEfiXenInfoGuid
>    gEfiEndOfDxeEventGroupGuid
> diff --git a/OvmfPkg/XenOvmf.dsc b/OvmfPkg/XenOvmf.dsc
> index 31a2185..8bce996 100644
> --- a/OvmfPkg/XenOvmf.dsc
> +++ b/OvmfPkg/XenOvmf.dsc
> @@ -590,6 +590,10 @@
>    OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
>    OvmfPkg/XenBusDxe/XenBusDxe.inf
>    OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
> +  OvmfPkg/XenConsoleIo/XenConsoleIo.inf {
> +    <LibraryClasses>
> +      SerialPortLib|OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf
> +  }
>    MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
>    MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
>    MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
> diff --git a/OvmfPkg/XenOvmf.fdf b/OvmfPkg/XenOvmf.fdf
> index f6876d7..a40d186 100644
> --- a/OvmfPkg/XenOvmf.fdf
> +++ b/OvmfPkg/XenOvmf.fdf
> @@ -223,6 +223,7 @@ INF  OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
>  INF  OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
>  INF  OvmfPkg/XenBusDxe/XenBusDxe.inf
>  INF  OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
> +INF  OvmfPkg/XenConsoleIo/XenConsoleIo.inf
>  
>  !if $(SECURE_BOOT_ENABLE) == TRUE
>    INF  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
> 

Okay, so this patch forced me to review the current additions of serial
port devpaths to ConIn, ConOut, ErrOut in

  OvmfPkg/Library/PlatformBootManagerLib/

I think I understand what you intend to do. I'd like to propose an
alternative I feel would be better.

You are introducing a new driver called "XenConsoleIo" which I assume is
a DXE_DRIVER module that produces gEfiSerialIoProtocolGuid. The reason I
can only "assume" is that you apparently forgot to include the driver in
the patch, with "git add". Nonetheless, without having seen the driver,
I claim that it should be unnecessary.

Namely, MdeModulePkg provides a generic platform serial driver, under

  MdeModulePkg/Universal/SerialDxe/SerialDxe.inf

This driver is already used in the ARM Xen guest platform:

  ArmVirtPkg/ArmVirtXen.dsc

with a dependency on

  OvmfPkg/Library/XenConsoleSerialPortLib/XenConsoleSerialPortLib.inf

which you also employ above.

Delegating the actual serial port access to the SerialPortLib class, the
SerialDxe driver produces one instance of EFI_SERIAL_IO_PROTOCOL. The
device path protocol instance that it installs on the handle is
constant, and known to other edk2 modules.

(
In turn, the TerminalDxe driver layers on top of the
EFI_SERIAL_IO_PROTOCOL instance, and produces simple text in/out
protocols on a child handle. The device path node appended specifically
for the child handle determines the terminal type (e.g., vt100, pc-ansi,
etc) to emulate. The terminal type can be selected by the platform by
adding a devpath to the Con* variables that ends with the desired device
path node, or else the TerminalDxe driver can fall back to a default
type. But, I digress.
)

What this all boils down to is:

(1) Rather than introducing a new driver (again, not having it seen),
please include "MdeModulePkg/Universal/SerialDxe/SerialDxe.inf" in the
XenOvmf DSC and FDF files.

You can resolve the SerialPortLib class to XenConsoleSerialPortLib
either for this one module only, or generally (same as in
"ArmVirtPkg/ArmVirtXen.dsc").

(I assume that in a Xen HVM guest, both the emulated serial port and the
paravirt xen console are available )

(2) In the code, we shouldn't locate the appropriate handle dynamically.
The full device path is known statically, in advance. Please refer to
"mSerialConsole" in

  ArmVirtPkg/Library/PlatformBootManagerLib/PlatformBm.c

Therefore I suggest that we add a "gXenPlatformConsole" array to

  OvmfPkg/Library/PlatformBootManagerLib/PlatformData.c

with an initializer that effects the following:

- gXenPlatformConsole[1] is entirely zeroed,

- gXenPlatformConsole[0].ConnectType = CONSOLE_IN |
                                       CONSOLE_OUT |
                                       STD_ERROR;

- gXenPlatformConsole[0].DevicePath should be what's seen in
"mSerialConsole" above, but with the terminal type GUID pre-filled to
PC-ANSI ("gPcAnsiTerminal").

Then, we shouldn't touch the PlatformInitializeConsole() function;
instead modify the PlatformInitializeConsole() call in
PlatformBootManagerBeforeConsole() like this:

  PlatformInitializeConsole (
    XenDetected() ? gXenPlatformConsole : gPlatformConsole);

This will cause PlatformInitializeConsole() to do the right thing, and
it won't introduce special handling for gEfiSerialIoProtocolGuid that
would superfluously run on QEMU as well.

Furthermore, in a Xen HVM guest, I reckon this will multiplex terminal
IO to both emulated serial and Xen console.

Thanks
Laszlo


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 13/14] OvmfPkg: Introduce XenIoPvhDxe to initialize Grant Tables
  2016-12-08 15:33 ` [PATCH RFC 13/14] OvmfPkg: Introduce XenIoPvhDxe to initialize Grant Tables Anthony PERARD
@ 2017-01-05 16:58   ` Laszlo Ersek
  0 siblings, 0 replies; 37+ messages in thread
From: Laszlo Ersek @ 2017-01-05 16:58 UTC (permalink / raw)
  To: Anthony PERARD, edk2-devel, xen-devel

On 12/08/16 16:33, Anthony PERARD wrote:
> This "device" use XenIoMmioLib to reserve some space to be use by grant
> tables. It's use 0xfc000000, which might not be a good choice...
> 
> There is probably a better way that using a device for this.
> ---
>  OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c   | 263 ++++++++++++++++++++++++++++++++++++
>  OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf |  45 ++++++
>  OvmfPkg/XenOvmf.dsc                 |   2 +
>  OvmfPkg/XenOvmf.fdf                 |   1 +
>  4 files changed, 311 insertions(+)
>  create mode 100644 OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c
>  create mode 100644 OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf

I recommend to check out the existent use of XenIoMmioLib, namely in
"ArmVirtPkg/XenioFdtDxe".

In brief, for such purposes a DXE_DRIVER is appropriate, where you
simply do the deed (call XenIoMmioInstall()) in the driver's entry point
function. No need for a UEFI_DRIVER module which conforms to the UEFI
Driver Model.

Regarding where to put the area: no clue. If it doesn't overlap any
memory area added in (Xen)PlatformPei with memory resource descriptors,
nor areas added later in DXE, with gDS->AddMemorySpace(), then it should
be fine.

>From a quick look, 0xFC000000 should work. For completeness, I'd also
modify the (DXE) driver to call gDS->AddMemorySpace() with type
EfiGcdMemoryTypeReserved, and also immediately call
gDS->AllocateMemorySpace() with the same type and EfiGcdAllocateAddress,
in order to allocate the exact reserved chunk.

(See "7.2 Global Coherency Domain Services" in vol2 of the Platform Init
spec for background.)

OTOH, I don't see why a simple AllocateReservedPages() call wouldn't
work (which would carve a chunk out of normal system memory for this).
Why did you comment that out in the code below?

Also, please don't forget the Citrix copyright notice etc etc.

Thanks
Laszlo

> 
> diff --git a/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c b/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c
> new file mode 100644
> index 0000000..12e076f
> --- /dev/null
> +++ b/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.c
> @@ -0,0 +1,263 @@
> +/** @file
> +
> +  XXX
> +
> +  XXX
> +
> +  This program and the accompanying materials are licensed and made available
> +  under the terms and conditions of the BSD License which accompanies this
> +  distribution. The full text of the license may be found at
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
> +  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/XenIoMmioLib.h>
> +
> +/* #include <Protocol/XenIo.h> */
> +STATIC BOOLEAN mXenIoInitialized = FALSE;
> +
> +/**
> +
> +  Device probe function for this driver.
> +
> +  The DXE core calls this function for any given device in order to see if the
> +  driver can drive the device.
> +
> +  @param[in]  This                The EFI_DRIVER_BINDING_PROTOCOL object
> +                                  incorporating this driver (independently of
> +                                  any device).
> +
> +  @param[in] DeviceHandle         The device to probe.
> +
> +  @param[in] RemainingDevicePath  Relevant only for bus drivers, ignored.
> +
> +
> +  @retval EFI_SUCCESS      The driver supports the device being probed.
> +
> +  @retval EFI_UNSUPPORTED  The driver does not support the device being probed.
> +
> +  @return                  Error codes from the OpenProtocol() boot service or
> +                           the PciIo protocol.
> +
> +**/
> +#if 1
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +XenIoPvhDeviceBindingSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL *This,
> +  IN EFI_HANDLE                  DeviceHandle,
> +  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
> +  )
> +{
> +
> +  // XXX check if running Xen PVH
> +  //
> +
> +  if (mXenIoInitialized) {
> +    return EFI_ALREADY_STARTED;
> +  }
> +
> +  DEBUG((EFI_D_INFO, "%a %d\n", __FUNCTION__, __LINE__));
> +  return EFI_SUCCESS;
> +}
> +#endif
> +
> +/**
> +
> +  After we've pronounced support for a specific device in
> +  DriverBindingSupported(), we start managing said device (passed in by the
> +  Driver Execution Environment) with the following service.
> +
> +  See DriverBindingSupported() for specification references.
> +
> +  @param[in]  This                The EFI_DRIVER_BINDING_PROTOCOL object
> +                                  incorporating this driver (independently of
> +                                  any device).
> +
> +  @param[in] DeviceHandle         The supported device to drive.
> +
> +  @param[in] RemainingDevicePath  Relevant only for bus drivers, ignored.
> +
> +
> +  @retval EFI_SUCCESS           The device was started.
> +
> +  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
> +
> +  @return                       Error codes from the OpenProtocol() boot
> +                                service, the PciIo protocol or the
> +                                InstallProtocolInterface() boot service.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +XenIoPvhDeviceBindingStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL *This,
> +  IN EFI_HANDLE                  DeviceHandle,
> +  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
> +  )
> +{
> +  EFI_STATUS                        Status;
> +  EFI_HANDLE Handle = NULL;
> +
> +  /* Status = XenIoMmioInstall(&Handle, (UINTN)AllocateReservedPages(4)); */
> +  Status = XenIoMmioInstall(&Handle, (UINTN)0xfc000000);
> +
> +  if (!EFI_ERROR (Status)) {
> +    mXenIoInitialized = TRUE;
> +    return EFI_SUCCESS;
> +  }
> +
> +  return Status;
> +}
> +
> +#if 1
> +/**
> +
> +  Stop driving the XenIo PCI device
> +
> +  @param[in] This               The EFI_DRIVER_BINDING_PROTOCOL object
> +                                incorporating this driver (independently of any
> +                                device).
> +
> +  @param[in] DeviceHandle       Stop driving this device.
> +
> +  @param[in] NumberOfChildren   Since this function belongs to a device driver
> +                                only (as opposed to a bus driver), the caller
> +                                environment sets NumberOfChildren to zero, and
> +                                we ignore it.
> +
> +  @param[in] ChildHandleBuffer  Ignored (corresponding to NumberOfChildren).
> +
> +  @retval EFI_SUCCESS           Driver instance has been stopped and the PCI
> +                                configuration attributes have been restored.
> +
> +  @return                       Error codes from the OpenProtocol() or
> +                                CloseProtocol(), UninstallProtocolInterface()
> +                                boot services.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +XenIoPvhDeviceBindingStop (
> +  IN EFI_DRIVER_BINDING_PROTOCOL *This,
> +  IN EFI_HANDLE                  DeviceHandle,
> +  IN UINTN                       NumberOfChildren,
> +  IN EFI_HANDLE                  *ChildHandleBuffer
> +  )
> +{
> +  /* return XenIoMmioUninstall(Handle); */
> +  return EFI_SUCCESS;
> +}
> +
> +
> +//
> +// The static object that groups the Supported() (ie. probe), Start() and
> +// Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata
> +// C, 10.1 EFI Driver Binding Protocol.
> +//
> +STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {
> +  &XenIoPvhDeviceBindingSupported,
> +  &XenIoPvhDeviceBindingStart,
> +  &XenIoPvhDeviceBindingStop,
> +  0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers
> +  NULL, // ImageHandle, to be overwritten by
> +        // EfiLibInstallDriverBindingComponentName2() in XenIoPvhDeviceEntryPoint()
> +  NULL  // DriverBindingHandle, ditto
> +};
> +
> +
> +//
> +// The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and
> +// EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's name
> +// in English, for display on standard console devices. This is recommended for
> +// UEFI drivers that follow the UEFI Driver Model. Refer to the Driver Writer's
> +// Guide for UEFI 2.3.1 v1.01, 11 UEFI Driver and Controller Names.
> +//
> +STATIC
> +EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {
> +  { "eng;en", L"XenIo PVH Driver" },
> +  { NULL,     NULL                }
> +};
> +
> +STATIC
> +EFI_COMPONENT_NAME_PROTOCOL gComponentName;
> +
> +EFI_STATUS
> +EFIAPI
> +XenIoPvhGetDriverName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
> +  IN  CHAR8                       *Language,
> +  OUT CHAR16                      **DriverName
> +  )
> +{
> +  return LookupUnicodeString2 (
> +           Language,
> +           This->SupportedLanguages,
> +           mDriverNameTable,
> +           DriverName,
> +           (BOOLEAN)(This == &gComponentName) // Iso639Language
> +           );
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +XenIoPvhGetDeviceName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
> +  IN  EFI_HANDLE                  DeviceHandle,
> +  IN  EFI_HANDLE                  ChildHandle,
> +  IN  CHAR8                       *Language,
> +  OUT CHAR16                      **ControllerName
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +STATIC
> +EFI_COMPONENT_NAME_PROTOCOL gComponentName = {
> +  &XenIoPvhGetDriverName,
> +  &XenIoPvhGetDeviceName,
> +  "eng" // SupportedLanguages, ISO 639-2 language codes
> +};
> +
> +STATIC
> +EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
> +  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)     &XenIoPvhGetDriverName,
> +  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) &XenIoPvhGetDeviceName,
> +  "en" // SupportedLanguages, RFC 4646 language codes
> +};
> +
> +#endif
> +
> +//
> +// Entry point of this driver.
> +//
> +EFI_STATUS
> +EFIAPI
> +XenIoPvhDeviceEntryPoint (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  /* DEBUG((EFI_D_ERROR, "%a %d\n", __FUNCTION__, __LINE__)); */
> +  /* return XenIoPvhDeviceBindingStart(ImageHandle); */
> +
> +  return EfiLibInstallDriverBindingComponentName2 (
> +           ImageHandle,
> +           SystemTable,
> +           &gDriverBinding,
> +           ImageHandle,
> +           &gComponentName,
> +           &gComponentName2
> +           );
> +}
> diff --git a/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf b/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
> new file mode 100644
> index 0000000..dbdfd6e
> --- /dev/null
> +++ b/OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
> @@ -0,0 +1,45 @@
> +## @file
> +#  XXX
> +#
> +#  Copyright (C) XXX
> +#
> +#  This program and the accompanying materials
> +#  are licensed and made available under the terms and conditions of the BSD License
> +#  which accompanies this distribution.  The full text of the license may be found at
> +#  http://opensource.org/licenses/bsd-license.php
> +#
> +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION               = 0x00010005
> +  BASE_NAME                 = XenIoPvhDxe
> +  FILE_GUID                 = 7a567cc4-0e75-4d7a-a305-c3db109b53ad
> +  MODULE_TYPE               = UEFI_DRIVER
> +  VERSION_STRING            = 1.0
> +  ENTRY_POINT               = XenIoPvhDeviceEntryPoint
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  OvmfPkg/OvmfPkg.dec
> +
> +[Sources]
> +  XenIoPvhDxe.c
> +
> +[LibraryClasses]
> +  UefiDriverEntryPoint
> +  UefiBootServicesTableLib
> +  MemoryAllocationLib
> +  BaseMemoryLib
> +  BaseLib
> +  UefiLib
> +  DebugLib
> +  XenIoMmioLib
> +
> +[Protocols]
> +  gEfiDriverBindingProtocolGuid
> +  gEfiComponentName2ProtocolGuid
> +  gEfiComponentNameProtocolGuid
> +  gXenIoProtocolGuid
> diff --git a/OvmfPkg/XenOvmf.dsc b/OvmfPkg/XenOvmf.dsc
> index 8bce996..a7a884e 100644
> --- a/OvmfPkg/XenOvmf.dsc
> +++ b/OvmfPkg/XenOvmf.dsc
> @@ -168,6 +168,7 @@
>    SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf
>    OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
>    XenHypercallLib|OvmfPkg/Library/XenHypercallLib/XenHypercallLib.inf
> +  XenIoMmioLib|OvmfPkg/Library/XenIoMmioLib/XenIoMmioLib.inf
>  
>  [LibraryClasses.common]
>  !if $(SECURE_BOOT_ENABLE) == TRUE
> @@ -587,6 +588,7 @@
>  !endif
>    }
>    OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
> +  OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
>    OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
>    OvmfPkg/XenBusDxe/XenBusDxe.inf
>    OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
> diff --git a/OvmfPkg/XenOvmf.fdf b/OvmfPkg/XenOvmf.fdf
> index a40d186..a500ab6 100644
> --- a/OvmfPkg/XenOvmf.fdf
> +++ b/OvmfPkg/XenOvmf.fdf
> @@ -220,6 +220,7 @@ INF  MdeModulePkg/Universal/Metronome/Metronome.inf
>  INF  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
>  
>  INF  OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
> +INF  OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
>  INF  OvmfPkg/XenIoPciDxe/XenIoPciDxe.inf
>  INF  OvmfPkg/XenBusDxe/XenBusDxe.inf
>  INF  OvmfPkg/XenPvBlkDxe/XenPvBlkDxe.inf
> 



^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 14/14] XenOvmf: Use a different RTC
  2016-12-08 15:33 ` [PATCH RFC 14/14] XenOvmf: Use a different RTC Anthony PERARD
@ 2017-01-05 17:02   ` Laszlo Ersek
  0 siblings, 0 replies; 37+ messages in thread
From: Laszlo Ersek @ 2017-01-05 17:02 UTC (permalink / raw)
  To: Anthony PERARD, edk2-devel, xen-devel

On 12/08/16 16:33, Anthony PERARD wrote:
> ---
>  OvmfPkg/XenOvmf.dsc | 5 ++++-
>  OvmfPkg/XenOvmf.fdf | 2 +-
>  2 files changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/OvmfPkg/XenOvmf.dsc b/OvmfPkg/XenOvmf.dsc
> index a7a884e..345157b 100644
> --- a/OvmfPkg/XenOvmf.dsc
> +++ b/OvmfPkg/XenOvmf.dsc
> @@ -567,7 +567,10 @@
>    }
>    MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
>    MdeModulePkg/Universal/Metronome/Metronome.inf
> -  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
> +  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf {
> +    <LibraryClasses>
> +      RealTimeClockLib|ArmVirtPkg/Library/XenRealTimeClockLib/XenRealTimeClockLib.inf
> +  }
>    MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
>    MdeModulePkg/Universal/BdsDxe/BdsDxe.inf {
>      <LibraryClasses>
> diff --git a/OvmfPkg/XenOvmf.fdf b/OvmfPkg/XenOvmf.fdf
> index a500ab6..65db2ba 100644
> --- a/OvmfPkg/XenOvmf.fdf
> +++ b/OvmfPkg/XenOvmf.fdf
> @@ -217,7 +217,7 @@ INF  MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
>  INF  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
>  INF  MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
>  INF  MdeModulePkg/Universal/Metronome/Metronome.inf
> -INF  PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf
> +INF  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
>  
>  INF  OvmfPkg/BlockMmioToBlockIoDxe/BlockIo.inf
>  INF  OvmfPkg/XenIoPvhDxe/XenIoPvhDxe.inf
> 

(1) The subject should be

  OvmfPkg/XenOvmf: use RealTimeClockRuntimeDxe from EmbeddedPkg

or similar.

(2) By tradition, ArmVirtPkg is welcome to consume modules from OvmfPkg,
but not the other way around. If you need

  ArmVirtPkg/Library/XenRealTimeClockLib

in an OvmfPkg platform, please move the library instance first to
OvmfPkg, redirecting the ArmVirtPkg references, and then consume the
library in OvmfPkg, internally to OvmfPkg.

Thanks
Laszlo


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests
  2017-01-04 19:52 ` [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests Laszlo Ersek
@ 2017-01-10 14:55   ` Anthony PERARD
  0 siblings, 0 replies; 37+ messages in thread
From: Anthony PERARD @ 2017-01-10 14:55 UTC (permalink / raw)
  To: Laszlo Ersek; +Cc: edk2-devel, xen-devel

On Wed, Jan 04, 2017 at 08:52:00PM +0100, Laszlo Ersek wrote:
> On 12/08/16 16:33, Anthony PERARD wrote:
> > Hi,
> > 
> > I've started to create a Xen specifig plaform, in OvmfPkg/XenOvmf.dsc
> > with the goal to make it work on both Xen HVM and Xen PVHv2
> 
> Does this mean we can ultimately move all Xen roles from the current
> platform DSC files to the new Xen DSC file entirely?

Yes, I had this in mind will working on the series. I would just need to
teach our build system (in xen.git) to look for this new platform file.

> If so (which I think I would like), then for each module M that exhibits
> all of the following properties:
> - M is dynamically customized to Xen vs. QEMU,
> - M is replaced by a dedicated module M' in the Xen DSC,
> I think we should also remove the Xen-specific code from the original M
> (as last step, likely in separate patches).
> 
> In addition, Xen platform specific device drivers should be removed as
> well from the original DSC files.
> 
> What do you think?

Yes, I think all of it sound good.

> > The first few patches only create the platform and duplicate some code from
> > OvmfPkg and the later patches (from OvmfPkg/XenPlatformPei: Add xen PVH
> > specific code) makes OVMF boot in a Xen PVH guest, and can boot a Linux.
> > 
> > == Part 1: XenOvmf.dsc
> > 
> > - OvmfPkg: Create platform XenOvmf
> > which for now remove virtio drivers and some SMM
> > 
> > - OvmfPkg/XenOvmf: Update debug IO port for Xen
> > 
> > - OvmfPkg/XenOvmf.dsc: Introduce XenResetVector
> > Just for one change, enable cache in CR0 as on Xen, OVMF run from RAM, that
> > disabling cache can make OVMF very slow.
> > 
> 
> ... I might reply to this email again (the remaining stuff), as I
> progress with the review.
> 
> Thanks
> Laszlo

Thanks,

-- 
Anthony PERARD


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 03/14] OvmfPkg/XenOvmf.dsc: Introduce XenResetVector
  2017-01-04 19:49   ` Laszlo Ersek
@ 2017-01-10 15:58     ` Anthony PERARD
  0 siblings, 0 replies; 37+ messages in thread
From: Anthony PERARD @ 2017-01-10 15:58 UTC (permalink / raw)
  To: Laszlo Ersek; +Cc: edk2-devel, xen-devel

On Wed, Jan 04, 2017 at 08:49:15PM +0100, Laszlo Ersek wrote:
> > diff --git a/OvmfPkg/XenResetVector/Ia32/PageTables64.asm b/OvmfPkg/XenResetVector/Ia32/PageTables64.asm
> > new file mode 100644
> > index 0000000..b5a4cf8
> > --- /dev/null
> > +++ b/OvmfPkg/XenResetVector/Ia32/PageTables64.asm
> > @@ -0,0 +1,93 @@
> > +;------------------------------------------------------------------------------
> > +; @file
> > +; Sets the CR3 register for 64-bit paging
> > +;
> > +; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
> > +; This program and the accompanying materials
> > +; are licensed and made available under the terms and conditions of the BSD License
> > +; which accompanies this distribution.  The full text of the license may be found at
> > +; http://opensource.org/licenses/bsd-license.php
> > +;
> > +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> > +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> > +;
> > +;------------------------------------------------------------------------------
> > +
> > +BITS    32
> > +
> > +%define PAGE_PRESENT            0x01
> > +%define PAGE_READ_WRITE         0x02
> > +%define PAGE_USER_SUPERVISOR    0x04
> > +%define PAGE_WRITE_THROUGH      0x08
> > +%define PAGE_CACHE_DISABLE     0x010
> > +%define PAGE_ACCESSED          0x020
> > +%define PAGE_DIRTY             0x040
> > +%define PAGE_PAT               0x080
> > +%define PAGE_GLOBAL           0x0100
> > +%define PAGE_2M_MBO            0x080
> > +%define PAGE_2M_PAT          0x01000
> > +
> > +%define PAGE_2M_PDE_ATTR (PAGE_2M_MBO + \
> > +                          PAGE_ACCESSED + \
> > +                          PAGE_DIRTY + \
> > +                          PAGE_READ_WRITE + \
> > +                          PAGE_PRESENT)
> > +
> > +%define PAGE_PDP_ATTR (PAGE_ACCESSED + \
> > +                       PAGE_READ_WRITE + \
> > +                       PAGE_PRESENT)
> > +
> > +
> > +;
> > +; Modified:  EAX, ECX
> > +;
> > +SetCr3ForPageTables64:
> > +
> > +    ;
> > +    ; For OVMF, build some initial page tables at 0x800000-0x806000.
> 
> (6) Are you intentionally undoing, in the copy, commit 73d66c5871cc? If
> so, why?

No, I just need to use --find-copies-harder to find out about recent
changes.

> For now I suspect that you originally created this patch before commit
> 73d66c5871cc came into existence. If that's the case, then please rebase
> (re-copy and customize) this patch to the most recent ResetVector state,
> including commit 73d66c5871cc.

I don't think I've customize this file, this could be a link, or I could
try to have the build system use the original file from
OvmfPkg/ResetVector.

Thanks,

-- 
Anthony PERARD


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 04/14] OvmfPkg: Introduce XenPlatformPei
  2017-01-05  9:59   ` Laszlo Ersek
@ 2017-01-10 16:08     ` Anthony PERARD
  0 siblings, 0 replies; 37+ messages in thread
From: Anthony PERARD @ 2017-01-10 16:08 UTC (permalink / raw)
  To: Laszlo Ersek; +Cc: edk2-devel, xen-devel

On Thu, Jan 05, 2017 at 10:59:24AM +0100, Laszlo Ersek wrote:
> On 12/08/16 16:33, Anthony PERARD wrote:
> > A copy of OvmfPkg/PlatformPei without some of QEMU specific
> > initialization, Xen does not support QemuFwCfg.
> > 
> > Contributed-under: TianoCore Contribution Agreement 1.0
> > Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> > ---
> >  OvmfPkg/XenOvmf.dsc                       |   2 +-
> >  OvmfPkg/XenOvmf.fdf                       |   2 +-
> >  OvmfPkg/XenPlatformPei/Cmos.c             |  64 ++++
> >  OvmfPkg/XenPlatformPei/Cmos.h             |  56 ++++
> >  OvmfPkg/XenPlatformPei/Fv.c               | 100 ++++++
> >  OvmfPkg/XenPlatformPei/MemDetect.c        | 449 +++++++++++++++++++++++++
> >  OvmfPkg/XenPlatformPei/Platform.c         | 536 ++++++++++++++++++++++++++++++
> >  OvmfPkg/XenPlatformPei/Platform.h         | 104 ++++++
> >  OvmfPkg/XenPlatformPei/Xen.c              | 231 +++++++++++++
> >  OvmfPkg/XenPlatformPei/Xen.h              |  45 +++
> >  OvmfPkg/XenPlatformPei/XenPlatformPei.inf | 110 ++++++
> >  11 files changed, 1697 insertions(+), 2 deletions(-)
> >  create mode 100644 OvmfPkg/XenPlatformPei/Cmos.c
> >  create mode 100644 OvmfPkg/XenPlatformPei/Cmos.h
> >  create mode 100644 OvmfPkg/XenPlatformPei/Fv.c
> >  create mode 100644 OvmfPkg/XenPlatformPei/MemDetect.c
> >  create mode 100644 OvmfPkg/XenPlatformPei/Platform.c
> >  create mode 100644 OvmfPkg/XenPlatformPei/Platform.h
> >  create mode 100644 OvmfPkg/XenPlatformPei/Xen.c
> >  create mode 100644 OvmfPkg/XenPlatformPei/Xen.h
> >  create mode 100644 OvmfPkg/XenPlatformPei/XenPlatformPei.inf
> 
> (1) You might want to add Citrix copyright notices to new files.
> 
> (2) This module is a good example where the moved Xen functionality
> (even for HVM guests) should be possible to remove from the original
> PlatformPei module. (In a later, final patch.) Is that right?

Yes, that should be possible.

> (3) In the commit message, please list the removed fw_cfg-dependent
> functionality in more detail (all of which is dynamically skipped when
> the current PlatformPei module runs on Xen):

Will do.

> - GetFirstNonAddress(): controlling the 64-bit PCI MMIO aperture via the
> (experimental) "opt/ovmf/X-PciMmio64Mb" file
> 
> - GetFirstNonAddress(): honoring the hotplug DIMM area
> ("etc/reserved-memory-end") in the placement of the 64-bit PCI MMIO aperture
> 
> - NoexecDxeInitialization() is removed, so PcdPropertiesTableEnable and
> PcdSetNxForStack are left constant FALSE (not set dynamically from
> "opt/ovmf/PcdXxxx")
> 
> - MaxCpuCountInitialization(), PublishPeiMemory(): the max CPU count is
> not taken from the QemuFwCfgItemSmpCpuCount fw_cfg key;
> PcdCpuMaxLogicalProcessorNumber is used intact and
> PcdCpuApInitTimeOutInMicroSeconds is never changed or used.
> 
> - InitializeXenPlatform(), S3Verification(): S3 is assumed disabled (not
> consulting "etc/system-states" via QemuFwCfgS3Enabled()).
> 
> - InstallFeatureControlCallback(): the feature control MSR is not set
> from "etc/msr_feature_control"
> 
> Also removed:
> -  SMRAM/TSEG-related low mem size adjusting (PcdSmmSmramRequire is
> assumed FALSE) in PublishPeiMemory(),
> - QemuInitializeRam() entirely,
> 
> (4) I think the removal of PcdSmmSmramRequire is incomplete. IMO this
> PCD should either be removed completely (all uses, including the INF
> reference), assuming a FALSE value in its place, or the PCD should not
> be touched at all. The FeaturePcdGet() call in PublishPeiMemory() --
> gating the "TSEG is chipped from the end of low RAM" stuff -- seems to
> be singled out for removal for no good reason.

Yes, I think I will remove all of if. There is not much reason to keep
something that is not tested, and I don't know if it can work on Xen. I
guess SMM can be readded later.

> (5) It would be nice to hint at the reason (which is implemented in a
> later patch) why a separate module is a good idea here. That is, why the
> expected PVH2 functionality is best not added to the current PlatformPei
> module.

Will do.

-- 
Anthony PERARD


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 06/14] OvmfPkg/XenPlatformPei: Add xen PVH specific code
  2017-01-05 10:30   ` Laszlo Ersek
@ 2017-01-10 16:18     ` Anthony PERARD
  2017-01-10 16:54       ` Laszlo Ersek
  0 siblings, 1 reply; 37+ messages in thread
From: Anthony PERARD @ 2017-01-10 16:18 UTC (permalink / raw)
  To: Laszlo Ersek; +Cc: edk2-devel, xen-devel

On Thu, Jan 05, 2017 at 11:30:32AM +0100, Laszlo Ersek wrote:
> On 12/08/16 16:33, Anthony PERARD wrote:
> > - learn about memory size from the E820
> > - ignore error if host bridge devid is 0xffff, PVH does not have PCI and
> >   reading from unexisting device return -1.
> > 
> > Contributed-under: TianoCore Contribution Agreement 1.0
> > Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
> > ---
> >  OvmfPkg/XenPlatformPei/MemDetect.c | 71 ++++++++++++++++++++++++++++++++++++++
> >  OvmfPkg/XenPlatformPei/Platform.c  |  5 +++
> >  OvmfPkg/XenPlatformPei/Platform.h  | 10 ++++++
> >  3 files changed, 86 insertions(+)
> > 
> > diff --git a/OvmfPkg/XenPlatformPei/MemDetect.c b/OvmfPkg/XenPlatformPei/MemDetect.c
> > index 4ecdf5e..0d80775 100644
> > --- a/OvmfPkg/XenPlatformPei/MemDetect.c
> > +++ b/OvmfPkg/XenPlatformPei/MemDetect.c
> > @@ -42,6 +42,70 @@ UINT8 mPhysMemAddressWidth;
> >  STATIC UINT32 mS3AcpiReservedMemoryBase;
> >  STATIC UINT32 mS3AcpiReservedMemorySize;
> >  
> > +STATIC UINT32 mXenLowerMemorySize = 0;
> > +STATIC UINT64 mXenHighMemorySize = 0;
> > +
> > +VOID
> > +XenReadMemorySizes (
> > +  VOID
> > +  )
> > +{
> > +  EFI_E820_ENTRY64  *E820Map;
> > +  UINT32            E820EntriesCount;
> > +  EFI_STATUS Status;
> > +
> > +  Status = XenGetE820Map (&E820Map, &E820EntriesCount);
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  mXenLowerMemorySize = 0;
> > +  mXenHighMemorySize = 0;
> > +
> > +  if (E820EntriesCount > 0) {
> > +    EFI_E820_ENTRY64 *Entry;
> > +    UINT32 Loop;
> > +
> > +    for (Loop = 0; Loop < E820EntriesCount; Loop++) {
> > +      Entry = E820Map + Loop;
> > +
> > +      //
> > +      // Only care about RAM
> > +      //
> > +      if (Entry->Type != EfiAcpiAddressRangeMemory) {
> > +        continue;
> > +      }
> > +
> > +      if ((Entry->BaseAddr + Entry->Length) <= SIZE_16MB) {
> > +        continue;
> > +      }
> > +
> > +      if (Entry->BaseAddr < SIZE_16MB) {
> > +        UINT64 bottom = Entry->BaseAddr;
> > +        UINT64 size = Entry->Length;
> > +        size -= SIZE_16MB - bottom;
> > +        bottom = SIZE_16MB;
> > +        mXenLowerMemorySize += size;
> > +        continue;
> > +      }
> > +      if (Entry->BaseAddr <= SIZE_4GB) {
> > +        UINT64 size = Entry->Length;
> > +        mXenLowerMemorySize += size;
> > +        continue;
> > +      }
> > +
> > +      if (Entry->BaseAddr == SIZE_4GB) {
> > +        mXenHighMemorySize = Entry->Length;
> > +        continue;
> > +      }
> > +
> > +      DEBUG ((EFI_D_INFO, "%a: ignored XenE820 entry (0x%llx, 0x%llx)\n",
> > +              __FUNCTION__,
> > +              Entry->BaseAddr,
> > +              Entry->Length));
> > +    }
> > +    mXenLowerMemorySize += SIZE_16MB;
> > +  }
> > +}
> > +
> >  UINT32
> >  GetSystemMemorySizeBelow4gb (
> >    VOID
> > @@ -50,6 +114,9 @@ GetSystemMemorySizeBelow4gb (
> >    UINT8 Cmos0x34;
> >    UINT8 Cmos0x35;
> >  
> > +  if (mXen && mXenLowerMemorySize)
> > +    return mXenLowerMemorySize;
> > +
> >    //
> >    // CMOS 0x34/0x35 specifies the system memory above 16 MB.
> >    // * CMOS(0x35) is the high byte
> > @@ -74,6 +141,10 @@ GetSystemMemorySizeAbove4gb (
> >    UINT32 Size;
> >    UINTN  CmosIndex;
> >  
> > +  // if lower memory is specified that way, return also high memory
> > +  if (mXen && mXenLowerMemorySize)
> > +    return mXenHighMemorySize;
> > +
> >    //
> >    // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
> >    // * CMOS(0x5d) is the most significant size byte
> > diff --git a/OvmfPkg/XenPlatformPei/Platform.c b/OvmfPkg/XenPlatformPei/Platform.c
> > index bf78878..9fc713c 100644
> > --- a/OvmfPkg/XenPlatformPei/Platform.c
> > +++ b/OvmfPkg/XenPlatformPei/Platform.c
> > @@ -362,6 +362,10 @@ MiscInitialization (
> >        AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL);
> >        AcpiEnBit  = ICH9_ACPI_CNTL_ACPI_EN;
> >        break;
> > +    case 0xffff:
> > +      // xen PVH, ignore
> > +      PcdStatus = PcdSet16S (PcdOvmfHostBridgePciDevId, mHostBridgeDevId);
> > +      return;
> 
> Can we create a new macro for 0xFFFF in
> "OvmfPkg/Include/OvmfPlatforms.h", and use that here?
> 
> Normally I would suggest a separate header file under "OvmfPkg/Include",
> similar to "Q35MchIch9.h" and "I440FxPiix4.h", and to include that new
> file in "OvmfPlatforms.h", but here we only need a single "chipset
> identifier", so I guess that can go directly into "OvmfPlatforms.h".
> 
> I mainly suggest this because in patch 08/14, the same 0xFFFF case label
> is being added to code shared with QEMU, and using a verbose macro there
> is much better than a magic number. In turn, we should use the same
> macro here, I think.

This value is just the result of a read to an incorrect location, and
the return value is -1. There is no PCI when running in Xen PVH, at
least for now. I think I should try harder to find out if OVMF is
running in PVH, and so I would not need this case 0xffff at all.

-- 
Anthony PERARD


^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH RFC 06/14] OvmfPkg/XenPlatformPei: Add xen PVH specific code
  2017-01-10 16:18     ` Anthony PERARD
@ 2017-01-10 16:54       ` Laszlo Ersek
  0 siblings, 0 replies; 37+ messages in thread
From: Laszlo Ersek @ 2017-01-10 16:54 UTC (permalink / raw)
  To: Anthony PERARD; +Cc: edk2-devel, xen-devel

On 01/10/17 17:18, Anthony PERARD wrote:
> On Thu, Jan 05, 2017 at 11:30:32AM +0100, Laszlo Ersek wrote:
>> On 12/08/16 16:33, Anthony PERARD wrote:
>>> - learn about memory size from the E820
>>> - ignore error if host bridge devid is 0xffff, PVH does not have PCI and
>>>   reading from unexisting device return -1.
>>>
>>> Contributed-under: TianoCore Contribution Agreement 1.0
>>> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
>>> ---
>>>  OvmfPkg/XenPlatformPei/MemDetect.c | 71 ++++++++++++++++++++++++++++++++++++++
>>>  OvmfPkg/XenPlatformPei/Platform.c  |  5 +++
>>>  OvmfPkg/XenPlatformPei/Platform.h  | 10 ++++++
>>>  3 files changed, 86 insertions(+)
>>>
>>> diff --git a/OvmfPkg/XenPlatformPei/MemDetect.c b/OvmfPkg/XenPlatformPei/MemDetect.c
>>> index 4ecdf5e..0d80775 100644
>>> --- a/OvmfPkg/XenPlatformPei/MemDetect.c
>>> +++ b/OvmfPkg/XenPlatformPei/MemDetect.c
>>> @@ -42,6 +42,70 @@ UINT8 mPhysMemAddressWidth;
>>>  STATIC UINT32 mS3AcpiReservedMemoryBase;
>>>  STATIC UINT32 mS3AcpiReservedMemorySize;
>>>  
>>> +STATIC UINT32 mXenLowerMemorySize = 0;
>>> +STATIC UINT64 mXenHighMemorySize = 0;
>>> +
>>> +VOID
>>> +XenReadMemorySizes (
>>> +  VOID
>>> +  )
>>> +{
>>> +  EFI_E820_ENTRY64  *E820Map;
>>> +  UINT32            E820EntriesCount;
>>> +  EFI_STATUS Status;
>>> +
>>> +  Status = XenGetE820Map (&E820Map, &E820EntriesCount);
>>> +  ASSERT_EFI_ERROR (Status);
>>> +
>>> +  mXenLowerMemorySize = 0;
>>> +  mXenHighMemorySize = 0;
>>> +
>>> +  if (E820EntriesCount > 0) {
>>> +    EFI_E820_ENTRY64 *Entry;
>>> +    UINT32 Loop;
>>> +
>>> +    for (Loop = 0; Loop < E820EntriesCount; Loop++) {
>>> +      Entry = E820Map + Loop;
>>> +
>>> +      //
>>> +      // Only care about RAM
>>> +      //
>>> +      if (Entry->Type != EfiAcpiAddressRangeMemory) {
>>> +        continue;
>>> +      }
>>> +
>>> +      if ((Entry->BaseAddr + Entry->Length) <= SIZE_16MB) {
>>> +        continue;
>>> +      }
>>> +
>>> +      if (Entry->BaseAddr < SIZE_16MB) {
>>> +        UINT64 bottom = Entry->BaseAddr;
>>> +        UINT64 size = Entry->Length;
>>> +        size -= SIZE_16MB - bottom;
>>> +        bottom = SIZE_16MB;
>>> +        mXenLowerMemorySize += size;
>>> +        continue;
>>> +      }
>>> +      if (Entry->BaseAddr <= SIZE_4GB) {
>>> +        UINT64 size = Entry->Length;
>>> +        mXenLowerMemorySize += size;
>>> +        continue;
>>> +      }
>>> +
>>> +      if (Entry->BaseAddr == SIZE_4GB) {
>>> +        mXenHighMemorySize = Entry->Length;
>>> +        continue;
>>> +      }
>>> +
>>> +      DEBUG ((EFI_D_INFO, "%a: ignored XenE820 entry (0x%llx, 0x%llx)\n",
>>> +              __FUNCTION__,
>>> +              Entry->BaseAddr,
>>> +              Entry->Length));
>>> +    }
>>> +    mXenLowerMemorySize += SIZE_16MB;
>>> +  }
>>> +}
>>> +
>>>  UINT32
>>>  GetSystemMemorySizeBelow4gb (
>>>    VOID
>>> @@ -50,6 +114,9 @@ GetSystemMemorySizeBelow4gb (
>>>    UINT8 Cmos0x34;
>>>    UINT8 Cmos0x35;
>>>  
>>> +  if (mXen && mXenLowerMemorySize)
>>> +    return mXenLowerMemorySize;
>>> +
>>>    //
>>>    // CMOS 0x34/0x35 specifies the system memory above 16 MB.
>>>    // * CMOS(0x35) is the high byte
>>> @@ -74,6 +141,10 @@ GetSystemMemorySizeAbove4gb (
>>>    UINT32 Size;
>>>    UINTN  CmosIndex;
>>>  
>>> +  // if lower memory is specified that way, return also high memory
>>> +  if (mXen && mXenLowerMemorySize)
>>> +    return mXenHighMemorySize;
>>> +
>>>    //
>>>    // CMOS 0x5b-0x5d specifies the system memory above 4GB MB.
>>>    // * CMOS(0x5d) is the most significant size byte
>>> diff --git a/OvmfPkg/XenPlatformPei/Platform.c b/OvmfPkg/XenPlatformPei/Platform.c
>>> index bf78878..9fc713c 100644
>>> --- a/OvmfPkg/XenPlatformPei/Platform.c
>>> +++ b/OvmfPkg/XenPlatformPei/Platform.c
>>> @@ -362,6 +362,10 @@ MiscInitialization (
>>>        AcpiCtlReg = POWER_MGMT_REGISTER_Q35 (ICH9_ACPI_CNTL);
>>>        AcpiEnBit  = ICH9_ACPI_CNTL_ACPI_EN;
>>>        break;
>>> +    case 0xffff:
>>> +      // xen PVH, ignore
>>> +      PcdStatus = PcdSet16S (PcdOvmfHostBridgePciDevId, mHostBridgeDevId);
>>> +      return;
>>
>> Can we create a new macro for 0xFFFF in
>> "OvmfPkg/Include/OvmfPlatforms.h", and use that here?
>>
>> Normally I would suggest a separate header file under "OvmfPkg/Include",
>> similar to "Q35MchIch9.h" and "I440FxPiix4.h", and to include that new
>> file in "OvmfPlatforms.h", but here we only need a single "chipset
>> identifier", so I guess that can go directly into "OvmfPlatforms.h".
>>
>> I mainly suggest this because in patch 08/14, the same 0xFFFF case label
>> is being added to code shared with QEMU, and using a verbose macro there
>> is much better than a magic number. In turn, we should use the same
>> macro here, I think.
> 
> This value is just the result of a read to an incorrect location, and
> the return value is -1. There is no PCI when running in Xen PVH, at
> least for now. I think I should try harder to find out if OVMF is
> running in PVH, and so I would not need this case 0xffff at all.
> 

Right, that would be best.

In fact, this affects two modules, (Xen)PlatformPei and
PlatformBootManagerLib. In both, we already have the XenDetected()
function. Maybe you can add a XenPvhDetected() function as well (which
would return TRUE only for PVH, while the original XenDetected() would
continue returning TRUE for both HVM and PVH). Then the PCI host bridge
ID checking could be entirely short-circuited if XenPvhDetected()
returned TRUE first.

Thanks
Laszlo




^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2017-01-10 16:54 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-12-08 15:33 [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests Anthony PERARD
2016-12-08 15:33 ` [PATCH RFC 01/14] OvmfPkg: Create platform XenOvmf Anthony PERARD
2017-01-04 19:14   ` Laszlo Ersek
2016-12-08 15:33 ` [PATCH RFC 02/14] OvmfPkg/XenOvmf: Update debug IO port for Xen Anthony PERARD
2017-01-04 19:23   ` Laszlo Ersek
2016-12-08 15:33 ` [PATCH RFC 03/14] OvmfPkg/XenOvmf.dsc: Introduce XenResetVector Anthony PERARD
2017-01-04 19:49   ` Laszlo Ersek
2017-01-10 15:58     ` Anthony PERARD
2016-12-08 15:33 ` [PATCH RFC 04/14] OvmfPkg: Introduce XenPlatformPei Anthony PERARD
2017-01-05  9:59   ` Laszlo Ersek
2017-01-10 16:08     ` Anthony PERARD
2016-12-08 15:33 ` [PATCH RFC 05/14] OvmfPkg/Library: add XenPciHostBridgeLib Anthony PERARD
2017-01-05 10:15   ` Laszlo Ersek
2016-12-08 15:33 ` [PATCH RFC 06/14] OvmfPkg/XenPlatformPei: Add xen PVH specific code Anthony PERARD
2017-01-05 10:30   ` Laszlo Ersek
2017-01-10 16:18     ` Anthony PERARD
2017-01-10 16:54       ` Laszlo Ersek
2016-12-08 15:33 ` [PATCH RFC 07/14] OvmfPkg/XenResetVector: Add new entry point for Xen PVH Anthony PERARD
2017-01-05 10:36   ` Laszlo Ersek
2016-12-08 15:33 ` [PATCH RFC 08/14] OvmfPkg/PlatformBootManagerLib: Workaround missing PCI bus on " Anthony PERARD
2017-01-05 10:38   ` Laszlo Ersek
2016-12-08 15:33 ` [PATCH RFC 09/14] OvmfPkg/ResetSystemLib: Add missing dependency on PciLib Anthony PERARD
2017-01-05 10:46   ` Laszlo Ersek
2016-12-08 15:33 ` [PATCH RFC 10/14] UefiCpuPkg/BaseXApicX2ApicLib: Fix initialisation on my system and Anthony PERARD
2016-12-09  6:48   ` Kinney, Michael D
2016-12-12 12:38     ` Anthony PERARD
     [not found]     ` <58dbbeb0-f600-ef3f-7f8c-5c110b0aa809@citrix.com>
2016-12-12 12:40       ` [Xen-devel] " Anthony PERARD
2016-12-08 15:33 ` [PATCH RFC 11/14] OvmfPkg/XenOvmf: Adding XenTimerLocalApic Anthony PERARD
2017-01-05 11:26   ` Laszlo Ersek
2016-12-08 15:33 ` [PATCH RFC 12/14] OvmfPkg/PlatformBootManagerLib: Use a Xen console for ConOut/ConIn Anthony PERARD
2017-01-05 16:38   ` Laszlo Ersek
2016-12-08 15:33 ` [PATCH RFC 13/14] OvmfPkg: Introduce XenIoPvhDxe to initialize Grant Tables Anthony PERARD
2017-01-05 16:58   ` Laszlo Ersek
2016-12-08 15:33 ` [PATCH RFC 14/14] XenOvmf: Use a different RTC Anthony PERARD
2017-01-05 17:02   ` Laszlo Ersek
2017-01-04 19:52 ` [PATCH RFC 00/14] Specific platform to run OVMF in Xen PVH and HVM guests Laszlo Ersek
2017-01-10 14:55   ` Anthony PERARD

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox