diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2013-04-15 17:06:04 -0500 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2013-04-15 17:06:04 -0500 |
commit | 4ceb193d30fe9b1cda0dc73bddb8051659926fb9 (patch) | |
tree | a9ffbe92293ba9b0cc3298591e7564aae19a0ef1 /hw | |
parent | a907cf59d8a41ecb909ad4367cd016c7d71f8546 (diff) | |
parent | c72dd2d04bd28f7ec6b073316270258684ba5fc3 (diff) |
Merge remote-tracking branch 'bonzini/hw-dirs' into staging
* bonzini/hw-dirs:
exec: remove useless declarations from memory-internal.h
memory: move core typedefs to qemu/typedefs.h
include: avoid useless includes of exec/ headers
sysemu: avoid proliferation of include/ subdirectories
tpm: reorganize headers and split hardware part
configure: fix TPM logic
acpi.h: make it self contained
acpi: move declarations from pc.h to acpi.h
hw: Add lost ARM core again
Fix failure to create q35 machine
Add linux-headers to QEMU_INCLUDES
arm: fix location of some include files
Conflicts:
configure
aliguori: trivial conflict in configure output
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'hw')
102 files changed, 1756 insertions, 113 deletions
diff --git a/hw/Makefile.objs b/hw/Makefile.objs index 1cb86fa323..b7a1613612 100644 --- a/hw/Makefile.objs +++ b/hw/Makefile.objs @@ -22,6 +22,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += scsi/ devices-dirs-$(CONFIG_SOFTMMU) += sd/ devices-dirs-$(CONFIG_SOFTMMU) += ssi/ devices-dirs-$(CONFIG_SOFTMMU) += timer/ +devices-dirs-$(CONFIG_TPM) += tpm/ devices-dirs-$(CONFIG_SOFTMMU) += usb/ devices-dirs-$(CONFIG_SOFTMMU) += virtio/ devices-dirs-$(CONFIG_SOFTMMU) += watchdog/ diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c index faec8dcebd..1ead1877c7 100644 --- a/hw/alpha/typhoon.c +++ b/hw/alpha/typhoon.c @@ -7,9 +7,8 @@ */ #include "cpu.h" -#include "exec/exec-all.h" #include "hw/hw.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "sysemu/sysemu.h" #include "alpha_sys.h" #include "exec/address-spaces.h" diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index a4bdd5f30f..2ae3576760 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -8,7 +8,7 @@ */ #include "hw/sysbus.h" -#include "hw/arm.h" +#include "hw/arm/arm.h" #include "hw/loader.h" #include "elf.h" diff --git a/hw/arm/boot.c b/hw/arm/boot.c index c79c590171..e9c09454ac 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -9,7 +9,7 @@ #include "config.h" #include "hw/hw.h" -#include "hw/arm.h" +#include "hw/arm/arm.h" #include "sysemu/sysemu.h" #include "hw/boards.h" #include "hw/loader.h" diff --git a/hw/arm/collie.c b/hw/arm/collie.c index 5420bb4ba8..a19857aaaf 100644 --- a/hw/arm/collie.c +++ b/hw/arm/collie.c @@ -11,9 +11,9 @@ #include "hw/hw.h" #include "hw/sysbus.h" #include "hw/boards.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "strongarm.h" -#include "hw/arm.h" +#include "hw/arm/arm.h" #include "hw/block/flash.h" #include "sysemu/blockdev.h" #include "exec/address-spaces.h" diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c index 78b8b7407a..c8101d3e84 100644 --- a/hw/arm/exynos4210.c +++ b/hw/arm/exynos4210.c @@ -24,7 +24,7 @@ #include "hw/boards.h" #include "sysemu/sysemu.h" #include "hw/sysbus.h" -#include "hw/arm.h" +#include "hw/arm/arm.h" #include "hw/loader.h" #include "hw/arm/exynos4210.h" #include "hw/usb/hcd-ehci.h" diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c index ba14a1fd09..74f110ba61 100644 --- a/hw/arm/exynos4_boards.c +++ b/hw/arm/exynos4_boards.c @@ -24,7 +24,7 @@ #include "sysemu/sysemu.h" #include "hw/sysbus.h" #include "net/net.h" -#include "hw/arm.h" +#include "hw/arm/arm.h" #include "exec/address-spaces.h" #include "hw/arm/exynos4210.h" #include "hw/boards.h" diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c index 4d800c9547..b8cab10ba6 100644 --- a/hw/arm/gumstix.c +++ b/hw/arm/gumstix.c @@ -38,7 +38,7 @@ #include "hw/arm/pxa.h" #include "net/net.h" #include "hw/block/flash.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "hw/boards.h" #include "sysemu/blockdev.h" #include "exec/address-spaces.h" diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c index 58f73c1bd3..0fd9465cfa 100644 --- a/hw/arm/highbank.c +++ b/hw/arm/highbank.c @@ -18,8 +18,8 @@ */ #include "hw/sysbus.h" -#include "hw/arm.h" -#include "hw/arm/devices.h" +#include "hw/arm/arm.h" +#include "hw/devices.h" #include "hw/loader.h" #include "net/net.h" #include "sysemu/sysemu.h" diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c index 8d0fb7584a..cca29719ec 100644 --- a/hw/arm/integratorcp.c +++ b/hw/arm/integratorcp.c @@ -8,9 +8,9 @@ */ #include "hw/sysbus.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "hw/boards.h" -#include "hw/arm.h" +#include "hw/arm/arm.h" #include "net/net.h" #include "exec/address-spaces.h" #include "sysemu/sysemu.h" diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c index 46264cdeac..cf90f5dc71 100644 --- a/hw/arm/kzm.c +++ b/hw/arm/kzm.c @@ -16,8 +16,8 @@ #include "hw/sysbus.h" #include "exec/address-spaces.h" #include "hw/hw.h" -#include "hw/arm.h" -#include "hw/arm/devices.h" +#include "hw/arm/arm.h" +#include "hw/devices.h" #include "net/net.h" #include "sysemu/sysemu.h" #include "hw/boards.h" diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c index b78e6f00d3..260e31481d 100644 --- a/hw/arm/mainstone.c +++ b/hw/arm/mainstone.c @@ -13,9 +13,9 @@ */ #include "hw/hw.h" #include "hw/arm/pxa.h" -#include "hw/arm.h" +#include "hw/arm/arm.h" #include "net/net.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "hw/boards.h" #include "hw/block/flash.h" #include "sysemu/blockdev.h" diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c index 97b13405e6..d2247fa1b9 100644 --- a/hw/arm/musicpal.c +++ b/hw/arm/musicpal.c @@ -10,8 +10,8 @@ */ #include "hw/sysbus.h" -#include "hw/arm.h" -#include "hw/arm/devices.h" +#include "hw/arm/arm.h" +#include "hw/devices.h" #include "net/net.h" #include "sysemu/sysemu.h" #include "hw/boards.h" diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c index ba8dc3e01a..4976438ae6 100644 --- a/hw/arm/nseries.c +++ b/hw/arm/nseries.c @@ -21,12 +21,12 @@ #include "qemu-common.h" #include "sysemu/sysemu.h" #include "hw/arm/omap.h" -#include "hw/arm.h" +#include "hw/arm/arm.h" #include "hw/irq.h" #include "ui/console.h" #include "hw/boards.h" #include "hw/i2c/i2c.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "hw/block/flash.h" #include "hw/hw.h" #include "hw/bt.h" diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c index 17caa61822..f59f0f291a 100644 --- a/hw/arm/omap1.c +++ b/hw/arm/omap1.c @@ -17,7 +17,7 @@ * with this program; if not, see <http://www.gnu.org/licenses/>. */ #include "hw/hw.h" -#include "hw/arm.h" +#include "hw/arm/arm.h" #include "hw/arm/omap.h" #include "sysemu/sysemu.h" #include "hw/arm/soc_dma.h" diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c index 010c483e8c..2ff43710e4 100644 --- a/hw/arm/omap2.c +++ b/hw/arm/omap2.c @@ -20,11 +20,11 @@ #include "sysemu/blockdev.h" #include "hw/hw.h" -#include "hw/arm.h" +#include "hw/arm/arm.h" #include "hw/arm/omap.h" #include "sysemu/sysemu.h" #include "qemu/timer.h" -#include "char/char.h" +#include "sysemu/char.h" #include "hw/block/flash.h" #include "hw/arm/soc_dma.h" #include "hw/sysbus.h" diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c index aa85602aa6..e421ece026 100644 --- a/hw/arm/omap_sx1.c +++ b/hw/arm/omap_sx1.c @@ -29,7 +29,7 @@ #include "ui/console.h" #include "hw/arm/omap.h" #include "hw/boards.h" -#include "hw/arm.h" +#include "hw/arm/arm.h" #include "hw/block/flash.h" #include "sysemu/blockdev.h" #include "exec/address-spaces.h" diff --git a/hw/arm/palm.c b/hw/arm/palm.c index 0bc11aed2b..b13d8108a4 100644 --- a/hw/arm/palm.c +++ b/hw/arm/palm.c @@ -22,8 +22,8 @@ #include "ui/console.h" #include "hw/arm/omap.h" #include "hw/boards.h" -#include "hw/arm.h" -#include "hw/arm/devices.h" +#include "hw/arm/arm.h" +#include "hw/devices.h" #include "hw/loader.h" #include "exec/address-spaces.h" diff --git a/hw/arm/pic_cpu.c b/hw/arm/pic_cpu.c index 787767f51f..875280aa97 100644 --- a/hw/arm/pic_cpu.c +++ b/hw/arm/pic_cpu.c @@ -8,7 +8,7 @@ */ #include "hw/hw.h" -#include "hw/arm.h" +#include "hw/arm/arm.h" #include "sysemu/kvm.h" /* Input 0 is IRQ and input 1 is FIQ. */ diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c index bbecc770ed..24b03a0d29 100644 --- a/hw/arm/pxa2xx.c +++ b/hw/arm/pxa2xx.c @@ -13,7 +13,7 @@ #include "hw/char/serial.h" #include "hw/i2c/i2c.h" #include "hw/ssi.h" -#include "char/char.h" +#include "sysemu/char.h" #include "sysemu/blockdev.h" static struct { diff --git a/hw/arm/realview.c b/hw/arm/realview.c index afd52d31be..feabfc58d4 100644 --- a/hw/arm/realview.c +++ b/hw/arm/realview.c @@ -8,9 +8,9 @@ */ #include "hw/sysbus.h" -#include "hw/arm.h" +#include "hw/arm/arm.h" #include "hw/arm/primecell.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "hw/pci/pci.h" #include "net/net.h" #include "sysemu/sysemu.h" diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c index fa434dc68e..c42668ae49 100644 --- a/hw/arm/spitz.c +++ b/hw/arm/spitz.c @@ -12,14 +12,14 @@ #include "hw/hw.h" #include "hw/arm/pxa.h" -#include "hw/arm.h" +#include "hw/arm/arm.h" #include "sysemu/sysemu.h" #include "hw/pcmcia.h" #include "hw/i2c/i2c.h" #include "hw/ssi.h" #include "hw/block/flash.h" #include "qemu/timer.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "hw/arm/sharpsl.h" #include "ui/console.h" #include "block/block.h" diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c index 952087ce2d..2b61e3c7f8 100644 --- a/hw/arm/stellaris.c +++ b/hw/arm/stellaris.c @@ -9,8 +9,8 @@ #include "hw/sysbus.h" #include "hw/ssi.h" -#include "hw/arm.h" -#include "hw/arm/devices.h" +#include "hw/arm/arm.h" +#include "hw/devices.h" #include "qemu/timer.h" #include "hw/i2c/i2c.h" #include "net/net.h" diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c index 5873a3c956..4d49306dd0 100644 --- a/hw/arm/strongarm.c +++ b/hw/arm/strongarm.c @@ -29,8 +29,8 @@ #include "hw/sysbus.h" #include "strongarm.h" #include "qemu/error-report.h" -#include "hw/arm.h" -#include "char/char.h" +#include "hw/arm/arm.h" +#include "sysemu/char.h" #include "sysemu/sysemu.h" #include "hw/ssi.h" diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c index c4362d4313..47818a5d01 100644 --- a/hw/arm/tosa.c +++ b/hw/arm/tosa.c @@ -13,8 +13,8 @@ #include "hw/hw.h" #include "hw/arm/pxa.h" -#include "hw/arm.h" -#include "hw/arm/devices.h" +#include "hw/arm/arm.h" +#include "hw/devices.h" #include "hw/arm/sharpsl.h" #include "hw/pcmcia.h" #include "block/block.h" diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c index d9be604481..25c665ab27 100644 --- a/hw/arm/versatilepb.c +++ b/hw/arm/versatilepb.c @@ -8,8 +8,8 @@ */ #include "hw/sysbus.h" -#include "hw/arm.h" -#include "hw/arm/devices.h" +#include "hw/arm/arm.h" +#include "hw/devices.h" #include "net/net.h" #include "sysemu/sysemu.h" #include "hw/pci/pci.h" diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c index 96e098579f..a077c62744 100644 --- a/hw/arm/vexpress.c +++ b/hw/arm/vexpress.c @@ -22,9 +22,9 @@ */ #include "hw/sysbus.h" -#include "hw/arm.h" +#include "hw/arm/arm.h" #include "hw/arm/primecell.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "net/net.h" #include "sysemu/sysemu.h" #include "hw/boards.h" diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c index 8d65f796f9..41505c32ba 100644 --- a/hw/arm/xilinx_zynq.c +++ b/hw/arm/xilinx_zynq.c @@ -16,7 +16,7 @@ */ #include "hw/sysbus.h" -#include "hw/arm.h" +#include "hw/arm/arm.h" #include "net/net.h" #include "exec/address-spaces.h" #include "sysemu/sysemu.h" diff --git a/hw/arm/z2.c b/hw/arm/z2.c index 3e272088f5..07a127b498 100644 --- a/hw/arm/z2.c +++ b/hw/arm/z2.c @@ -13,8 +13,8 @@ #include "hw/hw.h" #include "hw/arm/pxa.h" -#include "hw/arm.h" -#include "hw/arm/devices.h" +#include "hw/arm/arm.h" +#include "hw/devices.h" #include "hw/i2c/i2c.h" #include "hw/ssi.h" #include "hw/boards.h" diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index cd560e3747..55e9d0d37a 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -24,7 +24,7 @@ #include "hw/hw.h" #include "sysemu/blockdev.h" #include "hw/ssi.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #ifdef M25P80_ERR_DEBUG #define DB_PRINT(...) do { \ diff --git a/hw/bt/core.c b/hw/bt/core.c index 24ef4de49d..49012e028c 100644 --- a/hw/bt/core.c +++ b/hw/bt/core.c @@ -18,7 +18,7 @@ */ #include "qemu-common.h" -#include "bt/bt.h" +#include "sysemu/bt.h" #include "hw/bt.h" /* Slave implementations can ignore this */ diff --git a/hw/bt/hci-csr.c b/hw/bt/hci-csr.c index 55c819b085..16a25cb349 100644 --- a/hw/bt/hci-csr.c +++ b/hw/bt/hci-csr.c @@ -19,10 +19,10 @@ */ #include "qemu-common.h" -#include "char/char.h" +#include "sysemu/char.h" #include "qemu/timer.h" #include "hw/irq.h" -#include "bt/bt.h" +#include "sysemu/bt.h" #include "hw/bt.h" struct csrhci_s { diff --git a/hw/bt/hci.c b/hw/bt/hci.c index a76edea2c9..b53cd5dea2 100644 --- a/hw/bt/hci.c +++ b/hw/bt/hci.c @@ -21,7 +21,7 @@ #include "qemu-common.h" #include "qemu/timer.h" #include "hw/usb.h" -#include "bt/bt.h" +#include "sysemu/bt.h" #include "hw/bt.h" struct bt_hci_s { diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index 421ec998d6..c2a783430b 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -17,7 +17,7 @@ */ #include "hw/sysbus.h" -#include "char/char.h" +#include "sysemu/char.h" #include "qemu/timer.h" #ifdef CADENCE_UART_ERR_DEBUG diff --git a/hw/char/debugcon.c b/hw/char/debugcon.c index 0588eebb77..02c9577024 100644 --- a/hw/char/debugcon.c +++ b/hw/char/debugcon.c @@ -25,7 +25,7 @@ */ #include "hw/hw.h" -#include "char/char.h" +#include "sysemu/char.h" #include "hw/isa/isa.h" #include "hw/i386/pc.h" diff --git a/hw/char/escc.c b/hw/char/escc.c index 067b055fee..c2cb07f3bd 100644 --- a/hw/char/escc.c +++ b/hw/char/escc.c @@ -25,7 +25,7 @@ #include "hw/hw.h" #include "hw/sysbus.h" #include "hw/char/escc.h" -#include "char/char.h" +#include "sysemu/char.h" #include "ui/console.h" #include "trace.h" diff --git a/hw/char/etraxfs_ser.c b/hw/char/etraxfs_ser.c index b7499d775b..11820f5864 100644 --- a/hw/char/etraxfs_ser.c +++ b/hw/char/etraxfs_ser.c @@ -23,7 +23,7 @@ */ #include "hw/sysbus.h" -#include "char/char.h" +#include "sysemu/char.h" #include "qemu/log.h" #define D(x) diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c index 8b4e72ca11..5751816c62 100644 --- a/hw/char/exynos4210_uart.c +++ b/hw/char/exynos4210_uart.c @@ -21,7 +21,7 @@ #include "hw/sysbus.h" #include "sysemu/sysemu.h" -#include "char/char.h" +#include "sysemu/char.h" #include "hw/arm/exynos4210.h" diff --git a/hw/char/grlib_apbuart.c b/hw/char/grlib_apbuart.c index 62f799083c..a64453fb18 100644 --- a/hw/char/grlib_apbuart.c +++ b/hw/char/grlib_apbuart.c @@ -23,7 +23,7 @@ */ #include "hw/sysbus.h" -#include "char/char.h" +#include "sysemu/char.h" #include "trace.h" diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c index d7ec2090fd..2a2c230c55 100644 --- a/hw/char/imx_serial.c +++ b/hw/char/imx_serial.c @@ -20,7 +20,7 @@ #include "hw/hw.h" #include "hw/sysbus.h" #include "sysemu/sysemu.h" -#include "char/char.h" +#include "sysemu/char.h" #include "hw/arm/imx.h" //#define DEBUG_SERIAL 1 diff --git a/hw/char/ipoctal232.c b/hw/char/ipoctal232.c index fcd0af31b4..c9698a6bc4 100644 --- a/hw/char/ipoctal232.c +++ b/hw/char/ipoctal232.c @@ -10,7 +10,7 @@ #include "ipack.h" #include "qemu/bitops.h" -#include "char/char.h" +#include "sysemu/char.h" /* #define DEBUG_IPOCTAL */ diff --git a/hw/char/lm32_juart.c b/hw/char/lm32_juart.c index 93f0d1534e..839f3ebfe7 100644 --- a/hw/char/lm32_juart.c +++ b/hw/char/lm32_juart.c @@ -20,7 +20,7 @@ #include "hw/hw.h" #include "hw/sysbus.h" #include "trace.h" -#include "char/char.h" +#include "sysemu/char.h" #include "hw/lm32/lm32_juart.h" diff --git a/hw/char/lm32_uart.c b/hw/char/lm32_uart.c index 32bc37ac96..99721ab78d 100644 --- a/hw/char/lm32_uart.c +++ b/hw/char/lm32_uart.c @@ -25,7 +25,7 @@ #include "hw/hw.h" #include "hw/sysbus.h" #include "trace.h" -#include "char/char.h" +#include "sysemu/char.h" #include "qemu/error-report.h" enum { diff --git a/hw/char/mcf_uart.c b/hw/char/mcf_uart.c index 6724b1b718..3ec4705867 100644 --- a/hw/char/mcf_uart.c +++ b/hw/char/mcf_uart.c @@ -7,7 +7,7 @@ */ #include "hw/hw.h" #include "hw/m68k/mcf.h" -#include "char/char.h" +#include "sysemu/char.h" #include "exec/address-spaces.h" typedef struct { diff --git a/hw/char/milkymist-uart.c b/hw/char/milkymist-uart.c index f3bdf6991a..cbc7d73a6e 100644 --- a/hw/char/milkymist-uart.c +++ b/hw/char/milkymist-uart.c @@ -24,7 +24,7 @@ #include "hw/hw.h" #include "hw/sysbus.h" #include "trace.h" -#include "char/char.h" +#include "sysemu/char.h" #include "qemu/error-report.h" enum { diff --git a/hw/char/omap_uart.c b/hw/char/omap_uart.c index 26c14266fc..5bb36ed2c1 100644 --- a/hw/char/omap_uart.c +++ b/hw/char/omap_uart.c @@ -17,7 +17,7 @@ * 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 "char/char.h" +#include "sysemu/char.h" #include "hw/hw.h" #include "hw/arm/omap.h" #include "hw/char/serial.h" diff --git a/hw/char/parallel.c b/hw/char/parallel.c index 863a6fb4a9..b5e867f21c 100644 --- a/hw/char/parallel.c +++ b/hw/char/parallel.c @@ -23,7 +23,7 @@ * THE SOFTWARE. */ #include "hw/hw.h" -#include "char/char.h" +#include "sysemu/char.h" #include "hw/isa/isa.h" #include "hw/i386/pc.h" #include "sysemu/sysemu.h" diff --git a/hw/char/pl011.c b/hw/char/pl011.c index 332d5b970c..7079ef6be1 100644 --- a/hw/char/pl011.c +++ b/hw/char/pl011.c @@ -8,7 +8,7 @@ */ #include "hw/sysbus.h" -#include "char/char.h" +#include "sysemu/char.h" typedef struct { SysBusDevice busdev; diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c index 42ed54c9ab..bcc7893230 100644 --- a/hw/char/sclpconsole.c +++ b/hw/char/sclpconsole.c @@ -18,7 +18,7 @@ #include "hw/s390x/sclp.h" #include "hw/s390x/event-facility.h" -#include "char/char.h" +#include "sysemu/char.h" typedef struct ASCIIConsoleData { EventBufferHeader ebh; diff --git a/hw/char/serial.c b/hw/char/serial.c index 1151bf1bab..66b6348867 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -24,7 +24,7 @@ */ #include "hw/char/serial.h" -#include "char/char.h" +#include "sysemu/char.h" #include "qemu/timer.h" #include "exec/address-spaces.h" diff --git a/hw/char/sh_serial.c b/hw/char/sh_serial.c index 450c7d8551..b3286438ca 100644 --- a/hw/char/sh_serial.c +++ b/hw/char/sh_serial.c @@ -26,7 +26,7 @@ */ #include "hw/hw.h" #include "hw/sh4/sh.h" -#include "char/char.h" +#include "sysemu/char.h" #include "exec/address-spaces.h" //#define DEBUG_SERIAL diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c index 9df018a230..afcec1f182 100644 --- a/hw/char/spapr_vty.c +++ b/hw/char/spapr_vty.c @@ -1,5 +1,5 @@ #include "hw/qdev.h" -#include "char/char.h" +#include "sysemu/char.h" #include "hw/ppc/spapr.h" #include "hw/ppc/spapr_vio.h" diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c index 31f672c9a3..50350303cd 100644 --- a/hw/char/virtio-console.c +++ b/hw/char/virtio-console.c @@ -10,7 +10,7 @@ * the COPYING file in the top-level directory. */ -#include "char/char.h" +#include "sysemu/char.h" #include "qemu/error-report.h" #include "trace.h" #include "hw/virtio/virtio-serial.h" diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c index efc32320fa..eb7f450aba 100644 --- a/hw/char/xen_console.c +++ b/hw/char/xen_console.c @@ -30,7 +30,7 @@ #include <sys/mman.h> #include "hw/hw.h" -#include "char/char.h" +#include "sysemu/char.h" #include "hw/xen/xen_backend.h" #include <xen/io/console.h> diff --git a/hw/char/xilinx_uartlite.c b/hw/char/xilinx_uartlite.c index 079f4d4e1a..3f7e989f35 100644 --- a/hw/char/xilinx_uartlite.c +++ b/hw/char/xilinx_uartlite.c @@ -23,7 +23,7 @@ */ #include "hw/sysbus.h" -#include "char/char.h" +#include "sysemu/char.h" #define DUART(x) diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index 8c2e15205c..0eada32dcf 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -17,7 +17,7 @@ #include "hw/block/block.h" #include "net/hub.h" #include "qapi/visitor.h" -#include "char/char.h" +#include "sysemu/char.h" static void get_pointer(Object *obj, Visitor *v, Property *prop, const char *(*print)(void *ptr), diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index 9a0872d3b9..ddde18e6b4 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -5,7 +5,7 @@ #include "hw/block/block.h" #include "net/hub.h" #include "qapi/visitor.h" -#include "char/char.h" +#include "sysemu/char.h" void qdev_prop_set_after_realize(DeviceState *dev, const char *name, Error **errp) diff --git a/hw/display/blizzard.c b/hw/display/blizzard.c index 175c5cdd00..de7ccf87dc 100644 --- a/hw/display/blizzard.c +++ b/hw/display/blizzard.c @@ -20,7 +20,7 @@ #include "qemu-common.h" #include "ui/console.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "vga_int.h" #include "ui/pixel_ops.h" diff --git a/hw/display/sm501.c b/hw/display/sm501.c index 6b660ac1c0..9878df4af6 100644 --- a/hw/display/sm501.c +++ b/hw/display/sm501.c @@ -26,7 +26,7 @@ #include "hw/hw.h" #include "hw/char/serial.h" #include "ui/console.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "hw/sysbus.h" #include "hw/qdev-addr.h" #include "qemu/range.h" diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c index e252ce945f..178a21fd8d 100644 --- a/hw/display/tc6393xb.c +++ b/hw/display/tc6393xb.c @@ -11,7 +11,7 @@ * GNU GPL, version 2 or (at your option) any later version. */ #include "hw/hw.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "hw/block/flash.h" #include "ui/console.h" #include "ui/pixel_ops.h" diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c index 8e4266142d..e371569585 100644 --- a/hw/display/xenfb.c +++ b/hw/display/xenfb.c @@ -37,7 +37,7 @@ #include "hw/hw.h" #include "ui/console.h" -#include "char/char.h" +#include "sysemu/char.h" #include "hw/xen/xen_backend.h" #include <xen/event_channel.h> diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 8d75b34218..0d6e72b209 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -52,6 +52,7 @@ #include "sysemu/arch_init.h" #include "qemu/bitmap.h" #include "qemu/config-file.h" +#include "hw/acpi/acpi.h" /* debug PC/ISA interrupts */ //#define DEBUG_IRQ diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index cff8013b83..943758ad30 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -43,6 +43,7 @@ #include "hw/xen/xen.h" #include "exec/memory.h" #include "exec/address-spaces.h" +#include "hw/acpi/acpi.h" #include "cpu.h" #ifdef CONFIG_XEN # include <xen/hvm/hvm_info_table.h> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index d0ae8afba2..3405583f59 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -29,7 +29,6 @@ #include "monitor/monitor.h" #include "sysemu/dma.h" -#include "exec/cpu-common.h" #include "internal.h" #include <hw/ide/pci.h> #include <hw/ide/ahci.h> diff --git a/hw/ide/internal.h b/hw/ide/internal.h index 2c89b50c5e..0efb2da19b 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -8,7 +8,6 @@ */ #include <hw/ide.h> #include <hw/isa/isa.h> -#include "exec/iorange.h" #include "sysemu/dma.h" #include "sysemu/sysemu.h" #include "hw/block/block.h" diff --git a/hw/input/stellaris_input.c b/hw/input/stellaris_input.c index f83fc3f288..4e407922a0 100644 --- a/hw/input/stellaris_input.c +++ b/hw/input/stellaris_input.c @@ -7,7 +7,7 @@ * This code is licensed under the GPL. */ #include "hw/hw.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "ui/console.h" typedef struct { diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c index 34ee1fb3cf..a771cd5e52 100644 --- a/hw/input/tsc2005.c +++ b/hw/input/tsc2005.c @@ -21,7 +21,7 @@ #include "hw/hw.h" #include "qemu/timer.h" #include "ui/console.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #define TSC_CUT_RESOLUTION(value, p) ((value) >> (16 - (p ? 12 : 10))) diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c index e6c217c8db..9b854e77dd 100644 --- a/hw/input/tsc210x.c +++ b/hw/input/tsc210x.c @@ -24,7 +24,7 @@ #include "qemu/timer.h" #include "ui/console.h" #include "hw/arm/omap.h" /* For I2SCodec and uWireSlave */ -#include "hw/arm/devices.h" +#include "hw/devices.h" #define TSC_DATA_REGISTERS_PAGE 0x0 #define TSC_CONTROL_REGISTERS_PAGE 0x1 diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 67dbe68cdc..25fa43cb2d 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -12,7 +12,7 @@ #include "hw/sysbus.h" #include "qemu/timer.h" -#include "hw/arm.h" +#include "hw/arm/arm.h" #include "exec/address-spaces.h" #include "gic_internal.h" diff --git a/hw/isa/pc87312.c b/hw/isa/pc87312.c index 9f5e185685..82f7c80f9c 100644 --- a/hw/isa/pc87312.c +++ b/hw/isa/pc87312.c @@ -27,7 +27,7 @@ #include "qemu/error-report.h" #include "sysemu/blockdev.h" #include "sysemu/sysemu.h" -#include "char/char.h" +#include "sysemu/char.h" #include "trace.h" diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c index 6555a97e2e..1ca94980fb 100644 --- a/hw/lm32/lm32_boards.c +++ b/hw/lm32/lm32_boards.c @@ -20,7 +20,7 @@ #include "hw/sysbus.h" #include "hw/hw.h" #include "hw/block/flash.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "hw/boards.h" #include "hw/loader.h" #include "sysemu/blockdev.h" diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c index d02ca0cc04..cca93748aa 100644 --- a/hw/lm32/milkymist.c +++ b/hw/lm32/milkymist.c @@ -21,7 +21,7 @@ #include "hw/hw.h" #include "hw/block/flash.h" #include "sysemu/sysemu.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "hw/boards.h" #include "hw/loader.h" #include "elf.h" diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c index f61818b42b..ae7ff44423 100644 --- a/hw/microblaze/petalogix_ml605_mmu.c +++ b/hw/microblaze/petalogix_ml605_mmu.c @@ -30,7 +30,7 @@ #include "net/net.h" #include "hw/block/flash.h" #include "sysemu/sysemu.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "hw/boards.h" #include "hw/xilinx.h" #include "sysemu/blockdev.h" diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c index eedd60e38c..7c258f03af 100644 --- a/hw/microblaze/petalogix_s3adsp1800_mmu.c +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c @@ -28,7 +28,7 @@ #include "net/net.h" #include "hw/block/flash.h" #include "sysemu/sysemu.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "hw/boards.h" #include "hw/xilinx.h" #include "sysemu/blockdev.h" diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c index 3cf27fa822..1aac93a414 100644 --- a/hw/mips/mips_fulong2e.c +++ b/hw/mips/mips_fulong2e.c @@ -30,7 +30,7 @@ #include "hw/mips/mips.h" #include "hw/mips/cpudevs.h" #include "hw/pci/pci.h" -#include "char/char.h" +#include "sysemu/char.h" #include "sysemu/sysemu.h" #include "audio/audio.h" #include "qemu/log.h" diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index a3e936b77f..86f42b2ede 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -34,7 +34,7 @@ #include "hw/mips/mips.h" #include "hw/mips/cpudevs.h" #include "hw/pci/pci.h" -#include "char/char.h" +#include "sysemu/char.h" #include "sysemu/sysemu.h" #include "sysemu/arch_init.h" #include "hw/boards.h" diff --git a/hw/misc/cbus.c b/hw/misc/cbus.c index 3d9027f692..29b467b61f 100644 --- a/hw/misc/cbus.c +++ b/hw/misc/cbus.c @@ -22,7 +22,7 @@ #include "qemu-common.h" #include "hw/irq.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "sysemu/sysemu.h" //#define DEBUG diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c index f92ce19dde..a19a6d6d8c 100644 --- a/hw/misc/ivshmem.c +++ b/hw/misc/ivshmem.c @@ -24,7 +24,7 @@ #include "migration/migration.h" #include "qapi/qmp/qerror.h" #include "qemu/event_notifier.h" -#include "char/char.h" +#include "sysemu/char.h" #include <sys/mman.h> #include <sys/types.h> diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c index 04cf267f13..403fb868ae 100644 --- a/hw/net/lan9118.c +++ b/hw/net/lan9118.c @@ -12,7 +12,7 @@ #include "hw/sysbus.h" #include "net/net.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "sysemu/sysemu.h" #include "hw/ptimer.h" /* For crc32 */ diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c index f659256d6e..c2feae6eb8 100644 --- a/hw/net/smc91c111.c +++ b/hw/net/smc91c111.c @@ -9,7 +9,7 @@ #include "hw/sysbus.h" #include "net/net.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" /* For crc32 */ #include <zlib.h> diff --git a/hw/net/vmxnet_tx_pkt.c b/hw/net/vmxnet_tx_pkt.c index b1e795b3b2..fc01e4da3c 100644 --- a/hw/net/vmxnet_tx_pkt.c +++ b/hw/net/vmxnet_tx_pkt.c @@ -15,6 +15,7 @@ * */ +#include "hw/hw.h" #include "vmxnet_tx_pkt.h" #include "net/eth.h" #include "qemu-common.h" @@ -22,7 +23,6 @@ #include "net/checksum.h" #include "net/tap.h" #include "net/net.h" -#include "exec/cpu-common.h" enum { VMXNET_TX_PKT_VHDR_FRAG = 0, diff --git a/hw/net/xgmac.c b/hw/net/xgmac.c index 5275f4810d..1d9074a1d0 100644 --- a/hw/net/xgmac.c +++ b/hw/net/xgmac.c @@ -25,7 +25,7 @@ */ #include "hw/sysbus.h" -#include "char/char.h" +#include "sysemu/char.h" #include "qemu/log.h" #include "net/net.h" #include "net/checksum.h" diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c index ff87ac31d1..c0d7e62f32 100644 --- a/hw/ppc/spapr_events.c +++ b/hw/ppc/spapr_events.c @@ -26,7 +26,7 @@ */ #include "cpu.h" #include "sysemu/sysemu.h" -#include "char/char.h" +#include "sysemu/char.h" #include "hw/qdev.h" #include "sysemu/device_tree.h" diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index b71b59c5cf..8ecaa5f8ec 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -26,7 +26,7 @@ */ #include "cpu.h" #include "sysemu/sysemu.h" -#include "char/char.h" +#include "sysemu/char.h" #include "hw/qdev.h" #include "sysemu/device_tree.h" diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c index 92b43947f7..6728ba7ea0 100644 --- a/hw/ppc/virtex_ml507.c +++ b/hw/ppc/virtex_ml507.c @@ -27,7 +27,7 @@ #include "hw/char/serial.h" #include "hw/block/flash.h" #include "sysemu/sysemu.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "hw/boards.h" #include "sysemu/device_tree.h" #include "hw/loader.h" diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c index fe82bd62fe..3e4818e170 100644 --- a/hw/sh4/r2d.c +++ b/hw/sh4/r2d.c @@ -26,7 +26,7 @@ #include "hw/sysbus.h" #include "hw/hw.h" #include "hw/sh4/sh.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "sysemu/sysemu.h" #include "hw/boards.h" #include "hw/pci/pci.h" diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c index 3b27d4019a..78c77eff46 100644 --- a/hw/sparc/leon3.c +++ b/hw/sparc/leon3.c @@ -24,7 +24,7 @@ #include "hw/hw.h" #include "qemu/timer.h" #include "hw/ptimer.h" -#include "char/char.h" +#include "sysemu/char.h" #include "sysemu/sysemu.h" #include "hw/boards.h" #include "hw/loader.h" diff --git a/hw/timer/tusb6010.c b/hw/timer/tusb6010.c index 533938a9b4..50edc063d1 100644 --- a/hw/timer/tusb6010.c +++ b/hw/timer/tusb6010.c @@ -23,7 +23,7 @@ #include "hw/usb.h" #include "hw/arm/omap.h" #include "hw/irq.h" -#include "hw/arm/devices.h" +#include "hw/devices.h" #include "hw/sysbus.h" typedef struct TUSBState { diff --git a/hw/tpm/Makefile.objs b/hw/tpm/Makefile.objs new file mode 100644 index 0000000000..99f5983143 --- /dev/null +++ b/hw/tpm/Makefile.objs @@ -0,0 +1,2 @@ +common-obj-$(CONFIG_TPM_TIS) += tpm_tis.o +common-obj-$(CONFIG_TPM_PASSTHROUGH) += tpm_passthrough.o diff --git a/hw/tpm/tpm_int.h b/hw/tpm/tpm_int.h new file mode 100644 index 0000000000..08f87cb9a8 --- /dev/null +++ b/hw/tpm/tpm_int.h @@ -0,0 +1,60 @@ +/* + * TPM configuration + * + * Copyright (C) 2011-2013 IBM Corporation + * + * Authors: + * Stefan Berger <stefanb@us.ibm.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#ifndef TPM_TPM_INT_H +#define TPM_TPM_INT_H + +#include "exec/memory.h" +#include "tpm_tis.h" + +/* overall state of the TPM interface */ +struct TPMState { + ISADevice busdev; + MemoryRegion mmio; + + union { + TPMTISEmuState tis; + } s; + + uint8_t locty_number; + TPMLocality *locty_data; + + char *backend; + TPMBackend *be_driver; +}; + +#define TPM(obj) OBJECT_CHECK(TPMState, (obj), TYPE_TPM_TIS) + +struct tpm_req_hdr { + uint16_t tag; + uint32_t len; + uint32_t ordinal; +} QEMU_PACKED; + +struct tpm_resp_hdr { + uint16_t tag; + uint32_t len; + uint32_t errcode; +} QEMU_PACKED; + +#define TPM_TAG_RQU_COMMAND 0xc1 +#define TPM_TAG_RQU_AUTH1_COMMAND 0xc2 +#define TPM_TAG_RQU_AUTH2_COMMAND 0xc3 + +#define TPM_TAG_RSP_COMMAND 0xc4 +#define TPM_TAG_RSP_AUTH1_COMMAND 0xc5 +#define TPM_TAG_RSP_AUTH2_COMMAND 0xc6 + +#define TPM_FAIL 9 + +#define TPM_ORD_GetTicks 0xf1 + +#endif /* TPM_TPM_INT_H */ diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c new file mode 100644 index 0000000000..416b9b65c7 --- /dev/null +++ b/hw/tpm/tpm_passthrough.c @@ -0,0 +1,576 @@ +/* + * passthrough TPM driver + * + * Copyright (c) 2010 - 2013 IBM Corporation + * Authors: + * Stefan Berger <stefanb@us.ibm.com> + * + * Copyright (C) 2011 IAIK, Graz University of Technology + * Author: Andreas Niederl + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/> + */ + +#include <dirent.h> + +#include "qemu-common.h" +#include "qapi/error.h" +#include "qemu/sockets.h" +#include "sysemu/tpm_backend.h" +#include "tpm_int.h" +#include "hw/hw.h" +#include "hw/i386/pc.h" +#include "sysemu/tpm_backend_int.h" +#include "tpm_tis.h" + +/* #define DEBUG_TPM */ + +#ifdef DEBUG_TPM +#define DPRINTF(fmt, ...) \ + do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0) +#else +#define DPRINTF(fmt, ...) \ + do { } while (0) +#endif + +#define TYPE_TPM_PASSTHROUGH "tpm-passthrough" +#define TPM_PASSTHROUGH(obj) \ + OBJECT_CHECK(TPMPassthruState, (obj), TYPE_TPM_PASSTHROUGH) + +static const TPMDriverOps tpm_passthrough_driver; + +/* data structures */ +typedef struct TPMPassthruThreadParams { + TPMState *tpm_state; + + TPMRecvDataCB *recv_data_callback; + TPMBackend *tb; +} TPMPassthruThreadParams; + +struct TPMPassthruState { + TPMBackend parent; + + TPMBackendThread tbt; + + TPMPassthruThreadParams tpm_thread_params; + + char *tpm_dev; + int tpm_fd; + bool tpm_executing; + bool tpm_op_canceled; + int cancel_fd; + bool had_startup_error; +}; + +typedef struct TPMPassthruState TPMPassthruState; + +#define TPM_PASSTHROUGH_DEFAULT_DEVICE "/dev/tpm0" + +/* functions */ + +static void tpm_passthrough_cancel_cmd(TPMBackend *tb); + +static int tpm_passthrough_unix_write(int fd, const uint8_t *buf, uint32_t len) +{ + return send_all(fd, buf, len); +} + +static int tpm_passthrough_unix_read(int fd, uint8_t *buf, uint32_t len) +{ + return recv_all(fd, buf, len, true); +} + +static uint32_t tpm_passthrough_get_size_from_buffer(const uint8_t *buf) +{ + struct tpm_resp_hdr *resp = (struct tpm_resp_hdr *)buf; + + return be32_to_cpu(resp->len); +} + +/* + * Write an error message in the given output buffer. + */ +static void tpm_write_fatal_error_response(uint8_t *out, uint32_t out_len) +{ + if (out_len >= sizeof(struct tpm_resp_hdr)) { + struct tpm_resp_hdr *resp = (struct tpm_resp_hdr *)out; + + resp->tag = cpu_to_be16(TPM_TAG_RSP_COMMAND); + resp->len = cpu_to_be32(sizeof(struct tpm_resp_hdr)); + resp->errcode = cpu_to_be32(TPM_FAIL); + } +} + +static int tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt, + const uint8_t *in, uint32_t in_len, + uint8_t *out, uint32_t out_len) +{ + int ret; + + tpm_pt->tpm_op_canceled = false; + tpm_pt->tpm_executing = true; + + ret = tpm_passthrough_unix_write(tpm_pt->tpm_fd, in, in_len); + if (ret != in_len) { + if (!tpm_pt->tpm_op_canceled || + (tpm_pt->tpm_op_canceled && errno != ECANCELED)) { + error_report("tpm_passthrough: error while transmitting data " + "to TPM: %s (%i)\n", + strerror(errno), errno); + } + goto err_exit; + } + + tpm_pt->tpm_executing = false; + + ret = tpm_passthrough_unix_read(tpm_pt->tpm_fd, out, out_len); + if (ret < 0) { + if (!tpm_pt->tpm_op_canceled || + (tpm_pt->tpm_op_canceled && errno != ECANCELED)) { + error_report("tpm_passthrough: error while reading data from " + "TPM: %s (%i)\n", + strerror(errno), errno); + } + } else if (ret < sizeof(struct tpm_resp_hdr) || + tpm_passthrough_get_size_from_buffer(out) != ret) { + ret = -1; + error_report("tpm_passthrough: received invalid response " + "packet from TPM\n"); + } + +err_exit: + if (ret < 0) { + tpm_write_fatal_error_response(out, out_len); + } + + tpm_pt->tpm_executing = false; + + return ret; +} + +static int tpm_passthrough_unix_transfer(TPMPassthruState *tpm_pt, + const TPMLocality *locty_data) +{ + return tpm_passthrough_unix_tx_bufs(tpm_pt, + locty_data->w_buffer.buffer, + locty_data->w_offset, + locty_data->r_buffer.buffer, + locty_data->r_buffer.size); +} + +static void tpm_passthrough_worker_thread(gpointer data, + gpointer user_data) +{ + TPMPassthruThreadParams *thr_parms = user_data; + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(thr_parms->tb); + TPMBackendCmd cmd = (TPMBackendCmd)data; + + DPRINTF("tpm_passthrough: processing command type %d\n", cmd); + + switch (cmd) { + case TPM_BACKEND_CMD_PROCESS_CMD: + tpm_passthrough_unix_transfer(tpm_pt, + thr_parms->tpm_state->locty_data); + + thr_parms->recv_data_callback(thr_parms->tpm_state, + thr_parms->tpm_state->locty_number); + break; + case TPM_BACKEND_CMD_INIT: + case TPM_BACKEND_CMD_END: + case TPM_BACKEND_CMD_TPM_RESET: + /* nothing to do */ + break; + } +} + +/* + * Start the TPM (thread). If it had been started before, then terminate + * and start it again. + */ +static int tpm_passthrough_startup_tpm(TPMBackend *tb) +{ + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb); + + /* terminate a running TPM */ + tpm_backend_thread_end(&tpm_pt->tbt); + + tpm_backend_thread_create(&tpm_pt->tbt, + tpm_passthrough_worker_thread, + &tpm_pt->tpm_thread_params); + + return 0; +} + +static void tpm_passthrough_reset(TPMBackend *tb) +{ + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb); + + DPRINTF("tpm_passthrough: CALL TO TPM_RESET!\n"); + + tpm_passthrough_cancel_cmd(tb); + + tpm_backend_thread_end(&tpm_pt->tbt); + + tpm_pt->had_startup_error = false; +} + +static int tpm_passthrough_init(TPMBackend *tb, TPMState *s, + TPMRecvDataCB *recv_data_cb) +{ + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb); + + tpm_pt->tpm_thread_params.tpm_state = s; + tpm_pt->tpm_thread_params.recv_data_callback = recv_data_cb; + tpm_pt->tpm_thread_params.tb = tb; + + return 0; +} + +static bool tpm_passthrough_get_tpm_established_flag(TPMBackend *tb) +{ + return false; +} + +static bool tpm_passthrough_get_startup_error(TPMBackend *tb) +{ + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb); + + return tpm_pt->had_startup_error; +} + +static size_t tpm_passthrough_realloc_buffer(TPMSizedBuffer *sb) +{ + size_t wanted_size = 4096; /* Linux tpm.c buffer size */ + + if (sb->size != wanted_size) { + sb->buffer = g_realloc(sb->buffer, wanted_size); + sb->size = wanted_size; + } + return sb->size; +} + +static void tpm_passthrough_deliver_request(TPMBackend *tb) +{ + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb); + + tpm_backend_thread_deliver_request(&tpm_pt->tbt); +} + +static void tpm_passthrough_cancel_cmd(TPMBackend *tb) +{ + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb); + int n; + + /* + * As of Linux 3.7 the tpm_tis driver does not properly cancel + * commands on all TPM manufacturers' TPMs. + * Only cancel if we're busy so we don't cancel someone else's + * command, e.g., a command executed on the host. + */ + if (tpm_pt->tpm_executing) { + if (tpm_pt->cancel_fd >= 0) { + n = write(tpm_pt->cancel_fd, "-", 1); + if (n != 1) { + error_report("Canceling TPM command failed: %s\n", + strerror(errno)); + } else { + tpm_pt->tpm_op_canceled = true; + } + } else { + error_report("Cannot cancel TPM command due to missing " + "TPM sysfs cancel entry"); + } + } +} + +static const char *tpm_passthrough_create_desc(void) +{ + return "Passthrough TPM backend driver"; +} + +/* + * A basic test of a TPM device. We expect a well formatted response header + * (error response is fine) within one second. + */ +static int tpm_passthrough_test_tpmdev(int fd) +{ + struct tpm_req_hdr req = { + .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND), + .len = cpu_to_be32(sizeof(req)), + .ordinal = cpu_to_be32(TPM_ORD_GetTicks), + }; + struct tpm_resp_hdr *resp; + fd_set readfds; + int n; + struct timeval tv = { + .tv_sec = 1, + .tv_usec = 0, + }; + unsigned char buf[1024]; + + n = write(fd, &req, sizeof(req)); + if (n < 0) { + return errno; + } + if (n != sizeof(req)) { + return EFAULT; + } + + FD_ZERO(&readfds); + FD_SET(fd, &readfds); + + /* wait for a second */ + n = select(fd + 1, &readfds, NULL, NULL, &tv); + if (n != 1) { + return errno; + } + + n = read(fd, &buf, sizeof(buf)); + if (n < sizeof(struct tpm_resp_hdr)) { + return EFAULT; + } + + resp = (struct tpm_resp_hdr *)buf; + /* check the header */ + if (be16_to_cpu(resp->tag) != TPM_TAG_RSP_COMMAND || + be32_to_cpu(resp->len) != n) { + return EBADMSG; + } + + return 0; +} + +/* + * Check whether the given base path, e.g., /sys/class/misc/tpm0/device, + * is the sysfs directory of a TPM. A TPM sysfs directory should be uniquely + * recognizable by the file entries 'pcrs' and 'cancel'. + * Upon success 'true' is returned and the basebath buffer has '/cancel' + * appended. + */ +static bool tpm_passthrough_check_sysfs_cancel(char *basepath, size_t bufsz) +{ + char path[PATH_MAX]; + struct stat statbuf; + + snprintf(path, sizeof(path), "%s/pcrs", basepath); + if (stat(path, &statbuf) == -1 || !S_ISREG(statbuf.st_mode)) { + return false; + } + + snprintf(path, sizeof(path), "%s/cancel", basepath); + if (stat(path, &statbuf) == -1 || !S_ISREG(statbuf.st_mode)) { + return false; + } + + strncpy(basepath, path, bufsz); + + return true; +} + +/* + * Unless path or file descriptor set has been provided by user, + * determine the sysfs cancel file following kernel documentation + * in Documentation/ABI/stable/sysfs-class-tpm. + */ +static int tpm_passthrough_open_sysfs_cancel(TPMBackend *tb) +{ + int fd = -1; + unsigned int idx; + DIR *pnp_dir; + char path[PATH_MAX]; + struct dirent entry, *result; + int len; + + if (tb->cancel_path) { + fd = qemu_open(tb->cancel_path, O_WRONLY); + if (fd < 0) { + error_report("Could not open TPM cancel path : %s", + strerror(errno)); + } + return fd; + } + + snprintf(path, sizeof(path), "/sys/class/misc"); + pnp_dir = opendir(path); + if (pnp_dir != NULL) { + while (readdir_r(pnp_dir, &entry, &result) == 0 && + result != NULL) { + /* + * only allow /sys/class/misc/tpm%u type of paths + */ + if (sscanf(entry.d_name, "tpm%u%n", &idx, &len) < 1 || + len <= strlen("tpm") || + len != strlen(entry.d_name)) { + continue; + } + + snprintf(path, sizeof(path), "/sys/class/misc/%s/device", + entry.d_name); + if (!tpm_passthrough_check_sysfs_cancel(path, sizeof(path))) { + continue; + } + + fd = qemu_open(path, O_WRONLY); + break; + } + closedir(pnp_dir); + } + + if (fd >= 0) { + tb->cancel_path = g_strdup(path); + } + + return fd; +} + +static int tpm_passthrough_handle_device_opts(QemuOpts *opts, TPMBackend *tb) +{ + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb); + const char *value; + + value = qemu_opt_get(opts, "cancel-path"); + if (value) { + tb->cancel_path = g_strdup(value); + } + + value = qemu_opt_get(opts, "path"); + if (!value) { + value = TPM_PASSTHROUGH_DEFAULT_DEVICE; + } + + tpm_pt->tpm_dev = g_strdup(value); + + tb->path = g_strdup(tpm_pt->tpm_dev); + + tpm_pt->tpm_fd = qemu_open(tpm_pt->tpm_dev, O_RDWR); + if (tpm_pt->tpm_fd < 0) { + error_report("Cannot access TPM device using '%s': %s\n", + tpm_pt->tpm_dev, strerror(errno)); + goto err_free_parameters; + } + + if (tpm_passthrough_test_tpmdev(tpm_pt->tpm_fd)) { + error_report("'%s' is not a TPM device.\n", + tpm_pt->tpm_dev); + goto err_close_tpmdev; + } + + return 0; + + err_close_tpmdev: + qemu_close(tpm_pt->tpm_fd); + tpm_pt->tpm_fd = -1; + + err_free_parameters: + g_free(tb->path); + tb->path = NULL; + + g_free(tpm_pt->tpm_dev); + tpm_pt->tpm_dev = NULL; + + return 1; +} + +static TPMBackend *tpm_passthrough_create(QemuOpts *opts, const char *id) +{ + Object *obj = object_new(TYPE_TPM_PASSTHROUGH); + TPMBackend *tb = TPM_BACKEND(obj); + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb); + + tb->id = g_strdup(id); + /* let frontend set the fe_model to proper value */ + tb->fe_model = -1; + + tb->ops = &tpm_passthrough_driver; + + if (tpm_passthrough_handle_device_opts(opts, tb)) { + goto err_exit; + } + + tpm_pt->cancel_fd = tpm_passthrough_open_sysfs_cancel(tb); + if (tpm_pt->cancel_fd < 0) { + goto err_exit; + } + + return tb; + +err_exit: + g_free(tb->id); + + return NULL; +} + +static void tpm_passthrough_destroy(TPMBackend *tb) +{ + TPMPassthruState *tpm_pt = TPM_PASSTHROUGH(tb); + + tpm_passthrough_cancel_cmd(tb); + + tpm_backend_thread_end(&tpm_pt->tbt); + + qemu_close(tpm_pt->tpm_fd); + qemu_close(tpm_pt->cancel_fd); + + g_free(tb->id); + g_free(tb->path); + g_free(tb->cancel_path); + g_free(tpm_pt->tpm_dev); +} + +static const TPMDriverOps tpm_passthrough_driver = { + .type = TPM_TYPE_PASSTHROUGH, + .desc = tpm_passthrough_create_desc, + .create = tpm_passthrough_create, + .destroy = tpm_passthrough_destroy, + .init = tpm_passthrough_init, + .startup_tpm = tpm_passthrough_startup_tpm, + .realloc_buffer = tpm_passthrough_realloc_buffer, + .reset = tpm_passthrough_reset, + .had_startup_error = tpm_passthrough_get_startup_error, + .deliver_request = tpm_passthrough_deliver_request, + .cancel_cmd = tpm_passthrough_cancel_cmd, + .get_tpm_established_flag = tpm_passthrough_get_tpm_established_flag, +}; + +static void tpm_passthrough_inst_init(Object *obj) +{ +} + +static void tpm_passthrough_inst_finalize(Object *obj) +{ +} + +static void tpm_passthrough_class_init(ObjectClass *klass, void *data) +{ + TPMBackendClass *tbc = TPM_BACKEND_CLASS(klass); + + tbc->ops = &tpm_passthrough_driver; +} + +static const TypeInfo tpm_passthrough_info = { + .name = TYPE_TPM_PASSTHROUGH, + .parent = TYPE_TPM_BACKEND, + .instance_size = sizeof(TPMPassthruState), + .class_init = tpm_passthrough_class_init, + .instance_init = tpm_passthrough_inst_init, + .instance_finalize = tpm_passthrough_inst_finalize, +}; + +static void tpm_passthrough_register(void) +{ + type_register_static(&tpm_passthrough_info); + tpm_register_driver(&tpm_passthrough_driver); +} + +type_init(tpm_passthrough_register) diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c new file mode 100644 index 0000000000..d4d8152875 --- /dev/null +++ b/hw/tpm/tpm_tis.c @@ -0,0 +1,930 @@ +/* + * tpm_tis.c - QEMU's TPM TIS interface emulator + * + * Copyright (C) 2006,2010-2013 IBM Corporation + * + * Authors: + * Stefan Berger <stefanb@us.ibm.com> + * David Safford <safford@us.ibm.com> + * + * Xen 4 support: Andrease Niederl <andreas.niederl@iaik.tugraz.at> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + * Implementation of the TIS interface according to specs found at + * http://www.trustedcomputinggroup.org. This implementation currently + * supports version 1.21, revision 1.0. + * In the developers menu choose the PC Client section then find the TIS + * specification. + */ + +#include "sysemu/tpm_backend.h" +#include "tpm_int.h" +#include "block/block.h" +#include "exec/address-spaces.h" +#include "hw/hw.h" +#include "hw/i386/pc.h" +#include "hw/pci/pci_ids.h" +#include "tpm_tis.h" +#include "qemu-common.h" + +/*#define DEBUG_TIS */ + +#ifdef DEBUG_TIS +#define DPRINTF(fmt, ...) \ + do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0) +#else +#define DPRINTF(fmt, ...) \ + do { } while (0) +#endif + +/* whether the STS interrupt is supported */ +#define RAISE_STS_IRQ + +/* tis registers */ +#define TPM_TIS_REG_ACCESS 0x00 +#define TPM_TIS_REG_INT_ENABLE 0x08 +#define TPM_TIS_REG_INT_VECTOR 0x0c +#define TPM_TIS_REG_INT_STATUS 0x10 +#define TPM_TIS_REG_INTF_CAPABILITY 0x14 +#define TPM_TIS_REG_STS 0x18 +#define TPM_TIS_REG_DATA_FIFO 0x24 +#define TPM_TIS_REG_DID_VID 0xf00 +#define TPM_TIS_REG_RID 0xf04 + +/* vendor-specific registers */ +#define TPM_TIS_REG_DEBUG 0xf90 + +#define TPM_TIS_STS_VALID (1 << 7) +#define TPM_TIS_STS_COMMAND_READY (1 << 6) +#define TPM_TIS_STS_TPM_GO (1 << 5) +#define TPM_TIS_STS_DATA_AVAILABLE (1 << 4) +#define TPM_TIS_STS_EXPECT (1 << 3) +#define TPM_TIS_STS_RESPONSE_RETRY (1 << 1) + +#define TPM_TIS_BURST_COUNT_SHIFT 8 +#define TPM_TIS_BURST_COUNT(X) \ + ((X) << TPM_TIS_BURST_COUNT_SHIFT) + +#define TPM_TIS_ACCESS_TPM_REG_VALID_STS (1 << 7) +#define TPM_TIS_ACCESS_ACTIVE_LOCALITY (1 << 5) +#define TPM_TIS_ACCESS_BEEN_SEIZED (1 << 4) +#define TPM_TIS_ACCESS_SEIZE (1 << 3) +#define TPM_TIS_ACCESS_PENDING_REQUEST (1 << 2) +#define TPM_TIS_ACCESS_REQUEST_USE (1 << 1) +#define TPM_TIS_ACCESS_TPM_ESTABLISHMENT (1 << 0) + +#define TPM_TIS_INT_ENABLED (1 << 31) +#define TPM_TIS_INT_DATA_AVAILABLE (1 << 0) +#define TPM_TIS_INT_STS_VALID (1 << 1) +#define TPM_TIS_INT_LOCALITY_CHANGED (1 << 2) +#define TPM_TIS_INT_COMMAND_READY (1 << 7) + +#define TPM_TIS_INT_POLARITY_MASK (3 << 3) +#define TPM_TIS_INT_POLARITY_LOW_LEVEL (1 << 3) + +#ifndef RAISE_STS_IRQ + +#define TPM_TIS_INTERRUPTS_SUPPORTED (TPM_TIS_INT_LOCALITY_CHANGED | \ + TPM_TIS_INT_DATA_AVAILABLE | \ + TPM_TIS_INT_COMMAND_READY) + +#else + +#define TPM_TIS_INTERRUPTS_SUPPORTED (TPM_TIS_INT_LOCALITY_CHANGED | \ + TPM_TIS_INT_DATA_AVAILABLE | \ + TPM_TIS_INT_STS_VALID | \ + TPM_TIS_INT_COMMAND_READY) + +#endif + +#define TPM_TIS_CAP_INTERRUPT_LOW_LEVEL (1 << 4) /* support is mandatory */ +#define TPM_TIS_CAPABILITIES_SUPPORTED (TPM_TIS_CAP_INTERRUPT_LOW_LEVEL | \ + TPM_TIS_INTERRUPTS_SUPPORTED) + +#define TPM_TIS_TPM_DID 0x0001 +#define TPM_TIS_TPM_VID PCI_VENDOR_ID_IBM +#define TPM_TIS_TPM_RID 0x0001 + +#define TPM_TIS_NO_DATA_BYTE 0xff + +/* local prototypes */ + +static uint64_t tpm_tis_mmio_read(void *opaque, hwaddr addr, + unsigned size); + +/* utility functions */ + +static uint8_t tpm_tis_locality_from_addr(hwaddr addr) +{ + return (uint8_t)((addr >> TPM_TIS_LOCALITY_SHIFT) & 0x7); +} + +static uint32_t tpm_tis_get_size_from_buffer(const TPMSizedBuffer *sb) +{ + return be32_to_cpu(*(uint32_t *)&sb->buffer[2]); +} + +static void tpm_tis_show_buffer(const TPMSizedBuffer *sb, const char *string) +{ +#ifdef DEBUG_TIS + uint32_t len, i; + + len = tpm_tis_get_size_from_buffer(sb); + DPRINTF("tpm_tis: %s length = %d\n", string, len); + for (i = 0; i < len; i++) { + if (i && !(i % 16)) { + DPRINTF("\n"); + } + DPRINTF("%.2X ", sb->buffer[i]); + } + DPRINTF("\n"); +#endif +} + +/* + * Send a request to the TPM. + */ +static void tpm_tis_tpm_send(TPMState *s, uint8_t locty) +{ + TPMTISEmuState *tis = &s->s.tis; + + tpm_tis_show_buffer(&tis->loc[locty].w_buffer, "tpm_tis: To TPM"); + + s->locty_number = locty; + s->locty_data = &tis->loc[locty]; + + /* + * w_offset serves as length indicator for length of data; + * it's reset when the response comes back + */ + tis->loc[locty].state = TPM_TIS_STATE_EXECUTION; + + tpm_backend_deliver_request(s->be_driver); +} + +/* raise an interrupt if allowed */ +static void tpm_tis_raise_irq(TPMState *s, uint8_t locty, uint32_t irqmask) +{ + TPMTISEmuState *tis = &s->s.tis; + + if (!TPM_TIS_IS_VALID_LOCTY(locty)) { + return; + } + + if ((tis->loc[locty].inte & TPM_TIS_INT_ENABLED) && + (tis->loc[locty].inte & irqmask)) { + DPRINTF("tpm_tis: Raising IRQ for flag %08x\n", irqmask); + qemu_irq_raise(s->s.tis.irq); + tis->loc[locty].ints |= irqmask; + } +} + +static uint32_t tpm_tis_check_request_use_except(TPMState *s, uint8_t locty) +{ + uint8_t l; + + for (l = 0; l < TPM_TIS_NUM_LOCALITIES; l++) { + if (l == locty) { + continue; + } + if ((s->s.tis.loc[l].access & TPM_TIS_ACCESS_REQUEST_USE)) { + return 1; + } + } + + return 0; +} + +static void tpm_tis_new_active_locality(TPMState *s, uint8_t new_active_locty) +{ + TPMTISEmuState *tis = &s->s.tis; + bool change = (s->s.tis.active_locty != new_active_locty); + bool is_seize; + uint8_t mask; + + if (change && TPM_TIS_IS_VALID_LOCTY(s->s.tis.active_locty)) { + is_seize = TPM_TIS_IS_VALID_LOCTY(new_active_locty) && + tis->loc[new_active_locty].access & TPM_TIS_ACCESS_SEIZE; + + if (is_seize) { + mask = ~(TPM_TIS_ACCESS_ACTIVE_LOCALITY); + } else { + mask = ~(TPM_TIS_ACCESS_ACTIVE_LOCALITY| + TPM_TIS_ACCESS_REQUEST_USE); + } + /* reset flags on the old active locality */ + tis->loc[s->s.tis.active_locty].access &= mask; + + if (is_seize) { + tis->loc[tis->active_locty].access |= TPM_TIS_ACCESS_BEEN_SEIZED; + } + } + + tis->active_locty = new_active_locty; + + DPRINTF("tpm_tis: Active locality is now %d\n", s->s.tis.active_locty); + + if (TPM_TIS_IS_VALID_LOCTY(new_active_locty)) { + /* set flags on the new active locality */ + tis->loc[new_active_locty].access |= TPM_TIS_ACCESS_ACTIVE_LOCALITY; + tis->loc[new_active_locty].access &= ~(TPM_TIS_ACCESS_REQUEST_USE | + TPM_TIS_ACCESS_SEIZE); + } + + if (change) { + tpm_tis_raise_irq(s, tis->active_locty, TPM_TIS_INT_LOCALITY_CHANGED); + } +} + +/* abort -- this function switches the locality */ +static void tpm_tis_abort(TPMState *s, uint8_t locty) +{ + TPMTISEmuState *tis = &s->s.tis; + + tis->loc[locty].r_offset = 0; + tis->loc[locty].w_offset = 0; + + DPRINTF("tpm_tis: tis_abort: new active locality is %d\n", tis->next_locty); + + /* + * Need to react differently depending on who's aborting now and + * which locality will become active afterwards. + */ + if (tis->aborting_locty == tis->next_locty) { + tis->loc[tis->aborting_locty].state = TPM_TIS_STATE_READY; + tis->loc[tis->aborting_locty].sts = TPM_TIS_STS_COMMAND_READY; + tpm_tis_raise_irq(s, tis->aborting_locty, TPM_TIS_INT_COMMAND_READY); + } + + /* locality after abort is another one than the current one */ + tpm_tis_new_active_locality(s, tis->next_locty); + + tis->next_locty = TPM_TIS_NO_LOCALITY; + /* nobody's aborting a command anymore */ + tis->aborting_locty = TPM_TIS_NO_LOCALITY; +} + +/* prepare aborting current command */ +static void tpm_tis_prep_abort(TPMState *s, uint8_t locty, uint8_t newlocty) +{ + TPMTISEmuState *tis = &s->s.tis; + uint8_t busy_locty; + + tis->aborting_locty = locty; + tis->next_locty = newlocty; /* locality after successful abort */ + + /* + * only abort a command using an interrupt if currently executing + * a command AND if there's a valid connection to the vTPM. + */ + for (busy_locty = 0; busy_locty < TPM_TIS_NUM_LOCALITIES; busy_locty++) { + if (tis->loc[busy_locty].state == TPM_TIS_STATE_EXECUTION) { + /* + * request the backend to cancel. Some backends may not + * support it + */ + tpm_backend_cancel_cmd(s->be_driver); + return; + } + } + + tpm_tis_abort(s, locty); +} + +static void tpm_tis_receive_bh(void *opaque) +{ + TPMState *s = opaque; + TPMTISEmuState *tis = &s->s.tis; + uint8_t locty = s->locty_number; + + tis->loc[locty].sts = TPM_TIS_STS_VALID | TPM_TIS_STS_DATA_AVAILABLE; + tis->loc[locty].state = TPM_TIS_STATE_COMPLETION; + tis->loc[locty].r_offset = 0; + tis->loc[locty].w_offset = 0; + + if (TPM_TIS_IS_VALID_LOCTY(tis->next_locty)) { + tpm_tis_abort(s, locty); + } + +#ifndef RAISE_STS_IRQ + tpm_tis_raise_irq(s, locty, TPM_TIS_INT_DATA_AVAILABLE); +#else + tpm_tis_raise_irq(s, locty, + TPM_TIS_INT_DATA_AVAILABLE | TPM_TIS_INT_STS_VALID); +#endif +} + +/* + * Callback from the TPM to indicate that the response was received. + */ +static void tpm_tis_receive_cb(TPMState *s, uint8_t locty) +{ + TPMTISEmuState *tis = &s->s.tis; + + assert(s->locty_number == locty); + + qemu_bh_schedule(tis->bh); +} + +/* + * Read a byte of response data + */ +static uint32_t tpm_tis_data_read(TPMState *s, uint8_t locty) +{ + TPMTISEmuState *tis = &s->s.tis; + uint32_t ret = TPM_TIS_NO_DATA_BYTE; + uint16_t len; + + if ((tis->loc[locty].sts & TPM_TIS_STS_DATA_AVAILABLE)) { + len = tpm_tis_get_size_from_buffer(&tis->loc[locty].r_buffer); + + ret = tis->loc[locty].r_buffer.buffer[tis->loc[locty].r_offset++]; + if (tis->loc[locty].r_offset >= len) { + /* got last byte */ + tis->loc[locty].sts = TPM_TIS_STS_VALID; +#ifdef RAISE_STS_IRQ + tpm_tis_raise_irq(s, locty, TPM_TIS_INT_STS_VALID); +#endif + } + DPRINTF("tpm_tis: tpm_tis_data_read byte 0x%02x [%d]\n", + ret, tis->loc[locty].r_offset-1); + } + + return ret; +} + +#ifdef DEBUG_TIS +static void tpm_tis_dump_state(void *opaque, hwaddr addr) +{ + static const unsigned regs[] = { + TPM_TIS_REG_ACCESS, + TPM_TIS_REG_INT_ENABLE, + TPM_TIS_REG_INT_VECTOR, + TPM_TIS_REG_INT_STATUS, + TPM_TIS_REG_INTF_CAPABILITY, + TPM_TIS_REG_STS, + TPM_TIS_REG_DID_VID, + TPM_TIS_REG_RID, + 0xfff}; + int idx; + uint8_t locty = tpm_tis_locality_from_addr(addr); + hwaddr base = addr & ~0xfff; + TPMState *s = opaque; + TPMTISEmuState *tis = &s->s.tis; + + DPRINTF("tpm_tis: active locality : %d\n" + "tpm_tis: state of locality %d : %d\n" + "tpm_tis: register dump:\n", + tis->active_locty, + locty, tis->loc[locty].state); + + for (idx = 0; regs[idx] != 0xfff; idx++) { + DPRINTF("tpm_tis: 0x%04x : 0x%08x\n", regs[idx], + (uint32_t)tpm_tis_mmio_read(opaque, base + regs[idx], 4)); + } + + DPRINTF("tpm_tis: read offset : %d\n" + "tpm_tis: result buffer : ", + tis->loc[locty].r_offset); + for (idx = 0; + idx < tpm_tis_get_size_from_buffer(&tis->loc[locty].r_buffer); + idx++) { + DPRINTF("%c%02x%s", + tis->loc[locty].r_offset == idx ? '>' : ' ', + tis->loc[locty].r_buffer.buffer[idx], + ((idx & 0xf) == 0xf) ? "\ntpm_tis: " : ""); + } + DPRINTF("\n" + "tpm_tis: write offset : %d\n" + "tpm_tis: request buffer: ", + tis->loc[locty].w_offset); + for (idx = 0; + idx < tpm_tis_get_size_from_buffer(&tis->loc[locty].w_buffer); + idx++) { + DPRINTF("%c%02x%s", + tis->loc[locty].w_offset == idx ? '>' : ' ', + tis->loc[locty].w_buffer.buffer[idx], + ((idx & 0xf) == 0xf) ? "\ntpm_tis: " : ""); + } + DPRINTF("\n"); +} +#endif + +/* + * Read a register of the TIS interface + * See specs pages 33-63 for description of the registers + */ +static uint64_t tpm_tis_mmio_read(void *opaque, hwaddr addr, + unsigned size) +{ + TPMState *s = opaque; + TPMTISEmuState *tis = &s->s.tis; + uint16_t offset = addr & 0xffc; + uint8_t shift = (addr & 0x3) * 8; + uint32_t val = 0xffffffff; + uint8_t locty = tpm_tis_locality_from_addr(addr); + uint32_t avail; + + if (tpm_backend_had_startup_error(s->be_driver)) { + return val; + } + + switch (offset) { + case TPM_TIS_REG_ACCESS: + /* never show the SEIZE flag even though we use it internally */ + val = tis->loc[locty].access & ~TPM_TIS_ACCESS_SEIZE; + /* the pending flag is always calculated */ + if (tpm_tis_check_request_use_except(s, locty)) { + val |= TPM_TIS_ACCESS_PENDING_REQUEST; + } + val |= !tpm_backend_get_tpm_established_flag(s->be_driver); + break; + case TPM_TIS_REG_INT_ENABLE: + val = tis->loc[locty].inte; + break; + case TPM_TIS_REG_INT_VECTOR: + val = tis->irq_num; + break; + case TPM_TIS_REG_INT_STATUS: + val = tis->loc[locty].ints; + break; + case TPM_TIS_REG_INTF_CAPABILITY: + val = TPM_TIS_CAPABILITIES_SUPPORTED; + break; + case TPM_TIS_REG_STS: + if (tis->active_locty == locty) { + if ((tis->loc[locty].sts & TPM_TIS_STS_DATA_AVAILABLE)) { + val = TPM_TIS_BURST_COUNT( + tpm_tis_get_size_from_buffer(&tis->loc[locty].r_buffer) + - tis->loc[locty].r_offset) | tis->loc[locty].sts; + } else { + avail = tis->loc[locty].w_buffer.size + - tis->loc[locty].w_offset; + /* + * byte-sized reads should not return 0x00 for 0x100 + * available bytes. + */ + if (size == 1 && avail > 0xff) { + avail = 0xff; + } + val = TPM_TIS_BURST_COUNT(avail) | tis->loc[locty].sts; + } + } + break; + case TPM_TIS_REG_DATA_FIFO: + if (tis->active_locty == locty) { + switch (tis->loc[locty].state) { + case TPM_TIS_STATE_COMPLETION: + val = tpm_tis_data_read(s, locty); + break; + default: + val = TPM_TIS_NO_DATA_BYTE; + break; + } + } + break; + case TPM_TIS_REG_DID_VID: + val = (TPM_TIS_TPM_DID << 16) | TPM_TIS_TPM_VID; + break; + case TPM_TIS_REG_RID: + val = TPM_TIS_TPM_RID; + break; +#ifdef DEBUG_TIS + case TPM_TIS_REG_DEBUG: + tpm_tis_dump_state(opaque, addr); + break; +#endif + } + + if (shift) { + val >>= shift; + } + + DPRINTF("tpm_tis: read.%u(%08x) = %08x\n", size, (int)addr, (uint32_t)val); + + return val; +} + +/* + * Write a value to a register of the TIS interface + * See specs pages 33-63 for description of the registers + */ +static void tpm_tis_mmio_write_intern(void *opaque, hwaddr addr, + uint64_t val, unsigned size, + bool hw_access) +{ + TPMState *s = opaque; + TPMTISEmuState *tis = &s->s.tis; + uint16_t off = addr & 0xfff; + uint8_t locty = tpm_tis_locality_from_addr(addr); + uint8_t active_locty, l; + int c, set_new_locty = 1; + uint16_t len; + + DPRINTF("tpm_tis: write.%u(%08x) = %08x\n", size, (int)addr, (uint32_t)val); + + if (locty == 4 && !hw_access) { + DPRINTF("tpm_tis: Access to locality 4 only allowed from hardware\n"); + return; + } + + if (tpm_backend_had_startup_error(s->be_driver)) { + return; + } + + switch (off) { + case TPM_TIS_REG_ACCESS: + + if ((val & TPM_TIS_ACCESS_SEIZE)) { + val &= ~(TPM_TIS_ACCESS_REQUEST_USE | + TPM_TIS_ACCESS_ACTIVE_LOCALITY); + } + + active_locty = tis->active_locty; + + if ((val & TPM_TIS_ACCESS_ACTIVE_LOCALITY)) { + /* give up locality if currently owned */ + if (tis->active_locty == locty) { + DPRINTF("tpm_tis: Releasing locality %d\n", locty); + + uint8_t newlocty = TPM_TIS_NO_LOCALITY; + /* anybody wants the locality ? */ + for (c = TPM_TIS_NUM_LOCALITIES - 1; c >= 0; c--) { + if ((tis->loc[c].access & TPM_TIS_ACCESS_REQUEST_USE)) { + DPRINTF("tpm_tis: Locality %d requests use.\n", c); + newlocty = c; + break; + } + } + DPRINTF("tpm_tis: TPM_TIS_ACCESS_ACTIVE_LOCALITY: " + "Next active locality: %d\n", + newlocty); + + if (TPM_TIS_IS_VALID_LOCTY(newlocty)) { + set_new_locty = 0; + tpm_tis_prep_abort(s, locty, newlocty); + } else { + active_locty = TPM_TIS_NO_LOCALITY; + } + } else { + /* not currently the owner; clear a pending request */ + tis->loc[locty].access &= ~TPM_TIS_ACCESS_REQUEST_USE; + } + } + + if ((val & TPM_TIS_ACCESS_BEEN_SEIZED)) { + tis->loc[locty].access &= ~TPM_TIS_ACCESS_BEEN_SEIZED; + } + + if ((val & TPM_TIS_ACCESS_SEIZE)) { + /* + * allow seize if a locality is active and the requesting + * locality is higher than the one that's active + * OR + * allow seize for requesting locality if no locality is + * active + */ + while ((TPM_TIS_IS_VALID_LOCTY(tis->active_locty) && + locty > tis->active_locty) || + !TPM_TIS_IS_VALID_LOCTY(tis->active_locty)) { + bool higher_seize = FALSE; + + /* already a pending SEIZE ? */ + if ((tis->loc[locty].access & TPM_TIS_ACCESS_SEIZE)) { + break; + } + + /* check for ongoing seize by a higher locality */ + for (l = locty + 1; l < TPM_TIS_NUM_LOCALITIES; l++) { + if ((tis->loc[l].access & TPM_TIS_ACCESS_SEIZE)) { + higher_seize = TRUE; + break; + } + } + + if (higher_seize) { + break; + } + + /* cancel any seize by a lower locality */ + for (l = 0; l < locty - 1; l++) { + tis->loc[l].access &= ~TPM_TIS_ACCESS_SEIZE; + } + + tis->loc[locty].access |= TPM_TIS_ACCESS_SEIZE; + DPRINTF("tpm_tis: TPM_TIS_ACCESS_SEIZE: " + "Locality %d seized from locality %d\n", + locty, tis->active_locty); + DPRINTF("tpm_tis: TPM_TIS_ACCESS_SEIZE: Initiating abort.\n"); + set_new_locty = 0; + tpm_tis_prep_abort(s, tis->active_locty, locty); + break; + } + } + + if ((val & TPM_TIS_ACCESS_REQUEST_USE)) { + if (tis->active_locty != locty) { + if (TPM_TIS_IS_VALID_LOCTY(tis->active_locty)) { + tis->loc[locty].access |= TPM_TIS_ACCESS_REQUEST_USE; + } else { + /* no locality active -> make this one active now */ + active_locty = locty; + } + } + } + + if (set_new_locty) { + tpm_tis_new_active_locality(s, active_locty); + } + + break; + case TPM_TIS_REG_INT_ENABLE: + if (tis->active_locty != locty) { + break; + } + + tis->loc[locty].inte = (val & (TPM_TIS_INT_ENABLED | + TPM_TIS_INT_POLARITY_MASK | + TPM_TIS_INTERRUPTS_SUPPORTED)); + break; + case TPM_TIS_REG_INT_VECTOR: + /* hard wired -- ignore */ + break; + case TPM_TIS_REG_INT_STATUS: + if (tis->active_locty != locty) { + break; + } + + /* clearing of interrupt flags */ + if (((val & TPM_TIS_INTERRUPTS_SUPPORTED)) && + (tis->loc[locty].ints & TPM_TIS_INTERRUPTS_SUPPORTED)) { + tis->loc[locty].ints &= ~val; + if (tis->loc[locty].ints == 0) { + qemu_irq_lower(tis->irq); + DPRINTF("tpm_tis: Lowering IRQ\n"); + } + } + tis->loc[locty].ints &= ~(val & TPM_TIS_INTERRUPTS_SUPPORTED); + break; + case TPM_TIS_REG_STS: + if (tis->active_locty != locty) { + break; + } + + val &= (TPM_TIS_STS_COMMAND_READY | TPM_TIS_STS_TPM_GO | + TPM_TIS_STS_RESPONSE_RETRY); + + if (val == TPM_TIS_STS_COMMAND_READY) { + switch (tis->loc[locty].state) { + + case TPM_TIS_STATE_READY: + tis->loc[locty].w_offset = 0; + tis->loc[locty].r_offset = 0; + break; + + case TPM_TIS_STATE_IDLE: + tis->loc[locty].sts = TPM_TIS_STS_COMMAND_READY; + tis->loc[locty].state = TPM_TIS_STATE_READY; + tpm_tis_raise_irq(s, locty, TPM_TIS_INT_COMMAND_READY); + break; + + case TPM_TIS_STATE_EXECUTION: + case TPM_TIS_STATE_RECEPTION: + /* abort currently running command */ + DPRINTF("tpm_tis: %s: Initiating abort.\n", + __func__); + tpm_tis_prep_abort(s, locty, locty); + break; + + case TPM_TIS_STATE_COMPLETION: + tis->loc[locty].w_offset = 0; + tis->loc[locty].r_offset = 0; + /* shortcut to ready state with C/R set */ + tis->loc[locty].state = TPM_TIS_STATE_READY; + if (!(tis->loc[locty].sts & TPM_TIS_STS_COMMAND_READY)) { + tis->loc[locty].sts = TPM_TIS_STS_COMMAND_READY; + tpm_tis_raise_irq(s, locty, TPM_TIS_INT_COMMAND_READY); + } + tis->loc[locty].sts &= ~(TPM_TIS_STS_DATA_AVAILABLE); + break; + + } + } else if (val == TPM_TIS_STS_TPM_GO) { + switch (tis->loc[locty].state) { + case TPM_TIS_STATE_RECEPTION: + if ((tis->loc[locty].sts & TPM_TIS_STS_EXPECT) == 0) { + tpm_tis_tpm_send(s, locty); + } + break; + default: + /* ignore */ + break; + } + } else if (val == TPM_TIS_STS_RESPONSE_RETRY) { + switch (tis->loc[locty].state) { + case TPM_TIS_STATE_COMPLETION: + tis->loc[locty].r_offset = 0; + tis->loc[locty].sts = TPM_TIS_STS_VALID | + TPM_TIS_STS_DATA_AVAILABLE; + break; + default: + /* ignore */ + break; + } + } + break; + case TPM_TIS_REG_DATA_FIFO: + /* data fifo */ + if (tis->active_locty != locty) { + break; + } + + if (tis->loc[locty].state == TPM_TIS_STATE_IDLE || + tis->loc[locty].state == TPM_TIS_STATE_EXECUTION || + tis->loc[locty].state == TPM_TIS_STATE_COMPLETION) { + /* drop the byte */ + } else { + DPRINTF("tpm_tis: Byte to send to TPM: %02x\n", (uint8_t)val); + if (tis->loc[locty].state == TPM_TIS_STATE_READY) { + tis->loc[locty].state = TPM_TIS_STATE_RECEPTION; + tis->loc[locty].sts = TPM_TIS_STS_EXPECT | TPM_TIS_STS_VALID; + } + + if ((tis->loc[locty].sts & TPM_TIS_STS_EXPECT)) { + if (tis->loc[locty].w_offset < tis->loc[locty].w_buffer.size) { + tis->loc[locty].w_buffer. + buffer[tis->loc[locty].w_offset++] = (uint8_t)val; + } else { + tis->loc[locty].sts = TPM_TIS_STS_VALID; + } + } + + /* check for complete packet */ + if (tis->loc[locty].w_offset > 5 && + (tis->loc[locty].sts & TPM_TIS_STS_EXPECT)) { + /* we have a packet length - see if we have all of it */ +#ifdef RAISE_STS_IRQ + bool needIrq = !(tis->loc[locty].sts & TPM_TIS_STS_VALID); +#endif + len = tpm_tis_get_size_from_buffer(&tis->loc[locty].w_buffer); + if (len > tis->loc[locty].w_offset) { + tis->loc[locty].sts = TPM_TIS_STS_EXPECT | + TPM_TIS_STS_VALID; + } else { + /* packet complete */ + tis->loc[locty].sts = TPM_TIS_STS_VALID; + } +#ifdef RAISE_STS_IRQ + if (needIrq) { + tpm_tis_raise_irq(s, locty, TPM_TIS_INT_STS_VALID); + } +#endif + } + } + break; + } +} + +static void tpm_tis_mmio_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size) +{ + return tpm_tis_mmio_write_intern(opaque, addr, val, size, false); +} + +static const MemoryRegionOps tpm_tis_memory_ops = { + .read = tpm_tis_mmio_read, + .write = tpm_tis_mmio_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 1, + .max_access_size = 4, + }, +}; + +static int tpm_tis_do_startup_tpm(TPMState *s) +{ + return tpm_backend_startup_tpm(s->be_driver); +} + +/* + * This function is called when the machine starts, resets or due to + * S3 resume. + */ +static void tpm_tis_reset(DeviceState *dev) +{ + TPMState *s = TPM(dev); + TPMTISEmuState *tis = &s->s.tis; + int c; + + tpm_backend_reset(s->be_driver); + + tis->active_locty = TPM_TIS_NO_LOCALITY; + tis->next_locty = TPM_TIS_NO_LOCALITY; + tis->aborting_locty = TPM_TIS_NO_LOCALITY; + + for (c = 0; c < TPM_TIS_NUM_LOCALITIES; c++) { + tis->loc[c].access = TPM_TIS_ACCESS_TPM_REG_VALID_STS; + tis->loc[c].sts = 0; + tis->loc[c].inte = TPM_TIS_INT_POLARITY_LOW_LEVEL; + tis->loc[c].ints = 0; + tis->loc[c].state = TPM_TIS_STATE_IDLE; + + tis->loc[c].w_offset = 0; + tpm_backend_realloc_buffer(s->be_driver, &tis->loc[c].w_buffer); + tis->loc[c].r_offset = 0; + tpm_backend_realloc_buffer(s->be_driver, &tis->loc[c].r_buffer); + } + + tpm_tis_do_startup_tpm(s); +} + +static const VMStateDescription vmstate_tpm_tis = { + .name = "tpm", + .unmigratable = 1, +}; + +static Property tpm_tis_properties[] = { + DEFINE_PROP_UINT32("irq", TPMState, + s.tis.irq_num, TPM_TIS_IRQ), + DEFINE_PROP_STRING("tpmdev", TPMState, backend), + DEFINE_PROP_END_OF_LIST(), +}; + +static void tpm_tis_realizefn(DeviceState *dev, Error **errp) +{ + TPMState *s = TPM(dev); + TPMTISEmuState *tis = &s->s.tis; + + s->be_driver = qemu_find_tpm(s->backend); + if (!s->be_driver) { + error_setg(errp, "tpm_tis: backend driver with id %s could not be " + "found", s->backend); + return; + } + + s->be_driver->fe_model = TPM_MODEL_TPM_TIS; + + if (tpm_backend_init(s->be_driver, s, tpm_tis_receive_cb)) { + error_setg(errp, "tpm_tis: backend driver with id %s could not be " + "initialized", s->backend); + return; + } + + if (tis->irq_num > 15) { + error_setg(errp, "tpm_tis: IRQ %d for TPM TIS is outside valid range " + "of 0 to 15.\n", tis->irq_num); + return; + } + + tis->bh = qemu_bh_new(tpm_tis_receive_bh, s); + + isa_init_irq(&s->busdev, &tis->irq, tis->irq_num); +} + +static void tpm_tis_initfn(Object *obj) +{ + ISADevice *dev = ISA_DEVICE(obj); + TPMState *s = TPM(obj); + + memory_region_init_io(&s->mmio, &tpm_tis_memory_ops, s, "tpm-tis-mmio", + TPM_TIS_NUM_LOCALITIES << TPM_TIS_LOCALITY_SHIFT); + memory_region_add_subregion(isa_address_space(dev), TPM_TIS_ADDR_BASE, + &s->mmio); +} + +static void tpm_tis_uninitfn(Object *obj) +{ + TPMState *s = TPM(obj); + + memory_region_del_subregion(get_system_memory(), &s->mmio); + memory_region_destroy(&s->mmio); +} + +static void tpm_tis_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = tpm_tis_realizefn; + dc->props = tpm_tis_properties; + dc->reset = tpm_tis_reset; + dc->vmsd = &vmstate_tpm_tis; +} + +static const TypeInfo tpm_tis_info = { + .name = TYPE_TPM_TIS, + .parent = TYPE_ISA_DEVICE, + .instance_size = sizeof(TPMState), + .instance_init = tpm_tis_initfn, + .instance_finalize = tpm_tis_uninitfn, + .class_init = tpm_tis_class_init, +}; + +static void tpm_tis_register(void) +{ + type_register_static(&tpm_tis_info); + tpm_register_model(TPM_MODEL_TPM_TIS); +} + +type_init(tpm_tis_register) diff --git a/hw/tpm/tpm_tis.h b/hw/tpm/tpm_tis.h new file mode 100644 index 0000000000..916152ae3e --- /dev/null +++ b/hw/tpm/tpm_tis.h @@ -0,0 +1,75 @@ +/* + * tpm_tis.h - QEMU's TPM TIS interface emulator + * + * Copyright (C) 2006, 2010-2013 IBM Corporation + * + * Authors: + * Stefan Berger <stefanb@us.ibm.com> + * David Safford <safford@us.ibm.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + * Implementation of the TIS interface according to specs found at + * http://www.trustedcomputinggroup.org + * + */ +#ifndef TPM_TPM_TIS_H +#define TPM_TPM_TIS_H + +#include "hw/isa/isa.h" +#include "qemu-common.h" + +#define TPM_TIS_ADDR_BASE 0xFED40000 + +#define TPM_TIS_NUM_LOCALITIES 5 /* per spec */ +#define TPM_TIS_LOCALITY_SHIFT 12 +#define TPM_TIS_NO_LOCALITY 0xff + +#define TPM_TIS_IS_VALID_LOCTY(x) ((x) < TPM_TIS_NUM_LOCALITIES) + +#define TPM_TIS_IRQ 5 + +#define TPM_TIS_BUFFER_MAX 4096 + +#define TYPE_TPM_TIS "tpm-tis" + + +typedef enum { + TPM_TIS_STATE_IDLE = 0, + TPM_TIS_STATE_READY, + TPM_TIS_STATE_COMPLETION, + TPM_TIS_STATE_EXECUTION, + TPM_TIS_STATE_RECEPTION, +} TPMTISState; + +/* locality data -- all fields are persisted */ +typedef struct TPMLocality { + TPMTISState state; + uint8_t access; + uint8_t sts; + uint32_t inte; + uint32_t ints; + + uint16_t w_offset; + uint16_t r_offset; + TPMSizedBuffer w_buffer; + TPMSizedBuffer r_buffer; +} TPMLocality; + +typedef struct TPMTISEmuState { + QEMUBH *bh; + uint32_t offset; + uint8_t buf[TPM_TIS_BUFFER_MAX]; + + uint8_t active_locty; + uint8_t aborting_locty; + uint8_t next_locty; + + TPMLocality loc[TPM_TIS_NUM_LOCALITIES]; + + qemu_irq irq; + uint32_t irq_num; +} TPMTISEmuState; + +#endif /* TPM_TPM_TIS_H */ diff --git a/hw/usb/ccid-card-emulated.c b/hw/usb/ccid-card-emulated.c index 29dcd7acbf..d534c94c1a 100644 --- a/hw/usb/ccid-card-emulated.c +++ b/hw/usb/ccid-card-emulated.c @@ -32,7 +32,7 @@ #include <vcard_emul.h> #include "qemu/thread.h" -#include "char/char.h" +#include "sysemu/char.h" #include "monitor/monitor.h" #include "ccid.h" diff --git a/hw/usb/ccid-card-passthru.c b/hw/usb/ccid-card-passthru.c index 5e017ae0ca..71a45f674f 100644 --- a/hw/usb/ccid-card-passthru.c +++ b/hw/usb/ccid-card-passthru.c @@ -8,7 +8,7 @@ * See the COPYING file in the top-level directory. */ -#include "char/char.h" +#include "sysemu/char.h" #include "qemu/sockets.h" #include "monitor/monitor.h" #include "ccid.h" diff --git a/hw/usb/dev-bluetooth.c b/hw/usb/dev-bluetooth.c index 0f8aa48c85..68cc1d4fab 100644 --- a/hw/usb/dev-bluetooth.c +++ b/hw/usb/dev-bluetooth.c @@ -21,7 +21,7 @@ #include "qemu-common.h" #include "hw/usb.h" #include "hw/usb/desc.h" -#include "bt/bt.h" +#include "sysemu/bt.h" #include "hw/bt.h" struct USBBtState { diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c index 7c314dc59d..dd0a608bff 100644 --- a/hw/usb/dev-serial.c +++ b/hw/usb/dev-serial.c @@ -12,7 +12,7 @@ #include "qemu/error-report.h" #include "hw/usb.h" #include "hw/usb/desc.h" -#include "char/char.h" +#include "sysemu/char.h" //#define DEBUG_Serial diff --git a/hw/usb/libhw.c b/hw/usb/libhw.c index 75f022f4ec..d2d4b51b94 100644 --- a/hw/usb/libhw.c +++ b/hw/usb/libhw.c @@ -20,7 +20,7 @@ * THE SOFTWARE. */ #include "qemu-common.h" -#include "exec/cpu-common.h" +#include "hw/hw.h" #include "hw/usb.h" #include "sysemu/dma.h" diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index 0ddb0818d8..a594e954e4 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -30,7 +30,7 @@ #include "monitor/monitor.h" #include "sysemu/sysemu.h" #include "qemu/iov.h" -#include "char/char.h" +#include "sysemu/char.h" #include <dirent.h> #include <sys/ioctl.h> diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c index 6079b2a3a9..fcc223af06 100644 --- a/hw/virtio/virtio-rng.c +++ b/hw/virtio/virtio-rng.c @@ -14,7 +14,7 @@ #include "qapi/qmp/qerror.h" #include "hw/virtio/virtio.h" #include "hw/virtio/virtio-rng.h" -#include "qemu/rng.h" +#include "sysemu/rng.h" static bool is_guest_ready(VirtIORNG *vrng) { diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c index 2a8c9f5d1a..d82ce5d8a6 100644 --- a/hw/xen/xen_backend.c +++ b/hw/xen/xen_backend.c @@ -35,7 +35,7 @@ #include <sys/signal.h> #include "hw/hw.h" -#include "char/char.h" +#include "sysemu/char.h" #include "qemu/log.h" #include "hw/xen/xen_backend.h" diff --git a/hw/xtensa/xtensa_lx60.c b/hw/xtensa/xtensa_lx60.c index 2682eda2ad..650dd31c98 100644 --- a/hw/xtensa/xtensa_lx60.c +++ b/hw/xtensa/xtensa_lx60.c @@ -36,7 +36,7 @@ #include "hw/sysbus.h" #include "hw/block/flash.h" #include "sysemu/blockdev.h" -#include "char/char.h" +#include "sysemu/char.h" #include "xtensa_bootparam.h" typedef struct LxBoardDesc { |