From 3b96221f77f4181524657e145b51fa423f3faebe Mon Sep 17 00:00:00 2001 From: Anthony PERARD Date: Tue, 13 Aug 2019 12:30:48 +0100 Subject: 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 Reviewed-by: Laszlo Ersek Message-Id: <20190813113119.14804-5-anthony.perard@citrix.com> --- OvmfPkg/XenPlatformPei/Xen.c | 219 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 OvmfPkg/XenPlatformPei/Xen.c (limited to 'OvmfPkg/XenPlatformPei/Xen.c') 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.
+ Copyright (c) 2011, Andrei Warkentin + Copyright (c) 2019, Citrix Systems, Inc. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +// +// The package level header files this module uses +// +#include + +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +} -- cgit v1.2.3