[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v1 0/2] Add Atmel I2C TPM AT97SC3204T emulated devic
From: |
Fabio Urquiza |
Subject: |
[Qemu-devel] [PATCH v1 0/2] Add Atmel I2C TPM AT97SC3204T emulated device |
Date: |
Tue, 29 Nov 2016 16:30:50 -0300 |
### Overview ###
The TPM passthrough feature allow a developer to test TPM functionalities,
like Measure Boot, without the need to tamper with critical parts of the
host machine, ie. bootloader. It has been implemented to the x86 architecture
and have the same interface that is provided to PC machines: TPM TIS.
With the growing of use of the ARM server machines, also comes the need to
reuse the same security features that are present in the in the PC server
environment. So comes the need to use TPM devices in the ARM architecture.
This patchset provides a new frontend to the QEMU TPM passthrough with an
interface suitable to communicate with an ARM based machine.
### Technical details ###
The TPM devices on the PC architecture are integrated in a way that the
interface to it is made using an abstraction layer provided by the BIOS/UFI
firmware. That interface is not available to ARM machines, therefore a new
QEMU front end with a more suitable interface needed to be developed. The
options based on the available TPM devices in the market were I2C and SPI.
To make the choice, we look into the supported TPM drivers available to
ARM architecture in the Linux Kernel. One of the simplest drivers was the
ATMEL I2C TPM AT97SC3204T, so that was our target for the emulation.
We created a file called tpm_i2c_atmel.c based on the already available
tpm_tis.c, registering as a I2C_SLAVE_CLASS and calling the tpm_backend
functions.
One of the problems we had to address is regarding the behavior of the
ATMEL I2C TPM AT97SC3204T Linux driver. After the driver sends a request
to the TPM, it keeps polling the device with I2C read request. The real
AT97SC3204T hardware ignore those requests while the response is not ready
simply by not ACKing the I2C read on its address. When the response is
ready it will ACK the request and proceed writing the response in the wire.
The QEMU I2C API does not provide a way to not ACK I2C requests when the
device is not ready to transmit. In fact, if the device has been configured
in the virtual machine, QEMU will automatically ACK every request without
asking for the device permission for it. Therefore we created a flag in
the I2CSlave struct that tells the I2C subsystem that the device is busy
and not ready to ACK a I2C transfer. We understand that it could not be
the best solution to the problem, but it appears to be the solution that
have the least impact in the code overall. Suggestions on a different
approach would be welcome.
### Testing ###
We tested the feature in the versatilepb machine running Linux with
TrouSerS and tpm_tools:
qemu-system-arm -M versatilepb -kernel output/images/zImage \
-dtb output/images/versatile-pb.dtb \
-drive file=output/images/rootfs.ext2,if=scsi,format=raw \
-append "root=/dev/sda console=ttyAMA0,115200" -net nic,model=rtl8139 \
-net user -nographic -device tpm-tis,tpmdev=tpm-tpm0,address=0x20 \
-tpmdev
passthrough,id=tpm-tpm0,path=/dev/tpm0,cancel-path=/sys/devices/pnp0/00:08/tpm/tpm0/cancel
The following device needed to be included on the Device Tree:
i2c0: address@hidden {
#address-cells = <1>;
#size-cells = <0>;
compatible = "arm,versatile-i2c";
reg = <0x10002000 0x1000>;
address@hidden {
compatible = "dallas,ds1338";
reg = <0x68>;
};
address@hidden {
compatible = "atmel,at97sc3204t";
reg = <0x20>;
};
The following config needed to be enabled in the Linux Kernel:
I2C_VERSATILE=y
TCG_TPM=y
TCG_TIS_I2C_ATMEL=y
### Changes from V0 to v1 ###
- Fixed coding style problems found by Patchew.
Fabio Urquiza (2):
i2c: Add flag to NACK I2C transfers when busy
tpm: Add TPM I2C Atmel frontend
default-configs/aarch64-softmmu.mak | 1 +
default-configs/arm-softmmu.mak | 1 +
hw/i2c/core.c | 3 +
hw/tpm/Makefile.objs | 1 +
hw/tpm/tpm_i2c_atmel.c | 362 ++++++++++++++++++++++++++++++++++++
include/hw/i2c/i2c.h | 1 +
6 files changed, 369 insertions(+)
create mode 100644 hw/tpm/tpm_i2c_atmel.c
--
2.8.3