xref: /openbmc/u-boot/drivers/tpm/tpm2_tis_core.c (revision 3ac88d09)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2020, Linaro Limited
4  *
5  * Based on the Linux TIS core interface and U-Boot original SPI TPM driver
6  */
7 
8 #include <common.h>
9 #include <dm.h>
10 #include <tpm-v2.h>
11 #include <linux/delay.h>
12 #include <linux/unaligned/be_byteshift.h>
13 #include "tpm_tis.h"
14 
15 int tpm_tis_get_desc(struct udevice *dev, char *buf, int size)
16 {
17 	struct tpm_chip *chip = dev_get_priv(dev);
18 
19 	if (size < 80)
20 		return -ENOSPC;
21 
22 	return snprintf(buf, size,
23 			"%s v2.0: VendorID 0x%04x, DeviceID 0x%04x, RevisionID 0x%02x [%s]",
24 			dev->name, chip->vend_dev & 0xFFFF,
25 			chip->vend_dev >> 16, chip->rid,
26 			(chip->is_open ? "open" : "closed"));
27 }
28 
29 /**
30  * tpm_tis_check_locality - Check the current TPM locality
31  *
32  * @dev: TPM device
33  * @loc:  locality
34  *
35  * Return: True if the tested locality matches
36  */
37 static bool tpm_tis_check_locality(struct udevice *dev, int loc)
38 {
39 	struct tpm_chip *chip = dev_get_priv(dev);
40 	struct tpm_tis_phy_ops *phy_ops = chip->phy_ops;
41 	u8 locality;
42 
43 	phy_ops->read_bytes(dev, TPM_ACCESS(loc), 1, &locality);
44 	if ((locality & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID |
45 	    TPM_ACCESS_REQUEST_USE)) ==
46 	    (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) {
47 		chip->locality = loc;
48 		return true;
49 	}
50 
51 	return false;
52 }
53 
54 /**
55  * tpm_tis_request_locality - Request a locality from the TPM
56  *
57  * @dev:  TPM device
58  * @loc:  requested locality
59  *
60  * Return: 0 on success -1 on failure
61  */
62 int tpm_tis_request_locality(struct udevice *dev, int loc)
63 {
64 	struct tpm_chip *chip = dev_get_priv(dev);
65 	struct tpm_tis_phy_ops *phy_ops = chip->phy_ops;
66 	u8 buf = TPM_ACCESS_REQUEST_USE;
67 	unsigned long start, stop;
68 
69 	if (tpm_tis_check_locality(dev, loc))
70 		return 0;
71 
72 	phy_ops->write_bytes(dev, TPM_ACCESS(loc), 1, &buf);
73 	start = get_timer(0);
74 	stop = chip->timeout_a;
75 	do {
76 		if (tpm_tis_check_locality(dev, loc))
77 			return 0;
78 		mdelay(TPM_TIMEOUT_MS);
79 	} while (get_timer(start) < stop);
80 
81 	return -1;
82 }
83 
84 /**
85  * tpm_tis_status - Check the current device status
86  *
87  * @dev:   TPM device
88  * @status: return value of status
89  *
90  * Return: 0 on success, negative on failure
91  */
92 static int tpm_tis_status(struct udevice *dev, u8 *status)
93 {
94 	struct tpm_chip *chip = dev_get_priv(dev);
95 	struct tpm_tis_phy_ops *phy_ops = chip->phy_ops;
96 
97 	if (chip->locality < 0)
98 		return -EINVAL;
99 
100 	phy_ops->read_bytes(dev, TPM_STS(chip->locality), 1, status);
101 
102 	if ((*status & TPM_STS_READ_ZERO)) {
103 		log_err("TPM returned invalid status\n");
104 		return -EINVAL;
105 	}
106 
107 	return 0;
108 }
109 
110 /**
111  * tpm_tis_release_locality - Release the requested locality
112  *
113  * @dev: TPM device
114  * @loc:  requested locality
115  *
116  * Return: 0 on success, negative on failure
117  */
118 int tpm_tis_release_locality(struct udevice *dev, int loc)
119 {
120 	struct tpm_chip *chip = dev_get_priv(dev);
121 	struct tpm_tis_phy_ops *phy_ops = chip->phy_ops;
122 	u8 buf = TPM_ACCESS_ACTIVE_LOCALITY;
123 	int ret;
124 
125 	if (chip->locality < 0)
126 		return 0;
127 
128 	ret = phy_ops->write_bytes(dev, TPM_ACCESS(loc), 1, &buf);
129 	chip->locality = -1;
130 
131 	return ret;
132 }
133 
134 /**
135  * tpm_tis_wait_for_stat - Wait for TPM to become ready
136  *
137  * @dev:     TPM device
138  * @mask:    mask to match
139  * @timeout: timeout for retries
140  * @status:  current status
141  *
142  * Return: 0 on success, negative on failure
143  */
144 static int tpm_tis_wait_for_stat(struct udevice *dev, u8 mask,
145 				 unsigned long timeout, u8 *status)
146 {
147 	unsigned long start = get_timer(0);
148 	unsigned long stop = timeout;
149 	int ret;
150 
151 	do {
152 		mdelay(TPM_TIMEOUT_MS);
153 		ret = tpm_tis_status(dev, status);
154 		if (ret)
155 			return ret;
156 
157 		if ((*status & mask) == mask)
158 			return 0;
159 	} while (get_timer(start) < stop);
160 
161 	return -ETIMEDOUT;
162 }
163 
164 /**
165  * tpm_tis_get_burstcount - Get the burstcount for the data FIFO
166  *
167  * @dev:        TPM device
168  * @burstcount: current burstcount
169  *
170  * Return: 0 on success, negative on failure
171  */
172 static int tpm_tis_get_burstcount(struct udevice *dev, size_t *burstcount)
173 {
174 	struct tpm_chip *chip = dev_get_priv(dev);
175 	struct tpm_tis_phy_ops *phy_ops = chip->phy_ops;
176 	unsigned long start, stop;
177 	u32 burst;
178 
179 	if (chip->locality < 0)
180 		return -EINVAL;
181 
182 	/* wait for burstcount */
183 	start = get_timer(0);
184 	/*
185 	 * This is the TPMv2 defined timeout. Change this in case you want to
186 	 * make the driver compatile to TPMv1
187 	 */
188 	stop = chip->timeout_a;
189 	do {
190 		phy_ops->read32(dev, TPM_STS(chip->locality), &burst);
191 		*burstcount = (burst >> 8) & 0xFFFF;
192 		if (*burstcount)
193 			return 0;
194 
195 		mdelay(TPM_TIMEOUT_MS);
196 	} while (get_timer(start) < stop);
197 
198 	return -ETIMEDOUT;
199 }
200 
201 /**
202  * tpm_tis_ready - Cancel pending comands and get the device on a ready state
203  *
204  * @dev: TPM device
205  *
206  * Return: 0 on success, negative on failure
207  */
208 static int tpm_tis_ready(struct udevice *dev)
209 {
210 	struct tpm_chip *chip = dev_get_priv(dev);
211 	struct tpm_tis_phy_ops *phy_ops = chip->phy_ops;
212 	u8 data = TPM_STS_COMMAND_READY;
213 
214 	/* This will cancel any pending commands */
215 	return phy_ops->write_bytes(dev, TPM_STS(chip->locality), 1, &data);
216 }
217 
218 int tpm_tis_send(struct udevice *dev, const u8 *buf, size_t len)
219 {
220 	struct tpm_chip *chip = dev_get_priv(dev);
221 	struct tpm_tis_phy_ops *phy_ops = chip->phy_ops;
222 	size_t burstcnt, wr_size, sent = 0;
223 	u8 data = TPM_STS_GO;
224 	u8 status;
225 	int ret;
226 
227 	if (!chip)
228 		return -ENODEV;
229 
230 	ret = tpm_tis_request_locality(dev, 0);
231 	if (ret < 0)
232 		return -EBUSY;
233 
234 	ret = tpm_tis_status(dev, &status);
235 	if (ret)
236 		goto release_locality;
237 
238 	if (!(status & TPM_STS_COMMAND_READY)) {
239 		ret = tpm_tis_ready(dev);
240 		if (ret) {
241 			log_err("Can't cancel previous TPM operation\n");
242 			goto release_locality;
243 		}
244 		ret = tpm_tis_wait_for_stat(dev, TPM_STS_COMMAND_READY,
245 					    chip->timeout_b, &status);
246 		if (ret) {
247 			log_err("TPM not ready\n");
248 			goto release_locality;
249 		}
250 	}
251 
252 	while (len > 0) {
253 		ret = tpm_tis_get_burstcount(dev, &burstcnt);
254 		if (ret)
255 			goto release_locality;
256 
257 		wr_size = min(len, burstcnt);
258 		ret = phy_ops->write_bytes(dev, TPM_DATA_FIFO(chip->locality),
259 					   wr_size, buf + sent);
260 		if (ret < 0)
261 			goto release_locality;
262 
263 		ret = tpm_tis_wait_for_stat(dev, TPM_STS_VALID,
264 					    chip->timeout_c, &status);
265 		if (ret)
266 			goto release_locality;
267 
268 		sent += wr_size;
269 		len -= wr_size;
270 		/* make sure the TPM expects more data */
271 		if (len && !(status & TPM_STS_DATA_EXPECT)) {
272 			ret = -EIO;
273 			goto release_locality;
274 		}
275 	}
276 
277 	/*
278 	 * Make a final check ensuring everything is ok and the TPM expects no
279 	 * more data
280 	 */
281 	ret = tpm_tis_wait_for_stat(dev, TPM_STS_VALID, chip->timeout_c,
282 				    &status);
283 	if (ret)
284 		goto release_locality;
285 
286 	if (status & TPM_STS_DATA_EXPECT) {
287 		ret = -EIO;
288 		goto release_locality;
289 	}
290 
291 	ret = phy_ops->write_bytes(dev, TPM_STS(chip->locality), 1, &data);
292 	if (ret)
293 		goto release_locality;
294 
295 	return sent;
296 
297 release_locality:
298 	tpm_tis_ready(dev);
299 	tpm_tis_release_locality(dev, chip->locality);
300 
301 	return ret;
302 }
303 
304 static int tpm_tis_recv_data(struct udevice *dev, u8 *buf, size_t count)
305 {
306 	struct tpm_chip *chip = dev_get_priv(dev);
307 	struct tpm_tis_phy_ops *phy_ops = chip->phy_ops;
308 	int size = 0, len, ret;
309 	size_t burstcnt;
310 	u8 status;
311 
312 	while (size < count &&
313 	       tpm_tis_wait_for_stat(dev, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
314 				     chip->timeout_c, &status) == 0) {
315 		ret = tpm_tis_get_burstcount(dev, &burstcnt);
316 		if (ret)
317 			return ret;
318 
319 		len = min_t(int, burstcnt, count - size);
320 		ret = phy_ops->read_bytes(dev, TPM_DATA_FIFO(chip->locality),
321 					  len, buf + size);
322 		if (ret < 0)
323 			return ret;
324 
325 		size += len;
326 	}
327 
328 	return size;
329 }
330 
331 /**
332  * tpm_tis_recv - Receive data from a device
333  *
334  * @dev:  TPM device
335  * @buf:  buffer to copy data
336  * @size: buffer size
337  *
338  * Return: bytes read or negative on failure
339  */
340 int tpm_tis_recv(struct udevice *dev, u8 *buf, size_t count)
341 {
342 	struct tpm_chip *chip = dev_get_priv(dev);
343 	int size, expected;
344 
345 	if (count < TPM_HEADER_SIZE)
346 		return -E2BIG;
347 
348 	size = tpm_tis_recv_data(dev, buf, TPM_HEADER_SIZE);
349 	if (size < TPM_HEADER_SIZE) {
350 		log_err("TPM error, unable to read header\n");
351 		goto out;
352 	}
353 
354 	expected = get_unaligned_be32(buf + TPM_CMD_COUNT_OFFSET);
355 	if (expected > count) {
356 		size = -EIO;
357 		log_warning("Too much data: %d > %zu\n", expected, count);
358 		goto out;
359 	}
360 
361 	size += tpm_tis_recv_data(dev, &buf[TPM_HEADER_SIZE],
362 				   expected - TPM_HEADER_SIZE);
363 	if (size < expected) {
364 		log(LOGC_NONE, LOGL_ERR,
365 		    "TPM error, unable to read remaining bytes of result\n");
366 		size = -EIO;
367 		goto out;
368 	}
369 
370 out:
371 	tpm_tis_ready(dev);
372 	/* acquired in tpm_tis_send */
373 	tpm_tis_release_locality(dev, chip->locality);
374 
375 	return size;
376 }
377 
378 int tpm_tis_cleanup(struct udevice *dev)
379 {
380 	struct tpm_chip *chip = dev_get_priv(dev);
381 	int ret;
382 
383 	ret = tpm_tis_request_locality(dev, 0);
384 	if (ret)
385 		return ret;
386 
387 	tpm_tis_ready(dev);
388 
389 	tpm_tis_release_locality(dev, chip->locality);
390 
391 	return 0;
392 }
393 
394 int tpm_tis_open(struct udevice *dev)
395 {
396 	struct tpm_chip *chip = dev_get_priv(dev);
397 	int ret;
398 
399 	if (chip->is_open)
400 		return -EBUSY;
401 
402 	ret = tpm_tis_request_locality(dev, 0);
403 	if (!ret)
404 		chip->is_open = 1;
405 
406 	return ret;
407 }
408 
409 void tpm_tis_ops_register(struct udevice *dev, struct tpm_tis_phy_ops *ops)
410 {
411 	struct tpm_chip *chip = dev_get_priv(dev);
412 
413 	chip->phy_ops = ops;
414 }
415 
416 static bool tis_check_ops(struct tpm_tis_phy_ops *phy_ops)
417 {
418 	if (!phy_ops || !phy_ops->read_bytes || !phy_ops->write_bytes ||
419 	    !phy_ops->read32 || !phy_ops->write32)
420 		return false;
421 
422 	return true;
423 }
424 
425 int tpm_tis_init(struct udevice *dev)
426 {
427 	struct tpm_chip *chip = dev_get_priv(dev);
428 	struct tpm_tis_phy_ops *phy_ops = chip->phy_ops;
429 	int ret;
430 	u32 tmp;
431 
432 	if (!tis_check_ops(phy_ops)) {
433 		log_err("Driver bug. No bus ops defined\n");
434 		return -1;
435 	}
436 	ret = tpm_tis_request_locality(dev, 0);
437 	if (ret)
438 		return ret;
439 
440 	chip->timeout_a = TIS_SHORT_TIMEOUT_MS;
441 	chip->timeout_b = TIS_LONG_TIMEOUT_MS;
442 	chip->timeout_c = TIS_SHORT_TIMEOUT_MS;
443 	chip->timeout_d = TIS_SHORT_TIMEOUT_MS;
444 
445 	/* Disable interrupts */
446 	phy_ops->read32(dev, TPM_INT_ENABLE(chip->locality), &tmp);
447 	tmp |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT |
448 	       TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT;
449 	tmp &= ~TPM_GLOBAL_INT_ENABLE;
450 	phy_ops->write32(dev, TPM_INT_ENABLE(chip->locality), tmp);
451 
452 	phy_ops->read_bytes(dev, TPM_RID(chip->locality), 1, &chip->rid);
453 	phy_ops->read32(dev, TPM_DID_VID(chip->locality), &chip->vend_dev);
454 
455 	return tpm_tis_release_locality(dev, chip->locality);
456 }
457 
458 int tpm_tis_close(struct udevice *dev)
459 {
460 	struct tpm_chip *chip = dev_get_priv(dev);
461 	int ret = 0;
462 
463 	if (chip->is_open) {
464 		ret = tpm_tis_release_locality(dev, chip->locality);
465 		chip->is_open = 0;
466 	}
467 
468 	return ret;
469 }
470