summaryrefslogtreecommitdiff
path: root/OvmfPkg/SmmControl2Dxe/SmiFeatures.c
diff options
context:
space:
mode:
Diffstat (limited to 'OvmfPkg/SmmControl2Dxe/SmiFeatures.c')
-rw-r--r--OvmfPkg/SmmControl2Dxe/SmiFeatures.c246
1 files changed, 0 insertions, 246 deletions
diff --git a/OvmfPkg/SmmControl2Dxe/SmiFeatures.c b/OvmfPkg/SmmControl2Dxe/SmiFeatures.c
deleted file mode 100644
index 7c2cbd86ee..0000000000
--- a/OvmfPkg/SmmControl2Dxe/SmiFeatures.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/**@file
- Negotiate SMI features with QEMU, and configure UefiCpuPkg/PiSmmCpuDxeSmm
- accordingly.
-
- Copyright (C) 2016-2017, Red Hat, Inc.
-
- 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/BaseLib.h>
-#include <Library/DebugLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/PcdLib.h>
-#include <Library/QemuFwCfgLib.h>
-#include <Library/QemuFwCfgS3Lib.h>
-
-#include "SmiFeatures.h"
-
-//
-// The following bit value stands for "broadcast SMI" in the
-// "etc/smi/supported-features" and "etc/smi/requested-features" fw_cfg files.
-//
-#define ICH9_LPC_SMI_F_BROADCAST BIT0
-
-//
-// Provides a scratch buffer (allocated in EfiReservedMemoryType type memory)
-// for the S3 boot script fragment to write to and read from.
-//
-#pragma pack (1)
-typedef union {
- UINT64 Features;
- UINT8 FeaturesOk;
-} SCRATCH_BUFFER;
-#pragma pack ()
-
-//
-// These carry the selector keys of the "etc/smi/requested-features" and
-// "etc/smi/features-ok" fw_cfg files from NegotiateSmiFeatures() to
-// AppendFwCfgBootScript().
-//
-STATIC FIRMWARE_CONFIG_ITEM mRequestedFeaturesItem;
-STATIC FIRMWARE_CONFIG_ITEM mFeaturesOkItem;
-
-//
-// Carries the negotiated SMI features from NegotiateSmiFeatures() to
-// AppendFwCfgBootScript().
-//
-STATIC UINT64 mSmiFeatures;
-
-/**
- Negotiate SMI features with QEMU.
-
- @retval FALSE If SMI feature negotiation is not supported by QEMU. This is
- not an error, it just means that SaveSmiFeatures() should not
- be called.
-
- @retval TRUE SMI feature negotiation is supported, and it has completed
- successfully as well. (Failure to negotiate is a fatal error
- and the function never returns in that case.)
-**/
-BOOLEAN
-NegotiateSmiFeatures (
- VOID
- )
-{
- FIRMWARE_CONFIG_ITEM SupportedFeaturesItem;
- UINTN SupportedFeaturesSize;
- UINTN RequestedFeaturesSize;
- UINTN FeaturesOkSize;
-
- //
- // Look up the fw_cfg files used for feature negotiation. The selector keys
- // of "etc/smi/requested-features" and "etc/smi/features-ok" are saved
- // statically. If the files are missing, then QEMU doesn't support SMI
- // feature negotiation.
- //
- if (RETURN_ERROR (QemuFwCfgFindFile ("etc/smi/supported-features",
- &SupportedFeaturesItem, &SupportedFeaturesSize)) ||
- RETURN_ERROR (QemuFwCfgFindFile ("etc/smi/requested-features",
- &mRequestedFeaturesItem, &RequestedFeaturesSize)) ||
- RETURN_ERROR (QemuFwCfgFindFile ("etc/smi/features-ok",
- &mFeaturesOkItem, &FeaturesOkSize))) {
- DEBUG ((DEBUG_INFO, "%a: SMI feature negotiation unavailable\n",
- __FUNCTION__));
- return FALSE;
- }
-
- //
- // If the files are present but their sizes disagree with us, that's a fatal
- // error (we can't trust the behavior of SMIs either way).
- //
- if (SupportedFeaturesSize != sizeof mSmiFeatures ||
- RequestedFeaturesSize != sizeof mSmiFeatures ||
- FeaturesOkSize != sizeof (UINT8)) {
- DEBUG ((DEBUG_ERROR, "%a: size mismatch in feature negotiation\n",
- __FUNCTION__));
- goto FatalError;
- }
-
- //
- // Get the features supported by the host.
- //
- QemuFwCfgSelectItem (SupportedFeaturesItem);
- QemuFwCfgReadBytes (sizeof mSmiFeatures, &mSmiFeatures);
-
- //
- // We want broadcast SMI and nothing else.
- //
- mSmiFeatures &= ICH9_LPC_SMI_F_BROADCAST;
- QemuFwCfgSelectItem (mRequestedFeaturesItem);
- QemuFwCfgWriteBytes (sizeof mSmiFeatures, &mSmiFeatures);
-
- //
- // Invoke feature validation in QEMU. If the selection is accepted, the
- // features will be locked down. If the selection is rejected, feature
- // negotiation remains open; however we don't know what to do in that case,
- // so that's a fatal error.
- //
- QemuFwCfgSelectItem (mFeaturesOkItem);
- if (QemuFwCfgRead8 () != 1) {
- DEBUG ((DEBUG_ERROR, "%a: negotiation failed for feature bitmap 0x%Lx\n",
- __FUNCTION__, mSmiFeatures));
- goto FatalError;
- }
-
- if ((mSmiFeatures & ICH9_LPC_SMI_F_BROADCAST) == 0) {
- //
- // If we can't get broadcast SMIs from QEMU, that's acceptable too,
- // although not optimal.
- //
- DEBUG ((DEBUG_INFO, "%a: SMI broadcast unavailable\n", __FUNCTION__));
- } else {
- //
- // Configure the traditional AP sync / SMI delivery mode for
- // PiSmmCpuDxeSmm. Effectively, restore the UefiCpuPkg defaults, from which
- // the original QEMU behavior (i.e., unicast SMI) used to differ.
- //
- if (RETURN_ERROR (PcdSet64S (PcdCpuSmmApSyncTimeout, 1000000)) ||
- RETURN_ERROR (PcdSet8S (PcdCpuSmmSyncMode, 0x00))) {
- DEBUG ((DEBUG_ERROR, "%a: PiSmmCpuDxeSmm PCD configuration failed\n",
- __FUNCTION__));
- goto FatalError;
- }
- DEBUG ((DEBUG_INFO, "%a: using SMI broadcast\n", __FUNCTION__));
- }
-
- //
- // Negotiation successful (although we may not have gotten the optimal
- // feature set).
- //
- return TRUE;
-
-FatalError:
- ASSERT (FALSE);
- CpuDeadLoop ();
- //
- // Keep the compiler happy.
- //
- return FALSE;
-}
-
-/**
- FW_CFG_BOOT_SCRIPT_CALLBACK_FUNCTION provided to QemuFwCfgS3Lib.
-**/
-STATIC
-VOID
-EFIAPI
-AppendFwCfgBootScript (
- IN OUT VOID *Context, OPTIONAL
- IN OUT VOID *ExternalScratchBuffer
- )
-{
- SCRATCH_BUFFER *ScratchBuffer;
- RETURN_STATUS Status;
-
- ScratchBuffer = ExternalScratchBuffer;
-
- //
- // Write the negotiated feature bitmap into "etc/smi/requested-features".
- //
- ScratchBuffer->Features = mSmiFeatures;
- Status = QemuFwCfgS3ScriptWriteBytes (mRequestedFeaturesItem,
- sizeof ScratchBuffer->Features);
- if (RETURN_ERROR (Status)) {
- goto FatalError;
- }
-
- //
- // Read back "etc/smi/features-ok". This invokes the feature validation &
- // lockdown. (The validation succeeded at first boot.)
- //
- Status = QemuFwCfgS3ScriptReadBytes (mFeaturesOkItem,
- sizeof ScratchBuffer->FeaturesOk);
- if (RETURN_ERROR (Status)) {
- goto FatalError;
- }
-
- //
- // If "etc/smi/features-ok" read as 1, we're good. Otherwise, hang the S3
- // resume process.
- //
- Status = QemuFwCfgS3ScriptCheckValue (&ScratchBuffer->FeaturesOk,
- sizeof ScratchBuffer->FeaturesOk, MAX_UINT8, 1);
- if (RETURN_ERROR (Status)) {
- goto FatalError;
- }
-
- DEBUG ((DEBUG_VERBOSE, "%a: SMI feature negotiation boot script saved\n",
- __FUNCTION__));
- return;
-
-FatalError:
- ASSERT (FALSE);
- CpuDeadLoop ();
-}
-
-
-/**
- Append a boot script fragment that will re-select the previously negotiated
- SMI features during S3 resume.
-**/
-VOID
-SaveSmiFeatures (
- VOID
- )
-{
- RETURN_STATUS Status;
-
- //
- // We are already running at TPL_CALLBACK, on the stack of
- // OnS3SaveStateInstalled(). But that's okay, we can easily queue more
- // notification functions while executing a notification function.
- //
- Status = QemuFwCfgS3CallWhenBootScriptReady (AppendFwCfgBootScript, NULL,
- sizeof (SCRATCH_BUFFER));
- if (RETURN_ERROR (Status)) {
- ASSERT (FALSE);
- CpuDeadLoop ();
- }
-}