summaryrefslogtreecommitdiffstats
path: root/QuarkPlatformPkg/Library
diff options
context:
space:
mode:
authorMichael Kinney <michael.d.kinney@intel.com>2016-01-21 19:30:29 +0000
committermdkinney <mdkinney@Edk2>2016-01-21 19:30:29 +0000
commitdf8652455e701710748a50b3839621a3440df353 (patch)
tree67338c1776590e4a2739810e61ad39a27ab66e2b /QuarkPlatformPkg/Library
parent441a3678e1c94212b6cc250da9a4999451321b1d (diff)
downloadedk2-df8652455e701710748a50b3839621a3440df353.tar.gz
edk2-df8652455e701710748a50b3839621a3440df353.tar.bz2
edk2-df8652455e701710748a50b3839621a3440df353.zip
QuarkPlatformPkg: Add Tpm12DeviceLib instance for Atmel I2C TPM
Add new Tpm12DeviceLib instance for an Atmel I2C TPM Cc: Kelly Steele <kelly.steele@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Michael Kinney <michael.d.kinney@intel.com> Reviewed-by: Kelly Steele <kelly.steele@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19730 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'QuarkPlatformPkg/Library')
-rw-r--r--QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/TisPc.c419
-rw-r--r--QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.inf45
-rw-r--r--QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.uni21
3 files changed, 485 insertions, 0 deletions
diff --git a/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/TisPc.c b/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/TisPc.c
new file mode 100644
index 0000000000..4e5aa41370
--- /dev/null
+++ b/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/TisPc.c
@@ -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;
+}
diff --git a/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.inf b/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.inf
new file mode 100644
index 0000000000..5a8734f4c6
--- /dev/null
+++ b/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.inf
@@ -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
diff --git a/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.uni b/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.uni
new file mode 100644
index 0000000000..aaee1e2779
--- /dev/null
+++ b/QuarkPlatformPkg/Library/Tpm12DeviceLibAtmelI2c/Tpm12DeviceLibAtmelI2c.uni
@@ -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."
+