summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2023-02-28 09:50:16 -0500
committerTom Rini <[email protected]>2023-02-28 09:50:16 -0500
commitf10905b4b7b9b6888e2532cdfb3536d2244676cb (patch)
tree6609cc57d553683eaed0ccfb9dca295af66ef29c /test
parentc12fe739ea1ea9ba4ca289bd4e7b1293a9ccb256 (diff)
parenta11be4c303eabb142e074c7ca14b6ae0d293f0cb (diff)
Merge tag 'tpm-next-28022023' of https://source.denx.de/u-boot/custodians/u-boot-tpm into next
TPM auto startup and testing: Due to U-Boot's lazy binding we always relied on command line tools to initialize the TPM subsystem and devices. One exception is the EFI subsystem. When compiled with TCG2 measured boot support the TPM was automatically initialized. However that init was not complete. The TCG specs [0] (and specifically ยง12.3 Self-test modes) describe how self-tests on the device should be performed. This PR is adding an extra API function, that can be used to initialize the TPM2.0 properly. Simon added the equivalent for TPM1.2 and refactored the DM tests to include the new funtion. [0] https://trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-1-Architecture-01.07-2014-03-13.pdf
Diffstat (limited to 'test')
-rw-r--r--test/dm/tpm.c102
1 files changed, 97 insertions, 5 deletions
diff --git a/test/dm/tpm.c b/test/dm/tpm.c
index 0b46f799591..3defb3c3da1 100644
--- a/test/dm/tpm.c
+++ b/test/dm/tpm.c
@@ -11,24 +11,116 @@
#include <test/test.h>
#include <test/ut.h>
-/* Basic test of the TPM uclass */
+/*
+ * get_tpm_version() - Get a TPM of the given version
+ *
+ * @version: Version to get
+ * @devp: Returns the TPM device
+ * Returns: 0 if OK, -ENODEV if not found
+ */
+static int get_tpm_version(enum tpm_version version, struct udevice **devp)
+{
+ struct udevice *dev;
+
+ /*
+ * For now we have to probe each TPM, since the version is set up in
+ * of_to_plat(). We could require TPMs to declare their version when
+ * probed, to avoid this
+ */
+ uclass_foreach_dev_probe(UCLASS_TPM, dev) {
+ if (tpm_get_version(dev) == version) {
+ *devp = dev;
+ return 0;
+ }
+ }
+
+ return -ENODEV;
+}
+
+/* Basic test of initing a TPM */
+static int test_tpm_init(struct unit_test_state *uts, enum tpm_version version)
+{
+ struct udevice *dev;
+
+ /* check probe success */
+ ut_assertok(get_tpm_version(version, &dev));
+
+ ut_assertok(tpm_init(dev));
+
+ return 0;
+}
+
static int dm_test_tpm(struct unit_test_state *uts)
{
+ ut_assertok(test_tpm_init(uts, TPM_V1));
+ ut_assertok(test_tpm_init(uts, TPM_V2));
+
+ return 0;
+}
+DM_TEST(dm_test_tpm, UT_TESTF_SCAN_FDT);
+
+/* Test report_state */
+static int dm_test_tpm_report_state(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_assertok(get_tpm_version(TPM_V2, &dev));
ut_assert(tpm_report_state(dev, buf, sizeof(buf)));
ut_asserteq_str("init_done=0", buf);
- ut_assertok(tpm_init(dev));
+ ut_assertok(tpm_auto_start(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);
+DM_TEST(dm_test_tpm_report_state, UT_TESTF_SCAN_FDT);
+
+/**
+ * test_tpm_autostart() - check the tpm_auto_start() call
+ *
+ * @uts: Unit test state
+ * @version: TPM version to use
+ * @reinit: true to call tpm_init() first
+ * Returns 0 if OK, non-zero on failure
+ */
+static int test_tpm_autostart(struct unit_test_state *uts,
+ enum tpm_version version, bool reinit)
+{
+ struct udevice *dev;
+
+ /* check probe success */
+ ut_assertok(get_tpm_version(version, &dev));
+
+ if (reinit)
+ ut_assertok(tpm_init(dev));
+ /*
+ * tpm_auto_start will rerun tpm_init() if reinit, but handles the
+ * -EBUSY return code internally.
+ */
+ ut_assertok(tpm_auto_start(dev));
+
+ return 0;
+}
+
+static int dm_test_tpm_autostart(struct unit_test_state *uts)
+{
+ ut_assertok(test_tpm_autostart(uts, TPM_V1, false));
+ ut_assertok(test_tpm_autostart(uts, TPM_V2, false));
+
+ return 0;
+}
+DM_TEST(dm_test_tpm_autostart, UT_TESTF_SCAN_FDT);
+
+static int dm_test_tpm_autostart_reinit(struct unit_test_state *uts)
+{
+ ut_assertok(test_tpm_autostart(uts, TPM_V1, true));
+ ut_assertok(test_tpm_autostart(uts, TPM_V2, true));
+
+ return 0;
+}
+DM_TEST(dm_test_tpm_autostart_reinit, UT_TESTF_SCAN_FDT);