cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

st33zp24.c (12582B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * STMicroelectronics TPM Linux driver for TPM ST33ZP24
      4 * Copyright (C) 2009 - 2016 STMicroelectronics
      5 */
      6
      7#include <linux/module.h>
      8#include <linux/fs.h>
      9#include <linux/kernel.h>
     10#include <linux/delay.h>
     11#include <linux/wait.h>
     12#include <linux/freezer.h>
     13#include <linux/string.h>
     14#include <linux/interrupt.h>
     15#include <linux/gpio.h>
     16#include <linux/sched.h>
     17#include <linux/uaccess.h>
     18#include <linux/io.h>
     19#include <linux/slab.h>
     20
     21#include "../tpm.h"
     22#include "st33zp24.h"
     23
     24#define TPM_ACCESS			0x0
     25#define TPM_STS				0x18
     26#define TPM_DATA_FIFO			0x24
     27#define TPM_INTF_CAPABILITY		0x14
     28#define TPM_INT_STATUS			0x10
     29#define TPM_INT_ENABLE			0x08
     30
     31#define LOCALITY0			0
     32
     33enum st33zp24_access {
     34	TPM_ACCESS_VALID = 0x80,
     35	TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
     36	TPM_ACCESS_REQUEST_PENDING = 0x04,
     37	TPM_ACCESS_REQUEST_USE = 0x02,
     38};
     39
     40enum st33zp24_status {
     41	TPM_STS_VALID = 0x80,
     42	TPM_STS_COMMAND_READY = 0x40,
     43	TPM_STS_GO = 0x20,
     44	TPM_STS_DATA_AVAIL = 0x10,
     45	TPM_STS_DATA_EXPECT = 0x08,
     46};
     47
     48enum st33zp24_int_flags {
     49	TPM_GLOBAL_INT_ENABLE = 0x80,
     50	TPM_INTF_CMD_READY_INT = 0x080,
     51	TPM_INTF_FIFO_AVALAIBLE_INT = 0x040,
     52	TPM_INTF_WAKE_UP_READY_INT = 0x020,
     53	TPM_INTF_LOCALITY_CHANGE_INT = 0x004,
     54	TPM_INTF_STS_VALID_INT = 0x002,
     55	TPM_INTF_DATA_AVAIL_INT = 0x001,
     56};
     57
     58enum tis_defaults {
     59	TIS_SHORT_TIMEOUT = 750,
     60	TIS_LONG_TIMEOUT = 2000,
     61};
     62
     63/*
     64 * clear the pending interrupt.
     65 */
     66static u8 clear_interruption(struct st33zp24_dev *tpm_dev)
     67{
     68	u8 interrupt;
     69
     70	tpm_dev->ops->recv(tpm_dev->phy_id, TPM_INT_STATUS, &interrupt, 1);
     71	tpm_dev->ops->send(tpm_dev->phy_id, TPM_INT_STATUS, &interrupt, 1);
     72	return interrupt;
     73}
     74
     75/*
     76 * cancel the current command execution or set STS to COMMAND READY.
     77 */
     78static void st33zp24_cancel(struct tpm_chip *chip)
     79{
     80	struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
     81	u8 data;
     82
     83	data = TPM_STS_COMMAND_READY;
     84	tpm_dev->ops->send(tpm_dev->phy_id, TPM_STS, &data, 1);
     85}
     86
     87/*
     88 * return the TPM_STS register
     89 */
     90static u8 st33zp24_status(struct tpm_chip *chip)
     91{
     92	struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
     93	u8 data;
     94
     95	tpm_dev->ops->recv(tpm_dev->phy_id, TPM_STS, &data, 1);
     96	return data;
     97}
     98
     99/*
    100 * if the locality is active
    101 */
    102static bool check_locality(struct tpm_chip *chip)
    103{
    104	struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
    105	u8 data;
    106	u8 status;
    107
    108	status = tpm_dev->ops->recv(tpm_dev->phy_id, TPM_ACCESS, &data, 1);
    109	if (status && (data &
    110		(TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
    111		(TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID))
    112		return true;
    113
    114	return false;
    115}
    116
    117static int request_locality(struct tpm_chip *chip)
    118{
    119	struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
    120	unsigned long stop;
    121	long ret;
    122	u8 data;
    123
    124	if (check_locality(chip))
    125		return tpm_dev->locality;
    126
    127	data = TPM_ACCESS_REQUEST_USE;
    128	ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_ACCESS, &data, 1);
    129	if (ret < 0)
    130		return ret;
    131
    132	stop = jiffies + chip->timeout_a;
    133
    134	/* Request locality is usually effective after the request */
    135	do {
    136		if (check_locality(chip))
    137			return tpm_dev->locality;
    138		msleep(TPM_TIMEOUT);
    139	} while (time_before(jiffies, stop));
    140
    141	/* could not get locality */
    142	return -EACCES;
    143}
    144
    145static void release_locality(struct tpm_chip *chip)
    146{
    147	struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
    148	u8 data;
    149
    150	data = TPM_ACCESS_ACTIVE_LOCALITY;
    151
    152	tpm_dev->ops->send(tpm_dev->phy_id, TPM_ACCESS, &data, 1);
    153}
    154
    155/*
    156 * get_burstcount return the burstcount value
    157 */
    158static int get_burstcount(struct tpm_chip *chip)
    159{
    160	struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
    161	unsigned long stop;
    162	int burstcnt, status;
    163	u8 temp;
    164
    165	stop = jiffies + chip->timeout_d;
    166	do {
    167		status = tpm_dev->ops->recv(tpm_dev->phy_id, TPM_STS + 1,
    168					    &temp, 1);
    169		if (status < 0)
    170			return -EBUSY;
    171
    172		burstcnt = temp;
    173		status = tpm_dev->ops->recv(tpm_dev->phy_id, TPM_STS + 2,
    174					    &temp, 1);
    175		if (status < 0)
    176			return -EBUSY;
    177
    178		burstcnt |= temp << 8;
    179		if (burstcnt)
    180			return burstcnt;
    181		msleep(TPM_TIMEOUT);
    182	} while (time_before(jiffies, stop));
    183	return -EBUSY;
    184}
    185
    186static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask,
    187				bool check_cancel, bool *canceled)
    188{
    189	u8 status = chip->ops->status(chip);
    190
    191	*canceled = false;
    192	if ((status & mask) == mask)
    193		return true;
    194	if (check_cancel && chip->ops->req_canceled(chip, status)) {
    195		*canceled = true;
    196		return true;
    197	}
    198	return false;
    199}
    200
    201/*
    202 * wait for a TPM_STS value
    203 */
    204static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
    205			wait_queue_head_t *queue, bool check_cancel)
    206{
    207	struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
    208	unsigned long stop;
    209	int ret = 0;
    210	bool canceled = false;
    211	bool condition;
    212	u32 cur_intrs;
    213	u8 status;
    214
    215	/* check current status */
    216	status = st33zp24_status(chip);
    217	if ((status & mask) == mask)
    218		return 0;
    219
    220	stop = jiffies + timeout;
    221
    222	if (chip->flags & TPM_CHIP_FLAG_IRQ) {
    223		cur_intrs = tpm_dev->intrs;
    224		clear_interruption(tpm_dev);
    225		enable_irq(tpm_dev->irq);
    226
    227		do {
    228			if (ret == -ERESTARTSYS && freezing(current))
    229				clear_thread_flag(TIF_SIGPENDING);
    230
    231			timeout = stop - jiffies;
    232			if ((long) timeout <= 0)
    233				return -1;
    234
    235			ret = wait_event_interruptible_timeout(*queue,
    236						cur_intrs != tpm_dev->intrs,
    237						timeout);
    238			clear_interruption(tpm_dev);
    239			condition = wait_for_tpm_stat_cond(chip, mask,
    240						check_cancel, &canceled);
    241			if (ret >= 0 && condition) {
    242				if (canceled)
    243					return -ECANCELED;
    244				return 0;
    245			}
    246		} while (ret == -ERESTARTSYS && freezing(current));
    247
    248		disable_irq_nosync(tpm_dev->irq);
    249
    250	} else {
    251		do {
    252			msleep(TPM_TIMEOUT);
    253			status = chip->ops->status(chip);
    254			if ((status & mask) == mask)
    255				return 0;
    256		} while (time_before(jiffies, stop));
    257	}
    258
    259	return -ETIME;
    260}
    261
    262static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
    263{
    264	struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
    265	int size = 0, burstcnt, len, ret;
    266
    267	while (size < count &&
    268	       wait_for_stat(chip,
    269			     TPM_STS_DATA_AVAIL | TPM_STS_VALID,
    270			     chip->timeout_c,
    271			     &tpm_dev->read_queue, true) == 0) {
    272		burstcnt = get_burstcount(chip);
    273		if (burstcnt < 0)
    274			return burstcnt;
    275		len = min_t(int, burstcnt, count - size);
    276		ret = tpm_dev->ops->recv(tpm_dev->phy_id, TPM_DATA_FIFO,
    277					 buf + size, len);
    278		if (ret < 0)
    279			return ret;
    280
    281		size += len;
    282	}
    283	return size;
    284}
    285
    286static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id)
    287{
    288	struct tpm_chip *chip = dev_id;
    289	struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
    290
    291	tpm_dev->intrs++;
    292	wake_up_interruptible(&tpm_dev->read_queue);
    293	disable_irq_nosync(tpm_dev->irq);
    294
    295	return IRQ_HANDLED;
    296}
    297
    298/*
    299 * send TPM commands through the I2C bus.
    300 */
    301static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf,
    302			 size_t len)
    303{
    304	struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
    305	u32 status, i, size, ordinal;
    306	int burstcnt = 0;
    307	int ret;
    308	u8 data;
    309
    310	if (len < TPM_HEADER_SIZE)
    311		return -EBUSY;
    312
    313	ret = request_locality(chip);
    314	if (ret < 0)
    315		return ret;
    316
    317	status = st33zp24_status(chip);
    318	if ((status & TPM_STS_COMMAND_READY) == 0) {
    319		st33zp24_cancel(chip);
    320		if (wait_for_stat
    321		    (chip, TPM_STS_COMMAND_READY, chip->timeout_b,
    322		     &tpm_dev->read_queue, false) < 0) {
    323			ret = -ETIME;
    324			goto out_err;
    325		}
    326	}
    327
    328	for (i = 0; i < len - 1;) {
    329		burstcnt = get_burstcount(chip);
    330		if (burstcnt < 0)
    331			return burstcnt;
    332		size = min_t(int, len - i - 1, burstcnt);
    333		ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_DATA_FIFO,
    334					 buf + i, size);
    335		if (ret < 0)
    336			goto out_err;
    337
    338		i += size;
    339	}
    340
    341	status = st33zp24_status(chip);
    342	if ((status & TPM_STS_DATA_EXPECT) == 0) {
    343		ret = -EIO;
    344		goto out_err;
    345	}
    346
    347	ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_DATA_FIFO,
    348				 buf + len - 1, 1);
    349	if (ret < 0)
    350		goto out_err;
    351
    352	status = st33zp24_status(chip);
    353	if ((status & TPM_STS_DATA_EXPECT) != 0) {
    354		ret = -EIO;
    355		goto out_err;
    356	}
    357
    358	data = TPM_STS_GO;
    359	ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_STS, &data, 1);
    360	if (ret < 0)
    361		goto out_err;
    362
    363	if (chip->flags & TPM_CHIP_FLAG_IRQ) {
    364		ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
    365
    366		ret = wait_for_stat(chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
    367				tpm_calc_ordinal_duration(chip, ordinal),
    368				&tpm_dev->read_queue, false);
    369		if (ret < 0)
    370			goto out_err;
    371	}
    372
    373	return 0;
    374out_err:
    375	st33zp24_cancel(chip);
    376	release_locality(chip);
    377	return ret;
    378}
    379
    380static int st33zp24_recv(struct tpm_chip *chip, unsigned char *buf,
    381			    size_t count)
    382{
    383	int size = 0;
    384	u32 expected;
    385
    386	if (!chip)
    387		return -EBUSY;
    388
    389	if (count < TPM_HEADER_SIZE) {
    390		size = -EIO;
    391		goto out;
    392	}
    393
    394	size = recv_data(chip, buf, TPM_HEADER_SIZE);
    395	if (size < TPM_HEADER_SIZE) {
    396		dev_err(&chip->dev, "Unable to read header\n");
    397		goto out;
    398	}
    399
    400	expected = be32_to_cpu(*(__be32 *)(buf + 2));
    401	if (expected > count || expected < TPM_HEADER_SIZE) {
    402		size = -EIO;
    403		goto out;
    404	}
    405
    406	size += recv_data(chip, &buf[TPM_HEADER_SIZE],
    407			expected - TPM_HEADER_SIZE);
    408	if (size < expected) {
    409		dev_err(&chip->dev, "Unable to read remainder of result\n");
    410		size = -ETIME;
    411	}
    412
    413out:
    414	st33zp24_cancel(chip);
    415	release_locality(chip);
    416	return size;
    417}
    418
    419static bool st33zp24_req_canceled(struct tpm_chip *chip, u8 status)
    420{
    421	return (status == TPM_STS_COMMAND_READY);
    422}
    423
    424static const struct tpm_class_ops st33zp24_tpm = {
    425	.flags = TPM_OPS_AUTO_STARTUP,
    426	.send = st33zp24_send,
    427	.recv = st33zp24_recv,
    428	.cancel = st33zp24_cancel,
    429	.status = st33zp24_status,
    430	.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
    431	.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
    432	.req_canceled = st33zp24_req_canceled,
    433};
    434
    435/*
    436 * initialize the TPM device
    437 */
    438int st33zp24_probe(void *phy_id, const struct st33zp24_phy_ops *ops,
    439		   struct device *dev, int irq, int io_lpcpd)
    440{
    441	int ret;
    442	u8 intmask = 0;
    443	struct tpm_chip *chip;
    444	struct st33zp24_dev *tpm_dev;
    445
    446	chip = tpmm_chip_alloc(dev, &st33zp24_tpm);
    447	if (IS_ERR(chip))
    448		return PTR_ERR(chip);
    449
    450	tpm_dev = devm_kzalloc(dev, sizeof(struct st33zp24_dev),
    451			       GFP_KERNEL);
    452	if (!tpm_dev)
    453		return -ENOMEM;
    454
    455	tpm_dev->phy_id = phy_id;
    456	tpm_dev->ops = ops;
    457	dev_set_drvdata(&chip->dev, tpm_dev);
    458
    459	chip->timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
    460	chip->timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT);
    461	chip->timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
    462	chip->timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
    463
    464	tpm_dev->locality = LOCALITY0;
    465
    466	if (irq) {
    467		/* INTERRUPT Setup */
    468		init_waitqueue_head(&tpm_dev->read_queue);
    469		tpm_dev->intrs = 0;
    470
    471		if (request_locality(chip) != LOCALITY0) {
    472			ret = -ENODEV;
    473			goto _tpm_clean_answer;
    474		}
    475
    476		clear_interruption(tpm_dev);
    477		ret = devm_request_irq(dev, irq, tpm_ioserirq_handler,
    478				IRQF_TRIGGER_HIGH, "TPM SERIRQ management",
    479				chip);
    480		if (ret < 0) {
    481			dev_err(&chip->dev, "TPM SERIRQ signals %d not available\n",
    482				irq);
    483			goto _tpm_clean_answer;
    484		}
    485
    486		intmask |= TPM_INTF_CMD_READY_INT
    487			|  TPM_INTF_STS_VALID_INT
    488			|  TPM_INTF_DATA_AVAIL_INT;
    489
    490		ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_INT_ENABLE,
    491					 &intmask, 1);
    492		if (ret < 0)
    493			goto _tpm_clean_answer;
    494
    495		intmask = TPM_GLOBAL_INT_ENABLE;
    496		ret = tpm_dev->ops->send(tpm_dev->phy_id, (TPM_INT_ENABLE + 3),
    497					 &intmask, 1);
    498		if (ret < 0)
    499			goto _tpm_clean_answer;
    500
    501		tpm_dev->irq = irq;
    502		chip->flags |= TPM_CHIP_FLAG_IRQ;
    503
    504		disable_irq_nosync(tpm_dev->irq);
    505	}
    506
    507	return tpm_chip_register(chip);
    508_tpm_clean_answer:
    509	dev_info(&chip->dev, "TPM initialization fail\n");
    510	return ret;
    511}
    512EXPORT_SYMBOL(st33zp24_probe);
    513
    514void st33zp24_remove(struct tpm_chip *chip)
    515{
    516	tpm_chip_unregister(chip);
    517}
    518EXPORT_SYMBOL(st33zp24_remove);
    519
    520#ifdef CONFIG_PM_SLEEP
    521int st33zp24_pm_suspend(struct device *dev)
    522{
    523	struct tpm_chip *chip = dev_get_drvdata(dev);
    524	struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
    525
    526	int ret = 0;
    527
    528	if (gpio_is_valid(tpm_dev->io_lpcpd))
    529		gpio_set_value(tpm_dev->io_lpcpd, 0);
    530	else
    531		ret = tpm_pm_suspend(dev);
    532
    533	return ret;
    534}
    535EXPORT_SYMBOL(st33zp24_pm_suspend);
    536
    537int st33zp24_pm_resume(struct device *dev)
    538{
    539	struct tpm_chip *chip = dev_get_drvdata(dev);
    540	struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
    541	int ret = 0;
    542
    543	if (gpio_is_valid(tpm_dev->io_lpcpd)) {
    544		gpio_set_value(tpm_dev->io_lpcpd, 1);
    545		ret = wait_for_stat(chip,
    546				TPM_STS_VALID, chip->timeout_b,
    547				&tpm_dev->read_queue, false);
    548	} else {
    549		ret = tpm_pm_resume(dev);
    550		if (!ret)
    551			tpm1_do_selftest(chip);
    552	}
    553	return ret;
    554}
    555EXPORT_SYMBOL(st33zp24_pm_resume);
    556#endif
    557
    558MODULE_AUTHOR("TPM support (TPMsupport@list.st.com)");
    559MODULE_DESCRIPTION("ST33ZP24 TPM 1.2 driver");
    560MODULE_VERSION("1.3.0");
    561MODULE_LICENSE("GPL");