[Qemu-devel] [PATCH] TPM TIS device model
This patch adds a TIS device model for a v1.2 TPM to qemu. It is based on the Xen patch from IBM and adopted by removing the Xen-specific stuff. It works with the tpmd daemon of the tpm-emulator package. The following things are still missing: * locality support * cmdline option for the socket name Greetings, Bernhard Kauer diff -N -r -u qemu.old/Makefile.target qemu/Makefile.target --- qemu.old/Makefile.target2007-03-09 02:46:14.024009410 +0100 +++ qemu/Makefile.target2007-03-09 01:03:53.0 +0100 @@ -372,6 +372,7 @@ VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o VL_OBJS+= cirrus_vga.o mixeng.o apic.o parallel.o acpi.o piix_pci.o VL_OBJS+= usb-uhci.o smbus_eeprom.o +VL_OBJS+= tpm_tis.o CPPFLAGS += -DHAS_AUDIO endif ifeq ($(TARGET_BASE_ARCH), ppc) diff -N -r -u qemu.old/hw/pc.c qemu/hw/pc.c --- qemu.old/hw/pc.c2007-03-09 02:46:14.424026396 +0100 +++ qemu/hw/pc.c2007-03-09 01:14:26.507262699 +0100 @@ -734,6 +734,9 @@ if (i440fx_state) { i440fx_init_memory_mappings(i440fx_state); } + +tpm_tis_init(); + #if 0 /* ??? Need to figure out some way for the user to specify SCSI devices. */ diff -N -r -u qemu.old/hw/tpm_tis.c qemu/hw/tpm_tis.c --- qemu.old/hw/tpm_tis.c 1970-01-01 01:00:00.0 +0100 +++ qemu/hw/tpm_tis.c 2007-03-09 02:59:13.801196995 +0100 @@ -0,0 +1,992 @@ +/* + * tpm_tis.c - QEMU emulator for a 1.2 TPM with TIS interface + * + * Copyright (C) 2006 IBM Corporation + * + * Author: Stefan Berger <[EMAIL PROTECTED]> + * David Safford <[EMAIL PROTECTED]> + * Adopted for Qemu: Bernhard Kauer <[EMAIL PROTECTED]> + * + * 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. + * + * + * Implementation of the TIS interface according to specs at + * https://www.trustedcomputinggroup.org/groups/pc_client/TCG_PCClientTPMSpecification_1-20_1-00_FINAL.pdf + * + */ + +#include +#include +#include +#include +#include +#include +#include "vl.h" + +#define DEBUG_TPM +#define logfile stderr + +#define TPM_MAX_PKT 4096 + +#define VTPM_BAD_INSTANCE (uint32_t)0x + +#define TIS_ADDR_BASE 0xFED4 + +/* tis registers */ +#define TPM_REG_ACCESS0x00 +#define TPM_REG_INT_ENABLE0x08 +#define TPM_REG_INT_VECTOR0x0c +#define TPM_REG_INT_STATUS0x10 +#define TPM_REG_INTF_CAPABILITY 0x14 +#define TPM_REG_STS 0x18 +#define TPM_REG_DATA_FIFO 0x24 +#define TPM_REG_DID_VID 0xf00 +#define TPM_REG_RID 0xf04 + +#define STS_VALID(1 << 7) +#define STS_COMMAND_READY(1 << 6) +#define STS_TPM_GO (1 << 5) +#define STS_DATA_AVAILABLE (1 << 4) +#define STS_EXPECT (1 << 3) +#define STS_RESPONSE_RETRY (1 << 1) + +#define ACCESS_TPM_REG_VALID_STS (1 << 7) +#define ACCESS_ACTIVE_LOCALITY (1 << 5) +#define ACCESS_BEEN_SEIZED (1 << 4) +#define ACCESS_SEIZE (1 << 3) +#define ACCESS_PENDING_REQUEST (1 << 2) +#define ACCESS_REQUEST_USE (1 << 1) +#define ACCESS_TPM_ESTABLISHMENT (1 << 0) + +#define INT_ENABLED (1 << 31) +#define INT_DATA_AVAILABLE (1 << 0) +#define INT_LOCALITY_CHANGED (1 << 2) +#define INT_COMMAND_READY(1 << 7) + +#define INTERRUPTS_SUPPORTED (INT_LOCALITY_CHANGED | \ + INT_DATA_AVAILABLE | \ + INT_COMMAND_READY) +#define CAPABILITIES_SUPPORTED ((1 << 4) |\ + INTERRUPTS_SUPPORTED) + +enum { + STATE_IDLE = 0, + STATE_READY, + STATE_COMPLETION, + STATE_EXECUTION, + STATE_RECEPTION +}; + +#define NUM_LOCALITIES 5 +#define NO_LOCALITY 0xff + +#define IS_VALID_LOC(x) ((x) < NUM_LOCALITIES) + +#define TPM_DID 0x0001 +#define TPM_VID 0x0001 +#define TPM_RID 0x0001 + +/* if the connection to the vTPM should be closed after a successfully + received response; set to '0' to allow keeping the connection */ +#define FORCE_CLOSE 0 + +/* local data structures */ + +typedef struct TPMTx { +int fd[2]; +} tpmTx; + +typedef struct TPMBuffer { +uint8_t instance[4]; /* instance number in network byte order */ +uint8_t buf[TPM_MAX_PKT]; +} __attribute__((packed)) tpmBuffer; + +/* locality data */ +typedef struct TPMLocal { +uint32_t state; +uint8_t access; +uint8_t sts; +uint32_t inte; +uint32_t ints; +} tpmLoc; + +/* overall state of the TPM interface; 's' marks as save upon suspension */ +typedef struct TPMState { +uint32_t offset;/* s */ +tpmBuffer buffer; /* s *
[Qemu-devel] [PATCH] TPM TIS device model
This patch adds a TIS device model for a v1.2 TPM to qemu. It is based on the Xen patch from IBM and adopted by removing the Xen-specific stuff. It works with the tpmd daemon of the tpm-emulator package. The following things are still missing: * locality support * cmdline option for the socket name Greetings, Bernhard Kauer diff -N -r -u qemu.old/Makefile.target qemu/Makefile.target --- qemu.old/Makefile.target2007-03-09 02:46:14.024009410 +0100 +++ qemu/Makefile.target2007-03-09 01:03:53.0 +0100 @@ -372,6 +372,7 @@ VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o VL_OBJS+= cirrus_vga.o mixeng.o apic.o parallel.o acpi.o piix_pci.o VL_OBJS+= usb-uhci.o smbus_eeprom.o +VL_OBJS+= tpm_tis.o CPPFLAGS += -DHAS_AUDIO endif ifeq ($(TARGET_BASE_ARCH), ppc) diff -N -r -u qemu.old/hw/pc.c qemu/hw/pc.c --- qemu.old/hw/pc.c2007-03-09 02:46:14.424026396 +0100 +++ qemu/hw/pc.c2007-03-09 01:14:26.507262699 +0100 @@ -734,6 +734,9 @@ if (i440fx_state) { i440fx_init_memory_mappings(i440fx_state); } + +tpm_tis_init(); + #if 0 /* ??? Need to figure out some way for the user to specify SCSI devices. */ diff -N -r -u qemu.old/hw/tpm_tis.c qemu/hw/tpm_tis.c --- qemu.old/hw/tpm_tis.c 1970-01-01 01:00:00.0 +0100 +++ qemu/hw/tpm_tis.c 2007-03-09 02:59:13.801196995 +0100 @@ -0,0 +1,992 @@ +/* + * tpm_tis.c - QEMU emulator for a 1.2 TPM with TIS interface + * + * Copyright (C) 2006 IBM Corporation + * + * Author: Stefan Berger <[EMAIL PROTECTED]> + * David Safford <[EMAIL PROTECTED]> + * Adopted for Qemu: Bernhard Kauer <[EMAIL PROTECTED]> + * + * 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. + * + * + * Implementation of the TIS interface according to specs at + * https://www.trustedcomputinggroup.org/groups/pc_client/TCG_PCClientTPMSpecification_1-20_1-00_FINAL.pdf + * + */ + +#include +#include +#include +#include +#include +#include +#include "vl.h" + +#define DEBUG_TPM +#define logfile stderr + +#define TPM_MAX_PKT 4096 + +#define VTPM_BAD_INSTANCE (uint32_t)0x + +#define TIS_ADDR_BASE 0xFED4 + +/* tis registers */ +#define TPM_REG_ACCESS0x00 +#define TPM_REG_INT_ENABLE0x08 +#define TPM_REG_INT_VECTOR0x0c +#define TPM_REG_INT_STATUS0x10 +#define TPM_REG_INTF_CAPABILITY 0x14 +#define TPM_REG_STS 0x18 +#define TPM_REG_DATA_FIFO 0x24 +#define TPM_REG_DID_VID 0xf00 +#define TPM_REG_RID 0xf04 + +#define STS_VALID(1 << 7) +#define STS_COMMAND_READY(1 << 6) +#define STS_TPM_GO (1 << 5) +#define STS_DATA_AVAILABLE (1 << 4) +#define STS_EXPECT (1 << 3) +#define STS_RESPONSE_RETRY (1 << 1) + +#define ACCESS_TPM_REG_VALID_STS (1 << 7) +#define ACCESS_ACTIVE_LOCALITY (1 << 5) +#define ACCESS_BEEN_SEIZED (1 << 4) +#define ACCESS_SEIZE (1 << 3) +#define ACCESS_PENDING_REQUEST (1 << 2) +#define ACCESS_REQUEST_USE (1 << 1) +#define ACCESS_TPM_ESTABLISHMENT (1 << 0) + +#define INT_ENABLED (1 << 31) +#define INT_DATA_AVAILABLE (1 << 0) +#define INT_LOCALITY_CHANGED (1 << 2) +#define INT_COMMAND_READY(1 << 7) + +#define INTERRUPTS_SUPPORTED (INT_LOCALITY_CHANGED | \ + INT_DATA_AVAILABLE | \ + INT_COMMAND_READY) +#define CAPABILITIES_SUPPORTED ((1 << 4) |\ + INTERRUPTS_SUPPORTED) + +enum { + STATE_IDLE = 0, + STATE_READY, + STATE_COMPLETION, + STATE_EXECUTION, + STATE_RECEPTION +}; + +#define NUM_LOCALITIES 5 +#define NO_LOCALITY 0xff + +#define IS_VALID_LOC(x) ((x) < NUM_LOCALITIES) + +#define TPM_DID 0x0001 +#define TPM_VID 0x0001 +#define TPM_RID 0x0001 + +/* if the connection to the vTPM should be closed after a successfully + received response; set to '0' to allow keeping the connection */ +#define FORCE_CLOSE 0 + +/* local data structures */ + +typedef struct TPMTx { +int fd[2]; +} tpmTx; + +typedef struct TPMBuffer { +uint8_t instance[4]; /* instance number in network byte order */ +uint8_t buf[TPM_MAX_PKT]; +} __attribute__((packed)) tpmBuffer; + +/* locality data */ +typedef struct TPMLocal { +uint32_t state; +uint8_t access; +uint8_t sts; +uint32_t inte; +uint32_t ints; +} tpmLoc; + +/* overall state of the TPM interface; 's' marks as save upon suspension */ +typedef struct TPMState { +uint32_t offset;/* s */ +tpmBuffer buffer; /* s *