summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2011-08-12 12:05:17 -0700
committerSimon Glass <sjg@chromium.org>2011-08-29 10:59:29 -0700
commit8c056507ce8e3e53a6459b447685f20fb483b090 (patch)
tree960852498edddcab380ba0077ef836cd142f96bc /drivers
parent8a6096728551c0d3c051fe915341a766d18a2511 (diff)
Add tracing ability to the generic TPM driver.
Separate all register accesses into accessor functions (taking care of truncating values of the byte sized registers). Add code to trace register accesses when compiled with DEBUG defined. BUG=chrome-os-partner:4547 TEST=manual: . compile with DEBUG defined in line 14 and boot on Alex . try a TPM command: boot > tpm lpc_tpm: Read reg 0xf00 returns 0xb15d1 lpc_tpm: Found TPM SLB9635 TT 1.2 by Infineon lpc_tpm: Read reg 0x0 returns 0x81 lpc_tpm: Write reg 0x0 with 0x2 lpc_tpm: Read reg 0x0 returns 0xa1 lpc_tpm: Write reg 0x18 with 0x40 lpc_tpm: Read reg 0x18 returns 0xff000840 lpc_tpm: Read reg 0x0 returns 0xa1 lpc_tpm: Write reg 0x0 with 0x20 lpc_tpm: Read reg 0x0 returns 0x81 Change-Id: I13d14e1bc12e26abfe999c9540bfeee52e8d2f2d Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: http://gerrit.chromium.org/gerrit/5907 Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/tpm/generic_lpc_tpm.c75
1 files changed, 59 insertions, 16 deletions
diff --git a/drivers/tpm/generic_lpc_tpm.c b/drivers/tpm/generic_lpc_tpm.c
index a0c173ffbb..2704cf6d81 100644
--- a/drivers/tpm/generic_lpc_tpm.c
+++ b/drivers/tpm/generic_lpc_tpm.c
@@ -11,10 +11,24 @@
* Infineon slb9635), so this driver provides access to locality 0 only.
*/
+/* #define DEBUG */
#include <common.h>
#include <asm/io.h>
#include <tpm.h>
+#ifdef DEBUG
+#define TPM_DEBUG_ON 1
+#else
+#define TPM_DEBUG_ON 0
+#endif
+
+#define PREFIX "lpc_tpm: "
+#define TPM_DEBUG(fmt, args...) \
+ if (TPM_DEBUG_ON) { \
+ printf(PREFIX); \
+ printf(fmt , ##args); \
+ }
+
#ifndef CONFIG_TPM_TIS_BASE_ADDRESS
/* Base TPM address standard for x86 systems */
#define CONFIG_TPM_TIS_BASE_ADDRESS 0xfed40000
@@ -84,6 +98,38 @@ static const struct vendor_name vendor_names[] = {
*/
static u32 vendor_dev_id;
+static int is_byte_reg(u32 reg)
+{
+ /*
+ * These TPM registers are 8 bits wide and as such require byte access
+ * on writes and truncated value on reads.
+ */
+ return ((reg == TIS_REG_ACCESS) ||
+ (reg == TIS_REG_INT_VECTOR) ||
+ (reg == TIS_REG_DATA_FIFO));
+}
+
+/* TPM access functions are carved out to make tracing easier. */
+static u32 tpm_read(int locality, u32 reg)
+{
+ u32 value;
+ value = readl(TIS_REG(locality, reg));
+ if (is_byte_reg(reg))
+ value &= 0xff;
+ TPM_DEBUG("Read reg 0x%x returns 0x%x\n", reg, value);
+ return value;
+}
+
+static void tpm_write(u32 value, int locality, u32 reg)
+{
+ TPM_DEBUG("Write reg 0x%x with 0x%x\n", reg, value);
+
+ if (is_byte_reg(reg))
+ writeb(value & 0xff, TIS_REG(locality, reg));
+ else
+ writel(value, TIS_REG(locality, reg));
+}
+
/*
* tis_wait_reg()
*
@@ -101,7 +147,7 @@ static u32 vendor_dev_id;
static u32 tis_wait_reg(u8 reg, u8 locality, u32 time_ms, u8 mask, u8 expected)
{
while (time_ms > 0) {
- u8 value = readb(TIS_REG(locality, reg));
+ u32 value = tpm_read(locality, reg);
if ((value & mask) == expected)
return 0;
udelay(1000); /* 1 ms */
@@ -118,7 +164,7 @@ static u32 tis_wait_reg(u8 reg, u8 locality, u32 time_ms, u8 mask, u8 expected)
*/
static u32 tis_probe(void)
{
- u32 didvid = readl(TIS_REG(0, TIS_REG_DID_VID));
+ u32 didvid = tpm_read(0, TIS_REG_DID_VID);
int i;
const char *device_name = "unknown";
const char *vendor_name = device_name;
@@ -153,8 +199,7 @@ static u32 tis_probe(void)
break;
}
/* this will have to be converted into debug printout */
- printf("%s:%d found TPM %s by %s\n", __FILE__, __LINE__,
- device_name, vendor_name);
+ TPM_DEBUG("Found TPM %s by %s\n", device_name, vendor_name);
return 0;
}
@@ -179,7 +224,7 @@ static u32 tis_senddata(const u8 * const data, u32 len)
while (1) {
while (!burst && (ctr < 2000)) {
- burst = (u16) readl(TIS_REG(locality, TIS_REG_STS)) >> 8;
+ burst = (u16) (tpm_read(locality, TIS_REG_STS) >> 8);
if (!burst) {
udelay(100);
ctr++;
@@ -192,8 +237,7 @@ static u32 tis_senddata(const u8 * const data, u32 len)
}
while (1) {
- writeb(data[offset++],
- TIS_REG(locality, TIS_REG_DATA_FIFO));
+ tpm_write(data[offset++], locality, TIS_REG_DATA_FIFO);
burst--;
if (burst == 0 || offset == len)
@@ -222,9 +266,9 @@ static u32 tis_readresponse(u8 *buffer, u32 *len)
u32 offset = 0;
u8 locality = 0;
- while ((readb(TIS_REG(locality, TIS_REG_STS)) & TIS_STS_DATA_AVAILABLE) &&
- (offset < *len))
- buffer[offset++] = readb(TIS_REG(locality, TIS_REG_DATA_FIFO));
+ while ((tpm_read(locality, TIS_REG_STS) & TIS_STS_DATA_AVAILABLE) &&
+ (offset < *len))
+ buffer[offset++] = (u8) tpm_read(locality, TIS_REG_DATA_FIFO);
*len = offset;
return 0;
@@ -259,7 +303,7 @@ int tis_open(void)
return ~0;
/* now request access to locality */
- writeb(TIS_ACCESS_REQUEST_USE, TIS_REG(locality, TIS_REG_ACCESS));
+ tpm_write(TIS_ACCESS_REQUEST_USE, locality, TIS_REG_ACCESS);
/* did we get a lock? */
if (tis_wait_reg(TIS_REG_ACCESS, locality, TPM_MAX_EXECUTION_DELAY_MS,
@@ -270,8 +314,8 @@ int tis_open(void)
return ~0;
}
- writeb(TIS_STS_COMMAND_READY, TIS_REG(locality, TIS_REG_STS));
- if (tis_wait_reg(TIS_REG_STS, locality, TPM_MAX_EXECUTION_DELAY_MS,
+ tpm_write(TIS_STS_COMMAND_READY, locality, TIS_REG_STS);
+ if (tis_wait_reg(TIS_REG_STS, locality, TPM_MAX_EXECUTION_DELAY_MS,
TIS_STS_COMMAND_READY, TIS_STS_COMMAND_READY)) {
printf("%s:%d - failed to get 'command_ready' status\n",
__FILE__, __LINE__);
@@ -290,10 +334,9 @@ int tis_open(void)
int tis_close(void)
{
u8 locality = 0;
- if (readb(TIS_REG(locality, TIS_REG_ACCESS)) &
+ if (tpm_read(locality, TIS_REG_ACCESS) &
TIS_ACCESS_ACTIVE_LOCALITY) {
- writeb(TIS_ACCESS_ACTIVE_LOCALITY,
- TIS_REG(locality, TIS_REG_ACCESS));
+ tpm_write(TIS_ACCESS_ACTIVE_LOCALITY, locality, TIS_REG_ACCESS);
if (tis_wait_reg(TIS_REG_ACCESS, locality,
TPM_MAX_EXECUTION_DELAY_MS,