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

tpm_atmel.h (3295B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 * Copyright (C) 2005 IBM Corporation
      4 *
      5 * Authors:
      6 * Kylene Hall <kjhall@us.ibm.com>
      7 *
      8 * Maintained by: <tpmdd-devel@lists.sourceforge.net>
      9 *
     10 * Device driver for TCG/TCPA TPM (trusted platform module).
     11 * Specifications at www.trustedcomputinggroup.org
     12 *
     13 * These difference are required on power because the device must be
     14 * discovered through the device tree and iomap must be used to get
     15 * around the need for holes in the io_page_mask.  This does not happen
     16 * automatically because the tpm is not a normal pci device and lives
     17 * under the root node.
     18 */
     19
     20struct tpm_atmel_priv {
     21	int region_size;
     22	int have_region;
     23	unsigned long base;
     24	void __iomem *iobase;
     25};
     26
     27#ifdef CONFIG_PPC64
     28
     29#include <asm/prom.h>
     30
     31#define atmel_getb(priv, offset) readb(priv->iobase + offset)
     32#define atmel_putb(val, priv, offset) writeb(val, priv->iobase + offset)
     33#define atmel_request_region request_mem_region
     34#define atmel_release_region release_mem_region
     35
     36static inline void atmel_put_base_addr(void __iomem *iobase)
     37{
     38	iounmap(iobase);
     39}
     40
     41static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
     42{
     43	struct device_node *dn;
     44	unsigned long address, size;
     45	const unsigned int *reg;
     46	int reglen;
     47	int naddrc;
     48	int nsizec;
     49
     50	dn = of_find_node_by_name(NULL, "tpm");
     51
     52	if (!dn)
     53		return NULL;
     54
     55	if (!of_device_is_compatible(dn, "AT97SC3201")) {
     56		of_node_put(dn);
     57		return NULL;
     58	}
     59
     60	reg = of_get_property(dn, "reg", &reglen);
     61	naddrc = of_n_addr_cells(dn);
     62	nsizec = of_n_size_cells(dn);
     63
     64	of_node_put(dn);
     65
     66
     67	if (naddrc == 2)
     68		address = ((unsigned long) reg[0] << 32) | reg[1];
     69	else
     70		address = reg[0];
     71
     72	if (nsizec == 2)
     73		size =
     74		    ((unsigned long) reg[naddrc] << 32) | reg[naddrc + 1];
     75	else
     76		size = reg[naddrc];
     77
     78	*base = address;
     79	*region_size = size;
     80	return ioremap(*base, *region_size);
     81}
     82#else
     83#define atmel_getb(chip, offset) inb(atmel_get_priv(chip)->base + offset)
     84#define atmel_putb(val, chip, offset) \
     85	outb(val, atmel_get_priv(chip)->base + offset)
     86#define atmel_request_region request_region
     87#define atmel_release_region release_region
     88/* Atmel definitions */
     89enum tpm_atmel_addr {
     90	TPM_ATMEL_BASE_ADDR_LO = 0x08,
     91	TPM_ATMEL_BASE_ADDR_HI = 0x09
     92};
     93
     94static inline int tpm_read_index(int base, int index)
     95{
     96	outb(index, base);
     97	return inb(base+1) & 0xFF;
     98}
     99
    100/* Verify this is a 1.1 Atmel TPM */
    101static int atmel_verify_tpm11(void)
    102{
    103
    104	/* verify that it is an Atmel part */
    105	if (tpm_read_index(TPM_ADDR, 4) != 'A' ||
    106	    tpm_read_index(TPM_ADDR, 5) != 'T' ||
    107	    tpm_read_index(TPM_ADDR, 6) != 'M' ||
    108	    tpm_read_index(TPM_ADDR, 7) != 'L')
    109		return 1;
    110
    111	/* query chip for its version number */
    112	if (tpm_read_index(TPM_ADDR, 0x00) != 1 ||
    113	    tpm_read_index(TPM_ADDR, 0x01) != 1)
    114		return 1;
    115
    116	/* This is an atmel supported part */
    117	return 0;
    118}
    119
    120static inline void atmel_put_base_addr(void __iomem *iobase)
    121{
    122}
    123
    124/* Determine where to talk to device */
    125static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
    126{
    127	int lo, hi;
    128
    129	if (atmel_verify_tpm11() != 0)
    130		return NULL;
    131
    132	lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
    133	hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
    134
    135	*base = (hi << 8) | lo;
    136	*region_size = 2;
    137
    138	return ioport_map(*base, *region_size);
    139}
    140#endif