1 /* 2 * Copyright (c) 2011 The Chromium OS Authors. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 /* 8 * The code in this file is based on the article "Writing a TPM Device Driver" 9 * published on http://ptgmedia.pearsoncmg.com. 10 * 11 * One principal difference is that in the simplest config the other than 0 12 * TPM localities do not get mapped by some devices (for instance, by Infineon 13 * slb9635), so this driver provides access to locality 0 only. 14 */ 15 16 #include <common.h> 17 #include <dm.h> 18 #include <mapmem.h> 19 #include <tis.h> 20 #include <tpm.h> 21 #include <asm/io.h> 22 23 #define PREFIX "lpc_tpm: " 24 25 struct tpm_locality { 26 u32 access; 27 u8 padding0[4]; 28 u32 int_enable; 29 u8 vector; 30 u8 padding1[3]; 31 u32 int_status; 32 u32 int_capability; 33 u32 tpm_status; 34 u8 padding2[8]; 35 u8 data; 36 u8 padding3[3803]; 37 u32 did_vid; 38 u8 rid; 39 u8 padding4[251]; 40 }; 41 42 struct tpm_tis_lpc_priv { 43 struct tpm_locality *regs; 44 }; 45 46 /* 47 * This pointer refers to the TPM chip, 5 of its localities are mapped as an 48 * array. 49 */ 50 #define TPM_TOTAL_LOCALITIES 5 51 52 /* Some registers' bit field definitions */ 53 #define TIS_STS_VALID (1 << 7) /* 0x80 */ 54 #define TIS_STS_COMMAND_READY (1 << 6) /* 0x40 */ 55 #define TIS_STS_TPM_GO (1 << 5) /* 0x20 */ 56 #define TIS_STS_DATA_AVAILABLE (1 << 4) /* 0x10 */ 57 #define TIS_STS_EXPECT (1 << 3) /* 0x08 */ 58 #define TIS_STS_RESPONSE_RETRY (1 << 1) /* 0x02 */ 59 60 #define TIS_ACCESS_TPM_REG_VALID_STS (1 << 7) /* 0x80 */ 61 #define TIS_ACCESS_ACTIVE_LOCALITY (1 << 5) /* 0x20 */ 62 #define TIS_ACCESS_BEEN_SEIZED (1 << 4) /* 0x10 */ 63 #define TIS_ACCESS_SEIZE (1 << 3) /* 0x08 */ 64 #define TIS_ACCESS_PENDING_REQUEST (1 << 2) /* 0x04 */ 65 #define TIS_ACCESS_REQUEST_USE (1 << 1) /* 0x02 */ 66 #define TIS_ACCESS_TPM_ESTABLISHMENT (1 << 0) /* 0x01 */ 67 68 #define TIS_STS_BURST_COUNT_MASK (0xffff) 69 #define TIS_STS_BURST_COUNT_SHIFT (8) 70 71 /* 1 second is plenty for anything TPM does. */ 72 #define MAX_DELAY_US (1000 * 1000) 73 74 /* Retrieve burst count value out of the status register contents. */ 75 static u16 burst_count(u32 status) 76 { 77 return (status >> TIS_STS_BURST_COUNT_SHIFT) & 78 TIS_STS_BURST_COUNT_MASK; 79 } 80 81 /* TPM access wrappers to support tracing */ 82 static u8 tpm_read_byte(struct tpm_tis_lpc_priv *priv, const u8 *ptr) 83 { 84 u8 ret = readb(ptr); 85 debug(PREFIX "Read reg 0x%4.4x returns 0x%2.2x\n", 86 (u32)(uintptr_t)ptr - (u32)(uintptr_t)priv->regs, ret); 87 return ret; 88 } 89 90 static u32 tpm_read_word(struct tpm_tis_lpc_priv *priv, const u32 *ptr) 91 { 92 u32 ret = readl(ptr); 93 debug(PREFIX "Read reg 0x%4.4x returns 0x%8.8x\n", 94 (u32)(uintptr_t)ptr - (u32)(uintptr_t)priv->regs, ret); 95 return ret; 96 } 97 98 static void tpm_write_byte(struct tpm_tis_lpc_priv *priv, u8 value, u8 *ptr) 99 { 100 debug(PREFIX "Write reg 0x%4.4x with 0x%2.2x\n", 101 (u32)(uintptr_t)ptr - (u32)(uintptr_t)priv->regs, value); 102 writeb(value, ptr); 103 } 104 105 static void tpm_write_word(struct tpm_tis_lpc_priv *priv, u32 value, 106 u32 *ptr) 107 { 108 debug(PREFIX "Write reg 0x%4.4x with 0x%8.8x\n", 109 (u32)(uintptr_t)ptr - (u32)(uintptr_t)priv->regs, value); 110 writel(value, ptr); 111 } 112 113 /* 114 * tis_wait_reg() 115 * 116 * Wait for at least a second for a register to change its state to match the 117 * expected state. Normally the transition happens within microseconds. 118 * 119 * @reg - pointer to the TPM register 120 * @mask - bitmask for the bitfield(s) to watch 121 * @expected - value the field(s) are supposed to be set to 122 * 123 * Returns the register contents in case the expected value was found in the 124 * appropriate register bits, or -ETIMEDOUT on timeout. 125 */ 126 static int tis_wait_reg(struct tpm_tis_lpc_priv *priv, u32 *reg, u8 mask, 127 u8 expected) 128 { 129 u32 time_us = MAX_DELAY_US; 130 131 while (time_us > 0) { 132 u32 value = tpm_read_word(priv, reg); 133 if ((value & mask) == expected) 134 return value; 135 udelay(1); /* 1 us */ 136 time_us--; 137 } 138 139 return -ETIMEDOUT; 140 } 141 142 /* 143 * Probe the TPM device and try determining its manufacturer/device name. 144 * 145 * Returns 0 on success, -ve on error 146 */ 147 static int tpm_tis_lpc_probe(struct udevice *dev) 148 { 149 struct tpm_tis_lpc_priv *priv = dev_get_priv(dev); 150 u32 vid, did; 151 fdt_addr_t addr; 152 u32 didvid; 153 154 addr = dev_get_addr(dev); 155 if (addr == FDT_ADDR_T_NONE) 156 return -EINVAL; 157 priv->regs = map_sysmem(addr, 0); 158 didvid = tpm_read_word(priv, &priv->regs[0].did_vid); 159 160 vid = didvid & 0xffff; 161 did = (didvid >> 16) & 0xffff; 162 if (vid != 0x15d1 || did != 0xb) { 163 debug("Invalid vendor/device ID %04x/%04x\n", vid, did); 164 return -ENOSYS; 165 } 166 167 debug("Found TPM %s by %s\n", "SLB9635 TT 1.2", "Infineon"); 168 169 return 0; 170 } 171 172 /* 173 * tis_senddata() 174 * 175 * send the passed in data to the TPM device. 176 * 177 * @data - address of the data to send, byte by byte 178 * @len - length of the data to send 179 * 180 * Returns 0 on success, -ve on error (in case the device does not accept 181 * the entire command). 182 */ 183 static int tis_senddata(struct udevice *dev, const u8 *data, size_t len) 184 { 185 struct tpm_tis_lpc_priv *priv = dev_get_priv(dev); 186 struct tpm_locality *regs = priv->regs; 187 u32 offset = 0; 188 u16 burst = 0; 189 u32 max_cycles = 0; 190 u8 locality = 0; 191 u32 value; 192 193 value = tis_wait_reg(priv, ®s[locality].tpm_status, 194 TIS_STS_COMMAND_READY, TIS_STS_COMMAND_READY); 195 if (value == -ETIMEDOUT) { 196 printf("%s:%d - failed to get 'command_ready' status\n", 197 __FILE__, __LINE__); 198 return value; 199 } 200 burst = burst_count(value); 201 202 while (1) { 203 unsigned count; 204 205 /* Wait till the device is ready to accept more data. */ 206 while (!burst) { 207 if (max_cycles++ == MAX_DELAY_US) { 208 printf("%s:%d failed to feed %d bytes of %d\n", 209 __FILE__, __LINE__, len - offset, len); 210 return -ETIMEDOUT; 211 } 212 udelay(1); 213 burst = burst_count(tpm_read_word(priv, 214 ®s[locality].tpm_status)); 215 } 216 217 max_cycles = 0; 218 219 /* 220 * Calculate number of bytes the TPM is ready to accept in one 221 * shot. 222 * 223 * We want to send the last byte outside of the loop (hence 224 * the -1 below) to make sure that the 'expected' status bit 225 * changes to zero exactly after the last byte is fed into the 226 * FIFO. 227 */ 228 count = min((u32)burst, len - offset - 1); 229 while (count--) 230 tpm_write_byte(priv, data[offset++], 231 ®s[locality].data); 232 233 value = tis_wait_reg(priv, ®s[locality].tpm_status, 234 TIS_STS_VALID, TIS_STS_VALID); 235 236 if ((value == -ETIMEDOUT) || !(value & TIS_STS_EXPECT)) { 237 printf("%s:%d TPM command feed overflow\n", 238 __FILE__, __LINE__); 239 return value == -ETIMEDOUT ? value : -EIO; 240 } 241 242 burst = burst_count(value); 243 if ((offset == (len - 1)) && burst) { 244 /* 245 * We need to be able to send the last byte to the 246 * device, so burst size must be nonzero before we 247 * break out. 248 */ 249 break; 250 } 251 } 252 253 /* Send the last byte. */ 254 tpm_write_byte(priv, data[offset++], ®s[locality].data); 255 /* 256 * Verify that TPM does not expect any more data as part of this 257 * command. 258 */ 259 value = tis_wait_reg(priv, ®s[locality].tpm_status, 260 TIS_STS_VALID, TIS_STS_VALID); 261 if ((value == -ETIMEDOUT) || (value & TIS_STS_EXPECT)) { 262 printf("%s:%d unexpected TPM status 0x%x\n", 263 __FILE__, __LINE__, value); 264 return value == -ETIMEDOUT ? value : -EIO; 265 } 266 267 /* OK, sitting pretty, let's start the command execution. */ 268 tpm_write_word(priv, TIS_STS_TPM_GO, ®s[locality].tpm_status); 269 return 0; 270 } 271 272 /* 273 * tis_readresponse() 274 * 275 * read the TPM device response after a command was issued. 276 * 277 * @buffer - address where to read the response, byte by byte. 278 * @len - pointer to the size of buffer 279 * 280 * On success stores the number of received bytes to len and returns 0. On 281 * errors (misformatted TPM data or synchronization problems) returns 282 * -ve value. 283 */ 284 static int tis_readresponse(struct udevice *dev, u8 *buffer, size_t len) 285 { 286 struct tpm_tis_lpc_priv *priv = dev_get_priv(dev); 287 struct tpm_locality *regs = priv->regs; 288 u16 burst; 289 u32 value; 290 u32 offset = 0; 291 u8 locality = 0; 292 const u32 has_data = TIS_STS_DATA_AVAILABLE | TIS_STS_VALID; 293 u32 expected_count = len; 294 int max_cycles = 0; 295 296 /* Wait for the TPM to process the command. */ 297 value = tis_wait_reg(priv, ®s[locality].tpm_status, 298 has_data, has_data); 299 if (value == -ETIMEDOUT) { 300 printf("%s:%d failed processing command\n", 301 __FILE__, __LINE__); 302 return value; 303 } 304 305 do { 306 while ((burst = burst_count(value)) == 0) { 307 if (max_cycles++ == MAX_DELAY_US) { 308 printf("%s:%d TPM stuck on read\n", 309 __FILE__, __LINE__); 310 return -EIO; 311 } 312 udelay(1); 313 value = tpm_read_word(priv, ®s[locality].tpm_status); 314 } 315 316 max_cycles = 0; 317 318 while (burst-- && (offset < expected_count)) { 319 buffer[offset++] = tpm_read_byte(priv, 320 ®s[locality].data); 321 322 if (offset == 6) { 323 /* 324 * We got the first six bytes of the reply, 325 * let's figure out how many bytes to expect 326 * total - it is stored as a 4 byte number in 327 * network order, starting with offset 2 into 328 * the body of the reply. 329 */ 330 u32 real_length; 331 memcpy(&real_length, 332 buffer + 2, 333 sizeof(real_length)); 334 expected_count = be32_to_cpu(real_length); 335 336 if ((expected_count < offset) || 337 (expected_count > len)) { 338 printf("%s:%d bad response size %d\n", 339 __FILE__, __LINE__, 340 expected_count); 341 return -ENOSPC; 342 } 343 } 344 } 345 346 /* Wait for the next portion. */ 347 value = tis_wait_reg(priv, ®s[locality].tpm_status, 348 TIS_STS_VALID, TIS_STS_VALID); 349 if (value == -ETIMEDOUT) { 350 printf("%s:%d failed to read response\n", 351 __FILE__, __LINE__); 352 return value; 353 } 354 355 if (offset == expected_count) 356 break; /* We got all we needed. */ 357 358 } while ((value & has_data) == has_data); 359 360 /* 361 * Make sure we indeed read all there was. The TIS_STS_VALID bit is 362 * known to be set. 363 */ 364 if (value & TIS_STS_DATA_AVAILABLE) { 365 printf("%s:%d wrong receive status %x\n", 366 __FILE__, __LINE__, value); 367 return -EBADMSG; 368 } 369 370 /* Tell the TPM that we are done. */ 371 tpm_write_word(priv, TIS_STS_COMMAND_READY, 372 ®s[locality].tpm_status); 373 374 return offset; 375 } 376 377 static int tpm_tis_lpc_open(struct udevice *dev) 378 { 379 struct tpm_tis_lpc_priv *priv = dev_get_priv(dev); 380 struct tpm_locality *regs = priv->regs; 381 u8 locality = 0; /* we use locality zero for everything. */ 382 int ret; 383 384 /* now request access to locality. */ 385 tpm_write_word(priv, TIS_ACCESS_REQUEST_USE, ®s[locality].access); 386 387 /* did we get a lock? */ 388 ret = tis_wait_reg(priv, ®s[locality].access, 389 TIS_ACCESS_ACTIVE_LOCALITY, 390 TIS_ACCESS_ACTIVE_LOCALITY); 391 if (ret == -ETIMEDOUT) { 392 printf("%s:%d - failed to lock locality %d\n", 393 __FILE__, __LINE__, locality); 394 return ret; 395 } 396 397 tpm_write_word(priv, TIS_STS_COMMAND_READY, 398 ®s[locality].tpm_status); 399 return 0; 400 } 401 402 static int tpm_tis_lpc_close(struct udevice *dev) 403 { 404 struct tpm_tis_lpc_priv *priv = dev_get_priv(dev); 405 struct tpm_locality *regs = priv->regs; 406 u8 locality = 0; 407 408 if (tpm_read_word(priv, ®s[locality].access) & 409 TIS_ACCESS_ACTIVE_LOCALITY) { 410 tpm_write_word(priv, TIS_ACCESS_ACTIVE_LOCALITY, 411 ®s[locality].access); 412 413 if (tis_wait_reg(priv, ®s[locality].access, 414 TIS_ACCESS_ACTIVE_LOCALITY, 0) == -ETIMEDOUT) { 415 printf("%s:%d - failed to release locality %d\n", 416 __FILE__, __LINE__, locality); 417 return -ETIMEDOUT; 418 } 419 } 420 return 0; 421 } 422 423 static int tpm_tis_get_desc(struct udevice *dev, char *buf, int size) 424 { 425 if (size < 50) 426 return -ENOSPC; 427 428 return snprintf(buf, size, "1.2 TPM (vendor %s, chip %s)", 429 "Infineon", "SLB9635 TT 1.2"); 430 } 431 432 433 static const struct tpm_ops tpm_tis_lpc_ops = { 434 .open = tpm_tis_lpc_open, 435 .close = tpm_tis_lpc_close, 436 .get_desc = tpm_tis_get_desc, 437 .send = tis_senddata, 438 .recv = tis_readresponse, 439 }; 440 441 static const struct udevice_id tpm_tis_lpc_ids[] = { 442 { .compatible = "infineon,slb9635lpc" }, 443 { } 444 }; 445 446 U_BOOT_DRIVER(tpm_tis_lpc) = { 447 .name = "tpm_tis_lpc", 448 .id = UCLASS_TPM, 449 .of_match = tpm_tis_lpc_ids, 450 .ops = &tpm_tis_lpc_ops, 451 .probe = tpm_tis_lpc_probe, 452 .priv_auto_alloc_size = sizeof(struct tpm_tis_lpc_priv), 453 }; 454