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