[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 07/12] vTPM/TPM2: TPM2.0 TIS initialization and self test.



call the TPM 2.0 various registers that allow communication between
the TPM 2.0 and platform hardware and software. TPM2_SelfTest causes
the TPM 2.0 to perform a test of its capabilities.

Signed-off-by: Quan Xu <quan.xu@xxxxxxxxx>
---
 extras/mini-os/include/tpm_tis.h |   1 +
 extras/mini-os/tpm_tis.c         | 156 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 157 insertions(+)

diff --git a/extras/mini-os/include/tpm_tis.h b/extras/mini-os/include/tpm_tis.h
index 1faca0d..86e83f1 100644
--- a/extras/mini-os/include/tpm_tis.h
+++ b/extras/mini-os/include/tpm_tis.h
@@ -36,6 +36,7 @@
 struct tpm_chip;
 
 struct tpm_chip* init_tpm_tis(unsigned long baseaddr, int localities, unsigned 
int irq);
+struct tpm_chip* init_tpm2_tis(unsigned long baseaddr, int localities, 
unsigned int irq);
 void shutdown_tpm_tis(struct tpm_chip* tpm);
 
 int tpm_tis_request_locality(struct tpm_chip* tpm, int locality);
diff --git a/extras/mini-os/tpm_tis.c b/extras/mini-os/tpm_tis.c
index d78c465..debcc43 100644
--- a/extras/mini-os/tpm_tis.c
+++ b/extras/mini-os/tpm_tis.c
@@ -1363,5 +1363,161 @@ int tpm_tis_posix_fstat(int fd, struct stat* buf)
    return 0;
 }
 
+/* TPM 2.0 */
 
+/*TPM2.0 Selftest*/
+static void tpm2_selftest(struct tpm_chip* chip)
+{
+    uint8_t data[] = {
+        0x80, 0x1,
+        0x0, 0x0, 0x0, 0xb,
+        0x0, 0x0, 0x1, 0x43,
+        0x1,
+    };
+
+    tpm_transmit(chip, data, sizeof(data));
+}
+
+struct tpm_chip* init_tpm2_tis(unsigned long baseaddr, int localities, 
unsigned int irq)
+{
+    int i;
+    unsigned long addr;
+    struct tpm_chip* tpm = NULL;
+    uint32_t didvid;
+    uint32_t intfcaps;
+    uint32_t intmask;
+
+    printk("============= Init TPM2 TIS Driver ==============\n");
+
+    /*Sanity check the localities input */
+    if (localities & ~TPM_TIS_EN_LOCLALL) {
+        printk("init_tpm2_tis Invalid locality specification! %X\n", 
localities);
+        goto abort_egress;
+    }
+
+    printk("IOMEM Machine Base Address: %lX\n", baseaddr);
+
+    /* Create the tpm data structure */
+    tpm = malloc(sizeof(struct tpm_chip));
+    __init_tpm_chip(tpm);
+
+    /* Set the enabled localities - if 0 we leave default as all enabled */
+    if (localities != 0) {
+        tpm->enabled_localities = localities;
+    }
+    printk("Enabled Localities: ");
+    for (i = 0; i < 5; ++i) {
+        if (locality_enabled(tpm, i)) {
+            printk("%d ", i);
+        }
+    }
+    printk("\n");
+
+    /* Set the base machine address */
+    tpm->baseaddr = baseaddr;
+
+    /* Set default timeouts */
+    tpm->timeout_a = MILLISECS(TIS_SHORT_TIMEOUT);
+    tpm->timeout_b = MILLISECS(TIS_LONG_TIMEOUT);
+    tpm->timeout_c = MILLISECS(TIS_SHORT_TIMEOUT);
+    tpm->timeout_d = MILLISECS(TIS_SHORT_TIMEOUT);
+
+    /*Map the mmio pages */
+    addr = tpm->baseaddr;
+    for (i = 0; i < 5; ++i) {
+        if (locality_enabled(tpm, i)) {
+
+            /* Map the page in now */
+            if ((tpm->pages[i] = ioremap_nocache(addr, PAGE_SIZE)) == NULL) {
+                printk("Unable to map iomem page a address %p\n", addr);
+                goto abort_egress;
+            }
+
+            /* Set default locality to the first enabled one */
+            if (tpm->locality < 0) {
+                if (tpm_tis_request_locality(tpm, i) < 0) {
+                    printk("Unable to request locality %d??\n", i);
+                    goto abort_egress;
+                }
+            }
+        }
+        addr += PAGE_SIZE;
+    }
+
+    /* Get the vendor and device ids */
+    didvid = ioread32(TPM_DID_VID(tpm, tpm->locality));
+    tpm->did = didvid >> 16;
+    tpm->vid = didvid & 0xFFFF;
+
+    /* Get the revision id */
+    tpm->rid = ioread8(TPM_RID(tpm, tpm->locality));
+    printk("2.0 TPM (device-id=0x%X vendor-id = %X rev-id = %X)\n",
+           tpm->did, tpm->vid, tpm->rid);
+
+    intfcaps = ioread32(TPM_INTF_CAPS(tpm, tpm->locality));
+    printk("TPM interface capabilities (0x%x):\n", intfcaps);
+    if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
+        printk("\tBurst Count Static\n");
+    if (intfcaps & TPM_INTF_CMD_READY_INT)
+        printk("\tCommand Ready Int Support\n");
+    if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
+        printk("\tInterrupt Edge Falling\n");
+    if (intfcaps & TPM_INTF_INT_EDGE_RISING)
+        printk("\tInterrupt Edge Rising\n");
+    if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
+        printk("\tInterrupt Level Low\n");
+    if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
+        printk("\tInterrupt Level High\n");
+    if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT)
+        printk("\tLocality Change Int Support\n");
+    if (intfcaps & TPM_INTF_STS_VALID_INT)
+        printk("\tSts Valid Int Support\n");
+    if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
+        printk("\tData Avail Int Support\n");
+
+    /*Interupt setup */
+    intmask = ioread32(TPM_INT_ENABLE(tpm, tpm->locality));
+
+    intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT |
+               TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT;
+
+    iowrite32(TPM_INT_ENABLE(tpm, tpm->locality), intmask);
+
+    /*If interupts are enabled, handle it */
+    if (irq) {
+        if (irq != TPM_PROBE_IRQ) {
+            tpm->irq = irq;
+        } else {
+        /*FIXME add irq probing feature later */
+        printk("IRQ probing not implemented\n");
+        }
+    }
+
+    if (tpm->irq) {
+        iowrite8(TPM_INT_VECTOR(tpm, tpm->locality), tpm->irq);
+        if (bind_pirq(tpm->irq, 1, tpm_tis_irq_handler, tpm) != 0) {
+            printk("Unabled to request irq: %u for use\n", tpm->irq);
+            printk("Will use polling mode\n");
+            tpm->irq = 0;
+        } else {
+
+            /* Clear all existing */
+            iowrite32(TPM_INT_STATUS(tpm, tpm->locality),
+                                     ioread32(TPM_INT_STATUS(tpm, 
tpm->locality)));
+
+            /* Turn on interrupts */
+            iowrite32(TPM_INT_ENABLE(tpm, tpm->locality),
+                                     intmask | TPM_GLOBAL_INT_ENABLE);
+        }
+    }
+
+    tpm2_selftest(tpm);
+    return tpm;
+
+abort_egress:
+    if (tpm != NULL) {
+        shutdown_tpm_tis(tpm);
+    }
+    return NULL;
+}
 #endif
-- 
1.8.3.2


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.