summaryrefslogtreecommitdiff
path: root/Core/EM/TCG2/TisLib/TcgCommon.c
diff options
context:
space:
mode:
Diffstat (limited to 'Core/EM/TCG2/TisLib/TcgCommon.c')
-rw-r--r--Core/EM/TCG2/TisLib/TcgCommon.c808
1 files changed, 808 insertions, 0 deletions
diff --git a/Core/EM/TCG2/TisLib/TcgCommon.c b/Core/EM/TCG2/TisLib/TcgCommon.c
new file mode 100644
index 0000000..922514a
--- /dev/null
+++ b/Core/EM/TCG2/TisLib/TcgCommon.c
@@ -0,0 +1,808 @@
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TcgCommon.c 1 4/21/14 2:14p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:14p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TcgCommon.c $
+//
+// 1 4/21/14 2:14p Fredericko
+//
+// 3 3/17/14 3:04p Fredericko
+//
+// 2 3/11/14 6:00p Fredericko
+// [TAG] EIP151925
+// [Category] New Feature
+// [Description] Changes for TcgGeneric Regression Testing
+//
+// 1 10/08/13 11:58a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 10/03/13 12:34p Fredericko
+// Sha256 support policy update
+//
+// 1 7/10/13 5:50p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+// [Files] TisLib.cif
+// TisLib.mak
+// TcgTpm12.h
+// TpmLib.h
+// TcgCommon.h
+// ZTEICTcmOrdinals.h
+// TpmLib.c
+// TcgCommon.c
+// TisLib.sdl
+// sha1.h
+// INTTcgAcpi.h
+// TcgPc.h
+// TcmPc.h
+// TcgEfiTpm.h
+// TcgEFI12.h
+//
+// 9 3/19/12 6:13p Fredericko
+//
+// 8 3/29/11 12:24p Fredericko
+//
+// 7 3/28/11 12:12p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 6 5/19/10 5:07p Fredericko
+// Included File Header
+// Included File Revision History
+// Include \Updated AMI Function Headers
+// Code Beautification
+// EIP 37653
+//
+//*************************************************************************
+/*++
+
+ Copyright (c) 2005 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ TcgCommon.c
+
+ Abstract:
+
+ TCG Commands implemented for both PEI and DXE
+
+ --*/
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgCommon.c
+//
+// Description:
+// common TCG functions can be found here
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include "TcgCommon.h"
+#include <AmiDxeLib.h>
+#include "token.h"
+#include "Sha.h"
+
+#define TCG_EFI_HOB_LIST_GUID \
+ { 0x7739f24c, 0x93d7, 0x11d4, 0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d}
+
+#pragma pack (1)
+typedef struct _TCG_PCR_EVENT_HDR2 {
+ TCG_PCRINDEX PCRIndex;
+ TCG_EVENTTYPE EventType;
+} TCG_PCR_EVENT_HDR2;
+#pragma pack()
+
+UINT16
+__stdcall TcgCommonH2NS(
+ IN UINT16 Val )
+{
+ return TPM_H2NS( Val );
+}
+
+UINT32
+__stdcall TcgCommonH2NL(
+ IN UINT32 Val )
+{
+ return TPM_H2NL( Val );
+}
+
+
+
+VOID
+__stdcall TcgCommonCopyMem(
+ IN VOID *CallbackContext,
+ OUT VOID *Dest,
+ IN VOID *Src,
+ IN UINTN Size )
+{
+ CHAR8 *Destination8;
+ CHAR8 *Source8;
+
+ if ( Src < Dest )
+ {
+ Destination8 = (CHAR8*) Dest + Size - 1;
+ Source8 = (CHAR8*) Src + Size - 1;
+ while ( Size-- )
+ {
+ *(Destination8--) = *(Source8--);
+ }
+ }
+ else {
+ Destination8 = (CHAR8*) Dest;
+ Source8 = (CHAR8*) Src;
+ while ( Size-- )
+ {
+ *(Destination8++) = *(Source8++);
+ }
+ }
+}
+
+
+#pragma optimize("",off)
+UINTN FindNextLogLocation(TCG_PCR_EVENT_HDR *TcgLog, UINTN EventNum)
+{
+ TCG_PCR_EVENT_HDR2 *TcgLogNext = (TCG_PCR_EVENT_HDR2 *)TcgLog;
+ UINTN NextLoc =0;
+ UINT32 EventSize=0;
+ UINTN i=0;
+
+ if(EventNum == 0) return ((UINTN) TcgLogNext);
+ //return the location of the next log
+ for(i=0;i<EventNum;i++){
+ if(TcgLogNext == NULL)break;
+ if(TcgLogNext->PCRIndex > 24 || TcgLogNext->PCRIndex < 0)
+ break;
+
+ EventSize = *(UINT32 *)(((UINTN)TcgLogNext) + TPM_SHA1_160_HASH_LEN + sizeof(TCG_PCR_EVENT_HDR2));
+ NextLoc = (UINTN)(((UINTN)TcgLogNext)+ EventSize + sizeof(EventSize)+\
+ + TPM_SHA1_160_HASH_LEN + sizeof(TCG_PCR_EVENT_HDR2));
+
+ TcgLogNext = (TCG_PCR_EVENT_HDR2 *)NextLoc;
+ }
+ return ((UINTN) TcgLogNext);
+}
+#pragma optimize("",on)
+
+
+EFI_STATUS
+__stdcall TcgCommonLogEvent(
+ IN VOID *CallbackContext,
+ IN TCG_PCR_EVENT *EvtLog,
+ IN OUT UINT32 *TableSize,
+ IN UINT32 MaxSize,
+ IN TCG_PCR_EVENT *NewEntry,
+ IN UINT8 HashAlgorithm )
+{
+ UINT32 TempSize;
+
+ TempSize = sizeof(TCG_PCR_EVENT)-sizeof(NewEntry->Digest) - sizeof(UINT32)-1;
+ TcgCommonCopyMem( CallbackContext, EvtLog, NewEntry, TempSize );
+
+ if(HashAlgorithm == 0){
+ TcgCommonCopyMem( CallbackContext, (((UINT8 *)EvtLog) + TempSize), (UINT8 *)&NewEntry->Digest.digest, sizeof(NewEntry->Digest.digest) );
+ TempSize+=sizeof(NewEntry->Digest.digest);
+ TcgCommonCopyMem( CallbackContext, (((UINT8 *)EvtLog) + TempSize), (UINT8 *)&NewEntry->EventSize, sizeof(UINT32));
+ TempSize+=sizeof(UINT32);
+ TcgCommonCopyMem( CallbackContext, (((UINT8 *)EvtLog) + TempSize), NewEntry->Event, NewEntry->EventSize);
+ }
+ *TableSize += (TempSize + NewEntry->EventSize);
+ return EFI_SUCCESS;
+}
+
+
+
+EFI_STATUS
+__stdcall TcmCommonLogEvent(
+ IN VOID *CallbackContext,
+ IN TCM_PCR_EVENT *EvtLog,
+ IN OUT UINT32 *TableSize,
+ IN UINT32 MaxSize,
+ IN TCM_PCR_EVENT *NewEntry )
+{
+ UINT32 EvtSize;
+
+ EvtSize = NewEntry->EventSize + sizeof (*NewEntry) - 1;
+
+ if ( *TableSize + EvtSize > MaxSize )
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ EvtLog = (TCM_PCR_EVENT*)((UINT8*)EvtLog + *TableSize);
+ TcgCommonCopyMem( CallbackContext, EvtLog, NewEntry, EvtSize );
+
+ *TableSize += EvtSize;
+ return EFI_SUCCESS;
+}
+
+
+
+EFI_STATUS
+__stdcall TcgCommonSha1Start(
+ IN VOID *CallbackContext,
+ IN TCG_ALGORITHM_ID AlgId,
+ OUT UINT32 *MaxBytes )
+{
+ EFI_STATUS Status;
+ TPM_1_2_CMD_HEADER cmdSHA1Start = {
+ TPM_H2NS( TPM_TAG_RQU_COMMAND ),
+ TPM_H2NL( sizeof (TPM_1_2_CMD_HEADER)),
+ TPM_H2NL( TPM_ORD_SHA1Start )
+ };
+ TPM_1_2_RET_SHA1START retSHA1Start;
+ TPM_TRANSMIT_BUFFER InBuffer[1], OutBuffer[1];
+
+ if ( AlgId != TCG_ALG_SHA )
+ {
+ return EFI_UNSUPPORTED;
+ }
+
+ if(AutoSupportType()){
+ cmdSHA1Start.Ordinal = TPM_H2NL(TCM_ORD_SHA1Start);
+ }
+
+
+ InBuffer[0].Buffer = &cmdSHA1Start;
+ InBuffer[0].Size = sizeof (cmdSHA1Start);
+ OutBuffer[0].Buffer = &retSHA1Start;
+ OutBuffer[0].Size = sizeof (retSHA1Start);
+ Status = TCGPASSTHROUGH( CallbackContext, InBuffer, OutBuffer );
+
+ if ( EFI_ERROR( Status ) || retSHA1Start.Header.RetCode != 0 )
+ {
+ return Status;
+ }
+
+ if ( MaxBytes != NULL )
+ {
+ *MaxBytes = TcgCommonN2HL( retSHA1Start.MaxBytes );
+ }
+ return EFI_SUCCESS;
+}
+
+
+
+EFI_STATUS
+__stdcall TcgCommonSha1Update(
+ IN VOID *CallbackContext,
+ IN VOID *Data,
+ IN UINT32 DataLen,
+ IN UINT32 MaxBytes )
+{
+ EFI_STATUS Status;
+ TPM_1_2_CMD_SHA1UPDATE cmdSHA1Update;
+ TPM_1_2_RET_HEADER retSHA1Update;
+ TPM_TRANSMIT_BUFFER InBuffer[2], OutBuffer[1];
+ UINT8 *DataPtr;
+
+ if ( DataLen < 64 )
+ {
+ return EFI_SUCCESS;
+ }
+
+ cmdSHA1Update.Header.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ cmdSHA1Update.Header.Ordinal = TPM_H2NL( TPM_ORD_SHA1Update );
+
+ if(AutoSupportType()){
+ cmdSHA1Update.Header.Ordinal = TPM_H2NL(TCM_ORD_SHA1Update);
+ }
+
+ InBuffer[0].Buffer = &cmdSHA1Update;
+ InBuffer[0].Size = sizeof (cmdSHA1Update);
+ OutBuffer[0].Buffer = &retSHA1Update;
+ OutBuffer[0].Size = sizeof (retSHA1Update);
+
+ DataPtr = (UINT8*)Data;
+
+ do
+ {
+ InBuffer[1].Buffer = DataPtr;
+ InBuffer[1].Size = DataLen < MaxBytes ? DataLen : MaxBytes;
+
+ cmdSHA1Update.NumBytes = TcgCommonH2NL((UINT32)InBuffer[1].Size );
+ cmdSHA1Update.Header.ParamSize = TcgCommonH2NL(
+ (UINT32)InBuffer[1].Size + sizeof (cmdSHA1Update)
+ );
+
+ DataPtr += InBuffer[1].Size;
+ DataLen -= (UINT32)InBuffer[1].Size;
+
+ Status = TCGPASSTHROUGH( CallbackContext, InBuffer, OutBuffer );
+ } while ( !EFI_ERROR( Status ) && DataLen >= 64 );
+
+ return Status;
+}
+
+
+
+EFI_STATUS
+__stdcall TcgCommonSha1CompleteExtend(
+ IN VOID *CallbackContext,
+ IN VOID *Data,
+ IN UINT32 DataLen,
+ IN TPM_PCRINDEX PCRIndex,
+ OUT TCG_DIGEST *Digest,
+ OUT TCG_DIGEST *NewPCRValue )
+{
+ TPM_1_2_CMD_SHA1COMPLETEEXTEND cmdSHA1Complete;
+ TPM_1_2_RET_HEADER retSHA1Complete;
+ TPM_TRANSMIT_BUFFER InBuffer[2], OutBuffer[3];
+
+ if ( DataLen >= 64 )
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ cmdSHA1Complete.Header.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ cmdSHA1Complete.Header.ParamSize = TcgCommonH2NL(sizeof(cmdSHA1Complete)
+ + DataLen);
+ cmdSHA1Complete.Header.Ordinal = TPM_H2NL( TPM_ORD_SHA1CompleteExtend );
+
+ if(AutoSupportType()){
+ cmdSHA1Complete.Header.Ordinal = TPM_H2NL(TCM_ORD_SHA1CompleteExtend);
+ }
+
+ cmdSHA1Complete.PCRIndex = TcgCommonH2NL( PCRIndex );
+ cmdSHA1Complete.NumBytes = TcgCommonH2NL( DataLen );
+
+ InBuffer[0].Buffer = &cmdSHA1Complete;
+ InBuffer[0].Size = sizeof (cmdSHA1Complete);
+ InBuffer[1].Buffer = Data;
+ InBuffer[1].Size = DataLen;
+
+ OutBuffer[0].Buffer = &retSHA1Complete;
+ OutBuffer[0].Size = sizeof (retSHA1Complete);
+ OutBuffer[1].Buffer = Digest;
+ OutBuffer[1].Size = sizeof (*Digest);
+ OutBuffer[2].Buffer = NewPCRValue;
+ OutBuffer[2].Size = sizeof (*NewPCRValue);
+
+ return TCGPASSTHROUGH( CallbackContext, InBuffer, OutBuffer );
+}
+
+
+EFI_STATUS
+__stdcall TcmCommonSha1CompleteExtend(
+ IN VOID *CallbackContext,
+ IN VOID *Data,
+ IN UINT32 DataLen,
+ IN TPM_PCRINDEX PCRIndex,
+ OUT TCM_DIGEST *Digest,
+ OUT TCM_DIGEST *NewPCRValue )
+{
+ TPM_1_2_CMD_SHA1COMPLETEEXTEND cmdSHA1Complete;
+ TPM_1_2_RET_HEADER retSHA1Complete;
+ TPM_TRANSMIT_BUFFER InBuffer[2], OutBuffer[3];
+
+ if ( DataLen >= 64 )
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ cmdSHA1Complete.Header.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ cmdSHA1Complete.Header.ParamSize = TcgCommonH2NL(sizeof(cmdSHA1Complete)
+ + DataLen);
+ cmdSHA1Complete.Header.Ordinal = TPM_H2NL( TPM_ORD_SHA1CompleteExtend );
+
+ if(AutoSupportType()){
+ cmdSHA1Complete.Header.Ordinal = TPM_H2NL(TCM_ORD_SHA1CompleteExtend);
+ }
+
+ cmdSHA1Complete.PCRIndex = TcgCommonH2NL( PCRIndex );
+ cmdSHA1Complete.NumBytes = TcgCommonH2NL( DataLen );
+
+ InBuffer[0].Buffer = &cmdSHA1Complete;
+ InBuffer[0].Size = sizeof (cmdSHA1Complete);
+ InBuffer[1].Buffer = Data;
+ InBuffer[1].Size = DataLen;
+
+ OutBuffer[0].Buffer = &retSHA1Complete;
+ OutBuffer[0].Size = sizeof (retSHA1Complete);
+ OutBuffer[1].Buffer = Digest;
+ OutBuffer[1].Size = sizeof (*Digest);
+ OutBuffer[2].Buffer = NewPCRValue;
+ OutBuffer[2].Size = sizeof (*NewPCRValue);
+
+ return TCGPASSTHROUGH( CallbackContext, InBuffer, OutBuffer );
+}
+
+
+
+EFI_STATUS
+__stdcall TcmCommonExtend(
+ IN VOID *CallbackContext,
+ IN TPM_PCRINDEX PCRIndex,
+ IN TCM_DIGEST *Digest,
+ OUT TCM_DIGEST *NewPCRValue )
+{
+ TPM_1_2_CMD_HEADER cmdHeader;
+ TPM_1_2_RET_HEADER retHeader;
+ TPM_TRANSMIT_BUFFER InBuffer[3], OutBuffer[2];
+
+ InBuffer[0].Buffer = &cmdHeader;
+ InBuffer[0].Size = sizeof (cmdHeader);
+ InBuffer[1].Buffer = &PCRIndex;
+ InBuffer[1].Size = sizeof (PCRIndex);
+ InBuffer[2].Buffer = Digest->digest;
+ InBuffer[2].Size = sizeof (Digest->digest);
+
+ OutBuffer[0].Buffer = &retHeader;
+ OutBuffer[0].Size = sizeof (retHeader);
+ OutBuffer[1].Buffer = NewPCRValue->digest;
+ OutBuffer[1].Size = sizeof (NewPCRValue->digest);
+
+ cmdHeader.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ cmdHeader.ParamSize = TPM_H2NL(sizeof (cmdHeader)
+ + sizeof (PCRIndex) + sizeof (Digest->digest));
+
+ cmdHeader.Ordinal = TPM_H2NL( TCM_ORD_Extend );
+ PCRIndex = TcgCommonH2NL( PCRIndex );
+
+ return TCGPASSTHROUGH( CallbackContext, InBuffer, OutBuffer );
+}
+
+
+EFI_STATUS
+__stdcall Tcg20CommonExtend(
+ IN VOID *CallbackContext,
+ IN TPM_PCRINDEX PcrIndex,
+ IN TCG_DIGEST *Digest,
+ OUT TCG_DIGEST *NewPCRValue,
+ IN UINT8 DigestSize )
+{
+ TPM2_PCRExtend_cmd_t Cmd;
+ TPM2_PCRExtend_res_t Res;
+ TPM2_PCRExtend_res_t Tmpres;
+ UINT32 CmdSize;
+ UINT8 *Buffer;
+ UINT8 *AuthSizeOffset;
+ UINT8 *ResultBuf = NULL;
+ UINT32 ResultBufSize = 0;
+
+ TPM_TRANSMIT_BUFFER InBuffer[1], OutBuffer[1];
+
+ Cmd.Tag = (TPMI_ST_COMMAND_TAG)TPM_H2NS(TPM_ST_SESSIONS);
+ Cmd.CommandSize = TPM_H2NL(sizeof(Cmd));
+ Cmd.CommandCode = TPM_H2NL(TPM_CC_PCR_Extend);
+
+ Buffer = (UINT8 *)&Cmd.inputParameters;
+ *(UINT32 *)Buffer = TPM_H2NL(PcrIndex);
+ Buffer += sizeof(UINT32);
+
+ AuthSizeOffset = Buffer;
+ *(UINT32 *)Buffer = 0;
+ Buffer += sizeof(UINT32);
+
+ // pcr authHandle
+ *(UINT32 *)Buffer = TPM_H2NL(TPM_RS_PW);
+ Buffer += sizeof(UINT32);
+
+ // nonce = nullNonce
+ *(UINT16 *)Buffer = 0;
+ Buffer += sizeof(UINT16);
+
+ // sessionAttributes = 0
+ *(UINT8 *)Buffer = 0;
+ Buffer += sizeof(UINT8);
+
+ // auth = nullAuth
+ *(UINT16 *)Buffer = 0;
+ Buffer += sizeof(UINT16);
+
+ // authorizationSize
+ *(UINT32 *)AuthSizeOffset = TPM_H2NL((UINT32)(Buffer - AuthSizeOffset - sizeof(UINT32)));
+
+ //Digest count
+ *(UINT32 *)Buffer = TPM_H2NL(1);
+ Buffer += sizeof(UINT32);
+
+ //Hash alg
+ *(UINT16 *)Buffer = TPM_H2NS(TPM2_ALG_SHA1);
+ Buffer += sizeof(UINT16);
+
+ // Get the digest size based on Hash Alg
+ TcgCommonCopyMem(CallbackContext, Buffer, &Digest->digest, DigestSize);
+
+ Buffer += DigestSize;
+
+ CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
+ Cmd.CommandSize = TPM_H2NL(CmdSize);
+
+ ResultBuf = (UINT8 *) &Tmpres;
+ ResultBufSize = sizeof(Res);
+
+ InBuffer[0].Buffer = &Cmd;
+ InBuffer[0].Size = CmdSize;
+ OutBuffer[0].Buffer = ResultBuf;
+ OutBuffer[0].Size = ResultBufSize;
+
+ return TCGPASSTHROUGH( CallbackContext, InBuffer, OutBuffer );
+
+}
+
+
+
+
+EFI_STATUS
+__stdcall SHA1HashAll(
+ IN VOID *CallbackContext,
+ IN VOID *HashData,
+ IN UINTN HashDataLen,
+ OUT TCG_DIGEST *Digest
+)
+{
+ SHA1_CTX Sha1Ctx;
+ unsigned char DigestArray[20];
+
+ SHA1Init( &Sha1Ctx );
+
+ SHA1Update( &Sha1Ctx, HashData, (u32)HashDataLen );
+
+ SHA1Final( DigestArray, &Sha1Ctx );
+
+ TcgCommonCopyMem(
+ CallbackContext,
+ Digest->digest,
+ DigestArray,
+ sizeof (Digest->digest));
+
+ return EFI_SUCCESS;
+}
+
+
+/*
+EFI_STATUS
+__stdcall SHA2HashAll(
+ IN VOID *CallbackContext,
+ IN VOID *HashData,
+ IN UINTN HashDataLen,
+ OUT TCG_DIGEST *Digest
+)
+{
+ SHA2_CTX Sha2Ctx;
+ unsigned char DigestArray[32];
+
+ sha256_init( &Sha2Ctx );
+
+ sha256_process( &Sha2Ctx, HashData, (u32)HashDataLen );
+
+ sha256_done( &Sha2Ctx, DigestArray );
+
+ TcgCommonCopyMem(
+ CallbackContext,
+ Digest->digestSha2,
+ DigestArray,
+ sizeof (Digest->digestSha2));
+
+ return EFI_SUCCESS;
+}*/
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetHob
+//
+// Description: Find instance of a HOB type in a HOB list
+//
+// Input:
+// Type The HOB type to return.
+// HobStart The first HOB in the HOB list.
+//
+// Output:
+// Pointer to the Hob matching the type or NULL
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID* GetHob(
+ IN UINT16 Type,
+ IN VOID *HobStart )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = HobStart;
+
+ //
+ // Return input if not found
+ //
+ if ( HobStart == NULL )
+ {
+ return HobStart;
+ }
+
+ //
+ // Parse the HOB list, stop if end of list or matching type found.
+ //
+ while ( !END_OF_HOB_LIST( Hob ))
+ {
+ if ( Hob.Header->HobType == Type )
+ {
+ break;
+ }
+
+ Hob.Raw = GET_NEXT_HOB( Hob );
+ }
+
+ //
+ // Return input if not found
+ //
+ if ( END_OF_HOB_LIST( Hob ))
+ {
+ return HobStart;
+ }
+
+ return (VOID*)(Hob.Raw);
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CompareGuid
+//
+// Description: Compares two input GUIDs
+//
+// Input: Comparision status
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+BOOLEAN CompareGuid(
+ EFI_GUID *G1,
+ EFI_GUID *G2 )
+{
+ UINT32 *p1 = (UINT32*)G1, *p2 = (UINT32*)G2;
+ UINTN i;
+
+ for ( i = 0; i < 4; ++i )
+ {
+ if ( p1[i] != p2[i] )
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+ ;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: LocateATcgHob
+//
+// Description:
+//
+// Input:
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_GUID gEfiAmiTHobListGuid = TCG_EFI_HOB_LIST_GUID;
+VOID* LocateATcgHob(
+ UINTN NoTableEntries,
+ EFI_CONFIGURATION_TABLE *ConfigTable,
+ EFI_GUID *HOB_guid )
+{
+ VOID *HobStart;
+ VOID *PtrHob;
+
+ while ( NoTableEntries > 0 )
+ {
+ NoTableEntries--;
+
+ if ((!MemCmp(
+ &ConfigTable[NoTableEntries].VendorGuid,
+ &gEfiAmiTHobListGuid, sizeof(EFI_GUID)
+ )))
+ {
+ HobStart = ConfigTable[NoTableEntries].VendorTable;
+
+ if ( !EFI_ERROR(
+ GetNextGuidHob( &HobStart, HOB_guid, &PtrHob, NULL )
+ ))
+ {
+ return PtrHob;
+ }
+ }
+ }
+ return NULL;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetNextGuidHob
+//
+// Description: Find GUID HOB
+//
+// Input: HobStart A pointer to the start hob.
+// Guid A pointer to a guid.
+// Output:
+// Buffer A pointer to the buffer.
+// BufferSize Buffer size.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS GetNextGuidHob(
+ IN OUT VOID **HobStart,
+ IN EFI_GUID * Guid,
+ OUT VOID **Buffer,
+ OUT UINTN *BufferSize OPTIONAL )
+{
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS GuidHob;
+
+ if ( Buffer == NULL )
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for ( Status = EFI_NOT_FOUND; EFI_ERROR( Status );)
+ {
+ GuidHob.Raw = *HobStart;
+
+ if ( END_OF_HOB_LIST( GuidHob ))
+ {
+ return EFI_NOT_FOUND;
+ }
+
+ GuidHob.Raw = GetHob( EFI_HOB_TYPE_GUID_EXTENSION, *HobStart );
+
+ if ( GuidHob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION )
+ {
+ if ( CompareGuid( Guid, &GuidHob.Guid->Name ))
+ {
+ Status = EFI_SUCCESS;
+ *Buffer = (VOID*)((UINT8*)(&GuidHob.Guid->Name)
+ + sizeof (EFI_GUID));
+
+ if ( BufferSize != NULL )
+ {
+ *BufferSize = GuidHob.Header->HobLength
+ - sizeof (EFI_HOB_GUID_TYPE);
+ }
+ }
+ }
+
+ *HobStart = GET_NEXT_HOB( GuidHob );
+ }
+
+ return Status;
+}