diff --git a/.github/workflows/Platform-Build.yml b/.github/workflows/Platform-Build.yml index 33f159dd08..e0b2c9ae17 100644 --- a/.github/workflows/Platform-Build.yml +++ b/.github/workflows/Platform-Build.yml @@ -131,6 +131,11 @@ jobs: # Stuart Build: Perform the build using the specified architecture and target - name: Stuart Build + env: + # Mark builds of main (not pull requests) as official. The + # FirmwareVersionBlob plugin records this in the firmware version + # record and PcdMsvmFirmwareFlags. + OFFICIAL_BUILD: ${{ (github.event_name == 'push' && github.ref == 'refs/heads/main') && '1' || '' }} run: stuart_build -c MsvmPkg/PlatformBuild.py --verbose TOOL_CHAIN_TAG=${{matrix.tools}} TARGET=${{matrix.target}} BUILD_ARCH=${{matrix.arch}} # Upload the MSVM.fd file, MAP/, and PDB/ directories directly as an artifact diff --git a/MsvmPkg/BuildPlugins/FirmwareVersionBlob/FirmwareVersionBlob.py b/MsvmPkg/BuildPlugins/FirmwareVersionBlob/FirmwareVersionBlob.py new file mode 100644 index 0000000000..142001f13e --- /dev/null +++ b/MsvmPkg/BuildPlugins/FirmwareVersionBlob/FirmwareVersionBlob.py @@ -0,0 +1,135 @@ +## @file FirmwareVersionBlob.py +# Pre-build plugin that owns the firmware version data. +# +# It reads the single source of truth (MsvmPkg/FirmwareVersion.toml) plus the +# git state, then does two things from those same values so they can never +# drift: +# +# 1. Generates the machine-readable firmware version record +# (MSVM_FIRMWARE_VERSION_INFO) embedded as a RAW file in the DXE FV, which +# the host/VMM scans out of the loaded image ('MVFW' signature / file GUID). +# See MsvmPkg/Include/MsvmFirmwareVersion.h and the SECTION RAW reference in +# MsvmPkg/MsvmPkgX64.fdf / MsvmPkgAARCH64.fdf. +# +# 2. Injects the same values as build macros ("BLD_*_MSVM_FW_*") which the DSC +# binds to FixedAtBuild PCDs, so the firmware itself can read the version at +# runtime (e.g. to log it early). See the [PcdsFixedAtBuild] overrides in +# the platform DSC files. +# +# Runs before the platform build (do_pre_build), after stuart has populated the +# build environment, so BUILD_OUTPUT_BASE is guaranteed to be set and the macros +# are set in time for the build command. +# +## +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## +import logging +import os +import struct +import tomllib + +from edk2toolext.environment import repo_resolver +from edk2toolext.environment.plugintypes.uefi_build_plugin import IUefiBuildPlugin + + +class FirmwareVersionBlob(IUefiBuildPlugin): + # + # Layout of MSVM_FIRMWARE_VERSION_INFO (see + # MsvmPkg/Include/MsvmFirmwareVersion.h). All integers are little-endian; + # string fields are NUL-terminated ASCII. + # UINT32 Signature ('MVFW'), UINT16 StructVersion, UINT16 HeaderSize, + # UINT32 Flags, UINT16 InterfaceVersionMajor, UINT16 InterfaceVersionMinor, + # CHAR8 BaseVersion[16], CHAR8 GitCommit[48] + # + FW_VERSION_SIGNATURE = 0x5746564D # 'MVFW' little-endian + FW_VERSION_STRUCT_VERSION = 1 + FW_VERSION_FLAG_DIRTY = 0x1 # MSVM_FIRMWARE_VERSION_FLAG_DIRTY + FW_VERSION_FLAG_OFFICIAL = 0x2 # MSVM_FIRMWARE_VERSION_FLAG_OFFICIAL + FW_VERSION_BASE_VERSION_SIZE = 16 + FW_VERSION_GIT_COMMIT_SIZE = 48 + FW_VERSION_STRUCT_FORMAT = " makes stuart pass "-D =" to the build, which + # the DSC binds to the PcdMsvmFirmware* PCDs. + thebuilder.env.SetValue("BLD_*_MSVM_FW_INTERFACE_MAJOR", str(major), "FirmwareVersion.toml", True) + thebuilder.env.SetValue("BLD_*_MSVM_FW_INTERFACE_MINOR", str(minor), "FirmwareVersion.toml", True) + thebuilder.env.SetValue("BLD_*_MSVM_FW_BASE_VERSION", base_version, "FirmwareVersion.toml", True) + thebuilder.env.SetValue("BLD_*_MSVM_FW_GIT_COMMIT", commit, "git", True) + thebuilder.env.SetValue("BLD_*_MSVM_FW_FLAGS", str(flags), "git", True) + + # (2) Pack the same values into the host-facing FV record. + blob = struct.pack( + self.FW_VERSION_STRUCT_FORMAT, + self.FW_VERSION_SIGNATURE, + self.FW_VERSION_STRUCT_VERSION, + struct.calcsize(self.FW_VERSION_STRUCT_FORMAT), + flags, + major, + minor, + base_version.encode("ascii", "replace"), + commit.encode("ascii", "replace"), + ) + + # Emit into the per-build output directory so the artifact stays out of + # the source tree. stuart computes BUILD_OUTPUT_BASE as + # /_, which matches the FDF + # SECTION RAW path. + out_dir = thebuilder.env.GetValue("BUILD_OUTPUT_BASE") + out_path = os.path.join(out_dir, self.FW_VERSION_BLOB_SUBPATH) + os.makedirs(os.path.dirname(out_path), exist_ok=True) + with open(out_path, "wb") as f: + f.write(blob) + + logging.info( + f"Firmware version blob written: base={base_version} commit={commit}" + f"{' (dirty)' if dirty else ''}" + f"{' (official)' if flags & self.FW_VERSION_FLAG_OFFICIAL else ''}" + f" interface={major}.{minor}" + f" -> {out_path}" + ) + return 0 diff --git a/MsvmPkg/BuildPlugins/FirmwareVersionBlob/FirmwareVersionBlob_plug_in.json b/MsvmPkg/BuildPlugins/FirmwareVersionBlob/FirmwareVersionBlob_plug_in.json new file mode 100644 index 0000000000..9a39e3d326 --- /dev/null +++ b/MsvmPkg/BuildPlugins/FirmwareVersionBlob/FirmwareVersionBlob_plug_in.json @@ -0,0 +1,5 @@ +{ + "scope": "global", + "name": "Firmware Version Blob Uefi Build Plugin", + "module": "FirmwareVersionBlob" +} diff --git a/MsvmPkg/FirmwareVersion.toml b/MsvmPkg/FirmwareVersion.toml new file mode 100644 index 0000000000..24dfc65777 --- /dev/null +++ b/MsvmPkg/FirmwareVersion.toml @@ -0,0 +1,22 @@ +# Single source of truth for the firmware version numbers. +# +# Bump these by hand in code review. The build (see +# MsvmPkg/BuildPlugins/FirmwareVersionBlob) embeds them into the DXE FV version +# record (MSVM_FIRMWARE_VERSION_INFO) *and* into the FixedAtBuild PCDs that the +# firmware reads at runtime, so there is exactly one place to edit. + +# Firmware<->VMM interface (compatibility) contract version. Independent of the +# release below and of git state. It is a machine-comparable gate the VMM uses +# to decide whether it can talk to this firmware. +# - Bump major for a breaking change (an older VMM would malfunction). Reset +# minor to 0 on a major bump. +# - Bump minor for a backward-compatible addition the VMM can degrade without. +[interface] +major = 1 +minor = 0 + +# Release version prefix ("major.minor"). The GitHub release workflow may +# override this via the BASE_VERSION environment variable and assigns the patch +# number later, so only the prefix lives here. +[release] +version = "26.0" diff --git a/MsvmPkg/FirmwareVersionPcd.dsc.inc b/MsvmPkg/FirmwareVersionPcd.dsc.inc new file mode 100644 index 0000000000..ac0d7b4397 --- /dev/null +++ b/MsvmPkg/FirmwareVersionPcd.dsc.inc @@ -0,0 +1,20 @@ +## @file +# Firmware version record PCD value bindings, shared by MsvmPkgX64.dsc and +# MsvmPkgAARCH64.dsc so the list lives in one place. +# +# Binds the firmware version PCDs (declared in MsvmPkg/MsvmPkg.dec) to the +# build-time MSVM_FW_* macros injected by the FirmwareVersionBlob pre-build +# plugin, which sources them from MsvmPkg/FirmwareVersion.toml and git state. +# The macros are supplied by the plugin as "-D MSVM_FW_*=..."; nothing here +# needs a default because the plugin always runs before the build. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[PcdsFixedAtBuild.common] + gMsvmPkgTokenSpaceGuid.PcdMsvmFirmwareInterfaceVersionMajor|$(MSVM_FW_INTERFACE_MAJOR) + gMsvmPkgTokenSpaceGuid.PcdMsvmFirmwareInterfaceVersionMinor|$(MSVM_FW_INTERFACE_MINOR) + gMsvmPkgTokenSpaceGuid.PcdMsvmFirmwareBaseVersion|"$(MSVM_FW_BASE_VERSION)" + gMsvmPkgTokenSpaceGuid.PcdMsvmFirmwareGitCommit|"$(MSVM_FW_GIT_COMMIT)" + gMsvmPkgTokenSpaceGuid.PcdMsvmFirmwareFlags|$(MSVM_FW_FLAGS) diff --git a/MsvmPkg/Include/MsvmFirmwareVersion.h b/MsvmPkg/Include/MsvmFirmwareVersion.h new file mode 100644 index 0000000000..bb82951f42 --- /dev/null +++ b/MsvmPkg/Include/MsvmFirmwareVersion.h @@ -0,0 +1,135 @@ +/** @file + Defines the firmware version record that is embedded as a RAW file in the + firmware volume so the host/VMM can identify the firmware image mechanically + (i.e. by parsing the image bytes) at load time, without executing it. + + The record is generated at build time by MsvmPkg/PlatformBuild.py and placed + into the DXE firmware volume (see MsvmPkg/MsvmPkgX64.fdf / + MsvmPkg/MsvmPkgAARCH64.fdf) as a leaf file named by + gMsvmFirmwareVersionFileGuid. + + Host-side location strategy: + - Scan the loaded image for the 4-byte Signature ('MVFW'), OR + - Scan for the 16-byte file GUID (gMsvmFirmwareVersionFileGuid) that appears + in the FFS file header, then read the record that follows. + + All multi-byte integer fields are little-endian. String fields are ASCII and + NUL-terminated. The layout is append-only: new fields may be added at the end + guarded by StructVersion / HeaderSize, but existing fields and the Signature + must never change meaning so the host parser stays stable. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#pragma once + +// +// Signature 'MVFW' stored little-endian ('M','V','F','W'). +// +#define MSVM_FIRMWARE_VERSION_SIGNATURE SIGNATURE_32 ('M', 'V', 'F', 'W') + +// +// Current StructVersion value. Bump when the layout is extended. +// +#define MSVM_FIRMWARE_VERSION_STRUCT_VERSION 1 + +// +// Firmware/VMM interface (compatibility) version. This is a human-curated +// semantic contract version that is deliberately independent of the release +// (BaseVersion) and of git state. +// +// The value is NOT defined here. It lives in MsvmPkg/FirmwareVersion.toml (the +// single source of truth) and is embedded into this record and into the +// PcdMsvmFirmwareInterfaceVersionMajor/Minor FixedAtBuild PCDs at build time. +// Bump it there, by hand, in code review, whenever the contract between this +// firmware and the host/VMM changes: +// +// - Bump MAJOR for any breaking change: one where an existing VMM built +// against an older major would malfunction. This includes the firmware +// hard-requiring new VMM-provided behavior it cannot boot without. Reset +// MINOR to 0 on a major bump. +// - Bump MINOR for a backward-compatible addition: an optional capability the +// firmware can degrade gracefully without. +// +// The VMM supports a range of majors and refuses anything outside it (firmware +// too new or too old to talk to). A higher-than-known minor is always safe to +// proceed on; the VMM may additionally require a minimum minor for features it +// depends on. +// + +// +// Bit definitions for the Flags field. +// +// MSVM_FIRMWARE_VERSION_FLAG_DIRTY: the build was produced from a tree with +// uncommitted changes (modified tracked files or untracked files present), so +// GitCommit identifies the base commit but not the exact source that was built. +// When clear, GitCommit identifies the exact committed source state. +// +// MSVM_FIRMWARE_VERSION_FLAG_OFFICIAL: the build was produced by the official +// CI pipeline (e.g. building main), as opposed to a developer or pull-request +// build. Set from the OFFICIAL_BUILD build environment; clear otherwise. +// +#define MSVM_FIRMWARE_VERSION_FLAG_DIRTY BIT0 +#define MSVM_FIRMWARE_VERSION_FLAG_OFFICIAL BIT1 + +// +// Maximum sizes (including the terminating NUL) for the string fields. +// +#define MSVM_FIRMWARE_BASE_VERSION_SIZE 16 +#define MSVM_FIRMWARE_GIT_COMMIT_SIZE 48 + +#pragma pack(1) + +typedef struct { + // + // MSVM_FIRMWARE_VERSION_SIGNATURE. Lets the host find/validate the record by + // a flat byte scan regardless of FFS/section wrapping. + // + UINT32 Signature; + + // + // MSVM_FIRMWARE_VERSION_STRUCT_VERSION. Incremented when fields are added. + // + UINT16 StructVersion; + + // + // Size of this structure in bytes. Lets the host skip unknown trailing + // fields from a newer firmware build. + // + UINT16 HeaderSize; + + // + // Bitmask of MSVM_FIRMWARE_VERSION_FLAG_* values describing the build. + // + UINT32 Flags; + + // + // MSVM_FIRMWARE_INTERFACE_VERSION_MAJOR / _MINOR: the human-curated + // firmware/VMM compatibility contract version. Unlike BaseVersion this is a + // machine-comparable gate: the VMM checks these to decide whether it can talk + // to this firmware and should warn/bail early if not. The values live in + // MsvmPkg/FirmwareVersion.toml; see the interface version comment above for + // the bump rules. + // + UINT16 InterfaceVersionMajor; + UINT16 InterfaceVersionMinor; + + // + // Static "major.minor" release prefix (e.g. "26.0"). The release patch + // number is assigned later by the GitHub release workflow and is therefore + // not present here; resolve the full version by finding the release whose + // tag targets GitCommit. + // + CHAR8 BaseVersion[MSVM_FIRMWARE_BASE_VERSION_SIZE]; + + // + // Full 40-character git commit hash. Set to "unknown" when git information is + // unavailable at build time. Whether the tree was dirty at build time is + // reported separately via MSVM_FIRMWARE_VERSION_FLAG_DIRTY in Flags. + // + CHAR8 GitCommit[MSVM_FIRMWARE_GIT_COMMIT_SIZE]; +} MSVM_FIRMWARE_VERSION_INFO; + +#pragma pack() diff --git a/MsvmPkg/MsvmPkg.dec b/MsvmPkg/MsvmPkg.dec index 6132c50f98..4d600fba51 100644 --- a/MsvmPkg/MsvmPkg.dec +++ b/MsvmPkg/MsvmPkg.dec @@ -28,6 +28,12 @@ # Guid for FrontPage NV variable # gFrontPageNVVarGuid = {0x7f98efe9, 0x50aa, 0x4598, { 0xb7, 0xc1, 0xcb, 0x72, 0xe1, 0xcc, 0x52, 0x24 }} + # + # Names the RAW firmware-version record embedded in the DXE FV so the host/VMM + # can locate it. See MsvmPkg/Include/MsvmFirmwareVersion.h. + # {B8F2D3A4-6C7E-4E1B-9A2F-1D3C5E7A9B0D} + # + gMsvmFirmwareVersionFileGuid = {0xb8f2d3a4, 0x6c7e, 0x4e1b, {0x9a, 0x2f, 0x1d, 0x3c, 0x5e, 0x7a, 0x9b, 0x0d}} gMsvmVmbusClientGuid = {0x18dd3964, 0x3e8a, 0x4e42, {0x86, 0xfa, 0xc8, 0xe6, 0xb1, 0x91, 0xee, 0x0e}} # @@ -82,6 +88,17 @@ gMsvmPkgTokenSpaceGuid.PcdDxeFvBaseAddress|0x0|UINT64|0x6 gMsvmPkgTokenSpaceGuid.PcdDxeFvSize|0x0|UINT32|0x7 + # Firmware version record. These declare the PCD contract only; the values are + # injected at build time by MsvmPkg/BuildPlugins/FirmwareVersionBlob from the + # single source of truth (MsvmPkg/FirmwareVersion.toml + git), the same way + # PcdFdBaseAddress above gets its real value from the build. The defaults here + # are throwaway sentinels. See MsvmPkg/Include/MsvmFirmwareVersion.h. + gMsvmPkgTokenSpaceGuid.PcdMsvmFirmwareInterfaceVersionMajor|0|UINT16|0x7000 + gMsvmPkgTokenSpaceGuid.PcdMsvmFirmwareInterfaceVersionMinor|0|UINT16|0x7001 + gMsvmPkgTokenSpaceGuid.PcdMsvmFirmwareBaseVersion|"unknown"|VOID*|0x7002 + gMsvmPkgTokenSpaceGuid.PcdMsvmFirmwareGitCommit|"unknown"|VOID*|0x7003 + gMsvmPkgTokenSpaceGuid.PcdMsvmFirmwareFlags|0x0|UINT32|0x7004 + # Synthetic Timer Configuration gMsvmPkgTokenSpaceGuid.PcdSynicTimerSintIndex|0x1|UINT8|0x2000 gMsvmPkgTokenSpaceGuid.PcdSynicTimerTimerIndex|0x0|UINT8|0x2001 diff --git a/MsvmPkg/MsvmPkgAARCH64.dsc b/MsvmPkg/MsvmPkgAARCH64.dsc index 193e9cc059..c2c7e19dfd 100644 --- a/MsvmPkg/MsvmPkgAARCH64.dsc +++ b/MsvmPkg/MsvmPkgAARCH64.dsc @@ -361,6 +361,8 @@ # PERF MODULES END [PcdsFixedAtBuild.common] +!include MsvmPkg/FirmwareVersionPcd.dsc.inc + # Advanced Logger Config # PreMemPages comes from the SEC temp-RAM PEI heap. On X64, 6 is the # ceiling (7+ exhausts temp RAM) and 2 is the empirical minimum that diff --git a/MsvmPkg/MsvmPkgAARCH64.fdf b/MsvmPkg/MsvmPkgAARCH64.fdf index ab8f191a67..7bd3cefdc7 100644 --- a/MsvmPkg/MsvmPkgAARCH64.fdf +++ b/MsvmPkg/MsvmPkgAARCH64.fdf @@ -302,6 +302,16 @@ FILE FREEFORM = PCD(gMsvmPkgTokenSpaceGuid.PcdBootFailIndicatorFile) { SECTION RAW = MsvmPkg/FrontPage/Resources/NoBoot.bmp } +# +# Firmware version record (git commit + base release version). Generated at +# build time by MsvmPkg/PlatformBuild.py. The host/VMM locates this record by +# scanning the loaded image for the 'MVFW' signature or for this file GUID; see +# MsvmPkg/Include/MsvmFirmwareVersion.h for the layout. +# +FILE FREEFORM = B8F2D3A4-6C7E-4E1B-9A2F-1D3C5E7A9B0D { + SECTION RAW = $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/FwVersion/FwVersionBlob.bin +} + ################################################################################ # Rules section. [Rule.Common.SEC] diff --git a/MsvmPkg/MsvmPkgX64.dsc b/MsvmPkg/MsvmPkgX64.dsc index 8e5a3e58b5..94750b0425 100644 --- a/MsvmPkg/MsvmPkgX64.dsc +++ b/MsvmPkg/MsvmPkgX64.dsc @@ -360,6 +360,8 @@ # PERF MODULES END [PcdsFixedAtBuild.common] +!include MsvmPkg/FirmwareVersionPcd.dsc.inc + # Advanced Logger Config # # N.B PcdAdvancedLoggerBase is explicitly set to 0 for Hyper-V UEFI in order diff --git a/MsvmPkg/MsvmPkgX64.fdf b/MsvmPkg/MsvmPkgX64.fdf index 6efcd583f8..da08dc5ad2 100644 --- a/MsvmPkg/MsvmPkgX64.fdf +++ b/MsvmPkg/MsvmPkgX64.fdf @@ -349,6 +349,16 @@ FILE FREEFORM = PCD(gMsvmPkgTokenSpaceGuid.PcdBootFailIndicatorFile) { SECTION RAW = MsvmPkg/FrontPage/Resources/NoBoot.bmp } +# +# Firmware version record (git commit + base release version). Generated at +# build time by MsvmPkg/PlatformBuild.py. The host/VMM locates this record by +# scanning the loaded image for the 'MVFW' signature or for this file GUID; see +# MsvmPkg/Include/MsvmFirmwareVersion.h for the layout. +# +FILE FREEFORM = B8F2D3A4-6C7E-4E1B-9A2F-1D3C5E7A9B0D { + SECTION RAW = $(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/FwVersion/FwVersionBlob.bin +} + #FILE APPLICATION = c57ad6b7-0515-40a8-9d21-551652854e37 { # SECTION PE32 = ShellBinPkg/UefiShell/X64/Shell.efi # } diff --git a/MsvmPkg/PlatformBuild.py b/MsvmPkg/PlatformBuild.py index 3d60dd661f..51aaa15af0 100644 --- a/MsvmPkg/PlatformBuild.py +++ b/MsvmPkg/PlatformBuild.py @@ -86,18 +86,10 @@ def SetPlatformEnvAfterTarget(self): logging.debug("PlatformBuilder SetPlatformEnvAfterTarget") return 0 - def PlatformPostBuild(self): + def PlatformPreBuild(self): return 0 - - #------------------------------------------------------------------ - # - # Method to do stuff pre build. - # This is part of the build flow. - # Currently do nothing. - # - #------------------------------------------------------------------ - def PlatformPreBuild(self): + def PlatformPostBuild(self): return 0 # diff --git a/MsvmPkg/PlatformPei/Platform.c b/MsvmPkg/PlatformPei/Platform.c index b25d9d89d6..f897552d98 100644 --- a/MsvmPkg/PlatformPei/Platform.c +++ b/MsvmPkg/PlatformPei/Platform.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #if defined(MDE_CPU_AARCH64) #include @@ -992,6 +994,20 @@ Return Value: DEBUG((DEBUG_VERBOSE, ">>> *** Platform PEIM InitializePlatform@%p\n", InitializePlatform)); + // + // Log the firmware version as early as the logger is up. The values come + // from FixedAtBuild PCDs injected by the FirmwareVersionBlob build plugin + // from MsvmPkg/FirmwareVersion.toml + git state. + // + DEBUG((DEBUG_INFO, + "Hyper-V UEFI firmware: release %a interface %u.%u commit %a%a%a\n", + (CHAR8 *)PcdGetPtr(PcdMsvmFirmwareBaseVersion), + (UINT32)PcdGet16(PcdMsvmFirmwareInterfaceVersionMajor), + (UINT32)PcdGet16(PcdMsvmFirmwareInterfaceVersionMinor), + (CHAR8 *)PcdGetPtr(PcdMsvmFirmwareGitCommit), + ((PcdGet32(PcdMsvmFirmwareFlags) & MSVM_FIRMWARE_VERSION_FLAG_DIRTY) != 0) ? " (dirty)" : "", + ((PcdGet32(PcdMsvmFirmwareFlags) & MSVM_FIRMWARE_VERSION_FLAG_OFFICIAL) != 0) ? " (official)" : "")); + ZeroMem(&context, sizeof(context)); #if defined(MDE_CPU_AARCH64) diff --git a/MsvmPkg/PlatformPei/PlatformPei.inf b/MsvmPkg/PlatformPei/PlatformPei.inf index 8ff5b775f4..bd73739cd3 100644 --- a/MsvmPkg/PlatformPei/PlatformPei.inf +++ b/MsvmPkg/PlatformPei/PlatformPei.inf @@ -91,6 +91,11 @@ gMsvmPkgTokenSpaceGuid.PcdFvSize gMsvmPkgTokenSpaceGuid.PcdDxeFvBaseAddress gMsvmPkgTokenSpaceGuid.PcdDxeFvSize + gMsvmPkgTokenSpaceGuid.PcdMsvmFirmwareInterfaceVersionMajor + gMsvmPkgTokenSpaceGuid.PcdMsvmFirmwareInterfaceVersionMinor + gMsvmPkgTokenSpaceGuid.PcdMsvmFirmwareBaseVersion + gMsvmPkgTokenSpaceGuid.PcdMsvmFirmwareGitCommit + gMsvmPkgTokenSpaceGuid.PcdMsvmFirmwareFlags gMsvmPkgTokenSpaceGuid.PcdConfigBlobSize gMsvmPkgTokenSpaceGuid.PcdLegacyMemoryMap gMsvmPkgTokenSpaceGuid.PcdMadtPtr