Signed-off-by: Andreas Niederl <andreas.nied...@iaik.tugraz.at>
---
 Makefile.target |    3 +++
 hw/acpi.c       |   28 ++++++++++++++++++++++++++++
 hw/pc.h         |    1 +
 hw/tpm.h        |    2 ++
 hw/tpm_acpi.c   |   40 ++++++++++++++++++++++++++++++++++++++++
 hw/tpm_ssdt.dsl |   55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/tpm_ssdt.hex |   41 +++++++++++++++++++++++++++++++++++++++++
 hw/tpm_tis.c    |    1 +
 rules.mak       |    7 ++++++-
 vl.c            |   23 +++++++++++++++++++++++
 10 files changed, 200 insertions(+), 1 deletions(-)
 create mode 100644 hw/tpm_acpi.c
 create mode 100644 hw/tpm_ssdt.dsl
 create mode 100644 hw/tpm_ssdt.hex

diff --git a/Makefile.target b/Makefile.target
index 5a0fd40..33ffe19 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -211,6 +211,9 @@ obj-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o
 # Inter-VM PCI shared memory
 obj-$(CONFIG_KVM) += ivshmem.o
 
+# TPM acpi support
+obj-$(CONFIG_TPM) += tpm_acpi.o
+
 # Hardware support
 obj-i386-y += vga.o
 obj-i386-y += mc146818rtc.o i8259.o pc.o
diff --git a/hw/acpi.c b/hw/acpi.c
index 8071e7b..93656c5 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -35,6 +35,34 @@ struct acpi_table_header
 char *acpi_tables;
 size_t acpi_tables_len;
 
+
+/*
+ * add a table directly (e.g. iasl C source output)
+ */
+int acpi_table_add_raw(const char *t, uint32_t length)
+{
+    char *p;
+
+    if (!acpi_tables) {
+        acpi_tables_len = sizeof(uint16_t);
+        acpi_tables = qemu_mallocz(acpi_tables_len);
+    }
+    acpi_tables = qemu_realloc(acpi_tables,
+                               acpi_tables_len + sizeof(uint16_t) + length);
+    p = acpi_tables + acpi_tables_len;
+    acpi_tables_len += sizeof(uint16_t) + length;
+
+    *(uint16_t*)p = cpu_to_le32(length);
+    p += sizeof(uint16_t);
+
+    memcpy(p, t, length);
+
+    /* increase number of tables */
+    (*(uint16_t*)acpi_tables) =
+        cpu_to_le32(le32_to_cpu(*(uint16_t*)acpi_tables) + 1);
+    return 0;
+}
+
 static int acpi_checksum(const uint8_t *data, int len)
 {
     int sum, i;
diff --git a/hw/pc.h b/hw/pc.h
index d5d2f42..56ba5fc 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -118,6 +118,7 @@ extern size_t acpi_tables_len;
 
 void acpi_bios_init(void);
 int acpi_table_add(const char *table_desc);
+int acpi_table_add_raw(const char *table, uint32_t length);
 
 /* acpi_piix.c */
 
diff --git a/hw/tpm.h b/hw/tpm.h
index f3e1395..5dd40c8 100644
--- a/hw/tpm.h
+++ b/hw/tpm.h
@@ -19,4 +19,6 @@
 
 int qemu_tpm_add(QemuOpts *opts);
 
+int qemu_tpm_acpi_init(void);
+
 #endif /* TPM_H */
diff --git a/hw/tpm_acpi.c b/hw/tpm_acpi.c
new file mode 100644
index 0000000..8cfa98f
--- /dev/null
+++ b/hw/tpm_acpi.c
@@ -0,0 +1,40 @@
+/*
+ * tpm_acpi.c - ACPI integration for TPM device emulation
+ *
+ * Copyright (C) 2011 IAIK, Graz University of Technology
+ *
+ * Author: Andreas Niederl <andreas.nied...@iaik.tugraz.at>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ */
+
+#include "hw/pc.h"
+#include "hw/tpm.h"
+
+/*
+ * Add SSDT entry for TPM device
+ *
+ * Only one such entry is possible because it specifies a fixed MMIO address
+ * as required by the TIS 1.2 specification.
+ */
+int qemu_tpm_acpi_init(void)
+{
+    int ret = 0;
+#ifdef TARGET_I386
+    static int init = 0;
+
+#include "hw/tpm_ssdt.hex"
+
+    if (!init) {
+        ret  = acpi_table_add_raw((char*)AmlCode, sizeof(AmlCode));
+        init = 1;
+    }
+#endif
+
+    return ret;
+}
+
diff --git a/hw/tpm_ssdt.dsl b/hw/tpm_ssdt.dsl
new file mode 100644
index 0000000..d9a48a7
--- /dev/null
+++ b/hw/tpm_ssdt.dsl
@@ -0,0 +1,55 @@
+/*
+ * ACPI SSDT ASL definition for TPM device emulation
+ *
+ * Copyright (C) 2011 IAIK, Graz University of Technology
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>
+ */
+
+DefinitionBlock (
+    "tpm-ssdt.aml",    // Output Filename
+    "SSDT",             // Signature
+    0x01,               // DSDT Compliance Revision
+    "BXPC",             // OEMID
+    "TPM-SSDT",         // TABLE ID
+    0x1                 // OEM Revision
+    )
+{
+
+    Scope(\_SB) {
+        /* Pass-through TPM device with emulated TPM TIS interface */
+        Device (TPM) {
+            Name (_HID, EisaID ("ATM1200"))
+            Name (_CID, EisaId ("PNP0C31"))
+            Name (_STR, Unicode ("Emulated TPM TIS pass-through device"))
+            Name (BUF1, ResourceTemplate ()
+            {
+                    Memory32Fixed (ReadOnly,
+                                   0xFED40000,         // Address Base
+                                   0x00005000,         // Address Length
+                                  )
+                    IRQNoFlags () {11}
+            })
+            Method (_CRS, 0, Serialized)
+            {
+                Return (BUF1)
+            }
+            Method (_STA, 0)
+            {
+                Return (0x0F)
+            }
+        }
+
+    }
+}
+
diff --git a/hw/tpm_ssdt.hex b/hw/tpm_ssdt.hex
new file mode 100644
index 0000000..da1d4c3
--- /dev/null
+++ b/hw/tpm_ssdt.hex
@@ -0,0 +1,41 @@
+/*
+ * 
+ * Intel ACPI Component Architecture
+ * ASL Optimizing Compiler version 20090123 [Jun  3 2009]
+ * Copyright (C) 2000 - 2009 Intel Corporation
+ * Supports ACPI Specification Revision 3.0a
+ * 
+ * Compilation of "hw/tpm_ssdt.dsl" - Wed Feb  2 17:49:34 2011
+ * 
+ * C source code output
+ *
+ */
+unsigned char AmlCode[] =
+{
+    0x53,0x53,0x44,0x54,0xCC,0x00,0x00,0x00,  /* 00000000    "SSDT...." */
+    0x01,0xEC,0x42,0x58,0x50,0x43,0x00,0x00,  /* 00000008    "..BXPC.." */
+    0x54,0x50,0x4D,0x2D,0x53,0x53,0x44,0x54,  /* 00000010    "TPM-SSDT" */
+    0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
+    0x23,0x01,0x09,0x20,0x10,0x47,0x0A,0x5C,  /* 00000020    "#.. .G.\" */
+    0x5F,0x53,0x42,0x5F,0x5B,0x82,0x4E,0x09,  /* 00000028    "_SB_[.N." */
+    0x54,0x50,0x4D,0x5F,0x08,0x5F,0x48,0x49,  /* 00000030    "TPM_._HI" */
+    0x44,0x0C,0x06,0x8D,0x12,0x00,0x08,0x5F,  /* 00000038    "D......_" */
+    0x43,0x49,0x44,0x0C,0x41,0xD0,0x0C,0x31,  /* 00000040    "CID.A..1" */
+    0x08,0x5F,0x53,0x54,0x52,0x11,0x4E,0x04,  /* 00000048    "._STR.N." */
+    0x0A,0x4A,0x45,0x00,0x6D,0x00,0x75,0x00,  /* 00000050    ".JE.m.u." */
+    0x6C,0x00,0x61,0x00,0x74,0x00,0x65,0x00,  /* 00000058    "l.a.t.e." */
+    0x64,0x00,0x20,0x00,0x54,0x00,0x50,0x00,  /* 00000060    "d. .T.P." */
+    0x4D,0x00,0x20,0x00,0x54,0x00,0x49,0x00,  /* 00000068    "M. .T.I." */
+    0x53,0x00,0x20,0x00,0x70,0x00,0x61,0x00,  /* 00000070    "S. .p.a." */
+    0x73,0x00,0x73,0x00,0x2D,0x00,0x74,0x00,  /* 00000078    "s.s.-.t." */
+    0x68,0x00,0x72,0x00,0x6F,0x00,0x75,0x00,  /* 00000080    "h.r.o.u." */
+    0x67,0x00,0x68,0x00,0x20,0x00,0x64,0x00,  /* 00000088    "g.h. .d." */
+    0x65,0x00,0x76,0x00,0x69,0x00,0x63,0x00,  /* 00000090    "e.v.i.c." */
+    0x65,0x00,0x00,0x00,0x08,0x42,0x55,0x46,  /* 00000098    "e....BUF" */
+    0x31,0x11,0x14,0x0A,0x11,0x86,0x09,0x00,  /* 000000A0    "1......." */
+    0x00,0x00,0x00,0xD4,0xFE,0x00,0x50,0x00,  /* 000000A8    "......P." */
+    0x00,0x22,0x00,0x08,0x79,0x00,0x14,0x0B,  /* 000000B0    "."..y..." */
+    0x5F,0x43,0x52,0x53,0x08,0xA4,0x42,0x55,  /* 000000B8    "_CRS..BU" */
+    0x46,0x31,0x14,0x09,0x5F,0x53,0x54,0x41,  /* 000000C0    "F1.._STA" */
+    0x00,0xA4,0x0A,0x0F,
+};
diff --git a/hw/tpm_tis.c b/hw/tpm_tis.c
index a4c2a4e..589add6 100644
--- a/hw/tpm_tis.c
+++ b/hw/tpm_tis.c
@@ -635,6 +635,7 @@ static const VMStateDescription vmstate_tpm = {
     }
 };
 
+
 /*
  * initialize TIS interface
  */
diff --git a/rules.mak b/rules.mak
index ed59c9e..3c5cdc5 100644
--- a/rules.mak
+++ b/rules.mak
@@ -31,6 +31,11 @@ LINK = $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(CFLAGS) 
$(LDFLAGS) -o $@ $(1)
 %.a:
        $(call quiet-command,rm -f $@ && $(AR) rcs $@ $^,"  AR    
$(TARGET_DIR)$@")
 
+# ACPI table build rule
+%.hex: %.dsl
+       $(call quiet-command,iasl -tc -p $@ $<,"  GEN   $(TARGET_DIR)$@")
+
+
 quiet-command = $(if $(V),$1,$(if $(2),@echo $2 && $1, @$1))
 
 # cc-option
@@ -39,7 +44,7 @@ quiet-command = $(if $(V),$1,$(if $(2),@echo $2 && $1, @$1))
 cc-option = $(if $(shell $(CC) $1 $2 -S -o /dev/null -xc /dev/null \
               >/dev/null 2>&1 && echo OK), $2, $3)
 
-VPATH_SUFFIXES = %.c %.h %.S %.m %.mak %.texi
+VPATH_SUFFIXES = %.c %.h %.S %.m %.mak %.texi %.dsl
 set-vpath = $(if $1,$(foreach PATTERN,$(VPATH_SUFFIXES),$(eval vpath 
$(PATTERN) $1)))
 
 # find-in-path
diff --git a/vl.c b/vl.c
index b436952..f74f37a 100644
--- a/vl.c
+++ b/vl.c
@@ -151,6 +151,9 @@ int main(int argc, char **argv)
 #ifdef CONFIG_VIRTFS
 #include "fsdev/qemu-fsdev.h"
 #endif
+#ifdef CONFIG_TPM
+#include "hw/tpm.h"
+#endif
 
 #include "disas.h"
 
@@ -1647,6 +1650,19 @@ static int fsdev_init_func(QemuOpts *opts, void *opaque)
 }
 #endif
 
+#ifdef CONFIG_TPM
+static int tpm_acpi_init_func(QemuOpts *opts, void *opaque)
+{
+    int ret = 0;
+
+    if (strcmp(qemu_opt_get(opts, "driver"), "tpm") == 0) {
+        ret = qemu_tpm_acpi_init();
+    }
+
+    return ret;
+}
+#endif
+
 static int mon_init_func(QemuOpts *opts, void *opaque)
 {
     CharDriverState *chr;
@@ -2864,6 +2880,13 @@ int main(int argc, char **argv, char **envp)
     }
 #endif
 
+#ifdef CONFIG_TPM
+    /* register TPM acpi table before machine->init is called */
+    if (qemu_opts_foreach(qemu_find_opts("device"), tpm_acpi_init_func, NULL, 
1) != 0) {
+        exit(1);
+    }
+#endif
+
     os_daemonize();
 
     if (pid_file && qemu_create_pidfile(pid_file) != 0) {
-- 
1.7.4.1


Reply via email to