aboutsummaryrefslogtreecommitdiff
path: root/drivers/char/tpm/tpm.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/tpm/tpm.h')
-rw-r--r--drivers/char/tpm/tpm.h327
1 files changed, 288 insertions, 39 deletions
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 373b41f6b46..e4d0888d2ea 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -7,7 +7,7 @@
* Reiner Sailer <sailer@watson.ibm.com>
* Kylene Hall <kjhall@us.ibm.com>
*
- * Maintained by: <tpmdd_devel@lists.sourceforge.net>
+ * Maintained by: <tpmdd-devel@lists.sourceforge.net>
*
* Device driver for TCG/TCPA TPM (trusted platform module).
* Specifications at www.trustedcomputinggroup.org
@@ -19,14 +19,25 @@
*
*/
#include <linux/module.h>
-#include <linux/version.h>
-#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/fs.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/tpm.h>
+
+enum tpm_const {
+ TPM_MINOR = 224, /* officially assigned */
+ TPM_BUFSIZE = 4096,
+ TPM_NUM_DEVICES = 256,
+ TPM_RETRY = 50, /* 5 seconds */
+};
enum tpm_timeout {
TPM_TIMEOUT = 5, /* msecs */
+ TPM_TIMEOUT_RETRY = 100 /* msecs */
};
/* TPM addresses */
@@ -35,50 +46,80 @@ enum tpm_addr {
TPM_ADDR = 0x4E,
};
-extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr,
- char *);
-extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr,
- char *);
-extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr,
- char *);
-extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr,
- const char *, size_t);
+/* Indexes the duration array */
+enum tpm_duration {
+ TPM_SHORT = 0,
+ TPM_MEDIUM = 1,
+ TPM_LONG = 2,
+ TPM_UNDEFINED,
+};
+
+#define TPM_WARN_RETRY 0x800
+#define TPM_WARN_DOING_SELFTEST 0x802
+#define TPM_ERR_DEACTIVATED 0x6
+#define TPM_ERR_DISABLED 0x7
+#define TPM_ERR_INVALID_POSTINIT 38
+#define TPM_HEADER_SIZE 10
struct tpm_chip;
struct tpm_vendor_specific {
- u8 req_complete_mask;
- u8 req_complete_val;
- u8 req_canceled;
- u16 base; /* TPM base address */
-
- int (*recv) (struct tpm_chip *, u8 *, size_t);
- int (*send) (struct tpm_chip *, u8 *, size_t);
- void (*cancel) (struct tpm_chip *);
+ void __iomem *iobase; /* ioremapped address */
+ unsigned long base; /* TPM base address */
+
+ int irq;
+ int probed_irq;
+
+ int region_size;
+ int have_region;
+
struct miscdevice miscdev;
- struct attribute_group *attr_group;
+ struct list_head list;
+ int locality;
+ unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* jiffies */
+ bool timeout_adjusted;
+ unsigned long duration[3]; /* jiffies */
+ bool duration_adjusted;
+ void *priv;
+
+ wait_queue_head_t read_queue;
+ wait_queue_head_t int_queue;
+
+ u16 manufacturer_id;
};
+#define TPM_VPRIV(c) (c)->vendor.priv
+
+#define TPM_VID_INTEL 0x8086
+#define TPM_VID_WINBOND 0x1050
+#define TPM_VID_STM 0x104A
+
struct tpm_chip {
- struct pci_dev *pci_dev; /* PCI device stuff */
+ struct device *dev; /* Device stuff */
+ const struct tpm_class_ops *ops;
int dev_num; /* /dev/tpm# */
- int num_opens; /* only one allowed */
+ char devname[7];
+ unsigned long is_open; /* only one allowed */
int time_expired;
- /* Data passed to and from the tpm via the read/write calls */
- u8 *data_buffer;
- atomic_t data_pending;
- struct semaphore buffer_mutex;
+ struct mutex tpm_mutex; /* tpm is processing */
- struct timer_list user_read_timer; /* user needs to claim result */
- struct semaphore tpm_mutex; /* tpm is processing */
+ struct tpm_vendor_specific vendor;
- struct tpm_vendor_specific *vendor;
+ struct dentry **bios_dir;
struct list_head list;
+ void (*release) (struct device *);
};
+#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor)
+
+static inline void tpm_chip_put(struct tpm_chip *chip)
+{
+ module_put(chip->dev->driver->owner);
+}
+
static inline int tpm_read_index(int base, int index)
{
outb(index, base);
@@ -90,14 +131,222 @@ static inline void tpm_write_index(int base, int index, int value)
outb(index, base);
outb(value & 0xFF, base+1);
}
+struct tpm_input_header {
+ __be16 tag;
+ __be32 length;
+ __be32 ordinal;
+} __packed;
+
+struct tpm_output_header {
+ __be16 tag;
+ __be32 length;
+ __be32 return_code;
+} __packed;
+
+#define TPM_TAG_RQU_COMMAND cpu_to_be16(193)
+
+struct stclear_flags_t {
+ __be16 tag;
+ u8 deactivated;
+ u8 disableForceClear;
+ u8 physicalPresence;
+ u8 physicalPresenceLock;
+ u8 bGlobalLock;
+} __packed;
+
+struct tpm_version_t {
+ u8 Major;
+ u8 Minor;
+ u8 revMajor;
+ u8 revMinor;
+} __packed;
+
+struct tpm_version_1_2_t {
+ __be16 tag;
+ u8 Major;
+ u8 Minor;
+ u8 revMajor;
+ u8 revMinor;
+} __packed;
+
+struct timeout_t {
+ __be32 a;
+ __be32 b;
+ __be32 c;
+ __be32 d;
+} __packed;
+
+struct duration_t {
+ __be32 tpm_short;
+ __be32 tpm_medium;
+ __be32 tpm_long;
+} __packed;
+
+struct permanent_flags_t {
+ __be16 tag;
+ u8 disable;
+ u8 ownership;
+ u8 deactivated;
+ u8 readPubek;
+ u8 disableOwnerClear;
+ u8 allowMaintenance;
+ u8 physicalPresenceLifetimeLock;
+ u8 physicalPresenceHWEnable;
+ u8 physicalPresenceCMDEnable;
+ u8 CEKPUsed;
+ u8 TPMpost;
+ u8 TPMpostLock;
+ u8 FIPS;
+ u8 operator;
+ u8 enableRevokeEK;
+ u8 nvLocked;
+ u8 readSRKPub;
+ u8 tpmEstablished;
+ u8 maintenanceDone;
+ u8 disableFullDALogicInfo;
+} __packed;
+
+typedef union {
+ struct permanent_flags_t perm_flags;
+ struct stclear_flags_t stclear_flags;
+ bool owned;
+ __be32 num_pcrs;
+ struct tpm_version_t tpm_version;
+ struct tpm_version_1_2_t tpm_version_1_2;
+ __be32 manufacturer_id;
+ struct timeout_t timeout;
+ struct duration_t duration;
+} cap_t;
+
+enum tpm_capabilities {
+ TPM_CAP_FLAG = cpu_to_be32(4),
+ TPM_CAP_PROP = cpu_to_be32(5),
+ CAP_VERSION_1_1 = cpu_to_be32(0x06),
+ CAP_VERSION_1_2 = cpu_to_be32(0x1A)
+};
+
+enum tpm_sub_capabilities {
+ TPM_CAP_PROP_PCR = cpu_to_be32(0x101),
+ TPM_CAP_PROP_MANUFACTURER = cpu_to_be32(0x103),
+ TPM_CAP_FLAG_PERM = cpu_to_be32(0x108),
+ TPM_CAP_FLAG_VOL = cpu_to_be32(0x109),
+ TPM_CAP_PROP_OWNER = cpu_to_be32(0x111),
+ TPM_CAP_PROP_TIS_TIMEOUT = cpu_to_be32(0x115),
+ TPM_CAP_PROP_TIS_DURATION = cpu_to_be32(0x120),
+
+};
+
+struct tpm_getcap_params_in {
+ __be32 cap;
+ __be32 subcap_size;
+ __be32 subcap;
+} __packed;
+
+struct tpm_getcap_params_out {
+ __be32 cap_size;
+ cap_t cap;
+} __packed;
+
+struct tpm_readpubek_params_out {
+ u8 algorithm[4];
+ u8 encscheme[2];
+ u8 sigscheme[2];
+ __be32 paramsize;
+ u8 parameters[12]; /*assuming RSA*/
+ __be32 keysize;
+ u8 modulus[256];
+ u8 checksum[20];
+} __packed;
+
+typedef union {
+ struct tpm_input_header in;
+ struct tpm_output_header out;
+} tpm_cmd_header;
+
+struct tpm_pcrread_out {
+ u8 pcr_result[TPM_DIGEST_SIZE];
+} __packed;
+
+struct tpm_pcrread_in {
+ __be32 pcr_idx;
+} __packed;
+
+struct tpm_pcrextend_in {
+ __be32 pcr_idx;
+ u8 hash[TPM_DIGEST_SIZE];
+} __packed;
+
+/* 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18
+ * bytes, but 128 is still a relatively large number of random bytes and
+ * anything much bigger causes users of struct tpm_cmd_t to start getting
+ * compiler warnings about stack frame size. */
+#define TPM_MAX_RNG_DATA 128
+
+struct tpm_getrandom_out {
+ __be32 rng_data_len;
+ u8 rng_data[TPM_MAX_RNG_DATA];
+} __packed;
+
+struct tpm_getrandom_in {
+ __be32 num_bytes;
+} __packed;
+
+struct tpm_startup_in {
+ __be16 startup_type;
+} __packed;
+
+typedef union {
+ struct tpm_getcap_params_out getcap_out;
+ struct tpm_readpubek_params_out readpubek_out;
+ u8 readpubek_out_buffer[sizeof(struct tpm_readpubek_params_out)];
+ struct tpm_getcap_params_in getcap_in;
+ struct tpm_pcrread_in pcrread_in;
+ struct tpm_pcrread_out pcrread_out;
+ struct tpm_pcrextend_in pcrextend_in;
+ struct tpm_getrandom_in getrandom_in;
+ struct tpm_getrandom_out getrandom_out;
+ struct tpm_startup_in startup_in;
+} tpm_cmd_params;
+
+struct tpm_cmd_t {
+ tpm_cmd_header header;
+ tpm_cmd_params params;
+} __packed;
+
+ssize_t tpm_getcap(struct device *, __be32, cap_t *, const char *);
+
+ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
+ size_t bufsiz);
+extern int tpm_get_timeouts(struct tpm_chip *);
+extern void tpm_gen_interrupt(struct tpm_chip *);
+extern int tpm_do_selftest(struct tpm_chip *);
+extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32);
+extern struct tpm_chip* tpm_register_hardware(struct device *,
+ const struct tpm_class_ops *ops);
+extern void tpm_dev_vendor_release(struct tpm_chip *);
+extern void tpm_remove_hardware(struct device *);
+extern int tpm_pm_suspend(struct device *);
+extern int tpm_pm_resume(struct device *);
+extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long,
+ wait_queue_head_t *, bool);
+
+int tpm_dev_add_device(struct tpm_chip *chip);
+void tpm_dev_del_device(struct tpm_chip *chip);
+int tpm_sysfs_add_device(struct tpm_chip *chip);
+void tpm_sysfs_del_device(struct tpm_chip *chip);
+
+int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
+
+#ifdef CONFIG_ACPI
+extern int tpm_add_ppi(struct kobject *);
+extern void tpm_remove_ppi(struct kobject *);
+#else
+static inline int tpm_add_ppi(struct kobject *parent)
+{
+ return 0;
+}
-extern int tpm_register_hardware(struct pci_dev *,
- struct tpm_vendor_specific *);
-extern int tpm_open(struct inode *, struct file *);
-extern int tpm_release(struct inode *, struct file *);
-extern ssize_t tpm_write(struct file *, const char __user *, size_t,
- loff_t *);
-extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
-extern void __devexit tpm_remove(struct pci_dev *);
-extern int tpm_pm_suspend(struct pci_dev *, pm_message_t);
-extern int tpm_pm_resume(struct pci_dev *);
+static inline void tpm_remove_ppi(struct kobject *parent)
+{
+}
+#endif