mirror of https://github.com/xemu-project/xemu.git
TPM2 ACPI table support
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>
This commit is contained in:
parent
56a3c24ffc
commit
5cb18b3d7b
|
@ -9,7 +9,7 @@ obj-y += kvmvapic.o
|
||||||
obj-y += acpi-build.o
|
obj-y += acpi-build.o
|
||||||
hw/i386/acpi-build.o: hw/i386/acpi-build.c \
|
hw/i386/acpi-build.o: hw/i386/acpi-build.c \
|
||||||
hw/i386/acpi-dsdt.hex hw/i386/q35-acpi-dsdt.hex \
|
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`" \
|
iasl-option=$(shell if test -z "`$(1) $(2) 2>&1 > /dev/null`" \
|
||||||
; then echo "$(2)"; else echo "$(3)"; fi ;)
|
; then echo "$(2)"; else echo "$(3)"; fi ;)
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "hw/acpi/memory_hotplug.h"
|
#include "hw/acpi/memory_hotplug.h"
|
||||||
#include "sysemu/tpm.h"
|
#include "sysemu/tpm.h"
|
||||||
#include "hw/acpi/tpm.h"
|
#include "hw/acpi/tpm.h"
|
||||||
|
#include "sysemu/tpm_backend.h"
|
||||||
|
|
||||||
/* Supported chipsets: */
|
/* Supported chipsets: */
|
||||||
#include "hw/acpi/piix4.h"
|
#include "hw/acpi/piix4.h"
|
||||||
|
@ -106,7 +107,7 @@ typedef struct AcpiPmInfo {
|
||||||
|
|
||||||
typedef struct AcpiMiscInfo {
|
typedef struct AcpiMiscInfo {
|
||||||
bool has_hpet;
|
bool has_hpet;
|
||||||
bool has_tpm;
|
TPMVersion tpm_version;
|
||||||
const unsigned char *dsdt_code;
|
const unsigned char *dsdt_code;
|
||||||
unsigned dsdt_size;
|
unsigned dsdt_size;
|
||||||
uint16_t pvpanic_port;
|
uint16_t pvpanic_port;
|
||||||
|
@ -234,7 +235,7 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
|
||||||
static void acpi_get_misc_info(AcpiMiscInfo *info)
|
static void acpi_get_misc_info(AcpiMiscInfo *info)
|
||||||
{
|
{
|
||||||
info->has_hpet = hpet_find();
|
info->has_hpet = hpet_find();
|
||||||
info->has_tpm = tpm_find();
|
info->tpm_version = tpm_get_version();
|
||||||
info->pvpanic_port = pvpanic_port();
|
info->pvpanic_port = pvpanic_port();
|
||||||
info->applesmc_io_base = applesmc_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-tpm.hex"
|
||||||
|
#include "hw/i386/ssdt-tpm2.hex"
|
||||||
|
|
||||||
/* Assign BSEL property to all buses. In the future, this can be changed
|
/* Assign BSEL property to all buses. In the future, this can be changed
|
||||||
* to only assign to buses that support hotplug.
|
* 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));
|
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 {
|
typedef enum {
|
||||||
MEM_AFFINITY_NOFLAGS = 0,
|
MEM_AFFINITY_NOFLAGS = 0,
|
||||||
MEM_AFFINITY_ENABLED = (1 << 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);
|
acpi_add_table(table_offsets, tables_blob);
|
||||||
build_hpet(tables_blob, tables->linker);
|
build_hpet(tables_blob, tables->linker);
|
||||||
}
|
}
|
||||||
if (misc.has_tpm) {
|
if (misc.tpm_version != TPM_VERSION_UNSPEC) {
|
||||||
acpi_add_table(table_offsets, tables_blob);
|
acpi_add_table(table_offsets, tables_blob);
|
||||||
build_tpm_tcpa(tables_blob, tables->linker, tables->tcpalog);
|
build_tpm_tcpa(tables_blob, tables->linker, tables->tcpalog);
|
||||||
|
|
||||||
acpi_add_table(table_offsets, tables_blob);
|
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) {
|
if (guest_info->numa_nodes) {
|
||||||
acpi_add_table(table_offsets, tables_blob);
|
acpi_add_table(table_offsets, tables_blob);
|
||||||
|
|
|
@ -25,19 +25,5 @@ DefinitionBlock (
|
||||||
0x1 // OEM Revision
|
0x1 // OEM Revision
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Scope(\_SB) {
|
#include "ssdt-tpm-common.dsl"
|
||||||
/* 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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,12 @@ static unsigned char ssdt_tpm_aml[] = {
|
||||||
0x53,
|
0x53,
|
||||||
0x44,
|
0x44,
|
||||||
0x54,
|
0x54,
|
||||||
0x5d,
|
0x6b,
|
||||||
0x0,
|
0x0,
|
||||||
0x0,
|
0x0,
|
||||||
0x0,
|
0x0,
|
||||||
0x1,
|
0x1,
|
||||||
0x1c,
|
0x37,
|
||||||
0x42,
|
0x42,
|
||||||
0x58,
|
0x58,
|
||||||
0x50,
|
0x50,
|
||||||
|
@ -36,15 +36,26 @@ static unsigned char ssdt_tpm_aml[] = {
|
||||||
0x14,
|
0x14,
|
||||||
0x20,
|
0x20,
|
||||||
0x10,
|
0x10,
|
||||||
0x38,
|
0x46,
|
||||||
|
0x4,
|
||||||
0x5c,
|
0x5c,
|
||||||
|
0x2f,
|
||||||
|
0x3,
|
||||||
0x5f,
|
0x5f,
|
||||||
0x53,
|
0x53,
|
||||||
0x42,
|
0x42,
|
||||||
0x5f,
|
0x5f,
|
||||||
|
0x50,
|
||||||
|
0x43,
|
||||||
|
0x49,
|
||||||
|
0x30,
|
||||||
|
0x49,
|
||||||
|
0x53,
|
||||||
|
0x41,
|
||||||
|
0x5f,
|
||||||
0x5b,
|
0x5b,
|
||||||
0x82,
|
0x82,
|
||||||
0x30,
|
0x33,
|
||||||
0x54,
|
0x54,
|
||||||
0x50,
|
0x50,
|
||||||
0x4d,
|
0x4d,
|
||||||
|
@ -65,9 +76,9 @@ static unsigned char ssdt_tpm_aml[] = {
|
||||||
0x52,
|
0x52,
|
||||||
0x53,
|
0x53,
|
||||||
0x11,
|
0x11,
|
||||||
0x11,
|
0x14,
|
||||||
0xa,
|
0xa,
|
||||||
0xe,
|
0x11,
|
||||||
0x86,
|
0x86,
|
||||||
0x9,
|
0x9,
|
||||||
0x0,
|
0x0,
|
||||||
|
@ -80,6 +91,9 @@ static unsigned char ssdt_tpm_aml[] = {
|
||||||
0x50,
|
0x50,
|
||||||
0x0,
|
0x0,
|
||||||
0x0,
|
0x0,
|
||||||
|
0x22,
|
||||||
|
0x20,
|
||||||
|
0x0,
|
||||||
0x79,
|
0x79,
|
||||||
0x0,
|
0x0,
|
||||||
0x14,
|
0x14,
|
||||||
|
|
|
@ -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"
|
||||||
|
}
|
|
@ -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
|
||||||
|
};
|
|
@ -32,6 +32,7 @@
|
||||||
#include "tpm_tis.h"
|
#include "tpm_tis.h"
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
|
#include "sysemu/tpm_backend.h"
|
||||||
|
|
||||||
#define DEBUG_TIS 0
|
#define DEBUG_TIS 0
|
||||||
|
|
||||||
|
@ -961,6 +962,16 @@ static int tpm_tis_do_startup_tpm(TPMState *s)
|
||||||
return tpm_backend_startup_tpm(s->be_driver);
|
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
|
* This function is called when the machine starts, resets or due to
|
||||||
* S3 resume.
|
* S3 resume.
|
||||||
|
|
|
@ -450,6 +450,9 @@ typedef struct AcpiTableMcfg AcpiTableMcfg;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TCPA Description Table
|
* TCPA Description Table
|
||||||
|
*
|
||||||
|
* Following Level 00, Rev 00.37 of specs:
|
||||||
|
* http://www.trustedcomputinggroup.org/resources/tcg_acpi_specification
|
||||||
*/
|
*/
|
||||||
struct Acpi20Tcpa {
|
struct Acpi20Tcpa {
|
||||||
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
|
ACPI_TABLE_HEADER_DEF /* ACPI common table header */
|
||||||
|
@ -459,6 +462,21 @@ struct Acpi20Tcpa {
|
||||||
} QEMU_PACKED;
|
} QEMU_PACKED;
|
||||||
typedef struct Acpi20Tcpa Acpi20Tcpa;
|
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 */
|
/* DMAR - DMA Remapping table r2.2 */
|
||||||
struct AcpiTableDmar {
|
struct AcpiTableDmar {
|
||||||
ACPI_TABLE_HEADER_DEF
|
ACPI_TABLE_HEADER_DEF
|
||||||
|
|
|
@ -26,4 +26,9 @@
|
||||||
#define TPM_TCPA_ACPI_CLASS_CLIENT 0
|
#define TPM_TCPA_ACPI_CLASS_CLIENT 0
|
||||||
#define TPM_TCPA_ACPI_CLASS_SERVER 1
|
#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 */
|
#endif /* HW_ACPI_TPM_H */
|
||||||
|
|
|
@ -26,11 +26,18 @@ typedef enum TPMVersion {
|
||||||
TPM_VERSION_2_0 = 2,
|
TPM_VERSION_2_0 = 2,
|
||||||
} TPMVersion;
|
} TPMVersion;
|
||||||
|
|
||||||
|
TPMVersion tpm_tis_get_tpm_version(Object *obj);
|
||||||
|
|
||||||
#define TYPE_TPM_TIS "tpm-tis"
|
#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 */
|
#endif /* QEMU_TPM_H */
|
||||||
|
|
Loading…
Reference in New Issue