Revision: 19730
          http://sourceforge.net/p/edk2/code/19730
Author:   mdkinney
Date:     2016-01-21 19:30:29 +0000 (Thu, 21 Jan 2016)
Log Message:
-----------
QuarkPlatformPkg: Add Tpm12DeviceLib instance for Atmel I2C TPM

Add new Tpm12DeviceLib instance for an Atmel I2C TPM

Cc: Kelly Steele <[email protected]>
Cc: Jiewen Yao <[email protected]>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Michael Kinney <[email protected]>
Reviewed-by: Kelly Steele <[email protected]>
Reviewed-by: Jiewen Yao <[email protected]>

Added Paths:
-----------
    trunk/edk2/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/
    trunk/edk2/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/TisPc.c
    
trunk/edk2/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.inf
    
trunk/edk2/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.uni

Added: trunk/edk2/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/TisPc.c
===================================================================
--- trunk/edk2/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/TisPc.c          
                (rev 0)
+++ trunk/edk2/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/TisPc.c  
2016-01-21 19:30:29 UTC (rev 19730)
@@ -0,0 +1,419 @@
+/** @file
+  Basic TIS (TPM Interface Specification) functions for Atmel I2C TPM.
+
+  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD 
License
+  which accompanies this distribution.  The full text of the license may be 
found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <Library/Tpm12DeviceLib.h>
+#include <Library/BaseLib.h>
+#include <Library/TimerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/I2cLib.h>
+#include <Library/Tpm12CommandLib.h>
+
+//
+// Atmel I2C TPM slave address
+//
+#define ATMEL_I2C_TPM_SLAVE_ADDRESS      0x29
+
+//
+// Maximum I2C transfer size for Atmel I2C TPM
+//
+#define ATMEL_I2C_TPM_MAX_TRANSFER_SIZE  0x10
+
+//
+// Default TimeOut values in microseconds
+//
+#define TIS_TIMEOUT_A  ( 750 * 1000)  // 750ms
+#define TIS_TIMEOUT_B  (2000 * 1000)  // 2s
+#define TIS_TIMEOUT_C  ( 750 * 1000)  // 750ms
+#define TIS_TIMEOUT_D  ( 750 * 1000)  // 750ms
+
+/**
+  Send command to Atmel I2c TPM breaking request up into multiple I2C transfers
+  if required.
+
+  @param[in] Buffer  Pointer to TPM command data.
+  @param[in] Length  Number of bytes of TPM command data.
+
+  @retval EFI_SUCCESS    TPM command sent.
+  @retval EFI_NOT_FOUND  TPM chip doesn't exit.
+  @retval EFI_TIMEOUT    Can't get the TPM control in time.
+**/
+EFI_STATUS
+WriteTpmBufferMultiple (
+  IN UINT8  *Buffer,
+  IN UINTN  Length
+  )
+{
+  EFI_STATUS              Status;
+  EFI_I2C_DEVICE_ADDRESS  I2CDeviceAddr;
+  UINTN                   Index;
+  UINTN                   PartialLength;
+
+  I2CDeviceAddr.I2CDeviceAddress = ATMEL_I2C_TPM_SLAVE_ADDRESS;
+
+  DEBUG ((EFI_D_VERBOSE, "WriteTpmBufferMultiple: Addr=%02x  Length=%02x\n", 
I2CDeviceAddr.I2CDeviceAddress, Length));
+
+  for (PartialLength = 0; Length > 0; Length -= PartialLength, Buffer += 
PartialLength) {
+    //
+    // Write data to TPM.
+    //
+    PartialLength = MIN (Length, ATMEL_I2C_TPM_MAX_TRANSFER_SIZE);
+    Status = I2cWriteMultipleByte (
+      I2CDeviceAddr,
+      EfiI2CSevenBitAddrMode,
+      &PartialLength,
+      Buffer
+      );
+    DEBUG ((EFI_D_VERBOSE, "  "));
+    for (Index = 0; Index < PartialLength; Index++) {
+      DEBUG ((EFI_D_VERBOSE, "%02x ", Buffer[Index]));
+    }
+    DEBUG ((EFI_D_VERBOSE, "\n"));
+    if (EFI_ERROR (Status)) {
+      DEBUG ((EFI_D_VERBOSE, "  Status = %r\n", Status));
+      return Status;
+    }
+  }
+
+  DEBUG ((EFI_D_VERBOSE, "  Status = %r\n", Status));
+  return Status;
+}
+
+/**
+  Receive a response to a command from Atmel I2c TPM breaking response into
+  multiple I2C transfers if required.
+
+  @param[out] Buffer  Pointer to TPM response data.
+  @param[in]  Length  Maximum number of bytes to receive.
+
+  @retval EFI_SUCCESS    TPM response received.
+  @retval EFI_NOT_FOUND  TPM chip doesn't exit.
+  @retval EFI_TIMEOUT    Can't get the TPM control in time.
+**/
+EFI_STATUS
+ReadTpmBufferMultiple (
+  OUT UINT8  *Buffer,
+  IN  UINTN  Length
+  )
+{
+  EFI_STATUS              Status;
+  EFI_I2C_DEVICE_ADDRESS  I2CDeviceAddr;
+  UINTN                   WriteLength;
+  UINTN                   Index;
+  UINTN                   PartialLength;
+
+  I2CDeviceAddr.I2CDeviceAddress = ATMEL_I2C_TPM_SLAVE_ADDRESS;
+  WriteLength = 0;
+
+  DEBUG ((EFI_D_VERBOSE, "ReadTpmBufferMultiple: Addr=%02x  Length=%02x\n", 
I2CDeviceAddr.I2CDeviceAddress, Length));
+
+  for (PartialLength = 0; Length > 0; Length -= PartialLength, Buffer += 
PartialLength) {
+    //
+    // Read data from TPM.
+    //
+    PartialLength = MIN (Length, ATMEL_I2C_TPM_MAX_TRANSFER_SIZE);
+    Status = I2cReadMultipleByte (
+      I2CDeviceAddr,
+      EfiI2CSevenBitAddrMode,
+      &WriteLength,
+      &PartialLength,
+      Buffer
+      );
+    if (!EFI_ERROR (Status)) {
+      DEBUG ((EFI_D_VERBOSE, "  "));
+      for (Index = 0; Index < PartialLength; Index++) {
+        DEBUG ((EFI_D_VERBOSE, "%02x ", Buffer[Index]));
+      }
+      DEBUG ((EFI_D_VERBOSE, "\n"));
+    }
+    if (EFI_ERROR (Status)) {
+      DEBUG ((EFI_D_VERBOSE, "  Status = %r\n", Status));
+      return Status;
+    }
+  }
+
+  DEBUG ((EFI_D_VERBOSE, "  Status = %r\n", Status));
+  return Status;
+}
+
+/**
+  This service requests use TPM12.
+
+  @retval EFI_SUCCESS       Get the control of TPM12 chip.
+  @retval EFI_NOT_FOUND     TPM12 not found.
+  @retval EFI_DEVICE_ERROR  Unexpected device behavior.
+**/
+EFI_STATUS
+EFIAPI
+Tpm12RequestUseTpm (
+  VOID
+  )
+{
+  EFI_STATUS                 Status;
+  UINT8                      Data;
+  UINT64                     Current;
+  UINT64                     Previous;
+  UINT64                     Total;
+  UINT64                     Start;
+  UINT64                     End;
+  UINT64                     Timeout;
+  INT64                      Cycle;
+  INT64                      Delta;
+
+  //
+  // Get the current timer value
+  //
+  Current = GetPerformanceCounter();
+
+  //
+  // Initialize local variables
+  //
+  Start = 0;
+  End   = 0;
+  Total = 0;
+
+  //
+  // Retrieve the performance counter properties and compute the number of
+  // performance counter ticks required to reach the maximum TIS timeout of
+  // TIS_TIMEOUT_A.  TIS_TIMEOUT_A is in microseconds.
+  //
+  Timeout = DivU64x32 (
+              MultU64x32 (
+                GetPerformanceCounterProperties (&Start, &End),
+                TIS_TIMEOUT_A
+                ),
+              1000000
+              );
+  Cycle = End - Start;
+  if (Cycle < 0) {
+    Cycle = -Cycle;
+  }
+  Cycle++;
+
+  //
+  // Attempt to read a byte from the Atmel I2C TPM
+  //
+  do {
+    Status = ReadTpmBufferMultiple (&Data, sizeof(Data));
+
+    Previous = Current;
+    Current  = GetPerformanceCounter();
+    Delta = (INT64) (Current - Previous);
+    if (Start > End) {
+      Delta = -Delta;
+    }
+    if (Delta < 0) {
+      Delta += Cycle;
+    }
+    Total += Delta;
+    if (Total >= Timeout) {
+      Status = EFI_TIMEOUT;
+      DEBUG ((EFI_D_ERROR, "Atmel I2C TPM failed to read: %r\n", Status));
+      return Status;
+    }
+  } while (EFI_ERROR (Status));
+
+  //
+  // Send Physical Presence Command to Atmel I2C TPM
+  //
+  Status = Tpm12PhysicalPresence (TPM_PHYSICAL_PRESENCE_PRESENT);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Atmel I2C TPM failed to submit physical presence 
command: %r\n", Status));
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This service enables the sending of commands to the TPM12.
+
+  @param[in]     InputParameterBlockSize   Size of the TPM12 input parameter 
block.
+  @param[in]     InputParameterBlock       Pointer to the TPM12 input 
parameter block.
+  @param[in,out] OutputParameterBlockSize  Size of the TPM12 output parameter 
block.
+  @param[in]     OutputParameterBlock      Pointer to the TPM12 output 
parameter block.
+
+  @retval EFI_SUCCESS           The command byte stream was successfully sent 
to
+                                the device and a response was successfully 
received.
+  @retval EFI_DEVICE_ERROR      The command was not successfully sent to the
+                                device or a response was not successfully 
received
+                                from the device.
+  @retval EFI_BUFFER_TOO_SMALL  The output parameter block is too small.
+**/
+EFI_STATUS
+EFIAPI
+Tpm12SubmitCommand (
+  IN UINT32      InputParameterBlockSize,
+  IN UINT8       *InputParameterBlock,
+  IN OUT UINT32  *OutputParameterBlockSize,
+  IN UINT8       *OutputParameterBlock
+  )
+{
+  EFI_STATUS           Status;
+  UINT32               TpmOutSize;
+  TPM_RSP_COMMAND_HDR  *ResponseHeader;
+  UINT64               Current;
+  UINT64               Previous;
+  UINT64               Total;
+  UINT64               Start;
+  UINT64               End;
+  UINT64               Timeout;
+  INT64                Cycle;
+  INT64                Delta;
+
+  //
+  // Make sure response buffer is big enough to hold a response header
+  //
+  if (*OutputParameterBlockSize < sizeof (TPM_RSP_COMMAND_HDR)) {
+    Status = EFI_BUFFER_TOO_SMALL;
+    goto Done;
+  }
+
+  //
+  // Get the current timer value
+  //
+  Current = GetPerformanceCounter();
+
+  //
+  // Initialize local variables
+  //
+  Start = 0;
+  End   = 0;
+  Total = 0;
+
+  //
+  // Retrieve the performance counter properties and compute the number of
+  // performance counter ticks required to reach the maximum TIS timeout of
+  // TIS_TIMEOUT_A.  TIS_TIMEOUT_A is in microseconds.
+  //
+  Timeout = DivU64x32 (
+              MultU64x32 (
+                GetPerformanceCounterProperties (&Start, &End),
+                TIS_TIMEOUT_A
+                ),
+              1000000
+              );
+  Cycle = End - Start;
+  if (Cycle < 0) {
+    Cycle = -Cycle;
+  }
+  Cycle++;
+
+  //
+  // Send command
+  //
+  do {
+    Status = WriteTpmBufferMultiple (InputParameterBlock, 
InputParameterBlockSize);
+
+    Previous = Current;
+    Current  = GetPerformanceCounter();
+    Delta = (INT64) (Current - Previous);
+    if (Start > End) {
+      Delta = -Delta;
+    }
+    if (Delta < 0) {
+      Delta += Cycle;
+    }
+    Total += Delta;
+    if (Total >= Timeout) {
+      Status = EFI_TIMEOUT;
+      goto Done;
+    }
+  } while (EFI_ERROR (Status));
+
+  //
+  // Receive response header
+  //
+  do {
+    Status = ReadTpmBufferMultiple (OutputParameterBlock, sizeof 
(TPM_RSP_COMMAND_HDR));
+
+    Previous = Current;
+    Current  = GetPerformanceCounter();
+    Delta = (INT64) (Current - Previous);
+    if (Start > End) {
+      Delta = -Delta;
+    }
+    if (Delta < 0) {
+      Delta += Cycle;
+    }
+    Total += Delta;
+    if (Total >= Timeout) {
+      Status = EFI_TIMEOUT;
+      goto Done;
+    }
+  } while (EFI_ERROR (Status));
+
+  //
+  // Check the response data header (tag, parasize and returncode)
+  //
+  ResponseHeader = (TPM_RSP_COMMAND_HDR *)OutputParameterBlock;
+  if (SwapBytes16 (ReadUnaligned16 (&ResponseHeader->tag)) != 
TPM_TAG_RSP_COMMAND) {
+    Status = EFI_DEVICE_ERROR;
+    goto Done;
+  }
+
+  TpmOutSize = SwapBytes32 (ReadUnaligned32 (&ResponseHeader->paramSize));
+  if (TpmOutSize == sizeof (TPM_RSP_COMMAND_HDR)) {
+    Status = EFI_SUCCESS;
+    goto Done;
+  }
+  if (TpmOutSize < sizeof (TPM_RSP_COMMAND_HDR)) {
+    Status = EFI_DEVICE_ERROR;
+    goto Done;
+  }
+  if (*OutputParameterBlockSize < TpmOutSize) {
+    Status = EFI_BUFFER_TOO_SMALL;
+    goto Done;
+  }
+  *OutputParameterBlockSize = TpmOutSize;
+
+  //
+  // Receive the remaining data in the response header
+  //
+  do {
+    Status = ReadTpmBufferMultiple (
+               OutputParameterBlock + sizeof (TPM_RSP_COMMAND_HDR),
+               TpmOutSize - sizeof (TPM_RSP_COMMAND_HDR)
+               );
+
+    Previous = Current;
+    Current  = GetPerformanceCounter();
+    Delta = (INT64) (Current - Previous);
+    if (Start > End) {
+      Delta = -Delta;
+    }
+    if (Delta < 0) {
+      Delta += Cycle;
+    }
+    Total += Delta;
+    if (Total >= Timeout) {
+      Status = EFI_TIMEOUT;
+      goto Done;
+    }
+  } while (EFI_ERROR (Status));
+
+Done:
+  DEBUG ((
+    EFI_D_VERBOSE,
+    "Tpm12SubmitCommand() Status = %r  Time = %ld ms\n",
+    Status,
+    DivU64x64Remainder (
+      MultU64x32 (Total, 1000),
+      GetPerformanceCounterProperties (NULL, NULL),
+      NULL
+      )
+    ));
+
+  return Status;
+}

Added: 
trunk/edk2/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.inf
===================================================================
--- 
trunk/edk2/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.inf
                               (rev 0)
+++ 
trunk/edk2/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.inf
       2016-01-21 19:30:29 UTC (rev 19730)
@@ -0,0 +1,45 @@
+## @file
+#  Provides some common functions for the TCG feature for Atmel I2C TPM.
+#
+#  This instance provides basic TPM Interface Specification (TIS) functions
+#  or Atmel I2C TPM.
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD 
License
+# which accompanies this distribution. The full text of the license may be 
found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = Tpm12DeviceLibAtmelI2c
+  MODULE_UNI_FILE                = Tpm12DeviceLibAtmelI2c.uni
+  FILE_GUID                      = A0C0B7EF-99FF-417F-8B9F-5AD4701D90D6
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = Tpm12DeviceLib|PEIM DXE_DRIVER 
DXE_SMM_DRIVER UEFI_DRIVER
+
+#
+# The following information is for reference only and not required by the 
build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  TisPc.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  QuarkSocPkg/QuarkSocPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  TimerLib
+  DebugLib
+  I2cLib
+  Tpm12CommandLib

Added: 
trunk/edk2/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.uni
===================================================================
--- 
trunk/edk2/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.uni
                               (rev 0)
+++ 
trunk/edk2/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.uni
       2016-01-21 19:30:29 UTC (rev 19730)
@@ -0,0 +1,21 @@
+// /** @file
+// Provides some common functions for the TCG feature for Atmel I2C TPM.
+//
+// This instance provides basic TPM Interface Specification (TIS) functions
+// for Atmel I2C TPM.
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD 
License
+// which accompanies this distribution. The full text of the license may be 
found at
+// http://opensource.org/licenses/bsd-license.php
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR 
IMPLIED.
+//
+// **/
+
+#string STR_MODULE_ABSTRACT             #language en-US "Provides some common 
functions for the TCG feature for Atmel I2C TPM."
+
+#string STR_MODULE_DESCRIPTION          #language en-US "This instance 
provides basic TPM Interface Specification (TIS) functions for Atmel I2C TPM."
+


------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to