diff options
author | Anthony PERARD <anthony.perard@citrix.com> | 2019-08-13 12:30:48 +0100 |
---|---|---|
committer | Laszlo Ersek <lersek@redhat.com> | 2019-08-21 18:03:49 +0200 |
commit | 3b96221f77f4181524657e145b51fa423f3faebe (patch) | |
tree | 88f145ad14fd7253f93c9ea99d41a6b4887447cb /OvmfPkg/XenPlatformPei/Xen.c | |
parent | c05de360ec614f71716a201760b91ee055a5ff28 (diff) | |
download | edk2-3b96221f77f4181524657e145b51fa423f3faebe.tar.gz edk2-3b96221f77f4181524657e145b51fa423f3faebe.tar.bz2 edk2-3b96221f77f4181524657e145b51fa423f3faebe.zip |
OvmfPkg: Introduce XenPlatformPei
Introduce XenPlatformPei, a copy of OvmfPkg/PlatformPei without some
of QEMU specific initialization, Xen does not support QemuFwCfg.
This new module will be adjusted to accommodate Xen PVH.
fw_cfg dependents that have been removed, which are dynamically skipped
when running PlatformPei 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
fw_cfg "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 FeatureControl.c as there is nothing been executed)
Also removed:
- SMRAM/TSEG-related low mem size adjusting (PcdSmmSmramRequire is
assumed FALSE) in PublishPeiMemory(),
- QemuInitializeRam() entirely,
Xen related changes:
- Have removed the module variable mXen, as it should be always true.
- Have the platform PEI initialization fails if Xen has not been
detected.
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20190813113119.14804-5-anthony.perard@citrix.com>
Diffstat (limited to 'OvmfPkg/XenPlatformPei/Xen.c')
-rw-r--r-- | OvmfPkg/XenPlatformPei/Xen.c | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/OvmfPkg/XenPlatformPei/Xen.c b/OvmfPkg/XenPlatformPei/Xen.c new file mode 100644 index 0000000000..f4d0d1c73b --- /dev/null +++ b/OvmfPkg/XenPlatformPei/Xen.c @@ -0,0 +1,219 @@ +/**@file
+ Xen Platform PEI support
+
+ Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>
+ Copyright (c) 2019, Citrix Systems, Inc.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+//
+// 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"
+
+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 ((DEBUG_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")) {
+ return TRUE;
+ }
+ }
+
+ mXenLeaf = 0;
+ return FALSE;
+}
+
+
+VOID
+XenPublishRamRegions (
+ VOID
+ )
+{
+ EFI_E820_ENTRY64 *E820Map;
+ UINT32 E820EntriesCount;
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_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;
+}
|