diff options
author | Simon Glass | 2023-02-21 06:24:52 -0700 |
---|---|---|
committer | Ilias Apalodimas | 2023-02-28 09:44:33 +0200 |
commit | a11be4c303eabb142e074c7ca14b6ae0d293f0cb (patch) | |
tree | 99ebfce19f20a994bdc246bff46b39758675512e | |
parent | 4fef65715196364cb28ddbd7396b6015d78c778c (diff) |
tpm: Implement tpm_auto_start() for TPMv1.2
Add an implementation of this, moving the common call to tpm_init() up
into the common API implementation.
Add a test.
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
-rw-r--r-- | include/tpm-common.h | 2 | ||||
-rw-r--r-- | include/tpm-v1.h | 11 | ||||
-rw-r--r-- | lib/tpm-v1.c | 14 | ||||
-rw-r--r-- | lib/tpm-v2.c | 8 | ||||
-rw-r--r-- | lib/tpm_api.c | 19 | ||||
-rw-r--r-- | test/dm/tpm.c | 45 |
6 files changed, 87 insertions, 12 deletions
diff --git a/include/tpm-common.h b/include/tpm-common.h index b2c5404430f..1ba81386ce1 100644 --- a/include/tpm-common.h +++ b/include/tpm-common.h @@ -94,7 +94,7 @@ struct tpm_ops { * close(). * * @dev: Device to open - * @return 0 ok OK, -ve on error + * @return 0 ok OK, -EBUSY if already opened, other -ve on other error */ int (*open)(struct udevice *dev); diff --git a/include/tpm-v1.h b/include/tpm-v1.h index 33d53fb695e..60b71e2a4b6 100644 --- a/include/tpm-v1.h +++ b/include/tpm-v1.h @@ -591,4 +591,15 @@ u32 tpm_set_global_lock(struct udevice *dev); */ u32 tpm1_resume(struct udevice *dev); +/** + * tpm1_auto_start() - start up the TPM + * + * This does not do a self test. + * + * @dev TPM device + * Return: TPM2_RC_SUCCESS, on success, or when the TPM returns + * TPM_INVALID_POSTINIT; TPM_FAILEDSELFTEST, if the TPM is in failure state + */ +u32 tpm1_auto_start(struct udevice *dev); + #endif /* __TPM_V1_H */ diff --git a/lib/tpm-v1.c b/lib/tpm-v1.c index d0e3ab1b21d..60a18ca5040 100644 --- a/lib/tpm-v1.c +++ b/lib/tpm-v1.c @@ -69,6 +69,20 @@ u32 tpm1_continue_self_test(struct udevice *dev) return tpm_sendrecv_command(dev, command, NULL, NULL); } +u32 tpm1_auto_start(struct udevice *dev) +{ + u32 rc; + + rc = tpm1_startup(dev, TPM_ST_CLEAR); + /* continue on if the TPM is already inited */ + if (rc && rc != TPM_INVALID_POSTINIT) + return rc; + + rc = tpm1_self_test_full(dev); + + return rc; +} + u32 tpm1_clear_and_reenable(struct udevice *dev) { u32 ret; diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c index 895b093bcb1..9ab5b46df17 100644 --- a/lib/tpm-v2.c +++ b/lib/tpm-v2.c @@ -48,14 +48,6 @@ u32 tpm2_auto_start(struct udevice *dev) { u32 rc; - /* - * the tpm_init() will return -EBUSY if the init has already happened - * The selftest and startup code can run multiple times with no side - * effects - */ - rc = tpm_init(dev); - if (rc && rc != -EBUSY) - return rc; rc = tpm2_self_test(dev, TPMI_YES); if (rc == TPM2_RC_INITIALIZE) { diff --git a/lib/tpm_api.c b/lib/tpm_api.c index 5b2c11a277c..3ef5e811794 100644 --- a/lib/tpm_api.c +++ b/lib/tpm_api.c @@ -37,10 +37,23 @@ u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode) u32 tpm_auto_start(struct udevice *dev) { - if (tpm_is_v2(dev)) - return tpm2_auto_start(dev); + u32 rc; - return -ENOSYS; + /* + * the tpm_init() will return -EBUSY if the init has already happened + * The selftest and startup code can run multiple times with no side + * effects + */ + rc = tpm_init(dev); + if (rc && rc != -EBUSY) + return rc; + + if (tpm_is_v1(dev)) + return tpm1_auto_start(dev); + else if (tpm_is_v2(dev)) + return tpm2_auto_start(dev); + else + return -ENOSYS; } u32 tpm_resume(struct udevice *dev) diff --git a/test/dm/tpm.c b/test/dm/tpm.c index 7d880012090..3defb3c3da1 100644 --- a/test/dm/tpm.c +++ b/test/dm/tpm.c @@ -79,3 +79,48 @@ static int dm_test_tpm_report_state(struct unit_test_state *uts) return 0; } 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); |