]>
Commit | Line | Data |
---|---|---|
3bb4db4c SG |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
3 | * Copyright 2022 Google LLC | |
4 | * Written by Simon Glass <[email protected]> | |
5 | */ | |
6 | ||
d678a59d | 7 | #include <common.h> |
3bb4db4c SG |
8 | #include <dm.h> |
9 | #include <tpm_api.h> | |
10 | #include <dm/test.h> | |
11 | #include <test/test.h> | |
12 | #include <test/ut.h> | |
13 | ||
4fef6571 SG |
14 | /* |
15 | * get_tpm_version() - Get a TPM of the given version | |
16 | * | |
17 | * @version: Version to get | |
18 | * @devp: Returns the TPM device | |
19 | * Returns: 0 if OK, -ENODEV if not found | |
20 | */ | |
21 | static int get_tpm_version(enum tpm_version version, struct udevice **devp) | |
22 | { | |
23 | struct udevice *dev; | |
24 | ||
25 | /* | |
26 | * For now we have to probe each TPM, since the version is set up in | |
27 | * of_to_plat(). We could require TPMs to declare their version when | |
28 | * probed, to avoid this | |
29 | */ | |
30 | uclass_foreach_dev_probe(UCLASS_TPM, dev) { | |
31 | if (tpm_get_version(dev) == version) { | |
32 | *devp = dev; | |
33 | return 0; | |
34 | } | |
35 | } | |
36 | ||
37 | return -ENODEV; | |
38 | } | |
39 | ||
40 | /* Basic test of initing a TPM */ | |
41 | static int test_tpm_init(struct unit_test_state *uts, enum tpm_version version) | |
42 | { | |
43 | struct udevice *dev; | |
44 | ||
45 | /* check probe success */ | |
46 | ut_assertok(get_tpm_version(version, &dev)); | |
47 | ||
48 | ut_assertok(tpm_init(dev)); | |
49 | ||
50 | return 0; | |
51 | } | |
52 | ||
3bb4db4c | 53 | static int dm_test_tpm(struct unit_test_state *uts) |
4fef6571 SG |
54 | { |
55 | ut_assertok(test_tpm_init(uts, TPM_V1)); | |
56 | ut_assertok(test_tpm_init(uts, TPM_V2)); | |
57 | ||
58 | return 0; | |
59 | } | |
60 | DM_TEST(dm_test_tpm, UT_TESTF_SCAN_FDT); | |
61 | ||
62 | /* Test report_state */ | |
63 | static int dm_test_tpm_report_state(struct unit_test_state *uts) | |
3bb4db4c SG |
64 | { |
65 | struct udevice *dev; | |
66 | char buf[50]; | |
67 | ||
68 | /* check probe success */ | |
4fef6571 | 69 | ut_assertok(get_tpm_version(TPM_V2, &dev)); |
3bb4db4c SG |
70 | |
71 | ut_assert(tpm_report_state(dev, buf, sizeof(buf))); | |
72 | ut_asserteq_str("init_done=0", buf); | |
73 | ||
1b11de76 | 74 | ut_assertok(tpm_auto_start(dev)); |
3bb4db4c SG |
75 | |
76 | ut_assert(tpm_report_state(dev, buf, sizeof(buf))); | |
77 | ut_asserteq_str("init_done=1", buf); | |
78 | ||
79 | return 0; | |
80 | } | |
4fef6571 | 81 | DM_TEST(dm_test_tpm_report_state, UT_TESTF_SCAN_FDT); |
a11be4c3 SG |
82 | |
83 | /** | |
84 | * test_tpm_autostart() - check the tpm_auto_start() call | |
85 | * | |
86 | * @uts: Unit test state | |
87 | * @version: TPM version to use | |
88 | * @reinit: true to call tpm_init() first | |
89 | * Returns 0 if OK, non-zero on failure | |
90 | */ | |
91 | static int test_tpm_autostart(struct unit_test_state *uts, | |
92 | enum tpm_version version, bool reinit) | |
93 | { | |
94 | struct udevice *dev; | |
95 | ||
96 | /* check probe success */ | |
97 | ut_assertok(get_tpm_version(version, &dev)); | |
98 | ||
99 | if (reinit) | |
100 | ut_assertok(tpm_init(dev)); | |
aee56c03 IA |
101 | |
102 | /* | |
103 | * tpm_auto_start will rerun tpm_init() if reinit, but handles the | |
104 | * -EBUSY return code internally. | |
105 | */ | |
a11be4c3 SG |
106 | ut_assertok(tpm_auto_start(dev)); |
107 | ||
108 | return 0; | |
109 | } | |
110 | ||
111 | static int dm_test_tpm_autostart(struct unit_test_state *uts) | |
112 | { | |
113 | ut_assertok(test_tpm_autostart(uts, TPM_V1, false)); | |
114 | ut_assertok(test_tpm_autostart(uts, TPM_V2, false)); | |
115 | ||
116 | return 0; | |
117 | } | |
118 | DM_TEST(dm_test_tpm_autostart, UT_TESTF_SCAN_FDT); | |
119 | ||
120 | static int dm_test_tpm_autostart_reinit(struct unit_test_state *uts) | |
121 | { | |
122 | ut_assertok(test_tpm_autostart(uts, TPM_V1, true)); | |
123 | ut_assertok(test_tpm_autostart(uts, TPM_V2, true)); | |
124 | ||
125 | return 0; | |
126 | } | |
127 | DM_TEST(dm_test_tpm_autostart_reinit, UT_TESTF_SCAN_FDT); |