+++ /dev/null
-/** @file\r
- The TPM2 definition block in ACPI table for TrEE physical presence \r
- and MemoryClear.\r
-\r
-Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-DefinitionBlock (\r
- "Tpm.aml",\r
- "SSDT",\r
- 2,\r
- "INTEL ",\r
- "Tpm2Tabl",\r
- 0x1000\r
- )\r
-{\r
- Scope (\_SB)\r
- {\r
- Device (TPM)\r
- {\r
- //\r
- // TREE\r
- //\r
- Name (_HID, "MSFT0101")\r
- \r
- //\r
- // Readable name of this device, don't know if this way is correct yet\r
- //\r
- Name (_STR, Unicode ("TPM 2.0 Device"))\r
-\r
- //\r
- // Return the resource consumed by TPM device\r
- //\r
- Name (_CRS, ResourceTemplate () {\r
- Memory32Fixed (ReadWrite, 0xfed40000, 0x5000)\r
- })\r
-\r
- //\r
- // Operational region for Smi port access\r
- //\r
- OperationRegion (SMIP, SystemIO, 0xB2, 1)\r
- Field (SMIP, ByteAcc, NoLock, Preserve)\r
- { \r
- IOB2, 8\r
- }\r
-\r
- //\r
- // Operational region for TPM access\r
- //\r
- OperationRegion (TPMR, SystemMemory, 0xfed40000, 0x5000)\r
- Field (TPMR, AnyAcc, NoLock, Preserve)\r
- {\r
- ACC0, 8,\r
- }\r
-\r
- //\r
- // Operational region for TPM support, TPM Physical Presence and TPM Memory Clear\r
- // Region Offset 0xFFFF0000 and Length 0xF0 will be fixed in C code.\r
- //\r
- OperationRegion (TNVS, SystemMemory, 0xFFFF0000, 0xF0)\r
- Field (TNVS, AnyAcc, NoLock, Preserve)\r
- {\r
- PPIN, 8, // Software SMI for Physical Presence Interface\r
- PPIP, 32, // Used for save physical presence paramter\r
- PPRP, 32, // Physical Presence request operation response\r
- PPRQ, 32, // Physical Presence request operation\r
- LPPR, 32, // Last Physical Presence request operation\r
- FRET, 32, // Physical Presence function return code\r
- MCIN, 8, // Software SMI for Memory Clear Interface\r
- MCIP, 32, // Used for save the Mor paramter\r
- MORD, 32, // Memory Overwrite Request Data\r
- MRET, 32 // Memory Overwrite function return code\r
- }\r
-\r
- Method (PTS, 1, Serialized)\r
- { \r
- //\r
- // Detect Sx state for MOR, only S4, S5 need to handle\r
- //\r
- If (LAnd (LLess (Arg0, 6), LGreater (Arg0, 3)))\r
- { \r
- //\r
- // Bit4 -- DisableAutoDetect. 0 -- Firmware MAY autodetect.\r
- //\r
- If (LNot (And (MORD, 0x10)))\r
- {\r
- //\r
- // Triggle the SMI through ACPI _PTS method.\r
- //\r
- Store (0x02, MCIP)\r
- \r
- //\r
- // Triggle the SMI interrupt\r
- //\r
- Store (MCIN, IOB2)\r
- }\r
- }\r
- Return (0)\r
- } \r
-\r
- Method (_STA, 0)\r
- {\r
- if (LEqual (ACC0, 0xff))\r
- {\r
- Return (0)\r
- }\r
- Return (0x0f)\r
- }\r
-\r
- //\r
- // TCG Hardware Information\r
- //\r
- Method (HINF, 3, Serialized, 0, {BuffObj, PkgObj}, {UnknownObj, UnknownObj, UnknownObj}) // IntObj, IntObj, PkgObj\r
- {\r
- //\r
- // Switch by function index\r
- //\r
- Switch (ToInteger(Arg1))\r
- {\r
- Case (0)\r
- {\r
- //\r
- // Standard query\r
- //\r
- Return (Buffer () {0x03})\r
- }\r
- Case (1)\r
- {\r
- //\r
- // Return failure if no TPM present\r
- //\r
- Name(TPMV, Package () {0x01, Package () {0x2, 0x0}})\r
- if (LEqual (_STA (), 0x00))\r
- {\r
- Return (Package () {0x00})\r
- }\r
-\r
- //\r
- // Return TPM version\r
- //\r
- Return (TPMV)\r
- }\r
- Default {BreakPoint}\r
- }\r
- Return (Buffer () {0})\r
- }\r
-\r
- Name(TPM2, Package (0x02){\r
- Zero, \r
- Zero\r
- })\r
-\r
- Name(TPM3, Package (0x03){\r
- Zero, \r
- Zero,\r
- Zero\r
- })\r
-\r
- //\r
- // TCG Physical Presence Interface\r
- //\r
- Method (TPPI, 3, Serialized, 0, {BuffObj, PkgObj, IntObj, StrObj}, {UnknownObj, UnknownObj, UnknownObj}) // IntObj, IntObj, PkgObj\r
- { \r
- //\r
- // Switch by function index\r
- //\r
- Switch (ToInteger(Arg1))\r
- {\r
- Case (0)\r
- {\r
- //\r
- // Standard query, supports function 1-8\r
- //\r
- Return (Buffer () {0xFF, 0x01})\r
- }\r
- Case (1)\r
- {\r
- //\r
- // a) Get Physical Presence Interface Version\r
- //\r
- Return ("1.2")\r
- }\r
- Case (2)\r
- {\r
- //\r
- // b) Submit TPM Operation Request to Pre-OS Environment\r
- //\r
- \r
- Store (DerefOf (Index (Arg2, 0x00)), PPRQ)\r
- Store (0x02, PPIP)\r
- \r
- //\r
- // Triggle the SMI interrupt\r
- //\r
- Store (PPIN, IOB2)\r
- Return (FRET)\r
-\r
-\r
- }\r
- Case (3)\r
- {\r
- //\r
- // c) Get Pending TPM Operation Requested By the OS\r
- //\r
- \r
- Store (PPRQ, Index (TPM2, 0x01))\r
- Return (TPM2)\r
- }\r
- Case (4)\r
- {\r
- //\r
- // d) Get Platform-Specific Action to Transition to Pre-OS Environment\r
- //\r
- Return (2)\r
- }\r
- Case (5)\r
- {\r
- //\r
- // e) Return TPM Operation Response to OS Environment\r
- //\r
- Store (0x05, PPIP)\r
- \r
- //\r
- // Triggle the SMI interrupt\r
- //\r
- Store (PPIN, IOB2)\r
- \r
- Store (LPPR, Index (TPM3, 0x01))\r
- Store (PPRP, Index (TPM3, 0x02))\r
-\r
- Return (TPM3)\r
- }\r
- Case (6)\r
- {\r
-\r
- //\r
- // f) Submit preferred user language (Not implemented)\r
- //\r
-\r
- Return (3)\r
-\r
- }\r
- Case (7)\r
- {\r
- //\r
- // g) Submit TPM Operation Request to Pre-OS Environment 2\r
- //\r
- Store (7, PPIP)\r
- Store (DerefOf (Index (Arg2, 0x00)), PPRQ)\r
- \r
- //\r
- // Triggle the SMI interrupt \r
- //\r
- Store (PPIN, IOB2) \r
- Return (FRET)\r
- }\r
- Case (8)\r
- {\r
- //\r
- // e) Get User Confirmation Status for Operation\r
- //\r
- Store (8, PPIP)\r
- Store (DerefOf (Index (Arg2, 0x00)), PPRQ)\r
- \r
- //\r
- // Triggle the SMI interrupt\r
- //\r
- Store (PPIN, IOB2)\r
- \r
- Return (FRET)\r
- }\r
-\r
- Default {BreakPoint}\r
- }\r
- Return (1)\r
- }\r
-\r
- Method (TMCI, 3, Serialized, 0, IntObj, {UnknownObj, UnknownObj, UnknownObj}) // IntObj, IntObj, PkgObj\r
- {\r
- //\r
- // Switch by function index\r
- //\r
- Switch (ToInteger (Arg1))\r
- {\r
- Case (0)\r
- {\r
- //\r
- // Standard query, supports function 1-1\r
- //\r
- Return (Buffer () {0x03})\r
- }\r
- Case (1)\r
- {\r
- //\r
- // Save the Operation Value of the Request to MORD (reserved memory)\r
- //\r
- Store (DerefOf (Index (Arg2, 0x00)), MORD)\r
- \r
- //\r
- // Triggle the SMI through ACPI _DSM method.\r
- //\r
- Store (0x01, MCIP)\r
- \r
- //\r
- // Triggle the SMI interrupt\r
- //\r
- Store (MCIN, IOB2)\r
- Return (MRET)\r
- }\r
- Default {BreakPoint}\r
- }\r
- Return (1) \r
- }\r
-\r
- Method (_DSM, 4, Serialized, 0, UnknownObj, {BuffObj, IntObj, IntObj, PkgObj})\r
- {\r
-\r
- //\r
- // TCG Hardware Information\r
- //\r
- If(LEqual(Arg0, ToUUID ("cf8e16a5-c1e8-4e25-b712-4f54a96702c8")))\r
- {\r
- Return (HINF (Arg1, Arg2, Arg3))\r
- }\r
-\r
- //\r
- // TCG Physical Presence Interface\r
- //\r
- If(LEqual(Arg0, ToUUID ("3dddfaa6-361b-4eb4-a424-8d10089d1653")))\r
- {\r
- Return (TPPI (Arg1, Arg2, Arg3))\r
- }\r
-\r
- //\r
- // TCG Memory Clear Interface\r
- //\r
- If(LEqual(Arg0, ToUUID ("376054ed-cc13-4675-901c-4756d7f2d45d")))\r
- {\r
- Return (TMCI (Arg1, Arg2, Arg3))\r
- }\r
-\r
- Return (Buffer () {0})\r
- }\r
- }\r
- }\r
-}\r
+++ /dev/null
-/** @file\r
- It updates TPM2 items in ACPI table and registers SMI2 callback\r
- functions for TrEE physical presence, ClearMemory, and sample\r
- for dTPM StartMethod.\r
-\r
- Caution: This module requires additional review when modified.\r
- This driver will have external input - variable and ACPINvs data in SMM mode.\r
- This external input must be validated carefully to avoid security issue.\r
-\r
- PhysicalPresenceCallback() and MemoryClearCallback() will receive untrusted input and do some check.\r
-\r
-Copyright (c) 2013 - 2017, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "TrEESmm.h"\r
-\r
-EFI_TPM2_ACPI_TABLE mTpm2AcpiTemplate = {\r
- {\r
- EFI_ACPI_5_0_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE,\r
- sizeof (mTpm2AcpiTemplate),\r
- EFI_TPM2_ACPI_TABLE_REVISION_3,\r
- //\r
- // Compiler initializes the remaining bytes to 0\r
- // These fields should be filled in in production\r
- //\r
- },\r
- 0, // Flags\r
- 0, // Control Area\r
- EFI_TPM2_ACPI_TABLE_START_METHOD_TIS, // StartMethod\r
-};\r
-\r
-EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable;\r
-TCG_NVS *mTcgNvs;\r
-\r
-/**\r
- Software SMI callback for TPM physical presence which is called from ACPI method.\r
-\r
- Caution: This function may receive untrusted input.\r
- Variable and ACPINvs are external input, so this function will validate\r
- its data structure to be valid value.\r
-\r
- @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().\r
- @param[in] Context Points to an optional handler context which was specified when the\r
- handler was registered.\r
- @param[in, out] CommBuffer A pointer to a collection of data in memory that will\r
- be conveyed from a non-SMM environment into an SMM environment.\r
- @param[in, out] CommBufferSize The size of the CommBuffer.\r
-\r
- @retval EFI_SUCCESS The interrupt was handled successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PhysicalPresenceCallback (\r
- IN EFI_HANDLE DispatchHandle,\r
- IN CONST VOID *Context,\r
- IN OUT VOID *CommBuffer,\r
- IN OUT UINTN *CommBufferSize\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN DataSize;\r
- EFI_TREE_PHYSICAL_PRESENCE PpData;\r
- EFI_TREE_PHYSICAL_PRESENCE_FLAGS Flags;\r
- BOOLEAN RequestConfirmed;\r
-\r
- //\r
- // Get the Physical Presence variable\r
- //\r
- DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE);\r
- Status = mSmmVariable->SmmGetVariable (\r
- TREE_PHYSICAL_PRESENCE_VARIABLE,\r
- &gEfiTrEEPhysicalPresenceGuid,\r
- NULL,\r
- &DataSize,\r
- &PpData\r
- );\r
-\r
- DEBUG ((EFI_D_INFO, "[TPM2] PP callback, Parameter = %x, Request = %x\n", mTcgNvs->PhysicalPresence.Parameter, mTcgNvs->PhysicalPresence.Request));\r
-\r
- if (mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_RETURN_REQUEST_RESPONSE_TO_OS) {\r
- if (EFI_ERROR (Status)) {\r
- mTcgNvs->PhysicalPresence.ReturnCode = PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE;\r
- mTcgNvs->PhysicalPresence.LastRequest = 0;\r
- mTcgNvs->PhysicalPresence.Response = 0;\r
- DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
- return EFI_SUCCESS;\r
- }\r
- mTcgNvs->PhysicalPresence.ReturnCode = PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS;\r
- mTcgNvs->PhysicalPresence.LastRequest = PpData.LastPPRequest;\r
- mTcgNvs->PhysicalPresence.Response = PpData.PPResponse;\r
- } else if ((mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS) \r
- || (mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS_2)) {\r
- if (EFI_ERROR (Status)) {\r
- mTcgNvs->PhysicalPresence.ReturnCode = TREE_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
- DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
- return EFI_SUCCESS;\r
- }\r
- if ((mTcgNvs->PhysicalPresence.Request > TREE_PHYSICAL_PRESENCE_NO_ACTION_MAX) &&\r
- (mTcgNvs->PhysicalPresence.Request < TREE_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) ) {\r
- //\r
- // This command requires UI to prompt user for Auth data.\r
- //\r
- mTcgNvs->PhysicalPresence.ReturnCode = TREE_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (PpData.PPRequest != mTcgNvs->PhysicalPresence.Request) {\r
- PpData.PPRequest = (UINT8) mTcgNvs->PhysicalPresence.Request;\r
- DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE);\r
- Status = mSmmVariable->SmmSetVariable (\r
- TREE_PHYSICAL_PRESENCE_VARIABLE,\r
- &gEfiTrEEPhysicalPresenceGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- DataSize,\r
- &PpData\r
- );\r
- }\r
-\r
- if (EFI_ERROR (Status)) { \r
- mTcgNvs->PhysicalPresence.ReturnCode = TREE_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
- DEBUG ((EFI_D_ERROR, "[TPM2] Set PP variable failure! Status = %r\n", Status));\r
- return EFI_SUCCESS;\r
- }\r
- mTcgNvs->PhysicalPresence.ReturnCode = TREE_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;\r
-\r
- if (mTcgNvs->PhysicalPresence.Request >= TREE_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
- DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE_FLAGS);\r
- Status = mSmmVariable->SmmGetVariable (\r
- TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
- &gEfiTrEEPhysicalPresenceGuid,\r
- NULL,\r
- &DataSize,\r
- &Flags\r
- );\r
- if (EFI_ERROR (Status)) {\r
- Flags.PPFlags = 0;\r
- }\r
- mTcgNvs->PhysicalPresence.ReturnCode = TrEEPpVendorLibSubmitRequestToPreOSFunction (mTcgNvs->PhysicalPresence.Request, Flags.PPFlags);\r
- }\r
- } else if (mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_GET_USER_CONFIRMATION_STATUS_FOR_REQUEST) {\r
- if (EFI_ERROR (Status)) {\r
- mTcgNvs->PhysicalPresence.ReturnCode = TREE_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;\r
- DEBUG ((EFI_D_ERROR, "[TPM2] Get PP variable failure! Status = %r\n", Status));\r
- return EFI_SUCCESS;\r
- }\r
- //\r
- // Get the Physical Presence flags\r
- //\r
- DataSize = sizeof (EFI_TREE_PHYSICAL_PRESENCE_FLAGS);\r
- Status = mSmmVariable->SmmGetVariable (\r
- TREE_PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
- &gEfiTrEEPhysicalPresenceGuid,\r
- NULL,\r
- &DataSize,\r
- &Flags\r
- );\r
- if (EFI_ERROR (Status)) {\r
- mTcgNvs->PhysicalPresence.ReturnCode = TREE_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;\r
- DEBUG ((EFI_D_ERROR, "[TPM2] Get PP flags failure! Status = %r\n", Status));\r
- return EFI_SUCCESS;\r
- }\r
-\r
- RequestConfirmed = FALSE;\r
-\r
- switch (mTcgNvs->PhysicalPresence.Request) {\r
-\r
- case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR:\r
- case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_2:\r
- case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_3:\r
- case TREE_PHYSICAL_PRESENCE_CLEAR_CONTROL_CLEAR_4:\r
- if ((Flags.PPFlags & TREE_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR) != 0) {\r
- RequestConfirmed = TRUE;\r
- }\r
- break;\r
-\r
- case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE:\r
- RequestConfirmed = TRUE;\r
- break;\r
-\r
- case TREE_PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_TRUE:\r
- break;\r
-\r
- default:\r
- if (mTcgNvs->PhysicalPresence.Request <= TREE_PHYSICAL_PRESENCE_NO_ACTION_MAX) {\r
- RequestConfirmed = TRUE;\r
- } else {\r
- if (mTcgNvs->PhysicalPresence.Request < TREE_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
- mTcgNvs->PhysicalPresence.ReturnCode = TREE_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED; \r
- return EFI_SUCCESS;\r
- }\r
- }\r
- break;\r
- }\r
-\r
- if (RequestConfirmed) {\r
- mTcgNvs->PhysicalPresence.ReturnCode = TREE_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_NOT_REQUIRED;\r
- } else {\r
- mTcgNvs->PhysicalPresence.ReturnCode = TREE_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_REQUIRED;\r
- } \r
- if (mTcgNvs->PhysicalPresence.Request >= TREE_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
- mTcgNvs->PhysicalPresence.ReturnCode = TrEEPpVendorLibGetUserConfirmationStatusFunction (mTcgNvs->PhysicalPresence.Request, Flags.PPFlags);\r
- }\r
- } \r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
- Software SMI callback for MemoryClear which is called from ACPI method.\r
-\r
- Caution: This function may receive untrusted input.\r
- Variable and ACPINvs are external input, so this function will validate\r
- its data structure to be valid value.\r
-\r
- @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().\r
- @param[in] Context Points to an optional handler context which was specified when the\r
- handler was registered.\r
- @param[in, out] CommBuffer A pointer to a collection of data in memory that will\r
- be conveyed from a non-SMM environment into an SMM environment.\r
- @param[in, out] CommBufferSize The size of the CommBuffer.\r
-\r
- @retval EFI_SUCCESS The interrupt was handled successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-MemoryClearCallback (\r
- IN EFI_HANDLE DispatchHandle,\r
- IN CONST VOID *Context,\r
- IN OUT VOID *CommBuffer,\r
- IN OUT UINTN *CommBufferSize\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN DataSize;\r
- UINT8 MorControl;\r
-\r
- mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_SUCCESS;\r
- if (mTcgNvs->MemoryClear.Parameter == ACPI_FUNCTION_DSM_MEMORY_CLEAR_INTERFACE) {\r
- MorControl = (UINT8) mTcgNvs->MemoryClear.Request;\r
- } else if (mTcgNvs->MemoryClear.Parameter == ACPI_FUNCTION_PTS_CLEAR_MOR_BIT) {\r
- DataSize = sizeof (UINT8);\r
- Status = mSmmVariable->SmmGetVariable (\r
- MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,\r
- &gEfiMemoryOverwriteControlDataGuid,\r
- NULL,\r
- &DataSize,\r
- &MorControl\r
- );\r
- if (EFI_ERROR (Status)) {\r
- mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;\r
- DEBUG ((EFI_D_ERROR, "[TPM] Get MOR variable failure! Status = %r\n", Status));\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if (MOR_CLEAR_MEMORY_VALUE (MorControl) == 0x0) {\r
- return EFI_SUCCESS;\r
- }\r
- MorControl &= ~MOR_CLEAR_MEMORY_BIT_MASK;\r
- }\r
-\r
- DataSize = sizeof (UINT8);\r
- Status = mSmmVariable->SmmSetVariable (\r
- MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,\r
- &gEfiMemoryOverwriteControlDataGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- DataSize,\r
- &MorControl\r
- );\r
- if (EFI_ERROR (Status)) { \r
- mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;\r
- DEBUG ((EFI_D_ERROR, "[TPM] Set MOR variable failure! Status = %r\n", Status));\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Find the operation region in TCG ACPI table by given Name and Size,\r
- and initialize it if the region is found.\r
-\r
- @param[in, out] Table The TPM item in ACPI table.\r
- @param[in] Name The name string to find in TPM table.\r
- @param[in] Size The size of the region to find.\r
-\r
- @return The allocated address for the found region.\r
-\r
-**/\r
-VOID *\r
-AssignOpRegion (\r
- EFI_ACPI_DESCRIPTION_HEADER *Table,\r
- UINT32 Name,\r
- UINT16 Size\r
- )\r
-{\r
- EFI_STATUS Status;\r
- AML_OP_REGION_32_8 *OpRegion;\r
- EFI_PHYSICAL_ADDRESS MemoryAddress;\r
-\r
- MemoryAddress = SIZE_4GB - 1;\r
-\r
- //\r
- // Patch some pointers for the ASL code before loading the SSDT.\r
- //\r
- for (OpRegion = (AML_OP_REGION_32_8 *) (Table + 1);\r
- OpRegion <= (AML_OP_REGION_32_8 *) ((UINT8 *) Table + Table->Length);\r
- OpRegion = (AML_OP_REGION_32_8 *) ((UINT8 *) OpRegion + 1)) {\r
- if ((OpRegion->OpRegionOp == AML_EXT_REGION_OP) && \r
- (OpRegion->NameString == Name) &&\r
- (OpRegion->DWordPrefix == AML_DWORD_PREFIX) &&\r
- (OpRegion->BytePrefix == AML_BYTE_PREFIX)) {\r
-\r
- Status = gBS->AllocatePages(AllocateMaxAddress, EfiACPIMemoryNVS, EFI_SIZE_TO_PAGES (Size), &MemoryAddress);\r
- ASSERT_EFI_ERROR (Status);\r
- ZeroMem ((VOID *)(UINTN)MemoryAddress, Size);\r
- OpRegion->RegionOffset = (UINT32) (UINTN) MemoryAddress;\r
- OpRegion->RegionLen = (UINT8) Size;\r
- break;\r
- }\r
- }\r
-\r
- return (VOID *) (UINTN) MemoryAddress;\r
-}\r
-\r
-/**\r
- Initialize and publish TPM items in ACPI table.\r
-\r
- @retval EFI_SUCCESS The TCG ACPI table is published successfully.\r
- @retval Others The TCG ACPI table is not published.\r
-\r
-**/\r
-EFI_STATUS\r
-PublishAcpiTable (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_ACPI_TABLE_PROTOCOL *AcpiTable;\r
- UINTN TableKey;\r
- EFI_ACPI_DESCRIPTION_HEADER *Table;\r
- UINTN TableSize;\r
-\r
- Status = GetSectionFromFv (\r
- &gEfiCallerIdGuid,\r
- EFI_SECTION_RAW,\r
- 0,\r
- (VOID **) &Table,\r
- &TableSize\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
-\r
- //\r
- // Measure to PCR[0] with event EV_POST_CODE ACPI DATA\r
- //\r
- TpmMeasureAndLogData(\r
- 0,\r
- EV_POST_CODE,\r
- EV_POSTCODE_INFO_ACPI_DATA,\r
- ACPI_DATA_LEN,\r
- Table,\r
- TableSize\r
- );\r
-\r
-\r
- ASSERT (Table->OemTableId == SIGNATURE_64 ('T', 'p', 'm', '2', 'T', 'a', 'b', 'l'));\r
- CopyMem (Table->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (Table->OemId) );\r
- mTcgNvs = AssignOpRegion (Table, SIGNATURE_32 ('T', 'N', 'V', 'S'), (UINT16) sizeof (TCG_NVS));\r
- ASSERT (mTcgNvs != NULL);\r
-\r
- //\r
- // Publish the TPM ACPI table\r
- //\r
- Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- TableKey = 0;\r
- Status = AcpiTable->InstallAcpiTable (\r
- AcpiTable,\r
- Table,\r
- TableSize,\r
- &TableKey\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Publish TPM2 ACPI table\r
-\r
- @retval EFI_SUCCESS The TPM2 ACPI table is published successfully.\r
- @retval Others The TPM2 ACPI table is not published.\r
-\r
-**/\r
-EFI_STATUS\r
-PublishTpm2 (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_ACPI_TABLE_PROTOCOL *AcpiTable;\r
- UINTN TableKey;\r
- UINT64 OemTableId;\r
-\r
- //\r
- // Measure to PCR[0] with event EV_POST_CODE ACPI DATA\r
- //\r
- TpmMeasureAndLogData(\r
- 0,\r
- EV_POST_CODE,\r
- EV_POSTCODE_INFO_ACPI_DATA,\r
- ACPI_DATA_LEN,\r
- &mTpm2AcpiTemplate,\r
- sizeof(mTpm2AcpiTemplate)\r
- );\r
-\r
- CopyMem (mTpm2AcpiTemplate.Header.OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (mTpm2AcpiTemplate.Header.OemId));\r
- OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);\r
- CopyMem (&mTpm2AcpiTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));\r
- mTpm2AcpiTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision);\r
- mTpm2AcpiTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId);\r
- mTpm2AcpiTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision);\r
-\r
- //\r
- // Construct ACPI table\r
- //\r
- Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTable);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- Status = AcpiTable->InstallAcpiTable (\r
- AcpiTable,\r
- &mTpm2AcpiTemplate,\r
- sizeof(mTpm2AcpiTemplate),\r
- &TableKey\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- The driver's entry point.\r
-\r
- It install callbacks for TPM physical presence and MemoryClear, and locate \r
- SMM variable to be used in the callback function.\r
-\r
- @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
- @param[in] SystemTable A pointer to the EFI System Table.\r
- \r
- @retval EFI_SUCCESS The entry point is executed successfully.\r
- @retval Others Some error occurs when executing this entry point.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeTcgSmm (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch;\r
- EFI_SMM_SW_REGISTER_CONTEXT SwContext;\r
- EFI_HANDLE SwHandle;\r
-\r
- if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm20DtpmGuid)){\r
- DEBUG ((EFI_D_ERROR, "No TPM2 DTPM instance required!\n"));\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Status = PublishAcpiTable ();\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Get the Sw dispatch protocol and register SMI callback functions.\r
- //\r
- Status = gSmst->SmmLocateProtocol (&gEfiSmmSwDispatch2ProtocolGuid, NULL, (VOID**)&SwDispatch);\r
- ASSERT_EFI_ERROR (Status);\r
- SwContext.SwSmiInputValue = (UINTN) -1;\r
- Status = SwDispatch->Register (SwDispatch, PhysicalPresenceCallback, &SwContext, &SwHandle);\r
- ASSERT_EFI_ERROR (Status);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- mTcgNvs->PhysicalPresence.SoftwareSmi = (UINT8) SwContext.SwSmiInputValue;\r
-\r
- SwContext.SwSmiInputValue = (UINTN) -1;\r
- Status = SwDispatch->Register (SwDispatch, MemoryClearCallback, &SwContext, &SwHandle);\r
- ASSERT_EFI_ERROR (Status);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- mTcgNvs->MemoryClear.SoftwareSmi = (UINT8) SwContext.SwSmiInputValue;\r
- \r
- //\r
- // Locate SmmVariableProtocol.\r
- //\r
- Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID**)&mSmmVariable);\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Set TPM2 ACPI table\r
- //\r
- Status = PublishTpm2 ();\r
- ASSERT_EFI_ERROR (Status);\r
-\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r