]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Tcg/TcgSmm/TcgSmm.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / SecurityPkg / Tcg / TcgSmm / TcgSmm.c
CommitLineData
0c18794e 1/** @file\r
2 It updates TPM items in ACPI table and registers SMI callback\r
3 functions for physical presence and ClearMemory.\r
4\r
dc204d5a
JY
5 Caution: This module requires additional review when modified.\r
6 This driver will have external input - variable and ACPINvs data in SMM mode.\r
7 This external input must be validated carefully to avoid security issue.\r
8\r
9 PhysicalPresenceCallback() and MemoryClearCallback() will receive untrusted input and do some check.\r
10\r
b3548d32 11Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
289b714b 12SPDX-License-Identifier: BSD-2-Clause-Patent\r
0c18794e 13\r
14**/\r
15\r
82a1e09c 16#include "TcgSmm.h"\r
0c18794e 17\r
18EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable;\r
19TCG_NVS *mTcgNvs;\r
20\r
21/**\r
22 Software SMI callback for TPM physical presence which is called from ACPI method.\r
23\r
dc204d5a
JY
24 Caution: This function may receive untrusted input.\r
25 Variable and ACPINvs are external input, so this function will validate\r
26 its data structure to be valid value.\r
27\r
0c18794e 28 @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().\r
29 @param[in] Context Points to an optional handler context which was specified when the\r
30 handler was registered.\r
31 @param[in, out] CommBuffer A pointer to a collection of data in memory that will\r
32 be conveyed from a non-SMM environment into an SMM environment.\r
33 @param[in, out] CommBufferSize The size of the CommBuffer.\r
34\r
35 @retval EFI_SUCCESS The interrupt was handled successfully.\r
36\r
37**/\r
38EFI_STATUS\r
39EFIAPI\r
40PhysicalPresenceCallback (\r
c411b485
MK
41 IN EFI_HANDLE DispatchHandle,\r
42 IN CONST VOID *Context,\r
43 IN OUT VOID *CommBuffer,\r
44 IN OUT UINTN *CommBufferSize\r
0c18794e 45 )\r
46{\r
c411b485
MK
47 EFI_STATUS Status;\r
48 UINTN DataSize;\r
49 EFI_PHYSICAL_PRESENCE PpData;\r
50 EFI_PHYSICAL_PRESENCE_FLAGS Flags;\r
51 BOOLEAN RequestConfirmed;\r
0c18794e 52\r
53 //\r
54 // Get the Physical Presence variable\r
55 //\r
56 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);\r
c411b485
MK
57 Status = mSmmVariable->SmmGetVariable (\r
58 PHYSICAL_PRESENCE_VARIABLE,\r
59 &gEfiPhysicalPresenceGuid,\r
60 NULL,\r
61 &DataSize,\r
62 &PpData\r
63 );\r
0c18794e 64\r
e905fbb0 65 DEBUG ((DEBUG_INFO, "[TPM] PP callback, Parameter = %x\n", mTcgNvs->PhysicalPresence.Parameter));\r
82a1e09c 66 if (mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_RETURN_REQUEST_RESPONSE_TO_OS) {\r
4610b23a
JY
67 if (EFI_ERROR (Status)) {\r
68 mTcgNvs->PhysicalPresence.ReturnCode = PP_RETURN_TPM_OPERATION_RESPONSE_FAILURE;\r
69 mTcgNvs->PhysicalPresence.LastRequest = 0;\r
70 mTcgNvs->PhysicalPresence.Response = 0;\r
e905fbb0 71 DEBUG ((DEBUG_ERROR, "[TPM] Get PP variable failure! Status = %r\n", Status));\r
4610b23a
JY
72 return EFI_SUCCESS;\r
73 }\r
c411b485 74\r
4610b23a 75 mTcgNvs->PhysicalPresence.ReturnCode = PP_RETURN_TPM_OPERATION_RESPONSE_SUCCESS;\r
0c18794e 76 mTcgNvs->PhysicalPresence.LastRequest = PpData.LastPPRequest;\r
77 mTcgNvs->PhysicalPresence.Response = PpData.PPResponse;\r
c411b485
MK
78 } else if ( (mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS)\r
79 || (mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_SUBMIT_REQUEST_TO_BIOS_2))\r
80 {\r
4610b23a
JY
81 if (EFI_ERROR (Status)) {\r
82 mTcgNvs->PhysicalPresence.ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
e905fbb0 83 DEBUG ((DEBUG_ERROR, "[TPM] Get PP variable failure! Status = %r\n", Status));\r
4610b23a
JY
84 return EFI_SUCCESS;\r
85 }\r
c411b485 86\r
607599bf 87 if (mTcgNvs->PhysicalPresence.Request == PHYSICAL_PRESENCE_SET_OPERATOR_AUTH) {\r
0c18794e 88 //\r
82a1e09c 89 // This command requires UI to prompt user for Auth data.\r
0c18794e 90 //\r
4610b23a 91 mTcgNvs->PhysicalPresence.ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED;\r
0c18794e 92 return EFI_SUCCESS;\r
93 }\r
94\r
95 if (PpData.PPRequest != mTcgNvs->PhysicalPresence.Request) {\r
c411b485
MK
96 PpData.PPRequest = (UINT8)mTcgNvs->PhysicalPresence.Request;\r
97 DataSize = sizeof (EFI_PHYSICAL_PRESENCE);\r
98 Status = mSmmVariable->SmmSetVariable (\r
99 PHYSICAL_PRESENCE_VARIABLE,\r
100 &gEfiPhysicalPresenceGuid,\r
101 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
102 DataSize,\r
103 &PpData\r
104 );\r
0c18794e 105 }\r
106\r
b3548d32 107 if (EFI_ERROR (Status)) {\r
4610b23a 108 mTcgNvs->PhysicalPresence.ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE;\r
0c18794e 109 return EFI_SUCCESS;\r
110 }\r
c411b485 111\r
4610b23a
JY
112 mTcgNvs->PhysicalPresence.ReturnCode = TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS;\r
113\r
114 if (mTcgNvs->PhysicalPresence.Request >= TCG_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
115 DataSize = sizeof (EFI_PHYSICAL_PRESENCE_FLAGS);\r
c411b485
MK
116 Status = mSmmVariable->SmmGetVariable (\r
117 PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
118 &gEfiPhysicalPresenceGuid,\r
119 NULL,\r
120 &DataSize,\r
121 &Flags\r
122 );\r
4610b23a
JY
123 if (EFI_ERROR (Status)) {\r
124 Flags.PPFlags = TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION;\r
125 }\r
c411b485 126\r
4610b23a
JY
127 mTcgNvs->PhysicalPresence.ReturnCode = TcgPpVendorLibSubmitRequestToPreOSFunction (mTcgNvs->PhysicalPresence.Request, Flags.PPFlags);\r
128 }\r
82a1e09c 129 } else if (mTcgNvs->PhysicalPresence.Parameter == ACPI_FUNCTION_GET_USER_CONFIRMATION_STATUS_FOR_REQUEST) {\r
4610b23a
JY
130 if (EFI_ERROR (Status)) {\r
131 mTcgNvs->PhysicalPresence.ReturnCode = TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;\r
e905fbb0 132 DEBUG ((DEBUG_ERROR, "[TPM] Get PP variable failure! Status = %r\n", Status));\r
4610b23a
JY
133 return EFI_SUCCESS;\r
134 }\r
c411b485 135\r
ed094569
DG
136 //\r
137 // Get the Physical Presence flags\r
138 //\r
4610b23a 139 DataSize = sizeof (EFI_PHYSICAL_PRESENCE_FLAGS);\r
c411b485
MK
140 Status = mSmmVariable->SmmGetVariable (\r
141 PHYSICAL_PRESENCE_FLAGS_VARIABLE,\r
142 &gEfiPhysicalPresenceGuid,\r
143 NULL,\r
144 &DataSize,\r
145 &Flags\r
146 );\r
ed094569 147 if (EFI_ERROR (Status)) {\r
4610b23a 148 mTcgNvs->PhysicalPresence.ReturnCode = TCG_PP_GET_USER_CONFIRMATION_BLOCKED_BY_BIOS_CONFIGURATION;\r
e905fbb0 149 DEBUG ((DEBUG_ERROR, "[TPM] Get PP flags failure! Status = %r\n", Status));\r
ed094569
DG
150 return EFI_SUCCESS;\r
151 }\r
152\r
0c18794e 153 RequestConfirmed = FALSE;\r
154\r
053f31e3 155 switch (mTcgNvs->PPRequestUserConfirm) {\r
607599bf 156 case PHYSICAL_PRESENCE_ENABLE:\r
157 case PHYSICAL_PRESENCE_DISABLE:\r
158 case PHYSICAL_PRESENCE_ACTIVATE:\r
159 case PHYSICAL_PRESENCE_DEACTIVATE:\r
160 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE:\r
161 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE:\r
162 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_TRUE:\r
163 case PHYSICAL_PRESENCE_SET_OWNER_INSTALL_FALSE:\r
164 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_OWNER_TRUE:\r
165 case PHYSICAL_PRESENCE_DEACTIVATE_DISABLE_OWNER_FALSE:\r
4610b23a 166 if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION) != 0) {\r
0c18794e 167 RequestConfirmed = TRUE;\r
168 }\r
c411b485 169\r
0c18794e 170 break;\r
171\r
607599bf 172 case PHYSICAL_PRESENCE_CLEAR:\r
173 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR:\r
4610b23a 174 if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR) != 0) {\r
0c18794e 175 RequestConfirmed = TRUE;\r
176 }\r
c411b485 177\r
0c18794e 178 break;\r
179\r
607599bf 180 case PHYSICAL_PRESENCE_DEFERRED_PP_UNOWNERED_FIELD_UPGRADE:\r
4610b23a 181 if ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_MAINTENANCE) != 0) {\r
0c18794e 182 RequestConfirmed = TRUE;\r
183 }\r
c411b485 184\r
0c18794e 185 break;\r
186\r
607599bf 187 case PHYSICAL_PRESENCE_ENABLE_ACTIVATE_CLEAR_ENABLE_ACTIVATE:\r
188 case PHYSICAL_PRESENCE_CLEAR_ENABLE_ACTIVATE:\r
c411b485 189 if (((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_CLEAR) != 0) && ((Flags.PPFlags & TCG_BIOS_TPM_MANAGEMENT_FLAG_NO_PPI_PROVISION) != 0)) {\r
0c18794e 190 RequestConfirmed = TRUE;\r
191 }\r
c411b485 192\r
b3548d32 193 break;\r
0c18794e 194\r
607599bf 195 case PHYSICAL_PRESENCE_SET_NO_PPI_PROVISION_FALSE:\r
196 case PHYSICAL_PRESENCE_SET_NO_PPI_CLEAR_FALSE:\r
197 case PHYSICAL_PRESENCE_SET_NO_PPI_MAINTENANCE_FALSE:\r
198 case PHYSICAL_PRESENCE_NO_ACTION:\r
0c18794e 199 RequestConfirmed = TRUE;\r
200 break;\r
201\r
607599bf 202 case PHYSICAL_PRESENCE_SET_OPERATOR_AUTH:\r
0c18794e 203 //\r
204 // This command requires UI to prompt user for Auth data\r
0c18794e 205 //\r
b3548d32 206 mTcgNvs->PhysicalPresence.ReturnCode = TCG_PP_GET_USER_CONFIRMATION_NOT_IMPLEMENTED;\r
0c18794e 207 return EFI_SUCCESS;\r
4610b23a
JY
208 default:\r
209 break;\r
0c18794e 210 }\r
211\r
212 if (RequestConfirmed) {\r
4610b23a 213 mTcgNvs->PhysicalPresence.ReturnCode = TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_NOT_REQUIRED;\r
0c18794e 214 } else {\r
4610b23a 215 mTcgNvs->PhysicalPresence.ReturnCode = TCG_PP_GET_USER_CONFIRMATION_ALLOWED_AND_PPUSER_REQUIRED;\r
b3548d32 216 }\r
c411b485 217\r
4610b23a
JY
218 if (mTcgNvs->PhysicalPresence.Request >= TCG_PHYSICAL_PRESENCE_VENDOR_SPECIFIC_OPERATION) {\r
219 mTcgNvs->PhysicalPresence.ReturnCode = TcgPpVendorLibGetUserConfirmationStatusFunction (mTcgNvs->PhysicalPresence.Request, Flags.PPFlags);\r
220 }\r
b3548d32 221 }\r
0c18794e 222\r
223 return EFI_SUCCESS;\r
224}\r
225\r
0c18794e 226/**\r
227 Software SMI callback for MemoryClear which is called from ACPI method.\r
228\r
dc204d5a
JY
229 Caution: This function may receive untrusted input.\r
230 Variable and ACPINvs are external input, so this function will validate\r
231 its data structure to be valid value.\r
232\r
0c18794e 233 @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().\r
234 @param[in] Context Points to an optional handler context which was specified when the\r
235 handler was registered.\r
236 @param[in, out] CommBuffer A pointer to a collection of data in memory that will\r
237 be conveyed from a non-SMM environment into an SMM environment.\r
238 @param[in, out] CommBufferSize The size of the CommBuffer.\r
239\r
240 @retval EFI_SUCCESS The interrupt was handled successfully.\r
241\r
242**/\r
243EFI_STATUS\r
244EFIAPI\r
245MemoryClearCallback (\r
c411b485
MK
246 IN EFI_HANDLE DispatchHandle,\r
247 IN CONST VOID *Context,\r
248 IN OUT VOID *CommBuffer,\r
249 IN OUT UINTN *CommBufferSize\r
0c18794e 250 )\r
251{\r
c411b485
MK
252 EFI_STATUS Status;\r
253 UINTN DataSize;\r
254 UINT8 MorControl;\r
0c18794e 255\r
82a1e09c 256 mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_SUCCESS;\r
257 if (mTcgNvs->MemoryClear.Parameter == ACPI_FUNCTION_DSM_MEMORY_CLEAR_INTERFACE) {\r
c411b485 258 MorControl = (UINT8)mTcgNvs->MemoryClear.Request;\r
82a1e09c 259 } else if (mTcgNvs->MemoryClear.Parameter == ACPI_FUNCTION_PTS_CLEAR_MOR_BIT) {\r
0c18794e 260 DataSize = sizeof (UINT8);\r
c411b485
MK
261 Status = mSmmVariable->SmmGetVariable (\r
262 MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,\r
263 &gEfiMemoryOverwriteControlDataGuid,\r
264 NULL,\r
265 &DataSize,\r
266 &MorControl\r
267 );\r
0c18794e 268 if (EFI_ERROR (Status)) {\r
8a8c6c96 269 mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;\r
e905fbb0 270 DEBUG ((DEBUG_ERROR, "[TPM] Get MOR variable failure! Status = %r\n", Status));\r
0c18794e 271 return EFI_SUCCESS;\r
272 }\r
273\r
274 if (MOR_CLEAR_MEMORY_VALUE (MorControl) == 0x0) {\r
275 return EFI_SUCCESS;\r
276 }\r
c411b485 277\r
0c18794e 278 MorControl &= ~MOR_CLEAR_MEMORY_BIT_MASK;\r
831bb137
ZC
279 } else {\r
280 mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;\r
e905fbb0 281 DEBUG ((DEBUG_ERROR, "[TPM] MOR Parameter error! Parameter = %x\n", mTcgNvs->MemoryClear.Parameter));\r
831bb137 282 return EFI_SUCCESS;\r
0c18794e 283 }\r
284\r
285 DataSize = sizeof (UINT8);\r
c411b485
MK
286 Status = mSmmVariable->SmmSetVariable (\r
287 MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,\r
288 &gEfiMemoryOverwriteControlDataGuid,\r
289 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
290 DataSize,\r
291 &MorControl\r
292 );\r
b3548d32 293 if (EFI_ERROR (Status)) {\r
82a1e09c 294 mTcgNvs->MemoryClear.ReturnCode = MOR_REQUEST_GENERAL_FAILURE;\r
e905fbb0 295 DEBUG ((DEBUG_ERROR, "[TPM] Set MOR variable failure! Status = %r\n", Status));\r
82a1e09c 296 }\r
0c18794e 297\r
298 return EFI_SUCCESS;\r
299}\r
300\r
301/**\r
302 Find the operation region in TCG ACPI table by given Name and Size,\r
303 and initialize it if the region is found.\r
304\r
305 @param[in, out] Table The TPM item in ACPI table.\r
306 @param[in] Name The name string to find in TPM table.\r
307 @param[in] Size The size of the region to find.\r
308\r
309 @return The allocated address for the found region.\r
310\r
311**/\r
312VOID *\r
313AssignOpRegion (\r
c411b485
MK
314 EFI_ACPI_DESCRIPTION_HEADER *Table,\r
315 UINT32 Name,\r
316 UINT16 Size\r
0c18794e 317 )\r
318{\r
c411b485
MK
319 EFI_STATUS Status;\r
320 AML_OP_REGION_32_8 *OpRegion;\r
321 EFI_PHYSICAL_ADDRESS MemoryAddress;\r
0c18794e 322\r
323 MemoryAddress = SIZE_4GB - 1;\r
324\r
325 //\r
326 // Patch some pointers for the ASL code before loading the SSDT.\r
327 //\r
c411b485
MK
328 for (OpRegion = (AML_OP_REGION_32_8 *)(Table + 1);\r
329 OpRegion <= (AML_OP_REGION_32_8 *)((UINT8 *)Table + Table->Length);\r
330 OpRegion = (AML_OP_REGION_32_8 *)((UINT8 *)OpRegion + 1))\r
331 {\r
b3548d32 332 if ((OpRegion->OpRegionOp == AML_EXT_REGION_OP) &&\r
0c18794e 333 (OpRegion->NameString == Name) &&\r
0c18794e 334 (OpRegion->DWordPrefix == AML_DWORD_PREFIX) &&\r
c411b485
MK
335 (OpRegion->BytePrefix == AML_BYTE_PREFIX))\r
336 {\r
337 Status = gBS->AllocatePages (AllocateMaxAddress, EfiACPIMemoryNVS, EFI_SIZE_TO_PAGES (Size), &MemoryAddress);\r
0c18794e 338 ASSERT_EFI_ERROR (Status);\r
339 ZeroMem ((VOID *)(UINTN)MemoryAddress, Size);\r
c411b485
MK
340 OpRegion->RegionOffset = (UINT32)(UINTN)MemoryAddress;\r
341 OpRegion->RegionLen = (UINT8)Size;\r
0c18794e 342 break;\r
343 }\r
344 }\r
345\r
c411b485 346 return (VOID *)(UINTN)MemoryAddress;\r
0c18794e 347}\r
348\r
349/**\r
350 Initialize and publish TPM items in ACPI table.\r
351\r
352 @retval EFI_SUCCESS The TCG ACPI table is published successfully.\r
353 @retval Others The TCG ACPI table is not published.\r
354\r
355**/\r
356EFI_STATUS\r
357PublishAcpiTable (\r
358 VOID\r
359 )\r
360{\r
c411b485
MK
361 EFI_STATUS Status;\r
362 EFI_ACPI_TABLE_PROTOCOL *AcpiTable;\r
363 UINTN TableKey;\r
364 EFI_ACPI_DESCRIPTION_HEADER *Table;\r
365 UINTN TableSize;\r
0c18794e 366\r
367 Status = GetSectionFromFv (\r
368 &gEfiCallerIdGuid,\r
369 EFI_SECTION_RAW,\r
370 0,\r
c411b485 371 (VOID **)&Table,\r
0c18794e 372 &TableSize\r
373 );\r
374 ASSERT_EFI_ERROR (Status);\r
375\r
a332cfd3 376 //\r
377 // Measure to PCR[0] with event EV_POST_CODE ACPI DATA\r
378 //\r
c411b485 379 TpmMeasureAndLogData (\r
a332cfd3 380 0,\r
381 EV_POST_CODE,\r
382 EV_POSTCODE_INFO_ACPI_DATA,\r
383 ACPI_DATA_LEN,\r
384 Table,\r
385 TableSize\r
386 );\r
387\r
0c18794e 388 ASSERT (Table->OemTableId == SIGNATURE_64 ('T', 'c', 'g', 'T', 'a', 'b', 'l', 'e'));\r
c411b485
MK
389 CopyMem (Table->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof (Table->OemId));\r
390 mTcgNvs = AssignOpRegion (Table, SIGNATURE_32 ('T', 'N', 'V', 'S'), (UINT16)sizeof (TCG_NVS));\r
0c18794e 391 ASSERT (mTcgNvs != NULL);\r
392\r
393 //\r
394 // Publish the TPM ACPI table\r
395 //\r
c411b485 396 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable);\r
0c18794e 397 ASSERT_EFI_ERROR (Status);\r
398\r
399 TableKey = 0;\r
c411b485
MK
400 Status = AcpiTable->InstallAcpiTable (\r
401 AcpiTable,\r
402 Table,\r
403 TableSize,\r
404 &TableKey\r
405 );\r
0c18794e 406 ASSERT_EFI_ERROR (Status);\r
407\r
408 return Status;\r
409}\r
410\r
411/**\r
412 The driver's entry point.\r
413\r
b3548d32 414 It install callbacks for TPM physical presence and MemoryClear, and locate\r
0c18794e 415 SMM variable to be used in the callback function.\r
416\r
b3548d32 417 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
0c18794e 418 @param[in] SystemTable A pointer to the EFI System Table.\r
b3548d32 419\r
0c18794e 420 @retval EFI_SUCCESS The entry point is executed successfully.\r
421 @retval Others Some error occurs when executing this entry point.\r
422\r
423**/\r
424EFI_STATUS\r
425EFIAPI\r
426InitializeTcgSmm (\r
c411b485
MK
427 IN EFI_HANDLE ImageHandle,\r
428 IN EFI_SYSTEM_TABLE *SystemTable\r
0c18794e 429 )\r
430{\r
431 EFI_STATUS Status;\r
432 EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch;\r
433 EFI_SMM_SW_REGISTER_CONTEXT SwContext;\r
434 EFI_HANDLE SwHandle;\r
435\r
c411b485 436 if (!CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)) {\r
e905fbb0 437 DEBUG ((DEBUG_ERROR, "No TPM12 instance required!\n"));\r
c1d93242
JY
438 return EFI_UNSUPPORTED;\r
439 }\r
440\r
0c18794e 441 Status = PublishAcpiTable ();\r
442 ASSERT_EFI_ERROR (Status);\r
443\r
444 //\r
445 // Get the Sw dispatch protocol and register SMI callback functions.\r
446 //\r
c411b485 447 Status = gSmst->SmmLocateProtocol (&gEfiSmmSwDispatch2ProtocolGuid, NULL, (VOID **)&SwDispatch);\r
0c18794e 448 ASSERT_EFI_ERROR (Status);\r
c411b485
MK
449 SwContext.SwSmiInputValue = (UINTN)-1;\r
450 Status = SwDispatch->Register (SwDispatch, PhysicalPresenceCallback, &SwContext, &SwHandle);\r
0c18794e 451 ASSERT_EFI_ERROR (Status);\r
452 if (EFI_ERROR (Status)) {\r
453 return Status;\r
454 }\r
0c18794e 455\r
c411b485
MK
456 mTcgNvs->PhysicalPresence.SoftwareSmi = (UINT8)SwContext.SwSmiInputValue;\r
457\r
458 SwContext.SwSmiInputValue = (UINTN)-1;\r
459 Status = SwDispatch->Register (SwDispatch, MemoryClearCallback, &SwContext, &SwHandle);\r
0c18794e 460 ASSERT_EFI_ERROR (Status);\r
461 if (EFI_ERROR (Status)) {\r
462 return Status;\r
463 }\r
c411b485
MK
464\r
465 mTcgNvs->MemoryClear.SoftwareSmi = (UINT8)SwContext.SwSmiInputValue;\r
b3548d32 466\r
0c18794e 467 //\r
468 // Locate SmmVariableProtocol.\r
469 //\r
c411b485 470 Status = gSmst->SmmLocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&mSmmVariable);\r
0c18794e 471 ASSERT_EFI_ERROR (Status);\r
472\r
473 return EFI_SUCCESS;\r
474}\r