return 0;
}
+int do_tpm_report_state(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct udevice *dev;
+ char buf[80];
+ int rc;
+
+ rc = get_tpm(&dev);
+ if (rc)
+ return rc;
+ rc = tpm_report_state(dev, buf, sizeof(buf));
+ if (rc < 0) {
+ printf("Couldn't get TPM state (%d)\n", rc);
+ return CMD_RET_FAILURE;
+ }
+ printf("%s\n", buf);
+
+ return 0;
+}
+
int do_tpm_init(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
struct udevice *dev;
char *const argv[]);
int do_tpm_init(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
int do_tpm_info(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
+int do_tpm_report_state(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[]);
int do_tpm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]);
#endif /* __TPM_USER_UTILS_H */
static struct cmd_tbl tpm2_commands[] = {
U_BOOT_CMD_MKENT(device, 0, 1, do_tpm_device, "", ""),
U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""),
+ U_BOOT_CMD_MKENT(state, 0, 1, do_tpm_report_state, "", ""),
U_BOOT_CMD_MKENT(init, 0, 1, do_tpm_init, "", ""),
U_BOOT_CMD_MKENT(startup, 0, 1, do_tpm2_startup, "", ""),
U_BOOT_CMD_MKENT(self_test, 0, 1, do_tpm2_self_test, "", ""),
" Show all devices or set the specified device\n"
"info\n"
" Show information about the TPM.\n"
+"state\n"
+" Show internal state from the TPM (if available)\n"
"init\n"
" Initialize the software stack. Always the first command to issue.\n"
"startup <mode>\n"
return ops->get_desc(dev, buf, size);
}
+int tpm_report_state(struct udevice *dev, char *buf, int size)
+{
+ struct tpm_ops *ops = tpm_get_ops(dev);
+
+ if (!ops->report_state)
+ return -ENOSYS;
+
+ return ops->report_state(dev, buf, size);
+}
+
/* Returns max number of milliseconds to wait */
static ulong tpm_tis_i2c_calc_ordinal_duration(struct tpm_chip_priv *priv,
u32 ordinal)
return snprintf(buf, size, "Sandbox TPM2.x");
}
+static int sandbox_tpm2_report_state(struct udevice *dev, char *buf, int size)
+{
+ struct sandbox_tpm2 *priv = dev_get_priv(dev);
+
+ if (size < 40)
+ return -ENOSPC;
+
+ return snprintf(buf, size, "init_done=%d", priv->init_done);
+}
+
static int sandbox_tpm2_open(struct udevice *dev)
{
struct sandbox_tpm2 *tpm = dev_get_priv(dev);
.open = sandbox_tpm2_open,
.close = sandbox_tpm2_close,
.get_desc = sandbox_tpm2_get_desc,
+ .report_state = sandbox_tpm2_report_state,
.xfer = sandbox_tpm2_xfer,
};
int (*get_desc)(struct udevice *dev, char *buf, int size);
/**
+ * report_state() - Collect information about the current TPM state
+ *
+ * @dev: Device to check
+ * @buf: Buffer to put the string
+ * @size: Maximum size of buffer
+ * Return: return code of the operation (0 = success)
+ */
+ int (*report_state)(struct udevice *dev, char *buf, int size);
+
+ /**
* send() - send data to the TPM
*
* @dev: Device to talk to
int tpm_get_desc(struct udevice *dev, char *buf, int size);
/**
+ * tpm_report_state() - Collect information about the current TPM state
+ *
+ * @dev: Device to check
+ * @buf: Buffer to put the string
+ * @size: Maximum size of buffer
+ * Return: return code of the operation (0 = success)
+ */
+int tpm_report_state(struct udevice *dev, char *buf, int size);
+
+/**
* tpm_xfer() - send data to the TPM and get response
*
* This first uses the device's send() method to send the bytes. Then it calls
obj-$(CONFIG_UT_DM) += tag.o
obj-$(CONFIG_TEE) += tee.o
obj-$(CONFIG_TIMER) += timer.o
+obj-$(CONFIG_TPM_V2) += tpm.o
obj-$(CONFIG_DM_USB) += usb.o
obj-$(CONFIG_DM_VIDEO) += video.o
ifeq ($(CONFIG_VIRTIO_SANDBOX),y)
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2022 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <tpm_api.h>
+#include <dm/test.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+/* Basic test of the TPM uclass */
+static int dm_test_tpm(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ char buf[50];
+
+ /* check probe success */
+ ut_assertok(uclass_first_device_err(UCLASS_TPM, &dev));
+ ut_assert(tpm_is_v2(dev));
+
+ ut_assert(tpm_report_state(dev, buf, sizeof(buf)));
+ ut_asserteq_str("init_done=0", buf);
+
+ ut_assertok(tpm_init(dev));
+
+ ut_assert(tpm_report_state(dev, buf, sizeof(buf)));
+ ut_asserteq_str("init_done=1", buf);
+
+ return 0;
+}
+DM_TEST(dm_test_tpm, UT_TESTF_SCAN_FDT);