304 lines
8.7 KiB
C
304 lines
8.7 KiB
C
/** @file
|
|
This is the main DXE file for TXT. It represents an abstract outline of the
|
|
steps required during DXE for enabling TXT. Each individual step is further
|
|
abstracted behind a function call interface. This is intended to minimize
|
|
the need to modify this file when porting TXT to future platforms.
|
|
|
|
@copyright
|
|
INTEL CONFIDENTIAL
|
|
Copyright 1999 - 2020 Intel Corporation.
|
|
|
|
The source code contained or described herein and all documents related to the
|
|
source code ("Material") are owned by Intel Corporation or its suppliers or
|
|
licensors. Title to the Material remains with Intel Corporation or its suppliers
|
|
and licensors. The Material may contain trade secrets and proprietary and
|
|
confidential information of Intel Corporation and its suppliers and licensors,
|
|
and is protected by worldwide copyright and trade secret laws and treaty
|
|
provisions. No part of the Material may be used, copied, reproduced, modified,
|
|
published, uploaded, posted, transmitted, distributed, or disclosed in any way
|
|
without Intel's prior express written permission.
|
|
|
|
No license under any patent, copyright, trade secret or other intellectual
|
|
property right is granted to or conferred upon you by disclosure or delivery
|
|
of the Materials, either expressly, by implication, inducement, estoppel or
|
|
otherwise. Any license under such intellectual property rights must be
|
|
express and approved by Intel in writing.
|
|
|
|
Unless otherwise agreed by Intel in writing, you may not remove or alter
|
|
this notice or any other notice embedded in Materials by Intel or
|
|
Intel's suppliers or licensors in any way.
|
|
|
|
This file contains an 'Intel Peripheral Driver' and is uniquely identified as
|
|
"Intel Reference Module" and is licensed for Intel CPUs and chipsets under
|
|
the terms of your license agreement with Intel or your vendor. This file may
|
|
be modified by the user, subject to additional terms of the license agreement.
|
|
|
|
@par Specification Reference:
|
|
|
|
**/
|
|
|
|
#include "TxtDxeLib.h"
|
|
|
|
GLOBAL_REMOVE_IF_UNREFERENCED TXT_DXE_LIB_CONTEXT mTxtDxeCtx;
|
|
|
|
/**
|
|
This function gets registered as a callback to run the SCHECK function
|
|
from the TXT BIOS ACM as a result of Boot Events.
|
|
|
|
@param[in] Event A pointer to the Event that triggered the callback.
|
|
@param[in] Context A pointer to private data registered with the callback function.
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
ScheckCallback (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
VOID *ProtocolPointer;
|
|
|
|
///
|
|
/// Check if this is first time called by EfiCreateProtocolNotifyEvent() or not,
|
|
/// if it is, we will skip it until real event is triggered
|
|
///
|
|
Status = gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid, NULL, (VOID **) &ProtocolPointer);
|
|
if (EFI_SUCCESS != Status) {
|
|
return;
|
|
}
|
|
|
|
|
|
DEBUG ((DEBUG_INFO, "TXTDXE::Running of DoScheck\n"));
|
|
DoScheck (&mTxtDxeCtx);
|
|
|
|
///
|
|
/// Closed the event to avoid call twice when launch shell
|
|
///
|
|
gBS->CloseEvent (Event);
|
|
}
|
|
|
|
/**
|
|
Read CR4, clear SMXE (BIT14), and writeback CR4.
|
|
|
|
@param[in] None
|
|
|
|
@retval None
|
|
**/
|
|
|
|
VOID
|
|
DisableCR4Smx (
|
|
VOID
|
|
)
|
|
{
|
|
IA32_CR4 CR4;
|
|
|
|
CR4.UintN = AsmReadCr4 ();
|
|
CR4.Bits.SMXE = 0;
|
|
AsmWriteCr4 (CR4.UintN);
|
|
}
|
|
|
|
/**
|
|
|
|
TXT late init flow at thred scope
|
|
|
|
@param None
|
|
|
|
@retval None
|
|
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
DisableCR4SmxOnAllThreads (
|
|
VOID
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_MP_SERVICES_PROTOCOL *MpServices;
|
|
|
|
//
|
|
// Find the MpService Protocol to use with LT Config lock
|
|
//
|
|
Status = gBS->LocateProtocol (
|
|
&gEfiMpServiceProtocolGuid,
|
|
NULL,
|
|
(VOID **)&MpServices
|
|
);
|
|
|
|
ASSERT_EFI_ERROR (Status);
|
|
|
|
if (EFI_ERROR (Status) || (MpServices == NULL)) {
|
|
DEBUG ((DEBUG_ERROR, "\tMpService Protocol was not found\n"));
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Thread scope TXT flow flow
|
|
//
|
|
DEBUG ((DEBUG_INFO, "Disabling CR4.SMXE...\n"));
|
|
|
|
DisableCR4Smx ();
|
|
|
|
Status = MpServices->StartupAllAPs(
|
|
MpServices,
|
|
(EFI_AP_PROCEDURE) DisableCR4Smx,
|
|
FALSE,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
if (Status == EFI_NOT_STARTED) {
|
|
DEBUG ((DEBUG_ERROR, "APs not started, continue...\n"));
|
|
} else if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "Error clearing CR4.SMXE on all threads (%r), continuing..\n", Status));
|
|
}
|
|
}
|
|
|
|
/**
|
|
TxtDxeReadyToBoot: handle TXT-related flows before OS handoff.
|
|
|
|
@param[in] Event Event that triggered the callback.
|
|
@param[in] Context A pointer to private data registered with the callback function.
|
|
|
|
@retval None
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
TxtDxeReadyToBoot (
|
|
EFI_EVENT Event,
|
|
VOID *Context
|
|
)
|
|
{
|
|
DEBUG ((DEBUG_INFO, "%a: Entry\n",__FUNCTION__));
|
|
|
|
//Disable CR4.SMXE on all threads prior to OS-handoff.
|
|
DisableCR4SmxOnAllThreads ();
|
|
|
|
gBS->CloseEvent (Event);
|
|
|
|
DEBUG((DEBUG_INFO, "%a: Exit\n", __FUNCTION__));
|
|
}
|
|
|
|
/**
|
|
This is the entry point to the TXT DXE Driver. This routine checks to see if
|
|
the platform should be configured for TXT and if so, configures the platform
|
|
by reserving and initializing TXT Configuration Space and TXT Device Memory and
|
|
registering a callback to run SCHECK from the TXT BIOS ACM prior to boot.
|
|
|
|
If the platform should not be configured for TXT, this routine checks the
|
|
establishment bit in the TPM and resets it if it is asserted.
|
|
|
|
@param[in] ImageHandle A handle for this module
|
|
@param[in] SystemTable A pointer to the EFI System Table
|
|
|
|
@retval EFI_SUCCESS If TXT initialization succeed
|
|
@retval EFI_UNSUPPORTED If TXT criterias are not met
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
DriverEntry (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
void *Registration;
|
|
EFI_EVENT ReadyToBootEvent;
|
|
IA32_CR4 CR4;
|
|
|
|
ReadyToBootEvent = 0;
|
|
//
|
|
// Note: SMX feature can be enabled independently of TXT.
|
|
// Therefore check and register for SMXE disable, before
|
|
// checking TXT config status / exiting the driver.
|
|
//
|
|
CR4.UintN = AsmReadCr4 ();
|
|
if (CR4.Bits.SMXE == 1) {
|
|
DEBUG((DEBUG_ERROR, "TXTDXE::CR4.SMX Enabled. Calling EfiCreateEventReadyToBootEx\n"));
|
|
if ((EfiCreateEventReadyToBootEx (TPL_CALLBACK, TxtDxeReadyToBoot, NULL, &ReadyToBootEvent)) != EFI_SUCCESS) {
|
|
DEBUG ((DEBUG_ERROR, "TXTDXE::SMX Disable Ready To Boot Event creation failure\n"));
|
|
}
|
|
}
|
|
|
|
///
|
|
/// Initialize the platform specific code
|
|
///
|
|
Status = InitializeTxtDxeLib (ImageHandle, SystemTable, &mTxtDxeCtx);
|
|
///
|
|
/// If failure - assume TXT is not enabled
|
|
///
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "TXTDXE::InitializeTxtDxeLib failed.... Unloading\n"));
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
///
|
|
/// If ESTS.TXTRESET bit is set, skip all other functions since
|
|
/// attempt to execute GETSEC will hang system. Skipping allows to
|
|
/// boot to OS and let MLE assess situation.
|
|
///
|
|
if (IsTxtResetSet (&mTxtDxeCtx)) {
|
|
DEBUG ((DEBUG_ERROR, "TXTDXE::TXT_RESET bit is set.... Unloading\n"));
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
///
|
|
/// If TXT is enabled, configure platform appropriately.
|
|
/// Code assumes that if TXT is enabled by CPU driver than all checks
|
|
/// are passed, i.e. TPM is present, CPU and CS are TXT capable.
|
|
///
|
|
///
|
|
/// Add to check CPU TXT capable in case CPU drivers do not check additional requirements
|
|
///
|
|
if ((mTxtDxeCtx.TxtInfoData->ChipsetIsTxtCapable) && (IsTxtProcessor ()) && (IsTxtEnabled (&mTxtDxeCtx))) {
|
|
DEBUG ((DEBUG_INFO, "TXTDXE::TXT Enabled\n"));
|
|
|
|
///
|
|
/// Allocate and Initialize TXT Device Memory
|
|
///
|
|
Status = SetupTxtDeviceMemory (&mTxtDxeCtx);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "TXTDXE::SetupTxtDeviceMemory failed.... Unloading\n"));
|
|
return EFI_UNSUPPORTED;
|
|
}
|
|
|
|
///
|
|
/// Create callback to run SCHECK; this should execute before global SMI enable is locked
|
|
///
|
|
EfiCreateProtocolNotifyEvent (
|
|
&gEfiPciEnumerationCompleteProtocolGuid,
|
|
TPL_CALLBACK,
|
|
ScheckCallback,
|
|
NULL,
|
|
&Registration
|
|
);
|
|
|
|
} else {
|
|
///
|
|
/// TXT is not enabled, so make sure TPM Establishment
|
|
/// bit is de-asserted
|
|
///
|
|
DEBUG ((DEBUG_INFO, "TXTDXE::TXT Disabled\n"));
|
|
|
|
if (IsTxtEstablished (&mTxtDxeCtx)) {
|
|
///
|
|
/// We can invoke BIOS ACM function only if CS and CPU are TXT
|
|
/// capable
|
|
///
|
|
if ((mTxtDxeCtx.TxtInfoData->ChipsetIsTxtCapable) &&
|
|
(IsTxtProcessor ()) &&
|
|
!(mTxtDxeCtx.TxtInfoData->Flags & TPM_INIT_FAILED)
|
|
) {
|
|
DEBUG ((DEBUG_INFO, "TXTDXE::Resetting TPM Establishment bit\n"));
|
|
ResetTpmEstBit (&mTxtDxeCtx);
|
|
}
|
|
}
|
|
///
|
|
/// Reset AUX
|
|
///
|
|
Status = ResetTpmAux (&mTxtDxeCtx);
|
|
ASSERT_EFI_ERROR (Status);
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|