diff mbox

[PULL,48/57] TPM2 ACPI table support

Message ID 1433097192-8988-49-git-send-email-mst@redhat.com
State New
Headers show

Commit Message

Michael S. Tsirkin May 31, 2015, 6:37 p.m. UTC
From: Stefan Berger <stefanb@linux.vnet.ibm.com>

Add a TPM2 ACPI table if a TPM 2 is used in the backend.
Also add an SSDT for the TPM 2.

Rename tpm_find() to tpm_get_version() and have this function
return the version of the TPM found, TPMVersion_Unspec if
no TPM is found. Use the version number to build version
specific ACPI tables.

Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 include/hw/acpi/acpi-defs.h    | 18 ++++++++++++++++++
 include/hw/acpi/tpm.h          |  5 +++++
 include/sysemu/tpm.h           | 11 +++++++++--
 hw/i386/acpi-build.c           | 38 ++++++++++++++++++++++++++++++++++----
 hw/tpm/tpm_tis.c               | 11 +++++++++++
 hw/i386/Makefile.objs          |  2 +-
 hw/i386/ssdt-tpm.dsl           | 16 +---------------
 hw/i386/ssdt-tpm.hex.generated | 26 ++++++++++++++++++++------
 8 files changed, 99 insertions(+), 28 deletions(-)

Comments

Igor Mammedov June 4, 2015, 1:57 p.m. UTC | #1
On Sun, 31 May 2015 20:37:28 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> From: Stefan Berger <stefanb@linux.vnet.ibm.com>
[...]
> diff --git a/hw/i386/ssdt-tpm.dsl b/hw/i386/ssdt-tpm.dsl
> index 75d9691..d81478c 100644
> --- a/hw/i386/ssdt-tpm.dsl
> +++ b/hw/i386/ssdt-tpm.dsl
> @@ -25,19 +25,5 @@ DefinitionBlock (
>      0x1                 // OEM Revision
>      )
>  {
> -    Scope(\_SB) {
> -        /* TPM with emulated TPM TIS interface */
> -        Device (TPM) {
> -            Name (_HID, EisaID ("PNP0C31"))
> -            Name (_CRS, ResourceTemplate ()
> -            {
> -                Memory32Fixed (ReadWrite, TPM_TIS_ADDR_BASE,
> TPM_TIS_ADDR_SIZE)
> -                // older Linux tpm_tis drivers do not work with IRQ
> -                //IRQNoFlags () {TPM_TIS_IRQ}
> -            })
> -            Method (_STA, 0, NotSerialized) {
> -                Return (0x0F)
> -            }
> -        }
> -    }
> +#include "ssdt-tpm-common.dsl"
Stefan,

Original TPM had IRQNoFlags commented out but looking at current master 

hw/i386/ssdt-tpm.dsl:
...
{
#include "ssdt-tpm-common.dsl"
}

hw/i386/ssdt-tpm-common.dsl:
...
* Common parts for TPM 1.2 and TPM 2 (with slight differences for PPI)
...
        Device (TPM) {
            Name (_HID, EisaID ("PNP0C31"))
            Name (_CRS, ResourceTemplate ()
            {
                Memory32Fixed (ReadWrite, TPM_TIS_ADDR_BASE, TPM_TIS_ADDR_SIZE)
                IRQNoFlags () {TPM_TIS_IRQ}
            })
and TMP2 template includes the same ssdt-tpm-common.dsl so cited
difference in comment above is gone now which makes TPM and TPM2
the same.
Was it intended change or we have introduced a bug?
Stefan Berger June 5, 2015, 8:42 p.m. UTC | #2
On 06/04/2015 09:57 AM, Igor Mammedov wrote:
> On Sun, 31 May 2015 20:37:28 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
>
>> From: Stefan Berger <stefanb@linux.vnet.ibm.com>
> [...]
>> diff --git a/hw/i386/ssdt-tpm.dsl b/hw/i386/ssdt-tpm.dsl
>> index 75d9691..d81478c 100644
>> --- a/hw/i386/ssdt-tpm.dsl
>> +++ b/hw/i386/ssdt-tpm.dsl
>> @@ -25,19 +25,5 @@ DefinitionBlock (
>>       0x1                 // OEM Revision
>>       )
>>   {
>> -    Scope(\_SB) {
>> -        /* TPM with emulated TPM TIS interface */
>> -        Device (TPM) {
>> -            Name (_HID, EisaID ("PNP0C31"))
>> -            Name (_CRS, ResourceTemplate ()
>> -            {
>> -                Memory32Fixed (ReadWrite, TPM_TIS_ADDR_BASE,
>> TPM_TIS_ADDR_SIZE)
>> -                // older Linux tpm_tis drivers do not work with IRQ
>> -                //IRQNoFlags () {TPM_TIS_IRQ}
>> -            })
>> -            Method (_STA, 0, NotSerialized) {
>> -                Return (0x0F)
>> -            }
>> -        }
>> -    }
>> +#include "ssdt-tpm-common.dsl"
> Stefan,
>
> Original TPM had IRQNoFlags commented out but looking at current master
>
> hw/i386/ssdt-tpm.dsl:
> ...
> {
> #include "ssdt-tpm-common.dsl"
> }
>
> hw/i386/ssdt-tpm-common.dsl:
> ...
> * Common parts for TPM 1.2 and TPM 2 (with slight differences for PPI)
> ...
>          Device (TPM) {
>              Name (_HID, EisaID ("PNP0C31"))
>              Name (_CRS, ResourceTemplate ()
>              {
>                  Memory32Fixed (ReadWrite, TPM_TIS_ADDR_BASE, TPM_TIS_ADDR_SIZE)
>                  IRQNoFlags () {TPM_TIS_IRQ}
>              })
> and TMP2 template includes the same ssdt-tpm-common.dsl so cited
> difference in comment above is gone now which makes TPM and TPM2
> the same.
> Was it intended change or we have introduced a bug?
>

This was an intended change. Once the physical presence interface code 
is added, there will be a difference between the two.
diff mbox

Patch

diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index f503ec4..59cf277 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -450,6 +450,9 @@  typedef struct AcpiTableMcfg AcpiTableMcfg;
 
 /*
  * TCPA Description Table
+ *
+ * Following Level 00, Rev 00.37 of specs:
+ * http://www.trustedcomputinggroup.org/resources/tcg_acpi_specification
  */
 struct Acpi20Tcpa {
     ACPI_TABLE_HEADER_DEF                    /* ACPI common table header */
@@ -459,6 +462,21 @@  struct Acpi20Tcpa {
 } QEMU_PACKED;
 typedef struct Acpi20Tcpa Acpi20Tcpa;
 
+/*
+ * TPM2
+ *
+ * Following Level 00, Rev 00.37 of specs:
+ * http://www.trustedcomputinggroup.org/resources/tcg_acpi_specification
+ */
+struct Acpi20TPM2 {
+    ACPI_TABLE_HEADER_DEF
+    uint16_t platform_class;
+    uint16_t reserved;
+    uint64_t control_area_address;
+    uint32_t start_method;
+} QEMU_PACKED;
+typedef struct Acpi20TPM2 Acpi20TPM2;
+
 /* DMAR - DMA Remapping table r2.2 */
 struct AcpiTableDmar {
     ACPI_TABLE_HEADER_DEF
diff --git a/include/hw/acpi/tpm.h b/include/hw/acpi/tpm.h
index 792fcbf..6d516c6 100644
--- a/include/hw/acpi/tpm.h
+++ b/include/hw/acpi/tpm.h
@@ -26,4 +26,9 @@ 
 #define TPM_TCPA_ACPI_CLASS_CLIENT  0
 #define TPM_TCPA_ACPI_CLASS_SERVER  1
 
+#define TPM2_ACPI_CLASS_CLIENT      0
+#define TPM2_ACPI_CLASS_SERVER      1
+
+#define TPM2_START_METHOD_MMIO      6
+
 #endif /* HW_ACPI_TPM_H */
diff --git a/include/sysemu/tpm.h b/include/sysemu/tpm.h
index 848df41..c143890 100644
--- a/include/sysemu/tpm.h
+++ b/include/sysemu/tpm.h
@@ -26,11 +26,18 @@  typedef enum  TPMVersion {
     TPM_VERSION_2_0 = 2,
 } TPMVersion;
 
+TPMVersion tpm_tis_get_tpm_version(Object *obj);
+
 #define TYPE_TPM_TIS                "tpm-tis"
 
-static inline bool tpm_find(void)
+static inline TPMVersion tpm_get_version(void)
 {
-    return object_resolve_path_type("", TYPE_TPM_TIS, NULL);
+    Object *obj = object_resolve_path_type("", TYPE_TPM_TIS, NULL);
+
+    if (obj) {
+        return tpm_tis_get_tpm_version(obj);
+    }
+    return TPM_VERSION_UNSPEC;
 }
 
 #endif /* QEMU_TPM_H */
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 283d02e..2c7399b 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -41,6 +41,7 @@ 
 #include "hw/acpi/memory_hotplug.h"
 #include "sysemu/tpm.h"
 #include "hw/acpi/tpm.h"
+#include "sysemu/tpm_backend.h"
 
 /* Supported chipsets: */
 #include "hw/acpi/piix4.h"
@@ -106,7 +107,7 @@  typedef struct AcpiPmInfo {
 
 typedef struct AcpiMiscInfo {
     bool has_hpet;
-    bool has_tpm;
+    TPMVersion tpm_version;
     const unsigned char *dsdt_code;
     unsigned dsdt_size;
     uint16_t pvpanic_port;
@@ -234,7 +235,7 @@  static void acpi_get_pm_info(AcpiPmInfo *pm)
 static void acpi_get_misc_info(AcpiMiscInfo *info)
 {
     info->has_hpet = hpet_find();
-    info->has_tpm = tpm_find();
+    info->tpm_version = tpm_get_version();
     info->pvpanic_port = pvpanic_port();
     info->applesmc_io_base = applesmc_port();
 }
@@ -414,6 +415,7 @@  build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu,
 }
 
 #include "hw/i386/ssdt-tpm.hex"
+#include "hw/i386/ssdt-tpm2.hex"
 
 /* Assign BSEL property to all buses.  In the future, this can be changed
  * to only assign to buses that support hotplug.
@@ -1029,6 +1031,25 @@  build_tpm_ssdt(GArray *table_data, GArray *linker)
     memcpy(tpm_ptr, ssdt_tpm_aml, sizeof(ssdt_tpm_aml));
 }
 
+static void
+build_tpm2(GArray *table_data, GArray *linker)
+{
+    Acpi20TPM2 *tpm2_ptr;
+    void *tpm_ptr;
+
+    tpm_ptr = acpi_data_push(table_data, sizeof(ssdt_tpm2_aml));
+    memcpy(tpm_ptr, ssdt_tpm2_aml, sizeof(ssdt_tpm2_aml));
+
+    tpm2_ptr = acpi_data_push(table_data, sizeof *tpm2_ptr);
+
+    tpm2_ptr->platform_class = cpu_to_le16(TPM2_ACPI_CLASS_CLIENT);
+    tpm2_ptr->control_area_address = cpu_to_le64(0);
+    tpm2_ptr->start_method = cpu_to_le32(TPM2_START_METHOD_MMIO);
+
+    build_header(linker, table_data,
+                 (void *)tpm2_ptr, "TPM2", sizeof(*tpm2_ptr), 4);
+}
+
 typedef enum {
     MEM_AFFINITY_NOFLAGS      = 0,
     MEM_AFFINITY_ENABLED      = (1 << 0),
@@ -1343,12 +1364,21 @@  void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
         acpi_add_table(table_offsets, tables_blob);
         build_hpet(tables_blob, tables->linker);
     }
-    if (misc.has_tpm) {
+    if (misc.tpm_version != TPM_VERSION_UNSPEC) {
         acpi_add_table(table_offsets, tables_blob);
         build_tpm_tcpa(tables_blob, tables->linker, tables->tcpalog);
 
         acpi_add_table(table_offsets, tables_blob);
-        build_tpm_ssdt(tables_blob, tables->linker);
+        switch (misc.tpm_version) {
+        case TPM_VERSION_1_2:
+            build_tpm_ssdt(tables_blob, tables->linker);
+            break;
+        case TPM_VERSION_2_0:
+            build_tpm2(tables_blob, tables->linker);
+            break;
+        default:
+            assert(false);
+        }
     }
     if (guest_info->numa_nodes) {
         acpi_add_table(table_offsets, tables_blob);
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index e804757..0806b5f 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -32,6 +32,7 @@ 
 #include "tpm_tis.h"
 #include "qemu-common.h"
 #include "qemu/main-loop.h"
+#include "sysemu/tpm_backend.h"
 
 #define DEBUG_TIS 0
 
@@ -962,6 +963,16 @@  static int tpm_tis_do_startup_tpm(TPMState *s)
 }
 
 /*
+ * Get the TPMVersion of the backend device being used
+ */
+TPMVersion tpm_tis_get_tpm_version(Object *obj)
+{
+    TPMState *s = TPM(obj);
+
+    return tpm_backend_get_tpm_version(s->be_driver);
+}
+
+/*
  * This function is called when the machine starts, resets or due to
  * S3 resume.
  */
diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index e058a39..0be5d97 100644
--- a/hw/i386/Makefile.objs
+++ b/hw/i386/Makefile.objs
@@ -9,7 +9,7 @@  obj-y += kvmvapic.o
 obj-y += acpi-build.o
 hw/i386/acpi-build.o: hw/i386/acpi-build.c \
 	hw/i386/acpi-dsdt.hex hw/i386/q35-acpi-dsdt.hex \
-	hw/i386/ssdt-tpm.hex
+	hw/i386/ssdt-tpm.hex hw/i386/ssdt-tpm2.hex
 
 iasl-option=$(shell if test -z "`$(1) $(2) 2>&1 > /dev/null`" \
     ; then echo "$(2)"; else echo "$(3)"; fi ;)
diff --git a/hw/i386/ssdt-tpm.dsl b/hw/i386/ssdt-tpm.dsl
index 75d9691..d81478c 100644
--- a/hw/i386/ssdt-tpm.dsl
+++ b/hw/i386/ssdt-tpm.dsl
@@ -25,19 +25,5 @@  DefinitionBlock (
     0x1                 // OEM Revision
     )
 {
-    Scope(\_SB) {
-        /* TPM with emulated TPM TIS interface */
-        Device (TPM) {
-            Name (_HID, EisaID ("PNP0C31"))
-            Name (_CRS, ResourceTemplate ()
-            {
-                Memory32Fixed (ReadWrite, TPM_TIS_ADDR_BASE, TPM_TIS_ADDR_SIZE)
-                // older Linux tpm_tis drivers do not work with IRQ
-                //IRQNoFlags () {TPM_TIS_IRQ}
-            })
-            Method (_STA, 0, NotSerialized) {
-                Return (0x0F)
-            }
-        }
-    }
+#include "ssdt-tpm-common.dsl"
 }
diff --git a/hw/i386/ssdt-tpm.hex.generated b/hw/i386/ssdt-tpm.hex.generated
index e84dc6c..874418c 100644
--- a/hw/i386/ssdt-tpm.hex.generated
+++ b/hw/i386/ssdt-tpm.hex.generated
@@ -3,12 +3,12 @@  static unsigned char ssdt_tpm_aml[] = {
 0x53,
 0x44,
 0x54,
-0x5d,
+0x6b,
 0x0,
 0x0,
 0x0,
 0x1,
-0x1c,
+0x37,
 0x42,
 0x58,
 0x50,
@@ -36,15 +36,26 @@  static unsigned char ssdt_tpm_aml[] = {
 0x14,
 0x20,
 0x10,
-0x38,
+0x46,
+0x4,
 0x5c,
+0x2f,
+0x3,
 0x5f,
 0x53,
 0x42,
 0x5f,
+0x50,
+0x43,
+0x49,
+0x30,
+0x49,
+0x53,
+0x41,
+0x5f,
 0x5b,
 0x82,
-0x30,
+0x33,
 0x54,
 0x50,
 0x4d,
@@ -65,9 +76,9 @@  static unsigned char ssdt_tpm_aml[] = {
 0x52,
 0x53,
 0x11,
-0x11,
+0x14,
 0xa,
-0xe,
+0x11,
 0x86,
 0x9,
 0x0,
@@ -80,6 +91,9 @@  static unsigned char ssdt_tpm_aml[] = {
 0x50,
 0x0,
 0x0,
+0x22,
+0x20,
+0x0,
 0x79,
 0x0,
 0x14,