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