mirror of
https://github.com/tianocore/edk2
synced 2026-08-27 00:23:19 -04:00
Add "smcbios" to extended works in ci.yaml file and fix typos. Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
329 lines
9.6 KiB
C
329 lines
9.6 KiB
C
/** @file
|
|
Tpm2 device table generating Library
|
|
|
|
Copyright (c) 2025, Arm Limited. All rights reserved.<BR>
|
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
@par Reference(s):
|
|
- TCG ACPI specification.
|
|
(https://trustedcomputinggroup.org/resource/tcg-acpi-specification/)
|
|
**/
|
|
#include <IndustryStandard/DebugPort2Table.h>
|
|
#include <Library/AcpiLib.h>
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/PcdLib.h>
|
|
|
|
#include <Protocol/AcpiTable.h>
|
|
|
|
// Module specific include files.
|
|
#include <AcpiTableGenerator.h>
|
|
#include <ConfigurationManagerObject.h>
|
|
#include <ConfigurationManagerHelper.h>
|
|
#include <Library/AcpiHelperLib.h>
|
|
#include <Library/AmlLib/AmlLib.h>
|
|
#include <Protocol/ConfigurationManagerProtocol.h>
|
|
|
|
/** C array containing the compiled AML template.
|
|
This symbol is defined in the auto generated C file
|
|
containing the AML bytecode array.
|
|
*/
|
|
extern CHAR8 tpm2devicetabletemplate_aml_code[];
|
|
|
|
/** Fixup the TPM2 device UID (_UID).
|
|
|
|
@param [in] RootNodeHandle Pointer to the root of an AML tree.
|
|
@param [in] Uid UID for the TPM2 device.
|
|
|
|
@retval EFI_SUCCESS The function completed successfully.
|
|
@retval EFI_INVALID_PARAMETER Invalid parameter.
|
|
@retval EFI_NOT_FOUND Could not find information.
|
|
@retval EFI_OUT_OF_RESOURCES Out of resources.
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FixupTpm2DeviceUid (
|
|
IN AML_ROOT_NODE_HANDLE RootNodeHandle,
|
|
IN CONST UINT64 Uid
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
AML_OBJECT_NODE_HANDLE NameOpIdNode;
|
|
|
|
// Get the _UID NameOp object defined by the "Name ()" statement,
|
|
// and update its value.
|
|
Status = AmlFindNode (
|
|
RootNodeHandle,
|
|
"\\_SB_.TPM0._UID",
|
|
&NameOpIdNode
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
return AmlNameOpUpdateInteger (NameOpIdNode, (UINT64)Uid);
|
|
}
|
|
|
|
/** Fixup the Tpm2 device name.
|
|
|
|
@param [in] RootNodeHandle Pointer to the root of an AML tree.
|
|
@param [in] Name The Name to give to the Device.
|
|
Must be a NULL-terminated ASL NameString
|
|
e.g.: "DEV0", "DV15.DEV0", etc.
|
|
|
|
@retval EFI_SUCCESS The function completed successfully.
|
|
@retval EFI_INVALID_PARAMETER Invalid parameter.
|
|
@retval EFI_NOT_FOUND Could not find information.
|
|
@retval EFI_OUT_OF_RESOURCES Out of resources.
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FixupTpm2DeviceName (
|
|
IN AML_ROOT_NODE_HANDLE RootNodeHandle,
|
|
IN CONST CHAR8 *Name
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
AML_OBJECT_NODE_HANDLE DeviceNode;
|
|
|
|
// Get the COM0 variable defined by the "Device ()" statement.
|
|
Status = AmlFindNode (RootNodeHandle, "\\_SB_.TPM0", &DeviceNode);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
// Update the Device's name.
|
|
return AmlDeviceOpUpdateName (DeviceNode, Name);
|
|
}
|
|
|
|
/** Fixup the Tpm2 device _CRS values (BaseAddress, ...).
|
|
|
|
@param [in] RootNodeHandle Pointer to the root of an AML tree.
|
|
@param [in] TpmDevInfo Pointer to a TPM2 device Information
|
|
structure.
|
|
Get the device size Information from there.
|
|
|
|
@retval EFI_SUCCESS The function completed successfully.
|
|
@retval EFI_INVALID_PARAMETER Invalid parameter.
|
|
@retval EFI_NOT_FOUND Could not find information.
|
|
@retval EFI_OUT_OF_RESOURCES Out of resources.
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FixupTpm2DeviceCrs (
|
|
IN AML_ROOT_NODE_HANDLE RootNodeHandle,
|
|
IN CONST CM_ARCH_COMMON_TPM2_DEVICE_INFO *TpmDevInfo
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
AML_OBJECT_NODE_HANDLE NameOpCrsNode;
|
|
AML_DATA_NODE_HANDLE QWordRdNode;
|
|
|
|
// Get the "_CRS" object defined by the "Name ()" statement.
|
|
Status = AmlFindNode (
|
|
RootNodeHandle,
|
|
"\\_SB_.TPM0._CRS",
|
|
&NameOpCrsNode
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
// Get the first Rd node in the "_CRS" object.
|
|
Status = AmlNameOpGetFirstRdNode (NameOpCrsNode, &QWordRdNode);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
if (QWordRdNode == NULL) {
|
|
return EFI_INVALID_PARAMETER;
|
|
}
|
|
|
|
// Update the TPM2 device's base address and length.
|
|
Status = AmlUpdateRdQWord (
|
|
QWordRdNode,
|
|
TpmDevInfo->Tpm2DeviceBaseAddress,
|
|
TpmDevInfo->Tpm2DeviceSize
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/** Fixup the Tpm2 Device in the AML tree.
|
|
|
|
For each template value:
|
|
- find the node to update;
|
|
- update the value.
|
|
|
|
@param [in] RootNodeHandle Pointer to the root of the AML tree.
|
|
@param [in] TpmDevInfo Pointer to a TPM2 device Information
|
|
structure.
|
|
@param [in] Name The Name to give to the Device.
|
|
Must be a NULL-terminated ASL NameString
|
|
e.g.: "DEV0", "DV15.DEV0", etc.
|
|
@param [in] Uid UID for the TPM2 device.
|
|
|
|
@retval EFI_SUCCESS The function completed successfully.
|
|
@retval EFI_INVALID_PARAMETER Invalid parameter.
|
|
@retval EFI_NOT_FOUND Could not find information.
|
|
@retval EFI_OUT_OF_RESOURCES Out of resources.
|
|
**/
|
|
STATIC
|
|
EFI_STATUS
|
|
EFIAPI
|
|
FixupTpm2DeviceInfo (
|
|
IN AML_ROOT_NODE_HANDLE RootNodeHandle,
|
|
IN CONST CM_ARCH_COMMON_TPM2_DEVICE_INFO *TpmDevInfo,
|
|
IN CONST CHAR8 *Name,
|
|
IN CONST UINT64 Uid
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
ASSERT (RootNodeHandle != NULL);
|
|
ASSERT (TpmDevInfo != NULL);
|
|
ASSERT (Name != NULL);
|
|
|
|
// Fixup the _UID value.
|
|
Status = FixupTpm2DeviceUid (RootNodeHandle, Uid);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
// Fixup the _CRS values.
|
|
Status = FixupTpm2DeviceCrs (RootNodeHandle, TpmDevInfo);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
// Fixup the Tpm2 device name.
|
|
// This MUST be done at the end, otherwise AML paths won't be valid anymore.
|
|
return FixupTpm2DeviceName (RootNodeHandle, Name);
|
|
}
|
|
|
|
/** Build a SSDT table describing the TPM2 device.
|
|
|
|
The table created by this function must be freed by FreeSimpleTpm2DeviceTable.
|
|
|
|
@param [in] TpmDevInfo TPM2 device info to describe in the SSDT table.
|
|
@param [in] Name The Name to give to the Device.
|
|
Must be a NULL-terminated ASL NameString
|
|
e.g.: "DEV0", "DV15.DEV0", etc.
|
|
@param [in] Uid UID for the TPM2 device
|
|
@param [out] Table If success, pointer to the created SSDT table.
|
|
|
|
@retval EFI_SUCCESS Table generated successfully.
|
|
@retval EFI_INVALID_PARAMETER A parameter is invalid.
|
|
@retval EFI_NOT_FOUND Could not find information.
|
|
@retval EFI_OUT_OF_RESOURCES Could not allocate memory.
|
|
**/
|
|
EFI_STATUS
|
|
EFIAPI
|
|
BuildTpm2DeviceTable (
|
|
IN CONST CM_ARCH_COMMON_TPM2_DEVICE_INFO *TpmDevInfo,
|
|
IN CONST CHAR8 *Name,
|
|
IN CONST UINT64 Uid,
|
|
OUT EFI_ACPI_DESCRIPTION_HEADER **Table
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_STATUS Status1;
|
|
AML_ROOT_NODE_HANDLE RootNodeHandle;
|
|
|
|
ASSERT (TpmDevInfo != NULL);
|
|
ASSERT (Name != NULL);
|
|
ASSERT (Table != NULL);
|
|
|
|
// Parse the Tpm2 Device Table Template.
|
|
Status = AmlParseDefinitionBlock (
|
|
(EFI_ACPI_DESCRIPTION_HEADER *)tpm2devicetabletemplate_aml_code,
|
|
&RootNodeHandle
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((
|
|
DEBUG_ERROR,
|
|
"ERROR: TPM2-DEVICE-FIXUP:"
|
|
" Failed to parse SSDT TPM2 device Template. Status = %r\n",
|
|
Status
|
|
));
|
|
return Status;
|
|
}
|
|
|
|
// Fixup the template values.
|
|
Status = FixupTpm2DeviceInfo (
|
|
RootNodeHandle,
|
|
TpmDevInfo,
|
|
Name,
|
|
Uid
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((
|
|
DEBUG_ERROR,
|
|
"ERROR: TPM2-DEVICE-FIXUP: Failed to fixup SSDT TPM2 Device Table."
|
|
" Status = %r\n",
|
|
Status
|
|
));
|
|
goto ExitHandler;
|
|
}
|
|
|
|
// Serialize the tree.
|
|
Status = AmlSerializeDefinitionBlock (
|
|
RootNodeHandle,
|
|
Table
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((
|
|
DEBUG_ERROR,
|
|
"ERROR: TPM2-DEVICE-FIXUP: Failed to Serialize SSDT Table Data."
|
|
" Status = %r\n",
|
|
Status
|
|
));
|
|
}
|
|
|
|
ExitHandler:
|
|
// Cleanup
|
|
if (RootNodeHandle != NULL) {
|
|
Status1 = AmlDeleteTree (RootNodeHandle);
|
|
if (EFI_ERROR (Status1)) {
|
|
DEBUG ((
|
|
DEBUG_ERROR,
|
|
"ERROR: TPM2-DEVICE-FIXUP: Failed to cleanup AML tree."
|
|
" Status = %r\n",
|
|
Status1
|
|
));
|
|
// If Status was success but we failed to delete the AML Tree
|
|
// return Status1 else return the original error code, i.e. Status.
|
|
if (!EFI_ERROR (Status)) {
|
|
return Status1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/** Free an Tpm2 device table previously created by
|
|
the BuildTpm2DeviceTable function.
|
|
|
|
@param [in] Table Pointer to a Tpm2 Device table allocated by
|
|
the BuildTpm2DeviceTable function.
|
|
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
FreeTpm2DeviceTable (
|
|
IN EFI_ACPI_DESCRIPTION_HEADER *Table
|
|
)
|
|
{
|
|
ASSERT (Table != NULL);
|
|
FreePool (Table);
|
|
}
|