[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 3/3] TPM2 ACPI table support
From: |
Stefan Berger |
Subject: |
[Qemu-devel] [PATCH v2 3/3] TPM2 ACPI table support |
Date: |
Thu, 30 Apr 2015 22:44:08 -0400 |
Add a TPM2 ACPI table if a TPM 2 is used in the backend.
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 <address@hidden>
---
hw/i386/acpi-build.c | 34 ++++++++++++++++++++++++++++++----
hw/i386/acpi-defs.h | 18 ++++++++++++++++++
hw/tpm/tpm_tis.c | 11 +++++++++++
include/hw/acpi/tpm.h | 5 +++++
include/sysemu/tpm.h | 11 +++++++++--
5 files changed, 73 insertions(+), 6 deletions(-)
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index e761005..fa64646 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -42,6 +42,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"
@@ -111,7 +112,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;
@@ -239,7 +240,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();
}
@@ -1065,6 +1066,21 @@ 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;
+
+ 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),
@@ -1428,12 +1444,22 @@ 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;
+ case TPM_VERSION_UNSPEC:
+ /* not possible */
+ break;
+ }
}
if (guest_info->numa_nodes) {
acpi_add_table(table_offsets, tables_blob);
diff --git a/hw/i386/acpi-defs.h b/hw/i386/acpi-defs.h
index c4468f8..79ee9b1 100644
--- a/hw/i386/acpi-defs.h
+++ b/hw/i386/acpi-defs.h
@@ -316,6 +316,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 */
@@ -325,6 +328,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/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 636e6d3..be7e61f 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
@@ -963,6 +964,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/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 */
--
1.9.3