coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
tis_atmel.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <assert.h>
4 #include <commonlib/endian.h>
5 #include <commonlib/helpers.h>
6 #include <console/console.h>
7 #include <delay.h>
8 #include <device/i2c_simple.h>
9 #include <endian.h>
10 #include <lib.h>
11 #include <security/tpm/tis.h>
12 #include <timer.h>
13 #include <types.h>
14 
15 #define RECV_TIMEOUT (1 * 1000) /* 1 second */
16 #define XMIT_TIMEOUT (1 * 1000) /* 1 second */
17 #define SLEEP_DURATION 1000 /* microseconds */
18 
24 
25 int tis_open(void)
26 {
27  return 0;
28 }
29 
30 int tis_close(void)
31 {
32  return 0;
33 }
34 
35 int tis_init(void)
36 {
37  return 0;
38 }
39 
40 int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
41  uint8_t *recvbuf, size_t *rbuf_len)
42 {
43  size_t hdr_bytes;
44  struct tpm_output_header *header;
45  size_t max_recv_bytes;
46  size_t recv_bytes;
47  int status;
48  struct stopwatch sw;
49 
50  ASSERT(sbuf_size >= 10);
51  if (CONFIG(DRIVER_TPM_DISPLAY_TIS_BYTES)) {
52  /* Display the TPM command */
53  if (sbuf_size >= 10)
54  printk(BIOS_DEBUG, "TPM Command: 0x%08x\n",
55  read_at_be32(sendbuf, sizeof(uint16_t)
56  + sizeof(uint32_t)));
57  hexdump(sendbuf, sbuf_size);
58  }
59 
60  /* Send the command to the TPM */
62  while (1) {
63  status = i2c_write_raw(CONFIG_DRIVER_TPM_I2C_BUS,
64  CONFIG_DRIVER_TPM_I2C_ADDR, (uint8_t *)sendbuf,
65  sbuf_size);
66  if ((status < 0) && (!stopwatch_expired(&sw)))
67  continue;
68  if (status < 0)
69  return status;
70  break;
71  }
72 
73  /* Read the TPM response header */
74  max_recv_bytes = *rbuf_len;
75  ASSERT(max_recv_bytes >= sizeof(*header));
76  hdr_bytes = sizeof(*header);
77  header = (struct tpm_output_header *)recvbuf;
79  do {
80  status = i2c_read_raw(CONFIG_DRIVER_TPM_I2C_BUS,
81  CONFIG_DRIVER_TPM_I2C_ADDR, recvbuf, hdr_bytes);
82  if (status > 0)
83  break;
85  } while (!stopwatch_expired(&sw));
86  if (status != sizeof(*header))
87  return -1;
88 
89  /* Determine the number of bytes remaining */
90  recv_bytes = MIN(be32_to_cpu(*(uint32_t *)&header->length),
91  max_recv_bytes);
92 
93  /* Determine if there is additional response data */
94  if (recv_bytes > hdr_bytes) {
95  /* Display the TPM response */
96  if (CONFIG(DRIVER_TPM_DISPLAY_TIS_BYTES))
97  hexdump(recvbuf, hdr_bytes);
98 
99  /* Read the full TPM response */
100  status = i2c_read_raw(CONFIG_DRIVER_TPM_I2C_BUS,
101  CONFIG_DRIVER_TPM_I2C_ADDR, recvbuf, recv_bytes);
102  if (status < 0)
103  return status;
104  }
105 
106  /* Return the number of bytes received */
107  *rbuf_len = status;
108 
109  /* Display the TPM response */
110  if (CONFIG(DRIVER_TPM_DISPLAY_TIS_BYTES)) {
111  printk(BIOS_DEBUG, "TPM Response: 0x%08x\n",
112  read_at_be32(recvbuf, sizeof(uint16_t)
113  + sizeof(uint32_t)));
114  hexdump(recvbuf, *rbuf_len);
115  }
116 
117  /* Successful transfer */
118  return 0;
119 }
struct arm64_kernel_header header
Definition: fit_payload.c:30
#define ASSERT(x)
Definition: assert.h:44
#define MIN(a, b)
Definition: helpers.h:37
static uint32_t read_at_be32(const void *src, size_t offset)
Definition: endian.h:92
#define printk(level,...)
Definition: stdlib.h:16
@ CONFIG
Definition: dsi_common.h:201
static int i2c_write_raw(unsigned int bus, uint8_t slave, uint8_t *data, int len)
Definition: i2c_simple.h:72
static int i2c_read_raw(unsigned int bus, uint8_t slave, uint8_t *data, int len)
Definition: i2c_simple.h:57
static int stopwatch_expired(struct stopwatch *sw)
Definition: timer.h:152
static void stopwatch_init_msecs_expire(struct stopwatch *sw, long ms)
Definition: timer.h:133
void hexdump(const void *memory, size_t length)
Definition: hexdump.c:7
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
unsigned char uint8_t
Definition: stdint.h:8
uint32_t length
Definition: tis_atmel.c:21
uint32_t return_code
Definition: tis_atmel.c:22
uint16_t tag
Definition: tis_atmel.c:20
struct tpm_output_header __packed
#define XMIT_TIMEOUT
Definition: tis_atmel.c:16
#define SLEEP_DURATION
Definition: tis_atmel.c:17
int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size, uint8_t *recvbuf, size_t *rbuf_len)
Definition: tis_atmel.c:40
#define RECV_TIMEOUT
Definition: tis_atmel.c:15
int tis_close(void)
Definition: tis_atmel.c:30
int tis_open(void)
Definition: tis_atmel.c:25
int tis_init(void)
Definition: tis_atmel.c:35
void udelay(uint32_t us)
Definition: udelay.c:15