|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 07/14] 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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |