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