Skip to content

Commit

Permalink
TPM2 ACPI table support
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
stefanberger authored and mstsirkin committed Jun 1, 2015
1 parent 56a3c24 commit 5cb18b3
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 28 deletions.
2 changes: 1 addition & 1 deletion hw/i386/Makefile.objs
Expand Up @@ -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 ;)
Expand Down
38 changes: 34 additions & 4 deletions hw/i386/acpi-build.c
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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);
Expand Down
16 changes: 1 addition & 15 deletions hw/i386/ssdt-tpm.dsl
Expand Up @@ -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"
}
26 changes: 20 additions & 6 deletions hw/i386/ssdt-tpm.hex.generated
Expand Up @@ -3,12 +3,12 @@ static unsigned char ssdt_tpm_aml[] = {
0x53,
0x44,
0x54,
0x5d,
0x6b,
0x0,
0x0,
0x0,
0x1,
0x1c,
0x37,
0x42,
0x58,
0x50,
Expand Down Expand Up @@ -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,
Expand All @@ -65,9 +76,9 @@ static unsigned char ssdt_tpm_aml[] = {
0x52,
0x53,
0x11,
0x11,
0x14,
0xa,
0xe,
0x11,
0x86,
0x9,
0x0,
Expand All @@ -80,6 +91,9 @@ static unsigned char ssdt_tpm_aml[] = {
0x50,
0x0,
0x0,
0x22,
0x20,
0x0,
0x79,
0x0,
0x14,
Expand Down
29 changes: 29 additions & 0 deletions hw/i386/ssdt-tpm2.dsl
@@ -0,0 +1,29 @@
/*
* 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; either version 2 of the License, or
* (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "hw/acpi/tpm.h"

ACPI_EXTRACT_ALL_CODE ssdt_tpm2_aml

DefinitionBlock (
"ssdt-tpm2.aml", // Output Filename
"SSDT", // Signature
0x01, // SSDT Compliance Revision
"BXPC", // OEMID
"BXSSDT", // TABLE ID
0x1 // OEM Revision
)
{
#include "ssdt-tpm-common.dsl"
}
109 changes: 109 additions & 0 deletions hw/i386/ssdt-tpm2.hex.generated
@@ -0,0 +1,109 @@
static unsigned char ssdt_tpm2_aml[] = {
0x53,
0x53,
0x44,
0x54,
0x6b,
0x0,
0x0,
0x0,
0x1,
0x37,
0x42,
0x58,
0x50,
0x43,
0x0,
0x0,
0x42,
0x58,
0x53,
0x53,
0x44,
0x54,
0x0,
0x0,
0x1,
0x0,
0x0,
0x0,
0x49,
0x4e,
0x54,
0x4c,
0x7,
0x11,
0x14,
0x20,
0x10,
0x46,
0x4,
0x5c,
0x2f,
0x3,
0x5f,
0x53,
0x42,
0x5f,
0x50,
0x43,
0x49,
0x30,
0x49,
0x53,
0x41,
0x5f,
0x5b,
0x82,
0x33,
0x54,
0x50,
0x4d,
0x5f,
0x8,
0x5f,
0x48,
0x49,
0x44,
0xc,
0x41,
0xd0,
0xc,
0x31,
0x8,
0x5f,
0x43,
0x52,
0x53,
0x11,
0x14,
0xa,
0x11,
0x86,
0x9,
0x0,
0x1,
0x0,
0x0,
0xd4,
0xfe,
0x0,
0x50,
0x0,
0x0,
0x22,
0x20,
0x0,
0x79,
0x0,
0x14,
0x9,
0x5f,
0x53,
0x54,
0x41,
0x0,
0xa4,
0xa,
0xf
};
11 changes: 11 additions & 0 deletions hw/tpm/tpm_tis.c
Expand Up @@ -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

Expand Down Expand Up @@ -961,6 +962,16 @@ static int tpm_tis_do_startup_tpm(TPMState *s)
return tpm_backend_startup_tpm(s->be_driver);
}

/*
* 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.
Expand Down
18 changes: 18 additions & 0 deletions include/hw/acpi/acpi-defs.h
Expand Up @@ -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 */
Expand All @@ -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
Expand Down
5 changes: 5 additions & 0 deletions include/hw/acpi/tpm.h
Expand Up @@ -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 */

0 comments on commit 5cb18b3

Please sign in to comment.