summaryrefslogtreecommitdiff
path: root/Core/EM/TCG2/CRB_lib
diff options
context:
space:
mode:
Diffstat (limited to 'Core/EM/TCG2/CRB_lib')
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm20CRBLib.c171
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm20CRBLib.cif13
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm20CRBLib.h140
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm20CRBLib.mak87
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm20CRBLib.sdl61
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm2PttHciDeviceLib.c707
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm2PttHciDeviceLib.h170
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm2PttHciRegs.h99
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.cif12
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.mak52
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.sdl20
11 files changed, 1532 insertions, 0 deletions
diff --git a/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.c b/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.c
new file mode 100644
index 0000000..81a086d
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.c
@@ -0,0 +1,171 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/Tpm20CRBLib/Tpm20CRBLib.c 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/Tpm20CRBLib/Tpm20CRBLib.c $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 3 3/14/14 3:19p Fredericko
+//
+// 2 3/11/14 6:02p Fredericko
+// [TAG] EIP151925
+// [Category] New Feature
+// [Description] Changes for TcgGeneric Regression Testing
+//
+// 1 10/08/13 11:59a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 10/03/13 1:48p Fredericko
+//
+// 1 7/10/13 5:51p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name:
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <Efi.h>
+#include "Tpm20CRBLib.h"
+#include "AmiLib.h"
+#include <token.h>
+#include <Tpm20Includes\Tpm20.h>
+
+
+//Forward declare functions
+#if FTpmPlatformProfile == 1
+
+EFI_STATUS
+iTpmGetResponse (
+ IN OUT VOID *ResponseBuffer,
+ IN OUT UINT32 *ResponseSize
+ );
+
+EFI_STATUS
+iTpmSendCommand (
+ IN VOID *CommandBuffer,
+ IN UINT32 CommandSize
+ );
+
+EFI_STATUS
+CheckPspDevicePresent (
+ VOID
+ );
+
+#else
+
+EFI_STATUS
+EFIAPI
+PttHciReceive(
+ OUT UINT8 *FtpmBuffer,
+ OUT UINT32 *RespSize
+ );
+
+EFI_STATUS
+EFIAPI
+PttHciSend(
+ IN UINT8 *FtpmBuffer,
+ IN UINT32 DataLength
+ );
+
+BOOLEAN
+EFIAPI
+PttHciPresenceCheck();
+
+
+#endif
+
+BOOLEAN isTpm20CrbPresent()
+{
+ #if FTpmPlatformProfile == 1
+ if(!EFI_ERROR(CheckPspDevicePresent()))return TRUE;
+ return FALSE;
+ #else
+ return (PttHciPresenceCheck());
+ #endif
+}
+
+
+EFI_STATUS
+EFIAPI
+CrbSend(
+ IN UINT8 *InputBuffer,
+ IN UINT32 DataLength
+)
+{
+ #if FTpmPlatformProfile == 1
+ return(iTpmSendCommand(InputBuffer, DataLength));
+ #else
+ return (PttHciSend(InputBuffer, DataLength));
+ #endif
+}
+
+
+EFI_STATUS
+EFIAPI
+CrbReceive(
+ OUT UINT8 *OutBuffer,
+ OUT UINT32 *RespSize
+)
+{
+ #if FTpmPlatformProfile == 1
+ return(iTpmGetResponse(OutBuffer, RespSize));
+ #else
+ return (PttHciReceive(OutBuffer, RespSize));
+ #endif
+}
+
+EFI_STATUS
+EFIAPI
+CrbSubmitCmd(
+ IN UINT8 *InputBuffer,
+ IN UINT32 InputBufferSize,
+ OUT UINT8 *OutputBuffer,
+ OUT UINT32 *OutputBufferSize
+ )
+{
+ EFI_STATUS Status;
+
+ if(InputBuffer == NULL || OutputBuffer == NULL || InputBufferSize == 0){
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = CrbSend(InputBuffer, InputBufferSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ///
+ /// Receive the response data from TPM
+ ///
+ Status = CrbReceive(OutputBuffer, OutputBufferSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return Status;
+}
diff --git a/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.cif b/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.cif
new file mode 100644
index 0000000..5476df6
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "Tpm20CRBLib"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\CRB_lib"
+ RefName = "Tpm20CRBLib"
+[files]
+"Tpm20CRBLib.mak"
+"Tpm20CRBLib.c"
+"Tpm20CRBLib.h"
+"Tpm20CRBLib.sdl"
+[parts]
+"Tpm2PttLibrary"
+<endComponent>
diff --git a/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.h b/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.h
new file mode 100644
index 0000000..1182ab2
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.h
@@ -0,0 +1,140 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/Tpm20CRBLib/Tpm20CRBLib.h 2 6/14/14 12:24a Fredericko $
+//
+// $Revision: 2 $
+//
+// $Date: 6/14/14 12:24a $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/Tpm20CRBLib/Tpm20CRBLib.h $
+//
+// 2 6/14/14 12:24a Fredericko
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 11:59a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 9/16/13 1:51p Fredericko
+//
+// 1 7/10/13 5:51p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name:
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <Efi.h>
+#include <token.h>
+
+
+//Defines ACPI Interface for Control Resource Buffer Access
+#define TPM20H2NS(x) ((((x) << 8) | ((x) >> 8)) & 0xffff)
+#define TPM20H2NL(x) (TPM20H2NS ((x) >> 16) | (TPM20H2NS ((x) & 0xffff) << 16))
+
+#define CONTROL_AREA_RSVD 0x00
+#define CONTROL_AREA_ERROR 0x04
+#define CONTROL_AREA_CANCEL 0x08
+#define CONTROL_AREA_START 0x0C
+#define CONTROL_AREA_INT 0x10
+#define CONTROL_AREA_CMD_SZ 0x18
+#define CONTROL_AREA_CMD_BASE 0x1C
+#define CONTROL_AREA_RSP_SZ 0x24
+#define CONTROL_AREA_RSP_BASE 0x28
+
+//Timeouts
+#define TIMEOUT_A 500 ///< 500 microseconds
+#define TIMEOUT_B 500 * 1000 ///< 10ms (max command processing time in PK-TPM ca. 3ms)
+#define TIMEOUT_C 1000 * 1000 ///< 1s
+#define TIMEOUT_D 500 * 1000 ///< 500 ms
+#define POLLING_PERIOD 140 ///< Poll register every 140 microsecondss
+
+#define CRB_DEVICE_CMD 0x40
+#define CRB_DEVICE_STS 0x44
+
+#define TPM20_CRB_IDLE 0x02
+
+#define TPM20_MAX_COMMAND_SIZE 0x0F80
+#define StartStatusFieldSet 0x00000001
+
+#define TPM20_CRB_CMD_BASE 0x80
+#define TPM20_CRB_RSP_BASE 0x80
+
+#define TPM20_CRBSTATUS_START 0x00000001
+#define TPM20_CRB_ALL_CLEAR 0xFFFFFFFF
+
+#define RESPONSE_HEADER_SIZE 0x0a
+
+
+#pragma pack(1)
+
+typedef struct _STATUS_FIELD_
+{
+ UINT32 Rsvd;
+ UINT32 Error;
+ UINT32 Cancel;
+ UINT32 Start;
+}STATUS_FIELD;
+
+typedef struct _CONTROL_AREA_LAYOUT_
+{
+ STATUS_FIELD StatusFieled;
+ UINT64 IntCntrl;
+ UINT32 Cmd_Sz;
+ UINT64 Cmd_Addrs;
+ UINT32 Rsp_Sz;
+ UINT64 Rsp_Addrs;
+}CONTROL_AREA_LAYOUT;
+
+typedef struct _GENERIC_RESP_HDR_
+{
+ UINT16 Tag;
+ UINT32 RespSize;
+ UINT32 RespCode;
+}GENERIC_RESP_HDR;
+
+#pragma pack()
+
+
+EFI_STATUS
+EFIAPI
+CrbSubmitCmd(
+ IN UINT8 *InputBuffer,
+ IN UINT32 InputBufferSize,
+ OUT UINT8 *OutputBuffer,
+ OUT UINT32 *OutputBufferSize);
+
+BOOLEAN isTpm20CrbPresent();
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.mak b/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.mak
new file mode 100644
index 0000000..3fa1f66
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.mak
@@ -0,0 +1,87 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/Tpm20CRBLib/Tpm20CRBLib.mak 1 4/21/14 2:15p Fredericko $
+#
+# $Revision: 1 $
+#
+# $Date: 4/21/14 2:15p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/Tpm20CRBLib/Tpm20CRBLib.mak $
+#
+# 1 4/21/14 2:15p Fredericko
+#
+# 3 3/14/14 3:20p Fredericko
+#
+# 2 3/11/14 6:01p Fredericko
+# [TAG] EIP151925
+# [Category] New Feature
+# [Description] Changes for TcgGeneric Regression Testing
+#
+# 1 10/08/13 11:59a Fredericko
+# Initial Check-In for Tpm-Next module
+#
+# 2 10/03/13 1:48p Fredericko
+#
+# 1 7/10/13 5:50p Fredericko
+# [TAG] EIP120969
+# [Category] New Feature
+# [Description] TCG (TPM20)
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Tpm20CrbLib.mak
+#
+# Description: Make file for the Tpm20CrbLib component
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+Tpm20Crb_lib : $(BUILD_DIR)\Tpm20CRBLib.mak make_crb_lib make_crb_Peilib
+$(BUILD_DIR)\Tpm20CRBLib.lib: Tpm20Crb_lib
+$(BUILD_DIR)\IA32\Tpm20CRBLib.lib: Tpm20Crb_lib
+
+$(BUILD_DIR)\Tpm20CRBLib.mak : $(TPM20_CRBLIB)\Tpm20CrbLib.cif $(TPM20_CRBLIB)\Tpm20CrbLib.mak $(BUILD_RULES)
+ $(CIF2MAK) $(TPM20_CRBLIB)\Tpm20CrbLib.cif $(CIF2MAK_DEFAULTS)
+
+LIB_CFLAGS=$(CFLAGS)\
+ /I$(TPM20_CRBLIB)\
+ /I$(TCG_DIR)\Common\
+ /I$(TPM20_CRBLIB)\
+ /I$(TCG_DIR)\
+
+TCG_LIB_LITE_OBJS = \
+$(BUILD_DIR)\$(TPM20_CRBLIB)\Tpm20CrbLib.obj
+
+
+make_crb_lib: $(SHALIB) $(FWTPM20LIBx64)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\Tpm20CrbLib.mak all\
+ "CFLAGS=$(LIB_CFLAGS) "\
+ TYPE=LIBRARY
+
+make_crb_Peilib: $(SHALIBPEI) $(FWTPM20LIBx32)
+!IF "$(PROCESSOR)"=="x64"
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32\
+ /f $(BUILD_DIR)\Tpm20CrbLib.mak all\
+ "CFLAGS=$(LIB_CFLAGS) "\
+ TYPE=PEI_LIBRARY
+!ELSE
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\TisLib.mak all\
+ "CFLAGS=$(LIB_CFLAGS) "\
+ TYPE=PEI_LIBRARY
+!ENDIF \ No newline at end of file
diff --git a/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.sdl b/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.sdl
new file mode 100644
index 0000000..27c38ed
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.sdl
@@ -0,0 +1,61 @@
+TOKEN
+ Name = "TPM20CRB_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable TCG support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "TPM20_CRBLIB"
+ Help = "Tcg Directory"
+End
+
+MODULE
+ Help = "Includes TCG.mak to Project"
+ File = "Tpm20CRBLib.mak"
+End
+
+TOKEN
+ Name = "FTpmPlatformProfile"
+ Value = "0"
+ Help = "Set to 0 for Intel PTT and 1 for AMD PSP device"
+ TokenType = BOOLEAN
+ TargetMAK = Yes
+ TargetH = Yes
+END
+
+TOKEN
+ Name = "TPM20_CRBBASE"
+ Value = "0x0FED70000"
+ Help = "Start of Mem I/O region dedicated for TPM access"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FWTPM20LIBx32"
+ Value = " $(BUILD_DIR)\IA32\Tpm2PttLibrary.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "x64_BUILD" "=" "1"
+End
+
+TOKEN
+ Name = "FWTPM20LIBx32"
+ Value = " $(BUILD_DIR)\Tpm2PttLibrary.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "x64_BUILD" "=" "0"
+End
+
+TOKEN
+ Name = "FWTPM20LIBx64"
+ Value = "$(BUILD_DIR)\Tpm2PttLibrary.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
diff --git a/Core/EM/TCG2/CRB_lib/Tpm2PttHciDeviceLib.c b/Core/EM/TCG2/CRB_lib/Tpm2PttHciDeviceLib.c
new file mode 100644
index 0000000..edf31ac
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm2PttHciDeviceLib.c
@@ -0,0 +1,707 @@
+/** @file
+ Implements Platform Trust Technology (FTPM) HCI Device Library.
+
+@copyright
+ Copyright (c) 2012 - 2013 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.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include <efi.h>
+#include <AmiLib.h>
+#include "Tpm2PttHciRegs.h"
+#include "Tpm2PttHciDeviceLib.h"
+#include <Tpm20Includes\Tpm20.h>
+//#include <EfiCommonLib.h>
+
+
+#ifndef ASSERT
+#define ASSERT(Condition) if(!(Condition)) { \
+ EFI_DEADLOOP() \
+ }
+#endif
+
+#define MmioAddress(BaseAddr, Register) \
+ ( (UINTN)BaseAddr + (UINTN)(Register) )
+
+#define Mmio32Ptr(BaseAddr, Register) \
+ ( (volatile UINT32 *)MmioAddress(BaseAddr, Register) )
+
+#define Mmio32(BaseAddr, Register) \
+ *Mmio32Ptr(BaseAddr, Register)
+
+#define MmioRead32(Addr) \
+ Mmio32(Addr, 0)
+
+#define MmioWrite32(Addr, Value) \
+ (Mmio32(Addr, 0) = (UINT32)Value)
+
+#define TPM_H2NS( x ) \
+ (((UINT16)(x) << 8) | ((UINT16)(x) >> 8))
+#define TPM_H2NL( x ) \
+ (UINT32)((((UINT32)(x)) >> 24) \
+ | (((x) >> 8) & 0xff00) \
+ | ((x) << 24) \
+ | (((x) & 0xff00) << 8))
+
+#define TPM_N2HS( x ) TPM_H2NS( x )
+#define TPM_N2HL( x ) TPM_H2NL( x )
+
+#pragma pack (push, 1)
+typedef struct {
+ TPM_ST tag;
+ UINT32 paramSize;
+ TPM_RC responseCode;
+} TPM2_RESPONSE_HEADER;
+#pragma pack (pop)
+
+#define EFI_MAX_ADDRESS 0xFFFFFFFFFFFFFFFF
+
+
+#ifdef INT_EFI_DEBUG
+/**
+ Prints command or response buffer for debugging purposes.
+
+ @param[in] Buffer Buffer to print.
+ @param[in] BufferSize Buffer data length.
+**/
+VOID
+EFIAPI
+PttHciPrintBuffer(IN UINT8 *Buffer, IN UINT32 BufferSize)
+{
+ UINT32 Index;
+
+ DEBUG ((EFI_D_INFO, "Buffer Address: 0x%08x, Size: 0x%08x, Value:\n", Buffer, BufferSize));
+ for(Index = 0; Index < BufferSize; Index++){
+ DEBUG ((EFI_D_INFO, "%02x ", *(Buffer + Index)));
+ if((Index+1) % 16 == 0) DEBUG ((EFI_D_INFO, "\n"));
+ }
+ DEBUG ((EFI_D_INFO, "\n"));
+}
+#endif // EFI_DEBUG
+
+
+VOID MicroSecDelay (
+ UINTN Delay
+)
+{
+ UINTN Counter, i;
+ UINT32 Data32, PrevData;
+ UINTN Remainder;
+
+ Counter = (UINTN)Div64 ((UINT64)(Delay * 10), 3, &Remainder);
+ if (Remainder != 0) {
+ Counter++;
+ }
+ //
+ // Call WaitForTick for Counter + 1 ticks to try to guarantee Counter tick
+ // periods, thus attempting to ensure Microseconds of stall time.
+ //
+ if (Counter != 0) {
+
+ PrevData = IoRead32(PM_BASE_ADDRESS + 8);
+ for (i = 0; i < Counter; ) {
+ Data32 = IoRead32(PM_BASE_ADDRESS + 8);
+ if (Data32 < PrevData) { // Reset if there is a overlap
+ PrevData=Data32;
+ continue;
+ }
+ i += (Data32 - PrevData);
+ PrevData = Data32;
+ }
+ }
+ return;
+}
+
+
+/**
+ Copy data from the MMIO region to system memory by using 32-bit access.
+
+ Copy data from the MMIO region specified by starting address StartAddress
+ to system memory specified by Buffer by using 32-bit access. The total
+ number of byte to be copied is specified by Length. Buffer is returned.
+
+ If StartAddress is not aligned on a 32-bit boundary, then ASSERT().
+
+ If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ If Length is not aligned on a 32-bit boundary, then ASSERT().
+ If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param StartAddress The starting address for the MMIO region to be copied from.
+ @param Length The size, in bytes, of Buffer.
+ @param Buffer The pointer to a system memory buffer receiving the data read.
+
+ @return Buffer
+**/
+UINT32 *
+EFIAPI
+MmioReadBuffer32 (
+ IN UINTN StartAddress,
+ IN UINTN Length,
+ OUT UINT32 *Buffer
+ )
+{
+ UINT32 *ReturnBuffer;
+
+ ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);
+
+ ASSERT ((Length - 1) <= (EFI_MAX_ADDRESS - StartAddress));
+ ASSERT ((Length - 1) <= (EFI_MAX_ADDRESS - (UINTN) Buffer));
+
+ ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);
+ ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);
+
+ ReturnBuffer = Buffer;
+
+ while (Length != 0) {
+ *(Buffer++) = MmioRead32 (StartAddress);
+ StartAddress += sizeof (UINT32);
+ Length -= sizeof (UINT32);
+ }
+
+ return ReturnBuffer;
+}
+
+/**
+ Copy data from system memory to the MMIO region by using 32-bit access.
+
+ Copy data from system memory specified by Buffer to the MMIO region specified
+ by starting address StartAddress by using 32-bit access. The total number
+ of byte to be copied is specified by Length. Buffer is returned.
+
+ If StartAddress is not aligned on a 32-bit boundary, then ASSERT().
+
+ If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().
+ If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().
+
+ If Length is not aligned on a 32-bit boundary, then ASSERT().
+
+ If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param StartAddress The starting address for the MMIO region to be copied to.
+ @param Length The size, in bytes, of Buffer.
+ @param Buffer The pointer to a system memory buffer containing the data to write.
+
+ @return Buffer
+**/
+UINT32 *
+EFIAPI
+MmioWriteBuffer32 (
+ IN UINTN StartAddress,
+ IN UINTN Length,
+ IN CONST UINT32 *Buffer
+ )
+{
+ UINT32 *ReturnBuffer;
+
+ ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);
+
+ ASSERT ((Length - 1) <= (EFI_MAX_ADDRESS - StartAddress));
+ ASSERT ((Length - 1) <= (EFI_MAX_ADDRESS - (UINTN) Buffer));
+
+ ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);
+ ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);
+
+ ReturnBuffer = (UINT32 *) Buffer;
+
+ while (Length != 0) {
+ MmioWrite32 (StartAddress, *(Buffer++));
+
+ StartAddress += sizeof (UINT32);
+ Length -= sizeof (UINT32);
+ }
+
+ return ReturnBuffer;
+}
+
+/**
+ Checks whether FTPM is enabled (FTPM_STS::FTPM_EN).
+
+ @retval TRUE FTPM is enabled.
+ @retval FALSE FTPM is disabled. All LT writes will be dropped.
+ All LT reads will be returned with read data value of all 0’s.
+ The bit can only be written once per ME power cycle.
+
+**/
+BOOLEAN
+EFIAPI
+PttHciPresenceCheck (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: PttHciPresenceCheck start\n"));
+
+ DEBUG ((EFI_D_INFO, "Check FTPM_STS - ENABLED bit (@ 0x%08x)\n", (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS)));
+#endif
+ Status = PttHciWaitRegisterBits(
+ (EFI_PHYSICAL_ADDRESS)(UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS),
+ B_PTT_HCI_STS_ENABLED,
+ V_PTT_HCI_IGNORE_BITS,
+ PTT_HCI_TIMEOUT_A
+ );
+ if(Status == EFI_SUCCESS){
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Checks whether PTT is Ready
+
+ @retval TRUE PTT is ready.
+ @retval FALSE PTT is not ready
+
+**/
+BOOLEAN
+EFIAPI
+PttHciReadyCheck (
+ VOID
+ )
+{
+ UINT32 RegRead;
+
+ RegRead = MmioRead32 ((UINTN) ( R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS ));
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "Check PTT_STS - READY bit (@ 0x%08x)\n", RegRead));
+#endif
+
+ if(( B_PTT_HCI_STS_READY & RegRead) != 0){
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Checks whether TPM2_Startup command has been executed (FTPM_STS::STARTUP_EXEC).
+ If command was executed, it should not be redundantly issued again.
+
+ @retval TRUE Startup command executed already.
+ @retval FALSE Startup command not executed yet.
+
+**/
+BOOLEAN
+EFIAPI
+PttHciStartupExecuted (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: PttHciStartupExecuted start\n"));
+ DEBUG ((EFI_D_INFO, "Check FTPM_STS - STARTUP_EXECECUTED bit (@ 0x%08x)\n", (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS)));
+#endif
+ Status = PttHciWaitRegisterBits(
+ (EFI_PHYSICAL_ADDRESS)(UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS),
+ B_PTT_HCI_STS_STARTUP_EXEC,
+ V_PTT_HCI_IGNORE_BITS,
+ PTT_HCI_TIMEOUT_A
+ );
+ if(Status == EFI_SUCCESS){
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Sets FTPM_CMD and CA_START register to a defined value to indicate that a command is
+ available for processing.
+ Any host write to this register shall result in an interrupt to the ME firmware.
+
+ @retval EFI_SUCCESS Register successfully written.
+ @retval TBD
+
+**/
+EFI_STATUS
+EFIAPI
+PttHciRequestCommandExec (
+ VOID
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: PttHciRequestCommandExec start\n"));
+
+ DEBUG ((EFI_D_INFO, "Command ready for processing - write 0x%08x to FTPM_CA_START register (@ 0x%08x)\n",
+ V_PTT_HCI_COMMAND_AVAILABLE_START,
+ (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_START)));
+#endif
+ MmioWrite32((UINTN)R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_START, V_PTT_HCI_COMMAND_AVAILABLE_START);
+
+ ///
+ /// Write 0x1 to HCI CMD register to indicate that a command is available for processing
+ ///
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "Command ready for processing - write 0x%08x to FTPM_CMD register (@ 0x%08x)\n",
+ V_PTT_HCI_COMMAND_AVAILABLE_CMD,
+ (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CMD)));
+#endif
+ MmioWrite32((UINTN)R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CMD, V_PTT_HCI_COMMAND_AVAILABLE_CMD);
+
+ return Status;
+}
+
+/**
+ Checks whether the value of a FTPM register satisfies the input BIT setting.
+
+ @param[in] Register Address port of register to be checked.
+ @param[in] BitSet Check these data bits are set.
+ @param[in] BitClear Check these data bits are clear.
+ @param[in] TimeOut The max wait time (unit MicroSecond) when checking register.
+
+ @retval EFI_SUCCESS The register satisfies the check bit.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+**/
+EFI_STATUS
+EFIAPI
+PttHciWaitRegisterBits(
+ IN EFI_PHYSICAL_ADDRESS RegAddress,
+ IN UINT32 BitSet,
+ IN UINT32 BitClear,
+ IN UINT32 TimeOut
+ )
+{
+ UINT32 RegRead;
+ UINT32 WaitTime;
+
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: PttHciWaitRegisterBits start\n"));
+#endif
+
+ for (WaitTime = 0; WaitTime < TimeOut; WaitTime += PTT_HCI_POLLING_PERIOD){
+ RegRead = MmioRead32 ((UINTN)RegAddress);
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "RegRead: 0x%08x, BitSetMask: 0x%08x, BitClearMask: 0x%08x, WaitTime: %d (microsec)\n", RegRead, BitSet, BitClear, WaitTime));
+#endif
+
+ if (RegRead == 0xFFFFFFFF)
+ continue;
+
+ if ((RegRead & BitSet) == BitSet && (RegRead & BitClear) == 0) {
+ return EFI_SUCCESS;
+ }
+// MicroSecondDelay (PTT_HCI_POLLING_PERIOD); Override
+ MicroSecDelay(PTT_HCI_POLLING_PERIOD);
+ }
+ return EFI_TIMEOUT;
+}
+
+/**
+ Sends command to FTPM for execution.
+
+ @param[in] FtpmBuffer Buffer for TPM command data.
+ @param[in] DataLength TPM command data length.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+**/
+EFI_STATUS
+EFIAPI
+PttHciSend(
+ IN UINT8 *FtpmBuffer,
+ IN UINT32 DataLength
+ )
+{
+ EFI_STATUS Status;
+
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: PttHciSend start\n"));
+#endif
+ Status = PttHciWaitRegisterBits(
+ (EFI_PHYSICAL_ADDRESS)(UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_START),
+ V_PTT_HCI_IGNORE_BITS,
+ V_PTT_HCI_START_CLEAR,
+ PTT_HCI_TIMEOUT_A
+ );
+
+ if(EFI_ERROR (Status)){
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_ERROR, "FTPM_CA_START register not clear - TPM2 command cannot be sent! EFI_ERROR = %r\n", Status));
+#endif
+ return EFI_NOT_READY;
+ }
+ ///
+ /// Align command size to dword before writing to FTPM_CRB
+ ///
+ if(DataLength % 4 != 0){
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "Alignment: DataLength change from %d ", DataLength));
+#endif
+ DataLength += (4 - (DataLength % 4));
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "to %d\n", DataLength));
+#endif
+ }
+
+ MmioWriteBuffer32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB), (UINTN)DataLength, (UINT32*)FtpmBuffer);
+
+ ///
+ /// FTPM_CA_CMD - the physical address to which the TPM 2.0 driver will write the command to execute
+ ///
+ MmioWrite32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_CMD), R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB);
+ MmioWrite32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_CMD_SZ), S_PTT_HCI_CRB_LENGTH);
+
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "FTPM_CA_CMD (@ 0x%08x) written, value = 0x%08x\n",
+ (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_CMD),
+ R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB));
+ DEBUG ((EFI_D_INFO, "FTPM_CA_CMD_SZ (@ 0x%08x) written, value = 0x%08x\n",
+ (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_CMD_SZ), DataLength));
+#endif
+
+ ///
+ /// Set FTPM_CMD and FTPM_CA_START registers to indicate TPM command ready for execution
+ ///
+ Status = PttHciRequestCommandExec();
+#ifdef INT_EFI_DEBUG
+ if(Status == EFI_SUCCESS){
+ DEBUG ((EFI_D_INFO, "FTPM_CMD register written - TPM2 command available for processing\n"));
+ }
+#endif
+
+ return Status;
+}
+
+/**
+ Receives response data of last command from FTPM.
+
+ @param[out] FtpmBuffer Buffer for response data.
+ @param[out] RespSize Response data length.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+ @retval EFI_DEVICE_ERROR Unexpected device status.
+ @retval EFI_BUFFER_TOO_SMALL Response data is too long.
+**/
+EFI_STATUS
+EFIAPI
+PttHciReceive(
+ OUT UINT8 *FtpmBuffer,
+ OUT UINT32 *RespSize
+ )
+{
+ EFI_STATUS Status;
+ UINT16 Data16;
+ UINT32 Data32;
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: PttHciReceive start\n"));
+#endif
+
+ ///
+ /// Wait for the command completion - poll FTPM_CA_START clear
+ ///
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: Check Start status (FTPM_CA_START)\n"));
+#endif
+ Status = PttHciWaitRegisterBits(
+ (EFI_PHYSICAL_ADDRESS)(UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_START),
+ V_PTT_HCI_IGNORE_BITS,
+ V_PTT_HCI_START_CLEAR,
+ PTT_HCI_TIMEOUT_D
+ );
+ if(EFI_ERROR (Status)){
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_ERROR, "FTPM_CA_START register not clear - TPM2 response cannot be read! EFI_ERROR = %r\n", Status));
+#endif
+ goto Exit;
+ }
+
+ ///
+ /// Check for error condition - FTPM_CA_ERROR
+ ///
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: Check Error status (FTPM_CA_ERROR)\n"));
+#endif
+ Status = PttHciWaitRegisterBits(
+ (EFI_PHYSICAL_ADDRESS)(UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_ERROR),
+ V_PTT_HCI_IGNORE_BITS,
+ V_PTT_HCI_ALL_BITS_CLEAR,
+ PTT_HCI_TIMEOUT_A
+ );
+ if(EFI_ERROR (Status)){
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_ERROR, "FTPM_CA_ERROR register set - TPM2 response cannot be provided! EFI_ERROR = %r\n", Status));
+#endif
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "FTPM_CA_START register clear - TPM2 command processing completed - ready to read\n"));
+#endif
+
+ ///
+ /// Read the response data header
+ ///
+ MmioReadBuffer32((UINTN)R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB, PTT_HCI_RESPONSE_HEADER_SIZE, (UINT32*)FtpmBuffer);
+
+ ///
+ /// Check the reponse data header (tag, parasize and returncode)
+ ///
+ MemCpy (&Data16, FtpmBuffer, sizeof (UINT16));
+
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "TPM2_RESPONSE_HEADER.tag = 0x%04x\n", TPM_H2NS(Data16)));
+#endif
+
+ ///
+ /// TPM Rev 2.0 Part 2 - 6.9 TPM_ST (Structure Tags)
+ /// TPM_ST_RSP_COMMAND - Used in a response that has an error in the tag.
+ ///
+ if (TPM_H2NS(Data16) == TPM_ST_RSP_COMMAND) {
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_ERROR, "TPM2_RESPONSE_HEADER.tag = TPM_ST_RSP_COMMAND - Error in response!\n"));
+#endif
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ MemCpy(&Data32, (FtpmBuffer + 2), sizeof(UINT32));
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "TPM2_RESPONSE_HEADER.paramSize = 0x%08x\n", TPM_H2NL(Data32)));
+#endif
+
+ *RespSize = TPM_H2NL(Data32);
+
+ if(*RespSize == sizeof(TPM2_RESPONSE_HEADER)) {
+ Status = EFI_SUCCESS;
+ goto Exit;
+ }
+ if(*RespSize < sizeof(TPM2_RESPONSE_HEADER)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+ if(*RespSize > S_PTT_HCI_CRB_LENGTH) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Exit;
+ }
+
+ ///
+ /// Align command size to dword before writing to FTPM_CRB
+ ///
+ if(*RespSize % 4 != 0){
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "Alignment: RespSize change from %d ", *RespSize));
+#endif
+ *RespSize += (4 - (*RespSize % 4));
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "to %d\n", *RespSize));
+#endif
+ }
+
+ ///
+ /// Reading the entire response data
+ ///
+ MmioReadBuffer32((UINTN)R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB, *RespSize, (UINT32*)FtpmBuffer);
+
+ Exit:
+ if(!EFI_ERROR(Status)){
+ ///
+ /// FTPM_CA_CMD - the physical address from which the TPM 2.0 driver will read command responses
+ ///
+ MmioWrite32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_RSP), R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB);
+ MmioWrite32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_RSP_SZ),S_PTT_HCI_CRB_LENGTH);
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "FTPM_CA_RSP (@ 0x%08x) written, value = 0x%08x\n",
+ (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_RSP),
+ (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB)));
+ DEBUG ((EFI_D_INFO, "FTPM_CA_RSP_SZ (@ 0x%08x) written, value = 0x%08x\n",
+ (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_RSP_SZ), *RespSize));
+#endif
+ }
+
+ return Status;
+}
+
+/**
+ Sends formatted command to FTPM for execution and returns formatted response data.
+
+ @param[in] InputBuffer Buffer for the input data.
+ @param[in] InputBufferSize Size of the input buffer.
+ @param[out] ReturnBuffer Buffer for the output data.
+ @param[out] ReturnBufferSize Size of the output buffer.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+**/
+EFI_STATUS
+EFIAPI
+PttHciSubmitCommand(
+ IN UINT8 *InputBuffer,
+ IN UINT32 InputBufferSize,
+ OUT UINT8 *ReturnBuffer,
+ OUT UINT32 *ReturnBufferSize
+ )
+{
+ EFI_STATUS Status;
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: PttHciSubmitCommand start\n"));
+#endif
+
+ if(!PttHciReadyCheck()){
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_ERROR, "PTT device not ready. \n"));
+#endif
+ return EFI_NOT_READY;
+ }
+
+ if(InputBuffer == NULL || ReturnBuffer == NULL || InputBufferSize == 0){
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_ERROR, "Buffer == NULL or InputBufferSize == 0\n"));
+#endif
+ return EFI_INVALID_PARAMETER;
+ }
+
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: Command Buffer dump\n"));
+#endif
+
+ ///
+ /// Send the command to TPM
+ ///
+ Status = PttHciSend(InputBuffer, InputBufferSize);
+ if (EFI_ERROR (Status)) {
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_ERROR, "FTpmHciSend EFI_ERROR = %r\n", Status));
+#endif
+ return Status;
+ }
+
+ ///
+ /// Receive the response data from TPM
+ ///
+ Status = PttHciReceive(ReturnBuffer, ReturnBufferSize);
+ if (EFI_ERROR (Status)) {
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_ERROR, "FTpmHciReceive EFI_ERROR = %r\n", Status));
+#endif
+ return Status;
+ }
+
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: Response Buffer dump\n"));
+#endif
+
+ return Status;
+}
+
diff --git a/Core/EM/TCG2/CRB_lib/Tpm2PttHciDeviceLib.h b/Core/EM/TCG2/CRB_lib/Tpm2PttHciDeviceLib.h
new file mode 100644
index 0000000..bcb204f
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm2PttHciDeviceLib.h
@@ -0,0 +1,170 @@
+/** @file
+ Platform Trust Technology (FTPM) HCI Device Library
+
+@copyright
+ Copyright (c) 2012 -2013 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.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#ifndef _TPM2_PTT_HCI_DEVICE_LIB_H_
+#define _TPM2_PTT_HCI_DEVICE_LIB_H_
+
+#include <Efi.h>
+
+///
+/// Default Timeout values
+///
+#define PTT_HCI_TIMEOUT_A 500 ///< 500 microseconds
+// AMI-Core Override for PTT +
+//#define PTT_HCI_TIMEOUT_B 10 * 1000 ///< 10ms (max command processing time in PK-TPM ca. 3ms)
+#define PTT_HCI_TIMEOUT_B 500 * 1000 ///< 10ms (max command processing time in PK-TPM ca. 3ms)
+// AMI-Core Override for PTT -
+#define PTT_HCI_TIMEOUT_C 1000 * 1000 ///< 1s
+#define PTT_HCI_TIMEOUT_D 500 * 1000 ///< 500 ms
+#define PTT_HCI_POLLING_PERIOD 140 ///< Poll register every 140 microsecondss
+
+/// TPM2_RESPONSE_HEADER size (10B) aligned to dword
+#define PTT_HCI_RESPONSE_HEADER_SIZE 12 ///< 12B
+
+/**
+ Checks whether FTPM is enabled (FTPM_STS::FTPM_EN).
+
+ @retval TRUE FTPM is enabled.
+ @retval FALSE FTPM is disabled. All LT writes will be dropped.
+ All LT reads will be returned with read data value of all 0’s.
+ The bit can only be written once per ME power cycle.
+**/
+BOOLEAN
+EFIAPI
+PttHciPresenceCheck (
+ VOID
+ );
+
+/**
+ Checks whether TPM2_Startup command has been executed (FTPM_STS::STARTUP_EXEC).
+ If command was executed, it should not be redundantly issued again.
+
+ @retval TRUE Startup command executed already.
+ @retval FALSE Startup command not executed yet.
+**/
+BOOLEAN
+EFIAPI
+PttHciStartupExecuted (
+ VOID
+ );
+
+/**
+ Sets FTPM_CMD and CA_START register to a defined value to indicate that a command is
+ available for processing.
+ Any host write to this register shall result in an interrupt to the ME firmware.
+
+ @retval EFI_SUCCESS Register successfully written.
+ @retval TBD
+**/
+EFI_STATUS
+EFIAPI
+PttHciRequestCommandExec (
+ VOID
+ );
+
+/**
+ Checks whether the value of a FTPM register satisfies the input BIT setting.
+
+ @param[in] Register Address port of register to be checked.
+ @param[in] BitSet Check these data bits are set.
+ @param[in] BitClear Check these data bits are clear.
+ @param[in] TimeOut The max wait time (unit MicroSecond) when checking register.
+
+ @retval EFI_SUCCESS The register satisfies the check bit.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+**/
+EFI_STATUS
+EFIAPI
+PttHciWaitRegisterBits(
+ IN EFI_PHYSICAL_ADDRESS RegAddress,
+ IN UINT32 BitSet,
+ IN UINT32 BitClear,
+ IN UINT32 TimeOut
+ );
+
+/**
+ Sends command to FTPM for execution.
+
+ @param[in] FtpmBuffer Buffer for TPM command data.
+ @param[in] DataLength TPM command data length.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+**/
+EFI_STATUS
+EFIAPI
+PttHciSend(
+ IN UINT8 *FtpmBuffer,
+ IN UINT32 DataLength
+ );
+
+/**
+ Receives response data of last command from FTPM.
+
+ @param[out] FtpmBuffer Buffer for response data.
+ @param[out] RespSize Response data length.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+ @retval EFI_DEVICE_ERROR Unexpected device status.
+ @retval EFI_BUFFER_TOO_SMALL Response data is too long.
+**/
+EFI_STATUS
+EFIAPI
+PttHciReceive(
+ OUT UINT8 *FtpmBuffer,
+ OUT UINT32 *RespSize
+ );
+
+/**
+ Sends formatted command to FTPM for execution and returns formatted response data.
+
+ @param[in] InputBuffer Buffer for the input data.
+ @param[in] InputBufferSize Size of the input buffer.
+ @param[out] ReturnBuffer Buffer for the output data.
+ @param[out] ReturnBufferSize Size of the output buffer.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+**/
+EFI_STATUS
+EFIAPI
+PttHciSubmitCommand(
+ IN UINT8 *InputBuffer,
+ IN UINT32 InputBufferSize,
+ OUT UINT8 *ReturnBuffer,
+ OUT UINT32 *ReturnBufferSize
+ );
+
+/**
+ Checks whether PTT is Ready
+
+ @retval TRUE PTT is ready.
+ @retval FALSE PTT is not ready
+
+**/
+BOOLEAN
+EFIAPI
+PttHciReadyCheck (
+ VOID
+ );
+
+
+#endif
diff --git a/Core/EM/TCG2/CRB_lib/Tpm2PttHciRegs.h b/Core/EM/TCG2/CRB_lib/Tpm2PttHciRegs.h
new file mode 100644
index 0000000..1d1a484
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm2PttHciRegs.h
@@ -0,0 +1,99 @@
+/** @file
+ Register definitions for PTT HCI (Platform Trust Technology - Host Controller Interface).
+
+ Conventions:
+
+ - Prefixes:
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values of bits within the registers
+ Definitions beginning with "S_" are register sizes
+ Definitions beginning with "N_" are the bit position
+
+@copyright
+ Copyright (c) 2012 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.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#ifndef _TPM2_PTT_HCI_REGS_H_
+#define _TPM2_PTT_HCI_REGS_H_
+
+
+///
+/// FTPM HCI register base address
+///
+#define R_PTT_HCI_BASE_ADDRESS 0xFED70000
+
+//
+// FTPM HCI Control Area
+//
+#define R_PTT_HCI_CA_RSVD 0x00
+#define R_PTT_HCI_CA_ERROR 0x04
+#define R_PTT_HCI_CA_CANCEL 0x08
+#define R_PTT_HCI_CA_START 0x0C
+#define R_PTT_HCI_CA_INT_RSVD 0x10
+#define R_PTT_HCI_CA_CMD_SZ 0x18
+#define R_PTT_HCI_CA_CMD 0x1C
+#define R_PTT_HCI_CA_RSP_SZ 0x24
+#define R_PTT_HCI_CA_RSP 0x28
+
+//
+// FTPM HCI Private Area
+//
+#define R_PTT_HCI_CMD 0x40
+#define R_PTT_HCI_STS 0x44
+
+///
+/// FTPM HCI Command and Response Buffer
+///
+#define R_PTT_HCI_CRB 0x80
+
+//
+// R_PTT_HCI_STS Flags
+//
+#define B_PTT_HCI_STS_ENABLED 0x00000001 ///< BIT0
+#define B_PTT_HCI_STS_READY 0x00000002 ///< BIT1
+#define B_PTT_HCI_STS_ACM_AS_CRTM 0x00000004 ///< BIT2
+#define B_PTT_HCI_STS_STARTUP_EXEC 0x00000008 ///< BIT3
+
+//
+// Value written to R_PTT_HCI_CMD and CA_START
+// to indicate that a command is available for processing
+//
+#define V_PTT_HCI_COMMAND_AVAILABLE_START 0x00000001
+#define V_PTT_HCI_COMMAND_AVAILABLE_CMD 0x00000000
+#define V_PTT_HCI_BUFFER_ADDRESS_RDY 0x00000003
+
+///
+/// Ignore bit setting mask for WaitRegisterBits
+///
+#define V_PTT_HCI_IGNORE_BITS 0x00000000
+
+///
+/// All bits clear mask for WaitRegisterBits
+///
+#define V_PTT_HCI_ALL_BITS_CLEAR 0xFFFFFFFF
+#define V_PTT_HCI_START_CLEAR 0x00000001
+
+///
+/// Max FTPM command/reponse buffer length
+///
+#define S_PTT_HCI_CRB_LENGTH 3968 ///< 0xFED70080:0xFED70FFF = 3968 Bytes
+// AMI-Core Override for PTT +
+#define PM_BASE_ADDRESS 0x1800
+// AMI-Core Override for PTT -
+
+
+#endif
diff --git a/Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.cif b/Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.cif
new file mode 100644
index 0000000..c2c3718
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "Tpm2PttLibrary"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\CRB_lib"
+ RefName = "Tpm2PttLibrary"
+[files]
+"Tpm2PttLibrary.sdl"
+"Tpm2PttLibrary.mak"
+"Tpm2PttHciDeviceLib.h"
+"Tpm2PttHciDeviceLib.c"
+"Tpm2PttHciRegs.h"
+<endComponent>
diff --git a/Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.mak b/Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.mak
new file mode 100644
index 0000000..1c2be5c
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.mak
@@ -0,0 +1,52 @@
+# /*++
+# Copyright (c) 2009 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.
+# --*/
+# MAK file for the ModulePart:AtDxeLib
+Tpm2PttLibrary_Lib : $(BUILD_DIR)\Tpm2PttLibrary.mak Tpm2PttDxeLibBin Tpm2PttPeiLibBin
+$(BUILD_DIR)\Tpm2PttLibrary.lib: Tpm2PttLibrary_Lib
+$(BUILD_DIR)\IA32\Tpm2PttLibrary.lib: Tpm2PttLibrary_Lib
+
+$(BUILD_DIR)\Tpm2PttLibrary.mak : $(Tpm2PttLibrary_DIR)\Tpm2PttLibrary.cif $(Tpm2PttLibrary_DIR)\Tpm2PttLibrary.mak $(BUILD_RULES)
+ $(CIF2MAK) $(Tpm2PttLibrary_DIR)\Tpm2PttLibrary.cif $(CIF2MAK_DEFAULTS)
+
+LIB_CFLAGS=$(CFLAGS)\
+ /I$(TPM20_CRBLIB)\
+ /I$(TCG_DIR)\Common\
+ /I$(Tpm2PttLibrary_DIR)\
+ /I$(TCG_DIR)\
+
+Tpm2PttDxeLibBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\Tpm2PttLibrary.mak all \
+ "CFLAGS=$(LIB_CFLAGS) "\
+ LIBRARY_NAME=$(BUILD_DIR)\Tpm2PttLibrary.lib\
+ TYPE=LIBRARY
+
+
+Tpm2PttPeiLibBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32\
+ /f $(BUILD_DIR)\Tpm2PttLibrary.mak all \
+ "CFLAGS=$(LIB_CFLAGS) "\
+ TYPE=PEI_LIBRARY
+
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.sdl b/Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.sdl
new file mode 100644
index 0000000..1432273
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.sdl
@@ -0,0 +1,20 @@
+TOKEN
+ Name = "Tpm2PttLibrary_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "This driver will work for Intel FTPM only"
+End
+
+PATH
+ Name = "Tpm2PttLibrary_DIR"
+ Help = "Path"
+End
+
+
+MODULE
+ Help = "Includes Tpm2PttLibrary.mak to Project"
+ File = "Tpm2PttLibrary.mak"
+End