]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Tcg/TcgDxe/TcgDxe.c
Fix the issue that consplitter should not touch ConIn variable & do ConIn connection
[mirror_edk2.git] / SecurityPkg / Tcg / TcgDxe / TcgDxe.c
CommitLineData
0c18794e 1/** @file \r
2 This module implements TCG EFI Protocol.\r
3 \r
627c3961 4Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.<BR>\r
0c18794e 5This program and the accompanying materials \r
6are licensed and made available under the terms and conditions of the BSD License \r
7which accompanies this distribution. The full text of the license may be found at \r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <PiDxe.h>\r
16#include <IndustryStandard/Tpm12.h>\r
17#include <IndustryStandard/Acpi.h>\r
18#include <IndustryStandard/PeImage.h>\r
19#include <IndustryStandard/SmBios.h>\r
20\r
21#include <Guid/GlobalVariable.h>\r
22#include <Guid/SmBios.h>\r
23#include <Guid/HobList.h>\r
24#include <Guid/TcgEventHob.h>\r
25#include <Guid/EventGroup.h>\r
9e945f78 26#include <Guid/EventExitBootServiceFailed.h>\r
0c18794e 27#include <Protocol/DevicePath.h>\r
28#include <Protocol/TcgService.h>\r
29#include <Protocol/AcpiTable.h>\r
30\r
31#include <Library/DebugLib.h>\r
32#include <Library/BaseMemoryLib.h>\r
33#include <Library/UefiRuntimeServicesTableLib.h>\r
34#include <Library/UefiDriverEntryPoint.h>\r
35#include <Library/HobLib.h>\r
36#include <Library/UefiBootServicesTableLib.h>\r
37#include <Library/BaseLib.h>\r
38#include <Library/MemoryAllocationLib.h>\r
39#include <Library/PrintLib.h>\r
40#include <Library/TpmCommLib.h>\r
41#include <Library/PcdLib.h>\r
42#include <Library/UefiLib.h>\r
43\r
44#include "TpmComm.h"\r
45\r
46#define EFI_TCG_LOG_AREA_SIZE 0x10000\r
47\r
48#pragma pack (1)\r
49\r
50typedef struct _EFI_TCG_CLIENT_ACPI_TABLE {\r
51 EFI_ACPI_DESCRIPTION_HEADER Header;\r
52 UINT16 PlatformClass;\r
53 UINT32 Laml;\r
54 EFI_PHYSICAL_ADDRESS Lasa;\r
55} EFI_TCG_CLIENT_ACPI_TABLE;\r
56\r
57typedef struct _EFI_TCG_SERVER_ACPI_TABLE {\r
58 EFI_ACPI_DESCRIPTION_HEADER Header;\r
59 UINT16 PlatformClass;\r
60 UINT16 Reserved0;\r
61 UINT64 Laml;\r
62 EFI_PHYSICAL_ADDRESS Lasa;\r
63 UINT16 SpecRev;\r
64 UINT8 DeviceFlags;\r
65 UINT8 InterruptFlags;\r
66 UINT8 Gpe;\r
67 UINT8 Reserved1[3];\r
68 UINT32 GlobalSysInt;\r
69 EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE BaseAddress;\r
70 UINT32 Reserved2;\r
71 EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE ConfigAddress;\r
72 UINT8 PciSegNum;\r
73 UINT8 PciBusNum;\r
74 UINT8 PciDevNum;\r
75 UINT8 PciFuncNum;\r
76} EFI_TCG_SERVER_ACPI_TABLE;\r
77\r
78#pragma pack ()\r
79\r
80#define TCG_DXE_DATA_FROM_THIS(this) \\r
81 BASE_CR (this, TCG_DXE_DATA, TcgProtocol)\r
82\r
83typedef struct _TCG_DXE_DATA {\r
84 EFI_TCG_PROTOCOL TcgProtocol;\r
85 TCG_EFI_BOOT_SERVICE_CAPABILITY BsCap;\r
86 EFI_TCG_CLIENT_ACPI_TABLE *TcgClientAcpiTable;\r
87 EFI_TCG_SERVER_ACPI_TABLE *TcgServerAcpiTable;\r
88 UINTN EventLogSize;\r
89 UINT8 *LastEvent;\r
90 TIS_TPM_HANDLE TpmHandle;\r
91} TCG_DXE_DATA;\r
92\r
93\r
94\r
95EFI_TCG_CLIENT_ACPI_TABLE mTcgClientAcpiTemplate = {\r
96 {\r
97 EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE,\r
98 sizeof (mTcgClientAcpiTemplate),\r
99 0x02 //Revision\r
100 //\r
101 // Compiler initializes the remaining bytes to 0\r
102 // These fields should be filled in in production\r
103 //\r
104 },\r
105 0, // 0 for PC Client Platform Class\r
106 0, // Log Area Max Length\r
107 (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1) // Log Area Start Address\r
108};\r
109\r
110//\r
111// The following EFI_TCG_SERVER_ACPI_TABLE default setting is just one example,\r
112// the TPM device connectes to LPC, and also defined the ACPI _UID as 0xFF,\r
113// this _UID can be changed and should match with the _UID setting of the TPM \r
114// ACPI device object \r
115//\r
116EFI_TCG_SERVER_ACPI_TABLE mTcgServerAcpiTemplate = {\r
117 {\r
118 EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE,\r
119 sizeof (mTcgServerAcpiTemplate),\r
120 0x02 //Revision\r
121 //\r
122 // Compiler initializes the remaining bytes to 0\r
123 // These fields should be filled in in production\r
124 //\r
125 },\r
126 1, // 1 for Server Platform Class\r
127 0, // Reserved\r
128 0, // Log Area Max Length\r
129 (EFI_PHYSICAL_ADDRESS) (SIZE_4GB - 1), // Log Area Start Address\r
130 0x0100, // TCG Specification revision 1.0\r
131 2, // Device Flags\r
132 0, // Interrupt Flags\r
133 0, // GPE\r
134 {0}, // Reserved 3 bytes\r
135 0, // Global System Interrupt\r
136 {\r
137 EFI_ACPI_3_0_SYSTEM_MEMORY,\r
138 0,\r
139 0,\r
140 EFI_ACPI_3_0_BYTE,\r
141 TPM_BASE_ADDRESS // Base Address\r
142 },\r
143 0, // Reserved\r
144 {0}, // Configuration Address\r
145 0xFF, // ACPI _UID value of the device, can be changed for different platforms\r
146 0, // ACPI _UID value of the device, can be changed for different platforms\r
147 0, // ACPI _UID value of the device, can be changed for different platforms\r
148 0 // ACPI _UID value of the device, can be changed for different platforms\r
149};\r
150\r
151UINTN mBootAttempts = 0;\r
152CHAR16 mBootVarName[] = L"BootOrder";\r
153\r
154/**\r
155 This service provides EFI protocol capability information, state information \r
156 about the TPM, and Event Log state information.\r
157\r
158 @param[in] This Indicates the calling context\r
159 @param[out] ProtocolCapability The callee allocates memory for a TCG_BOOT_SERVICE_CAPABILITY \r
160 structure and fills in the fields with the EFI protocol \r
161 capability information and the current TPM state information.\r
162 @param[out] TCGFeatureFlags This is a pointer to the feature flags. No feature \r
163 flags are currently defined so this parameter \r
164 MUST be set to 0. However, in the future, \r
165 feature flags may be defined that, for example, \r
166 enable hash algorithm agility.\r
167 @param[out] EventLogLocation This is a pointer to the address of the event log in memory.\r
168 @param[out] EventLogLastEntry If the Event Log contains more than one entry, \r
169 this is a pointer to the address of the start of \r
170 the last entry in the event log in memory. \r
171\r
172 @retval EFI_SUCCESS Operation completed successfully.\r
173 @retval EFI_INVALID_PARAMETER ProtocolCapability does not match TCG capability.\r
174 \r
175**/\r
176EFI_STATUS\r
177EFIAPI\r
178TcgDxeStatusCheck (\r
179 IN EFI_TCG_PROTOCOL *This,\r
180 OUT TCG_EFI_BOOT_SERVICE_CAPABILITY *ProtocolCapability,\r
181 OUT UINT32 *TCGFeatureFlags,\r
182 OUT EFI_PHYSICAL_ADDRESS *EventLogLocation,\r
183 OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry\r
184 )\r
185{\r
186 TCG_DXE_DATA *TcgData;\r
187\r
188 TcgData = TCG_DXE_DATA_FROM_THIS (This);\r
189\r
190 if (ProtocolCapability != NULL) {\r
191 *ProtocolCapability = TcgData->BsCap;\r
192 }\r
193\r
194 if (TCGFeatureFlags != NULL) {\r
195 *TCGFeatureFlags = 0;\r
196 }\r
197\r
198 if (EventLogLocation != NULL) {\r
199 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) {\r
200 *EventLogLocation = TcgData->TcgClientAcpiTable->Lasa;\r
201 } else {\r
202 *EventLogLocation = TcgData->TcgServerAcpiTable->Lasa;\r
203 }\r
204 }\r
205\r
206 if (EventLogLastEntry != NULL) {\r
207 if (TcgData->BsCap.TPMDeactivatedFlag) {\r
208 *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)0;\r
209 } else {\r
210 *EventLogLastEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)TcgData->LastEvent;\r
211 }\r
212 }\r
213\r
214 return EFI_SUCCESS;\r
215}\r
216\r
217/**\r
218 This service abstracts the capability to do a hash operation on a data buffer.\r
219 \r
220 @param[in] This Indicates the calling context\r
221 @param[in] HashData Pointer to the data buffer to be hashed\r
222 @param[in] HashDataLen Length of the data buffer to be hashed\r
223 @param[in] AlgorithmId Identification of the Algorithm to use for the hashing operation\r
224 @param[in, out] HashedDataLen Resultant length of the hashed data\r
225 @param[in, out] HashedDataResult Resultant buffer of the hashed data \r
226 \r
227 @retval EFI_SUCCESS Operation completed successfully.\r
228 @retval EFI_INVALID_PARAMETER HashDataLen is NULL.\r
229 @retval EFI_INVALID_PARAMETER HashDataLenResult is NULL.\r
230 @retval EFI_OUT_OF_RESOURCES Cannot allocate buffer of size *HashedDataLen.\r
231 @retval EFI_UNSUPPORTED AlgorithmId not supported.\r
232 @retval EFI_BUFFER_TOO_SMALL *HashedDataLen < sizeof (TCG_DIGEST).\r
233 \r
234**/\r
235EFI_STATUS\r
236EFIAPI\r
237TcgDxeHashAll (\r
238 IN EFI_TCG_PROTOCOL *This,\r
239 IN UINT8 *HashData,\r
240 IN UINT64 HashDataLen,\r
241 IN TCG_ALGORITHM_ID AlgorithmId,\r
242 IN OUT UINT64 *HashedDataLen,\r
243 IN OUT UINT8 **HashedDataResult\r
244 )\r
245{\r
246 if (HashedDataLen == NULL || HashedDataResult == NULL) {\r
247 return EFI_INVALID_PARAMETER;\r
248 }\r
249\r
250 switch (AlgorithmId) {\r
251 case TPM_ALG_SHA:\r
252 if (*HashedDataLen == 0) {\r
253 *HashedDataLen = sizeof (TPM_DIGEST);\r
254 *HashedDataResult = AllocatePool ((UINTN) *HashedDataLen);\r
255 if (*HashedDataResult == NULL) {\r
256 return EFI_OUT_OF_RESOURCES;\r
257 }\r
258 }\r
259\r
260 if (*HashedDataLen < sizeof (TPM_DIGEST)) {\r
261 *HashedDataLen = sizeof (TPM_DIGEST);\r
262 return EFI_BUFFER_TOO_SMALL;\r
263 }\r
264 *HashedDataLen = sizeof (TPM_DIGEST);\r
265\r
f5af77a8 266 if (*HashedDataResult == NULL) {\r
267 *HashedDataResult = AllocatePool ((UINTN) *HashedDataLen);\r
268 } \r
269\r
0c18794e 270 return TpmCommHashAll (\r
271 HashData,\r
272 (UINTN) HashDataLen,\r
273 (TPM_DIGEST*)*HashedDataResult\r
274 );\r
275 default:\r
276 return EFI_UNSUPPORTED;\r
277 }\r
278}\r
279\r
280/**\r
281 Add a new entry to the Event Log.\r
282\r
283 @param[in] TcgData TCG_DXE_DATA structure.\r
284 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. \r
285 @param[in] NewEventData Pointer to the new event data. \r
286 \r
287 @retval EFI_SUCCESS The new event log entry was added.\r
288 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
289\r
290**/\r
291EFI_STATUS\r
292EFIAPI\r
293TcgDxeLogEventI (\r
294 IN TCG_DXE_DATA *TcgData,\r
295 IN TCG_PCR_EVENT_HDR *NewEventHdr,\r
296 IN UINT8 *NewEventData\r
297 )\r
298{\r
299 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) {\r
300 TcgData->LastEvent = (UINT8*)(UINTN)TcgData->TcgClientAcpiTable->Lasa;\r
301 return TpmCommLogEvent (\r
302 &TcgData->LastEvent,\r
303 &TcgData->EventLogSize,\r
304 (UINTN)TcgData->TcgClientAcpiTable->Laml,\r
305 NewEventHdr,\r
306 NewEventData\r
307 );\r
308 } else {\r
309 TcgData->LastEvent = (UINT8*)(UINTN)TcgData->TcgServerAcpiTable->Lasa;\r
310 return TpmCommLogEvent (\r
311 &TcgData->LastEvent,\r
312 &TcgData->EventLogSize,\r
313 (UINTN)TcgData->TcgServerAcpiTable->Laml,\r
314 NewEventHdr,\r
315 NewEventData\r
316 );\r
317 }\r
318}\r
319\r
320/**\r
321 This service abstracts the capability to add an entry to the Event Log.\r
322\r
323 @param[in] This Indicates the calling context\r
324 @param[in] TCGLogData Pointer to the start of the data buffer containing \r
325 the TCG_PCR_EVENT data structure. All fields in \r
326 this structure are properly filled by the caller.\r
327 @param[in, out] EventNumber The event number of the event just logged\r
328 @param[in] Flags Indicate additional flags. Only one flag has been \r
329 defined at this time, which is 0x01 and means the \r
330 extend operation should not be performed. All \r
331 other bits are reserved. \r
332 \r
333 @retval EFI_SUCCESS Operation completed successfully.\r
334 @retval EFI_OUT_OF_RESOURCES Insufficient memory in the event log to complete this action.\r
335 \r
336**/\r
337EFI_STATUS\r
338EFIAPI\r
339TcgDxeLogEvent (\r
340 IN EFI_TCG_PROTOCOL *This,\r
341 IN TCG_PCR_EVENT *TCGLogData,\r
342 IN OUT UINT32 *EventNumber,\r
343 IN UINT32 Flags\r
344 )\r
345{\r
346 TCG_DXE_DATA *TcgData;\r
347\r
348 TcgData = TCG_DXE_DATA_FROM_THIS (This);\r
349 \r
350 if (TcgData->BsCap.TPMDeactivatedFlag) {\r
351 return EFI_DEVICE_ERROR;\r
352 }\r
353 return TcgDxeLogEventI (\r
354 TcgData,\r
355 (TCG_PCR_EVENT_HDR*)TCGLogData,\r
356 TCGLogData->Event\r
357 );\r
358}\r
359\r
360/**\r
361 This service is a proxy for commands to the TPM.\r
362\r
363 @param[in] This Indicates the calling context\r
364 @param[in] TpmInputParameterBlockSize Size of the TPM input parameter block\r
365 @param[in] TpmInputParameterBlock Pointer to the TPM input parameter block\r
366 @param[in] TpmOutputParameterBlockSize Size of the TPM output parameter block\r
367 @param[in] TpmOutputParameterBlock Pointer to the TPM output parameter block\r
368\r
369 @retval EFI_SUCCESS Operation completed successfully.\r
370 @retval EFI_INVALID_PARAMETER Invalid ordinal.\r
371 @retval EFI_UNSUPPORTED Current Task Priority Level >= EFI_TPL_CALLBACK.\r
372 @retval EFI_TIMEOUT The TIS timed-out.\r
373 \r
374**/\r
375EFI_STATUS\r
376EFIAPI\r
377TcgDxePassThroughToTpm (\r
378 IN EFI_TCG_PROTOCOL *This,\r
379 IN UINT32 TpmInputParameterBlockSize,\r
380 IN UINT8 *TpmInputParameterBlock,\r
381 IN UINT32 TpmOutputParameterBlockSize,\r
382 IN UINT8 *TpmOutputParameterBlock\r
383 )\r
384{\r
385 TCG_DXE_DATA *TcgData;\r
386\r
387 TcgData = TCG_DXE_DATA_FROM_THIS (This);\r
388\r
389 return TisPcExecute (\r
390 TcgData->TpmHandle,\r
391 "%r%/%r",\r
392 TpmInputParameterBlock,\r
393 (UINTN) TpmInputParameterBlockSize,\r
394 TpmOutputParameterBlock,\r
395 (UINTN) TpmOutputParameterBlockSize\r
396 );\r
397}\r
398\r
399/**\r
400 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,\r
401 and add an entry to the Event Log.\r
402\r
403 @param[in] TcgData TCG_DXE_DATA structure.\r
404 @param[in] HashData Physical address of the start of the data buffer \r
405 to be hashed, extended, and logged.\r
406 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData\r
407 @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. \r
408 @param[in] NewEventData Pointer to the new event data. \r
409\r
410 @retval EFI_SUCCESS Operation completed successfully.\r
411 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
412 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
413\r
414**/\r
415EFI_STATUS\r
416EFIAPI\r
417TcgDxeHashLogExtendEventI (\r
418 IN TCG_DXE_DATA *TcgData,\r
419 IN UINT8 *HashData,\r
420 IN UINT64 HashDataLen,\r
421 IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,\r
422 IN UINT8 *NewEventData\r
423 )\r
424{\r
425 EFI_STATUS Status;\r
426\r
427 if (HashDataLen > 0) {\r
428 Status = TpmCommHashAll (\r
429 HashData,\r
430 (UINTN) HashDataLen,\r
431 &NewEventHdr->Digest\r
432 );\r
433 ASSERT_EFI_ERROR (Status);\r
434 }\r
435\r
436 Status = TpmCommExtend (\r
437 TcgData->TpmHandle,\r
438 &NewEventHdr->Digest,\r
439 NewEventHdr->PCRIndex,\r
440 NULL\r
441 );\r
442 if (!EFI_ERROR (Status)) {\r
443 Status = TcgDxeLogEventI (TcgData, NewEventHdr, NewEventData);\r
444 }\r
445\r
446 return Status;\r
447}\r
448\r
449/**\r
450 This service abstracts the capability to do a hash operation on a data buffer,\r
451 extend a specific TPM PCR with the hash result, and add an entry to the Event Log\r
452\r
453 @param[in] This Indicates the calling context\r
454 @param[in] HashData Physical address of the start of the data buffer \r
455 to be hashed, extended, and logged.\r
456 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData\r
457 @param[in] AlgorithmId Identification of the Algorithm to use for the hashing operation\r
458 @param[in, out] TCGLogData The physical address of the start of the data \r
459 buffer containing the TCG_PCR_EVENT data structure.\r
460 @param[in, out] EventNumber The event number of the event just logged.\r
461 @param[out] EventLogLastEntry Physical address of the first byte of the entry \r
462 just placed in the Event Log. If the Event Log was \r
463 empty when this function was called then this physical \r
464 address will be the same as the physical address of \r
465 the start of the Event Log.\r
466\r
467 @retval EFI_SUCCESS Operation completed successfully.\r
468 @retval EFI_UNSUPPORTED AlgorithmId != TPM_ALG_SHA.\r
469 @retval EFI_UNSUPPORTED Current TPL >= EFI_TPL_CALLBACK.\r
470 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
471 \r
472**/\r
473EFI_STATUS\r
474EFIAPI\r
475TcgDxeHashLogExtendEvent (\r
476 IN EFI_TCG_PROTOCOL *This,\r
477 IN EFI_PHYSICAL_ADDRESS HashData,\r
478 IN UINT64 HashDataLen,\r
479 IN TPM_ALGORITHM_ID AlgorithmId,\r
480 IN OUT TCG_PCR_EVENT *TCGLogData,\r
481 IN OUT UINT32 *EventNumber,\r
482 OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry\r
483 )\r
484{\r
485 TCG_DXE_DATA *TcgData;\r
486\r
487 TcgData = TCG_DXE_DATA_FROM_THIS (This);\r
488 \r
489 if (TcgData->BsCap.TPMDeactivatedFlag) {\r
490 return EFI_DEVICE_ERROR;\r
491 }\r
492 \r
493 if (AlgorithmId != TPM_ALG_SHA) {\r
494 return EFI_UNSUPPORTED;\r
495 }\r
496\r
497 return TcgDxeHashLogExtendEventI (\r
498 TcgData,\r
499 (UINT8 *) (UINTN) HashData,\r
500 HashDataLen,\r
501 (TCG_PCR_EVENT_HDR*)TCGLogData,\r
502 TCGLogData->Event\r
503 );\r
504}\r
505\r
506TCG_DXE_DATA mTcgDxeData = {\r
507 {\r
508 TcgDxeStatusCheck,\r
509 TcgDxeHashAll,\r
510 TcgDxeLogEvent,\r
511 TcgDxePassThroughToTpm,\r
512 TcgDxeHashLogExtendEvent\r
513 },\r
514 {\r
515 sizeof (mTcgDxeData.BsCap),\r
516 { 1, 2, 0, 0 },\r
517 { 1, 2, 0, 0 },\r
518 1,\r
519 TRUE,\r
520 FALSE\r
521 },\r
522 &mTcgClientAcpiTemplate,\r
523 &mTcgServerAcpiTemplate,\r
524 0,\r
525 NULL,\r
526 NULL\r
527};\r
528\r
529/**\r
530 Initialize the Event Log and log events passed from the PEI phase.\r
531\r
532 @retval EFI_SUCCESS Operation completed successfully.\r
533 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
534\r
535**/\r
536EFI_STATUS\r
537EFIAPI\r
538SetupEventLog (\r
539 VOID\r
540 )\r
541{\r
542 EFI_STATUS Status;\r
543 TCG_PCR_EVENT *TcgEvent;\r
544 EFI_PEI_HOB_POINTERS GuidHob;\r
545 EFI_PHYSICAL_ADDRESS Lasa;\r
546 \r
547 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) {\r
548 Lasa = mTcgClientAcpiTemplate.Lasa;\r
549 \r
550 Status = gBS->AllocatePages (\r
551 AllocateMaxAddress,\r
552 EfiACPIMemoryNVS,\r
553 EFI_SIZE_TO_PAGES (EFI_TCG_LOG_AREA_SIZE),\r
554 &Lasa\r
555 );\r
556 if (EFI_ERROR (Status)) {\r
557 return Status;\r
558 }\r
559 mTcgClientAcpiTemplate.Lasa = Lasa;\r
560 //\r
561 // To initialize them as 0xFF is recommended \r
562 // because the OS can know the last entry for that.\r
563 //\r
564 SetMem ((VOID *)(UINTN)mTcgClientAcpiTemplate.Lasa, EFI_TCG_LOG_AREA_SIZE, 0xFF);\r
565 mTcgClientAcpiTemplate.Laml = EFI_TCG_LOG_AREA_SIZE;\r
566 \r
567 } else {\r
568 Lasa = mTcgServerAcpiTemplate.Lasa;\r
569 \r
570 Status = gBS->AllocatePages (\r
571 AllocateMaxAddress,\r
572 EfiACPIMemoryNVS,\r
573 EFI_SIZE_TO_PAGES (EFI_TCG_LOG_AREA_SIZE),\r
574 &Lasa\r
575 );\r
576 if (EFI_ERROR (Status)) {\r
577 return Status;\r
578 }\r
579 mTcgServerAcpiTemplate.Lasa = Lasa;\r
580 //\r
581 // To initialize them as 0xFF is recommended \r
582 // because the OS can know the last entry for that.\r
583 //\r
584 SetMem ((VOID *)(UINTN)mTcgServerAcpiTemplate.Lasa, EFI_TCG_LOG_AREA_SIZE, 0xFF);\r
585 mTcgServerAcpiTemplate.Laml = EFI_TCG_LOG_AREA_SIZE;\r
586 }\r
587\r
588 GuidHob.Raw = GetHobList ();\r
589 while (!EFI_ERROR (Status) && \r
590 (GuidHob.Raw = GetNextGuidHob (&gTcgEventEntryHobGuid, GuidHob.Raw)) != NULL) {\r
591 TcgEvent = GET_GUID_HOB_DATA (GuidHob.Guid);\r
592 GuidHob.Raw = GET_NEXT_HOB (GuidHob);\r
593 Status = TcgDxeLogEventI (\r
594 &mTcgDxeData,\r
595 (TCG_PCR_EVENT_HDR*)TcgEvent,\r
596 TcgEvent->Event\r
597 );\r
598 }\r
599\r
600 return Status;\r
601}\r
602\r
603/**\r
604 Measure and log an action string, and extend the measurement result into PCR[5].\r
605\r
606 @param[in] String A specific string that indicates an Action event. \r
607 \r
608 @retval EFI_SUCCESS Operation completed successfully.\r
609 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
610\r
611**/\r
612EFI_STATUS\r
613EFIAPI\r
614TcgMeasureAction (\r
615 IN CHAR8 *String\r
616 )\r
617{\r
618 TCG_PCR_EVENT_HDR TcgEvent;\r
619\r
620 TcgEvent.PCRIndex = 5;\r
621 TcgEvent.EventType = EV_EFI_ACTION;\r
622 TcgEvent.EventSize = (UINT32)AsciiStrLen (String);\r
623 return TcgDxeHashLogExtendEventI (\r
624 &mTcgDxeData,\r
625 (UINT8*)String,\r
626 TcgEvent.EventSize,\r
627 &TcgEvent,\r
628 (UINT8 *) String\r
629 );\r
630}\r
631\r
632/**\r
633 Measure and log EFI handoff tables, and extend the measurement result into PCR[1].\r
634\r
635 @retval EFI_SUCCESS Operation completed successfully.\r
636 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
637\r
638**/\r
639EFI_STATUS\r
640EFIAPI\r
641MeasureHandoffTables (\r
642 VOID\r
643 )\r
644{\r
645 EFI_STATUS Status;\r
646 SMBIOS_TABLE_ENTRY_POINT *SmbiosTable;\r
647 TCG_PCR_EVENT_HDR TcgEvent;\r
648 EFI_HANDOFF_TABLE_POINTERS HandoffTables;\r
649\r
650 Status = EfiGetSystemConfigurationTable (\r
651 &gEfiSmbiosTableGuid,\r
652 (VOID **) &SmbiosTable\r
653 );\r
654\r
655 if (!EFI_ERROR (Status)) {\r
656 ASSERT (SmbiosTable != NULL);\r
657\r
658 TcgEvent.PCRIndex = 1;\r
659 TcgEvent.EventType = EV_EFI_HANDOFF_TABLES;\r
660 TcgEvent.EventSize = sizeof (HandoffTables);\r
661\r
662 HandoffTables.NumberOfTables = 1;\r
663 HandoffTables.TableEntry[0].VendorGuid = gEfiSmbiosTableGuid;\r
664 HandoffTables.TableEntry[0].VendorTable = SmbiosTable;\r
665\r
666 DEBUG ((DEBUG_INFO, "The Smbios Table starts at: 0x%x\n", SmbiosTable->TableAddress));\r
667 DEBUG ((DEBUG_INFO, "The Smbios Table size: 0x%x\n", SmbiosTable->TableLength));\r
668\r
669 Status = TcgDxeHashLogExtendEventI (\r
670 &mTcgDxeData,\r
671 (UINT8*)(UINTN)SmbiosTable->TableAddress,\r
672 SmbiosTable->TableLength,\r
673 &TcgEvent,\r
674 (UINT8*)&HandoffTables\r
675 );\r
676 }\r
677\r
678 return Status;\r
679}\r
680\r
681/**\r
682 Measure and log Separator event, and extend the measurement result into a specific PCR.\r
683\r
684 @param[in] PCRIndex PCR index. \r
685\r
686 @retval EFI_SUCCESS Operation completed successfully.\r
687 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
688\r
689**/\r
690EFI_STATUS\r
691EFIAPI\r
692MeasureSeparatorEvent (\r
693 IN TPM_PCRINDEX PCRIndex\r
694 )\r
695{\r
696 TCG_PCR_EVENT_HDR TcgEvent;\r
697 UINT32 EventData;\r
698\r
699 EventData = 0;\r
700 TcgEvent.PCRIndex = PCRIndex;\r
701 TcgEvent.EventType = EV_SEPARATOR;\r
702 TcgEvent.EventSize = (UINT32)sizeof (EventData);\r
703 return TcgDxeHashLogExtendEventI (\r
704 &mTcgDxeData,\r
705 (UINT8 *)&EventData,\r
706 sizeof (EventData),\r
707 &TcgEvent,\r
708 (UINT8 *)&EventData\r
709 );\r
710}\r
711\r
712/**\r
713 Read an EFI Variable.\r
714\r
715 This function allocates a buffer to return the contents of the variable. The caller is\r
716 responsible for freeing the buffer.\r
717\r
718 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
719 @param[in] VendorGuid A unique identifier for the vendor.\r
720 @param[out] VarSize The size of the variable data. \r
721\r
722 @return A pointer to the buffer to return the contents of the variable.Otherwise NULL.\r
723\r
724**/\r
725VOID *\r
726EFIAPI\r
727ReadVariable (\r
728 IN CHAR16 *VarName,\r
729 IN EFI_GUID *VendorGuid,\r
730 OUT UINTN *VarSize\r
731 )\r
732{\r
733 EFI_STATUS Status;\r
734 VOID *VarData;\r
735\r
736 *VarSize = 0;\r
737 Status = gRT->GetVariable (\r
738 VarName,\r
739 VendorGuid,\r
740 NULL,\r
741 VarSize,\r
742 NULL\r
743 );\r
744 if (Status != EFI_BUFFER_TOO_SMALL) {\r
745 return NULL;\r
746 }\r
747\r
748 VarData = AllocatePool (*VarSize);\r
749 if (VarData != NULL) {\r
750 Status = gRT->GetVariable (\r
751 VarName,\r
752 VendorGuid,\r
753 NULL,\r
754 VarSize,\r
755 VarData\r
756 );\r
757 if (EFI_ERROR (Status)) {\r
758 FreePool (VarData);\r
759 VarData = NULL;\r
760 *VarSize = 0;\r
761 }\r
762 }\r
763 return VarData;\r
764}\r
765\r
766/**\r
767 Measure and log an EFI variable, and extend the measurement result into a specific PCR.\r
768\r
769 @param[in] PCRIndex PCR Index. \r
770 @param[in] EventType Event type. \r
771 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
772 @param[in] VendorGuid A unique identifier for the vendor.\r
773 @param[in] VarData The content of the variable data. \r
774 @param[in] VarSize The size of the variable data. \r
775 \r
776 @retval EFI_SUCCESS Operation completed successfully.\r
777 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
778 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
779\r
780**/\r
781EFI_STATUS\r
782EFIAPI\r
783MeasureVariable (\r
784 IN TPM_PCRINDEX PCRIndex,\r
785 IN TCG_EVENTTYPE EventType,\r
786 IN CHAR16 *VarName,\r
787 IN EFI_GUID *VendorGuid,\r
788 IN VOID *VarData,\r
789 IN UINTN VarSize\r
790 )\r
791{\r
792 EFI_STATUS Status;\r
793 TCG_PCR_EVENT_HDR TcgEvent;\r
794 UINTN VarNameLength;\r
795 EFI_VARIABLE_DATA *VarLog;\r
796\r
797 VarNameLength = StrLen (VarName);\r
798 TcgEvent.PCRIndex = PCRIndex;\r
799 TcgEvent.EventType = EventType;\r
800 TcgEvent.EventSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize\r
801 - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));\r
802\r
803 VarLog = (EFI_VARIABLE_DATA*)AllocatePool (TcgEvent.EventSize);\r
804 if (VarLog == NULL) {\r
805 return EFI_OUT_OF_RESOURCES;\r
806 }\r
807\r
808 VarLog->VariableName = *VendorGuid;\r
809 VarLog->UnicodeNameLength = VarNameLength;\r
810 VarLog->VariableDataLength = VarSize;\r
811 CopyMem (\r
812 VarLog->UnicodeName,\r
813 VarName,\r
814 VarNameLength * sizeof (*VarName)\r
815 );\r
816 CopyMem (\r
817 (CHAR16 *)VarLog->UnicodeName + VarNameLength,\r
818 VarData,\r
819 VarSize\r
820 );\r
821\r
822 Status = TcgDxeHashLogExtendEventI (\r
823 &mTcgDxeData,\r
824 (UINT8*)VarData,\r
825 VarSize,\r
826 &TcgEvent,\r
827 (UINT8*)VarLog\r
828 );\r
829 FreePool (VarLog);\r
830 return Status;\r
831}\r
832\r
833/**\r
834 Read then Measure and log an EFI boot variable, and extend the measurement result into PCR[5].\r
835\r
836 @param[in] VarName A Null-terminated string that is the name of the vendor's variable.\r
837 @param[in] VendorGuid A unique identifier for the vendor.\r
838 @param[out] VarSize The size of the variable data. \r
839 @param[out] VarData Pointer to the content of the variable. \r
840 \r
841 @retval EFI_SUCCESS Operation completed successfully.\r
842 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
843 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
844\r
845**/\r
846EFI_STATUS\r
847EFIAPI\r
848ReadAndMeasureBootVariable (\r
849 IN CHAR16 *VarName,\r
850 IN EFI_GUID *VendorGuid,\r
851 OUT UINTN *VarSize,\r
852 OUT VOID **VarData\r
853 )\r
854{\r
855 EFI_STATUS Status;\r
856\r
857 *VarData = ReadVariable (VarName, VendorGuid, VarSize);\r
858 if (*VarData == NULL) {\r
859 return EFI_NOT_FOUND;\r
860 }\r
861\r
862 Status = MeasureVariable (\r
863 5,\r
864 EV_EFI_VARIABLE_BOOT,\r
865 VarName,\r
866 VendorGuid,\r
867 *VarData,\r
868 *VarSize\r
869 );\r
870 return Status;\r
871}\r
872\r
873/**\r
874 Measure and log all EFI boot variables, and extend the measurement result into a specific PCR.\r
875\r
876 The EFI boot variables are BootOrder and Boot#### variables.\r
877\r
878 @retval EFI_SUCCESS Operation completed successfully.\r
879 @retval EFI_OUT_OF_RESOURCES Out of memory.\r
880 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
881\r
882**/\r
883EFI_STATUS\r
884EFIAPI\r
885MeasureAllBootVariables (\r
886 VOID\r
887 )\r
888{\r
889 EFI_STATUS Status;\r
890 UINT16 *BootOrder;\r
891 UINTN BootCount;\r
892 UINTN Index;\r
893 VOID *BootVarData;\r
894 UINTN Size;\r
895\r
896 Status = ReadAndMeasureBootVariable (\r
897 mBootVarName,\r
898 &gEfiGlobalVariableGuid,\r
899 &BootCount,\r
900 (VOID **) &BootOrder\r
901 );\r
902 if (Status == EFI_NOT_FOUND) {\r
903 return EFI_SUCCESS;\r
904 }\r
905 ASSERT (BootOrder != NULL);\r
906\r
907 if (EFI_ERROR (Status)) {\r
908 FreePool (BootOrder);\r
909 return Status;\r
910 }\r
911\r
912 BootCount /= sizeof (*BootOrder);\r
913 for (Index = 0; Index < BootCount; Index++) {\r
914 UnicodeSPrint (mBootVarName, sizeof (mBootVarName), L"Boot%04x", BootOrder[Index]);\r
915 Status = ReadAndMeasureBootVariable (\r
916 mBootVarName,\r
917 &gEfiGlobalVariableGuid,\r
918 &Size,\r
919 &BootVarData\r
920 );\r
921 if (!EFI_ERROR (Status)) {\r
922 FreePool (BootVarData);\r
923 }\r
924 }\r
925\r
926 FreePool (BootOrder);\r
927 return EFI_SUCCESS;\r
928}\r
929\r
930/**\r
931 Ready to Boot Event notification handler.\r
932\r
933 Sequence of OS boot events is measured in this event notification handler.\r
934\r
935 @param[in] Event Event whose notification function is being invoked\r
936 @param[in] Context Pointer to the notification function's context\r
937\r
938**/\r
939VOID\r
940EFIAPI\r
941OnReadyToBoot (\r
942 IN EFI_EVENT Event,\r
943 IN VOID *Context\r
944 )\r
945{\r
946 EFI_STATUS Status;\r
947 TPM_PCRINDEX PcrIndex;\r
948\r
949 if (mBootAttempts == 0) {\r
950\r
951 //\r
952 // Measure handoff tables.\r
953 //\r
954 Status = MeasureHandoffTables ();\r
955 if (EFI_ERROR (Status)) {\r
956 DEBUG ((EFI_D_ERROR, "HOBs not Measured. Error!\n"));\r
957 }\r
958\r
959 //\r
960 // Measure BootOrder & Boot#### variables.\r
961 //\r
962 Status = MeasureAllBootVariables ();\r
963 if (EFI_ERROR (Status)) {\r
964 DEBUG ((EFI_D_ERROR, "Boot Variables not Measured. Error!\n"));\r
965 }\r
966\r
967 //\r
968 // 1. This is the first boot attempt.\r
969 //\r
970 Status = TcgMeasureAction (\r
971 EFI_CALLING_EFI_APPLICATION\r
972 );\r
973 ASSERT_EFI_ERROR (Status);\r
974\r
975 //\r
976 // 2. Draw a line between pre-boot env and entering post-boot env.\r
977 //\r
978 for (PcrIndex = 0; PcrIndex < 8; PcrIndex++) {\r
979 Status = MeasureSeparatorEvent (PcrIndex);\r
980 ASSERT_EFI_ERROR (Status);\r
981 }\r
982\r
983 //\r
984 // 3. Measure GPT. It would be done in SAP driver.\r
985 //\r
986\r
987 //\r
988 // 4. Measure PE/COFF OS loader. It would be done in SAP driver.\r
989 //\r
990\r
991 //\r
992 // 5. Read & Measure variable. BootOrder already measured.\r
993 //\r
994 } else {\r
995 //\r
996 // 6. Not first attempt, meaning a return from last attempt\r
997 //\r
998 Status = TcgMeasureAction (\r
999 EFI_RETURNING_FROM_EFI_APPLICATOIN\r
1000 );\r
1001 ASSERT_EFI_ERROR (Status);\r
1002 }\r
1003\r
1004 DEBUG ((EFI_D_INFO, "TPM TcgDxe Measure Data when ReadyToBoot\n"));\r
1005 //\r
1006 // Increase boot attempt counter.\r
1007 //\r
1008 mBootAttempts++;\r
1009}\r
1010\r
1011/**\r
1012 Install TCG ACPI Table when ACPI Table Protocol is available.\r
1013\r
0f7f6d23 1014 A system's firmware uses an ACPI table to identify the system's TCG capabilities \r
0c18794e 1015 to the Post-Boot environment. The information in this ACPI table is not guaranteed \r
1016 to be valid until the Host Platform transitions from pre-boot state to post-boot state. \r
1017\r
1018 @param[in] Event Event whose notification function is being invoked\r
1019 @param[in] Context Pointer to the notification function's context\r
1020**/\r
1021VOID\r
1022EFIAPI\r
1023InstallAcpiTable (\r
1024 IN EFI_EVENT Event,\r
1025 IN VOID* Context\r
1026 )\r
1027{\r
1028 UINTN TableKey;\r
1029 EFI_STATUS Status;\r
1030 EFI_ACPI_TABLE_PROTOCOL *AcpiTable;\r
1031 UINT8 Checksum;\r
1032\r
1033 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTable);\r
1034 if (EFI_ERROR (Status)) {\r
1035 return;\r
1036 }\r
1037\r
1038 if (PcdGet8 (PcdTpmPlatformClass) == TCG_PLATFORM_TYPE_CLIENT) {\r
1039 \r
1040 //\r
1041 // The ACPI table must be checksumed before calling the InstallAcpiTable() \r
1042 // service of the ACPI table protocol to install it.\r
1043 //\r
1044 Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgClientAcpiTemplate, sizeof (mTcgClientAcpiTemplate));\r
1045 mTcgClientAcpiTemplate.Header.Checksum = Checksum;\r
1046\r
1047 Status = AcpiTable->InstallAcpiTable (\r
1048 AcpiTable,\r
1049 &mTcgClientAcpiTemplate,\r
1050 sizeof (mTcgClientAcpiTemplate),\r
1051 &TableKey\r
1052 );\r
1053 } else {\r
1054\r
1055 //\r
1056 // The ACPI table must be checksumed before calling the InstallAcpiTable() \r
1057 // service of the ACPI table protocol to install it.\r
1058 //\r
1059 Checksum = CalculateCheckSum8 ((UINT8 *)&mTcgServerAcpiTemplate, sizeof (mTcgServerAcpiTemplate));\r
1060 mTcgServerAcpiTemplate.Header.Checksum = Checksum;\r
1061\r
1062 Status = AcpiTable->InstallAcpiTable (\r
1063 AcpiTable,\r
1064 &mTcgServerAcpiTemplate,\r
1065 sizeof (mTcgServerAcpiTemplate),\r
1066 &TableKey\r
1067 );\r
1068 }\r
1069 ASSERT_EFI_ERROR (Status);\r
1070}\r
1071\r
1072/**\r
1073 Exit Boot Services Event notification handler.\r
1074\r
1075 Measure invocation and success of ExitBootServices.\r
1076\r
1077 @param[in] Event Event whose notification function is being invoked\r
1078 @param[in] Context Pointer to the notification function's context\r
1079\r
1080**/\r
1081VOID\r
1082EFIAPI\r
1083OnExitBootServices (\r
1084 IN EFI_EVENT Event,\r
1085 IN VOID *Context\r
1086 )\r
1087{\r
1088 EFI_STATUS Status;\r
1089\r
1090 //\r
1091 // Measure invocation of ExitBootServices,\r
1092 //\r
1093 Status = TcgMeasureAction (\r
1094 EFI_EXIT_BOOT_SERVICES_INVOCATION\r
1095 );\r
1096 ASSERT_EFI_ERROR (Status);\r
1097\r
1098 //\r
1099 // Measure success of ExitBootServices\r
1100 //\r
1101 Status = TcgMeasureAction (\r
1102 EFI_EXIT_BOOT_SERVICES_SUCCEEDED\r
1103 );\r
1104 ASSERT_EFI_ERROR (Status);\r
1105}\r
1106\r
9e945f78 1107/**\r
1108 Exit Boot Services Failed Event notification handler.\r
1109\r
1110 Measure Failure of ExitBootServices.\r
1111\r
1112 @param[in] Event Event whose notification function is being invoked\r
1113 @param[in] Context Pointer to the notification function's context\r
1114\r
1115**/\r
1116VOID\r
1117EFIAPI\r
1118OnExitBootServicesFailed (\r
1119 IN EFI_EVENT Event,\r
1120 IN VOID *Context\r
1121 )\r
1122{\r
1123 EFI_STATUS Status;\r
1124\r
1125 //\r
1126 // Measure Failure of ExitBootServices,\r
1127 //\r
1128 Status = TcgMeasureAction (\r
1129 EFI_EXIT_BOOT_SERVICES_FAILED\r
1130 );\r
1131 ASSERT_EFI_ERROR (Status);\r
1132\r
1133}\r
1134\r
0c18794e 1135/**\r
1136 Get TPM Deactivated state.\r
1137\r
1138 @param[out] TPMDeactivatedFlag Returns TPM Deactivated state. \r
1139\r
1140 @retval EFI_SUCCESS Operation completed successfully.\r
1141 @retval EFI_DEVICE_ERROR The operation was unsuccessful.\r
1142\r
1143**/\r
1144EFI_STATUS\r
1145GetTpmStatus (\r
1146 OUT BOOLEAN *TPMDeactivatedFlag\r
1147 )\r
1148{\r
1149 EFI_STATUS Status;\r
1150 TPM_STCLEAR_FLAGS VFlags;\r
1151\r
1152 Status = TpmCommGetFlags (\r
1153 mTcgDxeData.TpmHandle,\r
1154 TPM_CAP_FLAG_VOLATILE,\r
1155 &VFlags,\r
1156 sizeof (VFlags)\r
1157 );\r
1158 if (!EFI_ERROR (Status)) {\r
1159 *TPMDeactivatedFlag = VFlags.deactivated;\r
1160 }\r
1161\r
1162 return Status;\r
1163}\r
1164\r
1165/**\r
1166 The driver's entry point.\r
1167\r
1168 It publishes EFI TCG Protocol.\r
1169\r
1170 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
1171 @param[in] SystemTable A pointer to the EFI System Table.\r
1172 \r
1173 @retval EFI_SUCCESS The entry point is executed successfully.\r
1174 @retval other Some error occurs when executing this entry point.\r
1175\r
1176**/\r
1177EFI_STATUS\r
1178EFIAPI\r
1179DriverEntry (\r
1180 IN EFI_HANDLE ImageHandle,\r
1181 IN EFI_SYSTEM_TABLE *SystemTable\r
1182 )\r
1183{\r
1184 EFI_STATUS Status;\r
1185 EFI_EVENT Event;\r
1186 VOID *Registration;\r
1187\r
1188 mTcgDxeData.TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;\r
1189 Status = TisPcRequestUseTpm (mTcgDxeData.TpmHandle);\r
1190 if (EFI_ERROR (Status)) {\r
1191 DEBUG ((EFI_D_ERROR, "TPM not detected!\n"));\r
1192 return Status;\r
1193 }\r
1194\r
1195 Status = GetTpmStatus (&mTcgDxeData.BsCap.TPMDeactivatedFlag);\r
1196 if (EFI_ERROR (Status)) {\r
1197 DEBUG ((\r
1198 EFI_D_ERROR,\r
1199 "Line %d in file " __FILE__ ":\n "\r
1200 "DriverEntry: TPM not working properly\n",\r
1201 __LINE__\r
1202 ));\r
1203 return Status;\r
1204 }\r
1205\r
1206 Status = gBS->InstallProtocolInterface (\r
1207 &ImageHandle,\r
1208 &gEfiTcgProtocolGuid,\r
1209 EFI_NATIVE_INTERFACE,\r
1210 &mTcgDxeData.TcgProtocol\r
1211 );\r
0c18794e 1212 if (!EFI_ERROR (Status) && !mTcgDxeData.BsCap.TPMDeactivatedFlag) {\r
1213 //\r
1214 // Setup the log area and copy event log from hob list to it\r
1215 //\r
1216 Status = SetupEventLog ();\r
1217 ASSERT_EFI_ERROR (Status);\r
1218\r
1219 //\r
1220 // Measure handoff tables, Boot#### variables etc.\r
1221 //\r
1222 Status = EfiCreateEventReadyToBootEx (\r
1223 TPL_CALLBACK,\r
1224 OnReadyToBoot,\r
1225 NULL,\r
1226 &Event\r
1227 );\r
1228\r
1229 Status = gBS->CreateEventEx (\r
1230 EVT_NOTIFY_SIGNAL,\r
1231 TPL_NOTIFY,\r
1232 OnExitBootServices,\r
1233 NULL,\r
1234 &gEfiEventExitBootServicesGuid,\r
1235 &Event\r
1236 );\r
9e945f78 1237\r
1238 //\r
1239 // Measure Exit Boot Service failed \r
1240 //\r
1241 Status = gBS->CreateEventEx (\r
1242 EVT_NOTIFY_SIGNAL,\r
1243 TPL_NOTIFY,\r
1244 OnExitBootServicesFailed,\r
1245 NULL,\r
1246 &gEventExitBootServicesFailedGuid,\r
1247 &Event\r
1248 );\r
0c18794e 1249 }\r
1250\r
627c3961 1251 //\r
1252 // Install ACPI Table\r
1253 //\r
1254 EfiCreateProtocolNotifyEvent (&gEfiAcpiTableProtocolGuid, TPL_CALLBACK, InstallAcpiTable, NULL, &Registration);\r
1255 \r
0c18794e 1256 return Status;\r
1257}\r