]> git.proxmox.com Git - mirror_edk2.git/blame - SecurityPkg/Tcg/TcgPei/TcgPei.c
Set mode 0 (80x25) when Consplitter does not exist.
[mirror_edk2.git] / SecurityPkg / Tcg / TcgPei / TcgPei.c
CommitLineData
0c18794e 1/** @file\r
2 Initialize TPM device and measure FVs before handing off control to DXE.\r
3\r
5a500332 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 <PiPei.h>\r
16\r
17#include <IndustryStandard/Tpm12.h>\r
18#include <IndustryStandard/UefiTcgPlatform.h>\r
19#include <Ppi/FirmwareVolumeInfo.h>\r
20#include <Ppi/LockPhysicalPresence.h>\r
21#include <Ppi/TpmInitialized.h>\r
22#include <Ppi/FirmwareVolume.h>\r
23#include <Guid/TcgEventHob.h>\r
24#include <Library/DebugLib.h>\r
25#include <Library/BaseMemoryLib.h>\r
26#include <Library/PeiServicesLib.h>\r
27#include <Library/PeimEntryPoint.h>\r
28#include <Library/TpmCommLib.h>\r
29#include <Library/HobLib.h>\r
30#include <Library/PcdLib.h>\r
31#include <Library/PeiServicesTablePointerLib.h>\r
333a53ee 32#include <Library/BaseLib.h>\r
0c18794e 33\r
34#include "TpmComm.h"\r
35\r
36BOOLEAN mImageInMemory = FALSE;\r
37\r
38EFI_PEI_PPI_DESCRIPTOR mTpmInitializedPpiList = {\r
39 EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
40 &gPeiTpmInitializedPpiGuid,\r
41 NULL\r
42};\r
43\r
44/**\r
45 Lock physical presence if needed.\r
46\r
47 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r
48 @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
49 @param[in] Ppi Address of the PPI that was installed.\r
50\r
51 @retval EFI_SUCCESS Operation completed successfully.\r
52\r
53**/\r
54EFI_STATUS\r
55EFIAPI\r
56PhysicalPresencePpiNotifyCallback (\r
57 IN EFI_PEI_SERVICES **PeiServices,\r
58 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
59 IN VOID *Ppi\r
60 );\r
61\r
62/**\r
63 Measure and record the Firmware Volum Information once FvInfoPPI install.\r
64\r
65 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
66 @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
67 @param[in] Ppi Address of the PPI that was installed.\r
68\r
69 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.\r
70 @return Others Fail to measure FV.\r
71\r
72**/\r
73EFI_STATUS\r
74EFIAPI\r
75FirmwareVolmeInfoPpiNotifyCallback (\r
76 IN EFI_PEI_SERVICES **PeiServices,\r
77 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
78 IN VOID *Ppi\r
79 );\r
80\r
81EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = {\r
82 {\r
83 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,\r
84 &gPeiLockPhysicalPresencePpiGuid,\r
85 PhysicalPresencePpiNotifyCallback\r
86 },\r
87 {\r
88 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
89 &gEfiPeiFirmwareVolumeInfoPpiGuid,\r
90 FirmwareVolmeInfoPpiNotifyCallback \r
91 }\r
92};\r
93\r
0c18794e 94EFI_PLATFORM_FIRMWARE_BLOB mMeasuredFvInfo[FixedPcdGet32 (PcdPeiCoreMaxFvSupported)];\r
95UINT32 mMeasuredFvIndex = 0;\r
96\r
97/**\r
98 Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result,\r
99 and build a GUIDed HOB recording the event which will be passed to the DXE phase and\r
100 added into the Event Log.\r
101\r
102 @param[in] PeiServices Describes the list of possible PEI Services.\r
103 @param[in] HashData Physical address of the start of the data buffer \r
104 to be hashed, extended, and logged.\r
105 @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData.\r
106 @param[in] TpmHandle TPM handle.\r
107 @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. \r
108 @param[in] NewEventData Pointer to the new event data. \r
109\r
110 @retval EFI_SUCCESS Operation completed successfully.\r
111 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
112 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
113\r
114**/\r
115EFI_STATUS\r
116HashLogExtendEvent (\r
117 IN EFI_PEI_SERVICES **PeiServices,\r
118 IN UINT8 *HashData,\r
119 IN UINTN HashDataLen,\r
120 IN TIS_TPM_HANDLE TpmHandle,\r
121 IN TCG_PCR_EVENT_HDR *NewEventHdr,\r
122 IN UINT8 *NewEventData\r
123 )\r
124{\r
125 EFI_STATUS Status;\r
126 VOID *HobData;\r
127\r
128 HobData = NULL;\r
129 if (HashDataLen != 0) {\r
130 Status = TpmCommHashAll (\r
131 HashData,\r
132 HashDataLen,\r
133 &NewEventHdr->Digest\r
134 );\r
135 ASSERT_EFI_ERROR (Status);\r
136 }\r
137\r
138 Status = TpmCommExtend (\r
139 PeiServices,\r
140 TpmHandle,\r
141 &NewEventHdr->Digest,\r
142 NewEventHdr->PCRIndex,\r
143 NULL\r
144 );\r
145 ASSERT_EFI_ERROR (Status);\r
146\r
147 HobData = BuildGuidHob (\r
148 &gTcgEventEntryHobGuid,\r
149 sizeof (*NewEventHdr) + NewEventHdr->EventSize\r
150 );\r
151 if (HobData == NULL) {\r
152 return EFI_OUT_OF_RESOURCES;\r
153 }\r
154\r
155 CopyMem (HobData, NewEventHdr, sizeof (*NewEventHdr));\r
156 HobData = (VOID *) ((UINT8*)HobData + sizeof (*NewEventHdr));\r
157 CopyMem (HobData, NewEventData, NewEventHdr->EventSize);\r
158 return EFI_SUCCESS;\r
159}\r
160\r
161/**\r
162 Measure CRTM version.\r
163\r
164 @param[in] PeiServices Describes the list of possible PEI Services.\r
165 @param[in] TpmHandle TPM handle.\r
166\r
167 @retval EFI_SUCCESS Operation completed successfully.\r
168 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
169 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
170\r
171**/\r
172EFI_STATUS\r
173EFIAPI\r
174MeasureCRTMVersion (\r
175 IN EFI_PEI_SERVICES **PeiServices,\r
176 IN TIS_TPM_HANDLE TpmHandle\r
177 )\r
178{\r
179 TCG_PCR_EVENT_HDR TcgEventHdr;\r
180\r
181 //\r
333a53ee 182 // Use FirmwareVersion string to represent CRTM version.\r
0c18794e 183 // OEMs should get real CRTM version string and measure it.\r
184 //\r
185\r
186 TcgEventHdr.PCRIndex = 0;\r
187 TcgEventHdr.EventType = EV_S_CRTM_VERSION;\r
333a53ee 188 TcgEventHdr.EventSize = StrSize((CHAR16*)PcdGetPtr (PcdFirmwareVersionString));\r
189\r
0c18794e 190 return HashLogExtendEvent (\r
191 PeiServices,\r
333a53ee 192 (UINT8*)PcdGetPtr (PcdFirmwareVersionString),\r
0c18794e 193 TcgEventHdr.EventSize,\r
194 TpmHandle,\r
195 &TcgEventHdr,\r
333a53ee 196 (UINT8*)PcdGetPtr (PcdFirmwareVersionString)\r
0c18794e 197 );\r
198}\r
199\r
200/**\r
201 Measure FV image. \r
202 Add it into the measured FV list after the FV is measured successfully. \r
203\r
204 @param[in] FvBase Base address of FV image.\r
205 @param[in] FvLength Length of FV image.\r
206\r
207 @retval EFI_SUCCESS Fv image is measured successfully \r
208 or it has been already measured.\r
209 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
210 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
211\r
212**/\r
213EFI_STATUS\r
214EFIAPI\r
215MeasureFvImage (\r
216 IN EFI_PHYSICAL_ADDRESS FvBase,\r
217 IN UINT64 FvLength\r
218 )\r
219{\r
220 UINT32 Index;\r
221 EFI_STATUS Status;\r
222 EFI_PLATFORM_FIRMWARE_BLOB FvBlob;\r
223 TCG_PCR_EVENT_HDR TcgEventHdr;\r
224 TIS_TPM_HANDLE TpmHandle;\r
225\r
226 TpmHandle = (TIS_TPM_HANDLE) (UINTN) TPM_BASE_ADDRESS;\r
227\r
228 //\r
229 // Check whether FV is in the measured FV list.\r
230 //\r
231 for (Index = 0; Index < mMeasuredFvIndex; Index ++) {\r
232 if (mMeasuredFvInfo[Index].BlobBase == FvBase) {\r
233 return EFI_SUCCESS;\r
234 }\r
235 }\r
236 \r
237 //\r
238 // Measure and record the FV to the TPM\r
239 //\r
240 FvBlob.BlobBase = FvBase;\r
241 FvBlob.BlobLength = FvLength;\r
242\r
243 DEBUG ((DEBUG_INFO, "The FV which is measured by TcgPei starts at: 0x%x\n", FvBlob.BlobBase));\r
244 DEBUG ((DEBUG_INFO, "The FV which is measured by TcgPei has the size: 0x%x\n", FvBlob.BlobLength));\r
245\r
246 TcgEventHdr.PCRIndex = 0;\r
247 TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB;\r
248 TcgEventHdr.EventSize = sizeof (FvBlob);\r
249\r
250 Status = HashLogExtendEvent (\r
251 (EFI_PEI_SERVICES **) GetPeiServicesTablePointer(),\r
252 (UINT8*) (UINTN) FvBlob.BlobBase,\r
253 (UINTN) FvBlob.BlobLength,\r
254 TpmHandle,\r
255 &TcgEventHdr,\r
256 (UINT8*) &FvBlob\r
257 );\r
258 ASSERT_EFI_ERROR (Status);\r
259\r
260 //\r
261 // Add new FV into the measured FV list.\r
262 //\r
263 ASSERT (mMeasuredFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported));\r
264 if (mMeasuredFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) {\r
265 mMeasuredFvInfo[mMeasuredFvIndex].BlobBase = FvBase;\r
266 mMeasuredFvInfo[mMeasuredFvIndex++].BlobLength = FvLength;\r
267 }\r
268\r
269 return Status;\r
270}\r
271\r
272/**\r
273 Measure main BIOS.\r
274\r
275 @param[in] PeiServices Describes the list of possible PEI Services.\r
276 @param[in] TpmHandle TPM handle.\r
277\r
278 @retval EFI_SUCCESS Operation completed successfully.\r
279 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
280 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
281\r
282**/\r
283EFI_STATUS\r
284EFIAPI\r
285MeasureMainBios (\r
286 IN EFI_PEI_SERVICES **PeiServices,\r
287 IN TIS_TPM_HANDLE TpmHandle\r
288 )\r
289{\r
290 EFI_STATUS Status;\r
291 UINT32 FvInstances;\r
292 EFI_PEI_FV_HANDLE VolumeHandle;\r
293 EFI_FV_INFO VolumeInfo;\r
294 EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;\r
295 \r
296 FvInstances = 0;\r
297 while (TRUE) {\r
298 //\r
299 // Traverse all firmware volume instances of Static Core Root of Trust for Measurement\r
300 // (S-CRTM), this firmware volume measure policy can be modified/enhanced by special\r
301 // platform for special CRTM TPM measuring.\r
302 //\r
303 Status = PeiServicesFfsFindNextVolume (FvInstances, &VolumeHandle);\r
304 if (EFI_ERROR (Status)) {\r
305 break;\r
306 }\r
307 \r
308 //\r
309 // Measure and record the firmware volume that is dispatched by PeiCore\r
310 //\r
311 Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo);\r
312 ASSERT_EFI_ERROR (Status);\r
313 //\r
314 // Locate the corresponding FV_PPI according to founded FV's format guid\r
315 //\r
316 Status = PeiServicesLocatePpi (\r
317 &VolumeInfo.FvFormat, \r
318 0, \r
319 NULL,\r
320 (VOID**)&FvPpi\r
321 );\r
322 if (!EFI_ERROR (Status)) {\r
323 MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) VolumeInfo.FvStart, VolumeInfo.FvSize);\r
324 }\r
325\r
326 FvInstances++;\r
327 }\r
328\r
329 return EFI_SUCCESS;\r
330}\r
331\r
332/**\r
333 Measure and record the Firmware Volum Information once FvInfoPPI install.\r
334\r
335 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
336 @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
337 @param[in] Ppi Address of the PPI that was installed.\r
338\r
339 @retval EFI_SUCCESS The FV Info is measured and recorded to TPM.\r
340 @return Others Fail to measure FV.\r
341\r
342**/\r
343EFI_STATUS\r
344EFIAPI\r
345FirmwareVolmeInfoPpiNotifyCallback (\r
346 IN EFI_PEI_SERVICES **PeiServices,\r
347 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
348 IN VOID *Ppi\r
349 )\r
350{\r
351 EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *Fv;\r
352 EFI_STATUS Status;\r
353 EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;\r
354\r
355 Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *) Ppi;\r
356\r
357 //\r
358 // The PEI Core can not dispatch or load files from memory mapped FVs that do not support FvPpi.\r
359 //\r
360 Status = PeiServicesLocatePpi (\r
361 &Fv->FvFormat, \r
362 0, \r
363 NULL,\r
364 (VOID**)&FvPpi\r
365 );\r
366 if (EFI_ERROR (Status)) {\r
367 return EFI_SUCCESS;\r
368 }\r
369 \r
370 //\r
371 // This is an FV from an FFS file, and the parent FV must have already been measured,\r
372 // No need to measure twice, so just returns\r
373 //\r
374 if (Fv->ParentFvName != NULL || Fv->ParentFileName != NULL ) {\r
375 return EFI_SUCCESS;\r
376 }\r
377\r
378 return MeasureFvImage ((EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo, Fv->FvInfoSize);\r
379}\r
380\r
381/**\r
5a500332 382 Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by corresponding PCDs.\r
383 And lock physical presence if needed.\r
0c18794e 384\r
385 @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation\r
386 @param[in] NotifyDescriptor Address of the notification descriptor data structure.\r
387 @param[in] Ppi Address of the PPI that was installed.\r
388\r
389 @retval EFI_SUCCESS Operation completed successfully.\r
390 @retval EFI_ABORTED physicalPresenceCMDEnable is locked.\r
391 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
392\r
393**/\r
394EFI_STATUS\r
395EFIAPI\r
396PhysicalPresencePpiNotifyCallback (\r
397 IN EFI_PEI_SERVICES **PeiServices,\r
398 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,\r
399 IN VOID *Ppi\r
400 )\r
401{\r
402 EFI_STATUS Status;\r
403 PEI_LOCK_PHYSICAL_PRESENCE_PPI *LockPhysicalPresencePpi;\r
404 BOOLEAN LifetimeLock;\r
405 BOOLEAN CmdEnable;\r
406 TIS_TPM_HANDLE TpmHandle;\r
5a500332 407 TPM_PHYSICAL_PRESENCE PhysicalPresenceValue;\r
0c18794e 408\r
409 TpmHandle = (TIS_TPM_HANDLE) (UINTN) TPM_BASE_ADDRESS;\r
0c18794e 410\r
5a500332 411 Status = TpmCommGetCapability (PeiServices, TpmHandle, NULL, &LifetimeLock, &CmdEnable);\r
412 if (EFI_ERROR (Status)) {\r
413 return Status;\r
0c18794e 414 }\r
415\r
416 //\r
5a500332 417 // 1. Set physicalPresenceLifetimeLock, physicalPresenceHWEnable and physicalPresenceCMDEnable bit by PCDs.\r
0c18794e 418 //\r
5a500332 419 if (PcdGetBool (PcdPhysicalPresenceLifetimeLock) && !LifetimeLock) {\r
420 //\r
421 // Lock TPM LifetimeLock is required, and LifetimeLock is not locked yet. \r
422 //\r
423 PhysicalPresenceValue = TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK;\r
424\r
425 if (PcdGetBool (PcdPhysicalPresenceCmdEnable)) {\r
426 PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_CMD_ENABLE;\r
427 CmdEnable = TRUE;\r
428 } else {\r
429 PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_CMD_DISABLE;\r
430 CmdEnable = FALSE;\r
431 }\r
0c18794e 432\r
5a500332 433 if (PcdGetBool (PcdPhysicalPresenceHwEnable)) {\r
434 PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_HW_ENABLE;\r
435 } else {\r
436 PhysicalPresenceValue |= TPM_PHYSICAL_PRESENCE_HW_DISABLE;\r
437 } \r
438 \r
439 Status = TpmCommPhysicalPresence (\r
440 PeiServices,\r
441 TpmHandle,\r
442 PhysicalPresenceValue\r
443 );\r
444 if (EFI_ERROR (Status)) {\r
445 return Status;\r
446 }\r
447 }\r
448 \r
449 //\r
450 // 2. Lock physical presence if it is required.\r
451 //\r
452 LockPhysicalPresencePpi = (PEI_LOCK_PHYSICAL_PRESENCE_PPI *) Ppi;\r
453 if (!LockPhysicalPresencePpi->LockPhysicalPresence ((CONST EFI_PEI_SERVICES**) PeiServices)) {\r
454 return EFI_SUCCESS;\r
0c18794e 455 }\r
456\r
457 if (!CmdEnable) {\r
458 if (LifetimeLock) {\r
459 //\r
460 // physicalPresenceCMDEnable is locked, can't change.\r
461 //\r
462 return EFI_ABORTED;\r
463 }\r
464\r
465 //\r
466 // Enable physical presence command\r
467 // It is necessary in order to lock physical presence\r
468 //\r
469 Status = TpmCommPhysicalPresence (\r
470 PeiServices,\r
471 TpmHandle,\r
472 TPM_PHYSICAL_PRESENCE_CMD_ENABLE\r
473 );\r
474 if (EFI_ERROR (Status)) {\r
475 return Status;\r
476 }\r
477 }\r
478\r
479 //\r
480 // Lock physical presence\r
481 // \r
482 Status = TpmCommPhysicalPresence (\r
483 PeiServices,\r
484 TpmHandle,\r
485 TPM_PHYSICAL_PRESENCE_LOCK\r
486 );\r
487 return Status;\r
488}\r
489\r
490/**\r
491 Check if TPM chip is activeated or not.\r
492\r
493 @param[in] PeiServices Describes the list of possible PEI Services.\r
494 @param[in] TpmHandle TPM handle.\r
495\r
496 @retval TRUE TPM is activated.\r
497 @retval FALSE TPM is deactivated.\r
498\r
499**/\r
500BOOLEAN\r
501EFIAPI\r
502IsTpmUsable (\r
503 IN EFI_PEI_SERVICES **PeiServices,\r
504 IN TIS_TPM_HANDLE TpmHandle\r
505 )\r
506{\r
507 EFI_STATUS Status;\r
508 BOOLEAN Deactivated;\r
509\r
510 Status = TpmCommGetCapability (PeiServices, TpmHandle, &Deactivated, NULL, NULL);\r
511 if (EFI_ERROR (Status)) {\r
512 return FALSE;\r
513 }\r
514 return (BOOLEAN)(!Deactivated); \r
515}\r
516\r
517/**\r
518 Do measurement after memory is ready.\r
519\r
520 @param[in] PeiServices Describes the list of possible PEI Services.\r
521\r
522 @retval EFI_SUCCESS Operation completed successfully.\r
523 @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event.\r
524 @retval EFI_DEVICE_ERROR The command was unsuccessful.\r
525\r
526**/\r
527EFI_STATUS\r
528EFIAPI\r
529PeimEntryMP (\r
530 IN EFI_PEI_SERVICES **PeiServices\r
531 )\r
532{\r
533 EFI_STATUS Status;\r
534 TIS_TPM_HANDLE TpmHandle;\r
535\r
536 TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;\r
537 Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle);\r
538 if (EFI_ERROR (Status)) {\r
539 return Status;\r
540 }\r
541\r
542 if (IsTpmUsable (PeiServices, TpmHandle)) {\r
543 Status = MeasureCRTMVersion (PeiServices, TpmHandle);\r
544 ASSERT_EFI_ERROR (Status);\r
545\r
546 Status = MeasureMainBios (PeiServices, TpmHandle);\r
547 } \r
548\r
549 //\r
550 // Post callbacks:\r
551 // 1). for the FvInfoPpi services to measure and record\r
552 // the additional Fvs to TPM\r
553 // 2). for the OperatorPresencePpi service to determine whether to \r
554 // lock the TPM\r
555 //\r
556 Status = PeiServicesNotifyPpi (&mNotifyList[0]);\r
557 ASSERT_EFI_ERROR (Status);\r
558\r
559 return Status;\r
560}\r
561\r
562/**\r
563 Entry point of this module.\r
564\r
565 @param[in] FileHandle Handle of the file being invoked.\r
566 @param[in] PeiServices Describes the list of possible PEI Services.\r
567\r
568 @return Status.\r
569\r
570**/\r
571EFI_STATUS\r
572EFIAPI\r
573PeimEntryMA (\r
574 IN EFI_PEI_FILE_HANDLE FileHandle,\r
575 IN CONST EFI_PEI_SERVICES **PeiServices\r
576 )\r
577{\r
578 EFI_STATUS Status;\r
579 EFI_BOOT_MODE BootMode;\r
580 TIS_TPM_HANDLE TpmHandle;\r
581\r
582 if (PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm)) {\r
583 return EFI_UNSUPPORTED;\r
584 }\r
585\r
055c829c 586 //\r
587 // Initialize TPM device\r
588 //\r
589 Status = PeiServicesGetBootMode (&BootMode);\r
590 ASSERT_EFI_ERROR (Status);\r
591\r
592 //\r
593 // In S3 path, skip shadow logic. no measurement is required\r
594 //\r
595 if (BootMode != BOOT_ON_S3_RESUME) {\r
596 Status = (**PeiServices).RegisterForShadow(FileHandle);\r
597 if (Status == EFI_ALREADY_STARTED) {\r
598 mImageInMemory = TRUE;\r
599 } else if (Status == EFI_NOT_FOUND) {\r
600 ASSERT_EFI_ERROR (Status);\r
601 }\r
0c18794e 602 }\r
603\r
604 if (!mImageInMemory) {\r
0c18794e 605 TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS;\r
606 Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle);\r
607 if (EFI_ERROR (Status)) {\r
608 DEBUG ((DEBUG_ERROR, "TPM not detected!\n"));\r
609 return Status;\r
610 }\r
611\r
612 Status = TpmCommStartup ((EFI_PEI_SERVICES**)PeiServices, TpmHandle, BootMode);\r
613 if (EFI_ERROR (Status) ) {\r
614 return Status;\r
615 }\r
616 Status = TpmCommContinueSelfTest ((EFI_PEI_SERVICES**)PeiServices, TpmHandle);\r
617 if (EFI_ERROR (Status)) {\r
618 return Status;\r
619 }\r
620 Status = PeiServicesInstallPpi (&mTpmInitializedPpiList);\r
621 ASSERT_EFI_ERROR (Status);\r
622 }\r
623\r
624 if (mImageInMemory) {\r
625 Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices);\r
626 if (EFI_ERROR (Status)) {\r
627 return Status;\r
628 }\r
629 }\r
630\r
631 return Status;\r
632}\r