]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
e76cb927 SG |
2 | /* |
3 | * Copyright (c) 2015 Google, Inc | |
e76cb927 SG |
4 | */ |
5 | ||
6 | #include <common.h> | |
7 | #include <command.h> | |
8 | #include <environment.h> | |
d677bfe2 | 9 | #include <tpm-v1.h> |
e76cb927 SG |
10 | |
11 | /* Prints error and returns on failure */ | |
12 | #define TPM_CHECK(tpm_command) do { \ | |
13 | uint32_t result; \ | |
14 | \ | |
15 | result = (tpm_command); \ | |
16 | if (result != TPM_SUCCESS) { \ | |
17 | printf("TEST FAILED: line %d: " #tpm_command ": 0x%x\n", \ | |
18 | __LINE__, result); \ | |
19 | return result; \ | |
20 | } \ | |
21 | } while (0) | |
22 | ||
23 | #define INDEX0 0xda70 | |
24 | #define INDEX1 0xda71 | |
25 | #define INDEX2 0xda72 | |
26 | #define INDEX3 0xda73 | |
27 | #define INDEX_INITIALISED 0xda80 | |
28 | #define PHYS_PRESENCE 4 | |
29 | #define PRESENCE 8 | |
30 | ||
31 | static uint32_t TlclStartupIfNeeded(void) | |
32 | { | |
33 | uint32_t result = tpm_startup(TPM_ST_CLEAR); | |
34 | ||
35 | return result == TPM_INVALID_POSTINIT ? TPM_SUCCESS : result; | |
36 | } | |
37 | ||
38 | static int test_timer(void) | |
39 | { | |
40 | printf("get_timer(0) = %lu\n", get_timer(0)); | |
41 | return 0; | |
42 | } | |
43 | ||
44 | static uint32_t tpm_get_flags(uint8_t *disable, uint8_t *deactivated, | |
45 | uint8_t *nvlocked) | |
46 | { | |
47 | struct tpm_permanent_flags pflags; | |
48 | uint32_t result; | |
49 | ||
50 | result = tpm_get_permanent_flags(&pflags); | |
51 | if (result) | |
52 | return result; | |
53 | if (disable) | |
54 | *disable = pflags.disable; | |
55 | if (deactivated) | |
56 | *deactivated = pflags.deactivated; | |
57 | if (nvlocked) | |
58 | *nvlocked = pflags.nv_locked; | |
59 | debug("TPM: Got flags disable=%d, deactivated=%d, nvlocked=%d\n", | |
60 | pflags.disable, pflags.deactivated, pflags.nv_locked); | |
61 | ||
62 | return 0; | |
63 | } | |
64 | ||
e76cb927 SG |
65 | static uint32_t tpm_nv_write_value_lock(uint32_t index) |
66 | { | |
67 | debug("TPM: Write lock 0x%x\n", index); | |
68 | ||
69 | return tpm_nv_write_value(index, NULL, 0); | |
70 | } | |
71 | ||
e76cb927 SG |
72 | static int tpm_is_owned(void) |
73 | { | |
74 | uint8_t response[TPM_PUBEK_SIZE]; | |
75 | uint32_t result; | |
76 | ||
77 | result = tpm_read_pubek(response, sizeof(response)); | |
78 | ||
79 | return result != TPM_SUCCESS; | |
80 | } | |
81 | ||
82 | static int test_early_extend(void) | |
83 | { | |
84 | uint8_t value_in[20]; | |
85 | uint8_t value_out[20]; | |
86 | ||
87 | printf("Testing earlyextend ..."); | |
88 | tpm_init(); | |
89 | TPM_CHECK(tpm_startup(TPM_ST_CLEAR)); | |
90 | TPM_CHECK(tpm_continue_self_test()); | |
91 | TPM_CHECK(tpm_extend(1, value_in, value_out)); | |
92 | printf("done\n"); | |
93 | return 0; | |
94 | } | |
95 | ||
96 | static int test_early_nvram(void) | |
97 | { | |
98 | uint32_t x; | |
99 | ||
100 | printf("Testing earlynvram ..."); | |
101 | tpm_init(); | |
102 | TPM_CHECK(tpm_startup(TPM_ST_CLEAR)); | |
103 | TPM_CHECK(tpm_continue_self_test()); | |
104 | TPM_CHECK(tpm_tsc_physical_presence(PRESENCE)); | |
105 | TPM_CHECK(tpm_nv_read_value(INDEX0, (uint8_t *)&x, sizeof(x))); | |
106 | printf("done\n"); | |
107 | return 0; | |
108 | } | |
109 | ||
110 | static int test_early_nvram2(void) | |
111 | { | |
112 | uint32_t x; | |
113 | ||
114 | printf("Testing earlynvram2 ..."); | |
115 | tpm_init(); | |
116 | TPM_CHECK(tpm_startup(TPM_ST_CLEAR)); | |
117 | TPM_CHECK(tpm_continue_self_test()); | |
118 | TPM_CHECK(tpm_tsc_physical_presence(PRESENCE)); | |
119 | TPM_CHECK(tpm_nv_write_value(INDEX0, (uint8_t *)&x, sizeof(x))); | |
120 | printf("done\n"); | |
121 | return 0; | |
122 | } | |
123 | ||
124 | static int test_enable(void) | |
125 | { | |
126 | uint8_t disable = 0, deactivated = 0; | |
127 | ||
128 | printf("Testing enable ...\n"); | |
129 | tpm_init(); | |
130 | TPM_CHECK(TlclStartupIfNeeded()); | |
131 | TPM_CHECK(tpm_self_test_full()); | |
132 | TPM_CHECK(tpm_tsc_physical_presence(PRESENCE)); | |
133 | TPM_CHECK(tpm_get_flags(&disable, &deactivated, NULL)); | |
134 | printf("\tdisable is %d, deactivated is %d\n", disable, deactivated); | |
135 | TPM_CHECK(tpm_physical_enable()); | |
136 | TPM_CHECK(tpm_physical_set_deactivated(0)); | |
137 | TPM_CHECK(tpm_get_flags(&disable, &deactivated, NULL)); | |
138 | printf("\tdisable is %d, deactivated is %d\n", disable, deactivated); | |
139 | if (disable == 1 || deactivated == 1) | |
140 | printf("\tfailed to enable or activate\n"); | |
141 | printf("\tdone\n"); | |
142 | return 0; | |
143 | } | |
144 | ||
145 | #define reboot() do { \ | |
146 | printf("\trebooting...\n"); \ | |
147 | reset_cpu(0); \ | |
148 | } while (0) | |
149 | ||
150 | static int test_fast_enable(void) | |
151 | { | |
152 | uint8_t disable = 0, deactivated = 0; | |
153 | int i; | |
154 | ||
155 | printf("Testing fastenable ...\n"); | |
156 | tpm_init(); | |
157 | TPM_CHECK(TlclStartupIfNeeded()); | |
158 | TPM_CHECK(tpm_self_test_full()); | |
159 | TPM_CHECK(tpm_tsc_physical_presence(PRESENCE)); | |
160 | TPM_CHECK(tpm_get_flags(&disable, &deactivated, NULL)); | |
161 | printf("\tdisable is %d, deactivated is %d\n", disable, deactivated); | |
162 | for (i = 0; i < 2; i++) { | |
163 | TPM_CHECK(tpm_force_clear()); | |
164 | TPM_CHECK(tpm_get_flags(&disable, &deactivated, NULL)); | |
165 | printf("\tdisable is %d, deactivated is %d\n", disable, | |
166 | deactivated); | |
167 | assert(disable == 1 && deactivated == 1); | |
168 | TPM_CHECK(tpm_physical_enable()); | |
169 | TPM_CHECK(tpm_physical_set_deactivated(0)); | |
170 | TPM_CHECK(tpm_get_flags(&disable, &deactivated, NULL)); | |
171 | printf("\tdisable is %d, deactivated is %d\n", disable, | |
172 | deactivated); | |
173 | assert(disable == 0 && deactivated == 0); | |
174 | } | |
175 | printf("\tdone\n"); | |
176 | return 0; | |
177 | } | |
178 | ||
179 | static int test_global_lock(void) | |
180 | { | |
181 | uint32_t zero = 0; | |
182 | uint32_t result; | |
183 | uint32_t x; | |
184 | ||
185 | printf("Testing globallock ...\n"); | |
186 | tpm_init(); | |
187 | TPM_CHECK(TlclStartupIfNeeded()); | |
188 | TPM_CHECK(tpm_self_test_full()); | |
189 | TPM_CHECK(tpm_tsc_physical_presence(PRESENCE)); | |
190 | TPM_CHECK(tpm_nv_read_value(INDEX0, (uint8_t *)&x, sizeof(x))); | |
191 | TPM_CHECK(tpm_nv_write_value(INDEX0, (uint8_t *)&zero, | |
192 | sizeof(uint32_t))); | |
193 | TPM_CHECK(tpm_nv_read_value(INDEX1, (uint8_t *)&x, sizeof(x))); | |
194 | TPM_CHECK(tpm_nv_write_value(INDEX1, (uint8_t *)&zero, | |
195 | sizeof(uint32_t))); | |
196 | TPM_CHECK(tpm_set_global_lock()); | |
197 | /* Verifies that write to index0 fails */ | |
198 | x = 1; | |
199 | result = tpm_nv_write_value(INDEX0, (uint8_t *)&x, sizeof(x)); | |
200 | assert(result == TPM_AREA_LOCKED); | |
201 | TPM_CHECK(tpm_nv_read_value(INDEX0, (uint8_t *)&x, sizeof(x))); | |
202 | assert(x == 0); | |
203 | /* Verifies that write to index1 is still possible */ | |
204 | x = 2; | |
205 | TPM_CHECK(tpm_nv_write_value(INDEX1, (uint8_t *)&x, sizeof(x))); | |
206 | TPM_CHECK(tpm_nv_read_value(INDEX1, (uint8_t *)&x, sizeof(x))); | |
207 | assert(x == 2); | |
208 | /* Turns off PP */ | |
209 | tpm_tsc_physical_presence(PHYS_PRESENCE); | |
210 | /* Verifies that write to index1 fails */ | |
211 | x = 3; | |
212 | result = tpm_nv_write_value(INDEX1, (uint8_t *)&x, sizeof(x)); | |
213 | assert(result == TPM_BAD_PRESENCE); | |
214 | TPM_CHECK(tpm_nv_read_value(INDEX1, (uint8_t *)&x, sizeof(x))); | |
215 | assert(x == 2); | |
216 | printf("\tdone\n"); | |
217 | return 0; | |
218 | } | |
219 | ||
220 | static int test_lock(void) | |
221 | { | |
222 | printf("Testing lock ...\n"); | |
223 | tpm_init(); | |
224 | tpm_startup(TPM_ST_CLEAR); | |
225 | tpm_self_test_full(); | |
226 | tpm_tsc_physical_presence(PRESENCE); | |
227 | tpm_nv_write_value_lock(INDEX0); | |
228 | printf("\tLocked 0x%x\n", INDEX0); | |
229 | printf("\tdone\n"); | |
230 | return 0; | |
231 | } | |
232 | ||
233 | static void initialise_spaces(void) | |
234 | { | |
235 | uint32_t zero = 0; | |
236 | uint32_t perm = TPM_NV_PER_WRITE_STCLEAR | TPM_NV_PER_PPWRITE; | |
237 | ||
238 | printf("\tInitialising spaces\n"); | |
239 | tpm_nv_set_locked(); /* useful only the first time */ | |
240 | tpm_nv_define_space(INDEX0, perm, 4); | |
241 | tpm_nv_write_value(INDEX0, (uint8_t *)&zero, 4); | |
242 | tpm_nv_define_space(INDEX1, perm, 4); | |
243 | tpm_nv_write_value(INDEX1, (uint8_t *)&zero, 4); | |
244 | tpm_nv_define_space(INDEX2, perm, 4); | |
245 | tpm_nv_write_value(INDEX2, (uint8_t *)&zero, 4); | |
246 | tpm_nv_define_space(INDEX3, perm, 4); | |
247 | tpm_nv_write_value(INDEX3, (uint8_t *)&zero, 4); | |
248 | perm = TPM_NV_PER_READ_STCLEAR | TPM_NV_PER_WRITE_STCLEAR | | |
249 | TPM_NV_PER_PPWRITE; | |
250 | tpm_nv_define_space(INDEX_INITIALISED, perm, 1); | |
251 | } | |
252 | ||
253 | static int test_readonly(void) | |
254 | { | |
255 | uint8_t c; | |
256 | uint32_t index_0, index_1, index_2, index_3; | |
257 | int read0, read1, read2, read3; | |
258 | ||
259 | printf("Testing readonly ...\n"); | |
260 | tpm_init(); | |
261 | tpm_startup(TPM_ST_CLEAR); | |
262 | tpm_self_test_full(); | |
263 | tpm_tsc_physical_presence(PRESENCE); | |
264 | /* | |
265 | * Checks if initialisation has completed by trying to read-lock a | |
266 | * space that's created at the end of initialisation | |
267 | */ | |
268 | if (tpm_nv_read_value(INDEX_INITIALISED, &c, 0) == TPM_BADINDEX) { | |
269 | /* The initialisation did not complete */ | |
270 | initialise_spaces(); | |
271 | } | |
272 | ||
273 | /* Checks if spaces are OK or messed up */ | |
274 | read0 = tpm_nv_read_value(INDEX0, (uint8_t *)&index_0, sizeof(index_0)); | |
275 | read1 = tpm_nv_read_value(INDEX1, (uint8_t *)&index_1, sizeof(index_1)); | |
276 | read2 = tpm_nv_read_value(INDEX2, (uint8_t *)&index_2, sizeof(index_2)); | |
277 | read3 = tpm_nv_read_value(INDEX3, (uint8_t *)&index_3, sizeof(index_3)); | |
278 | if (read0 || read1 || read2 || read3) { | |
279 | printf("Invalid contents\n"); | |
280 | return 0; | |
281 | } | |
282 | ||
283 | /* | |
284 | * Writes space, and locks it. Then attempts to write again. | |
285 | * I really wish I could use the imperative. | |
286 | */ | |
287 | index_0 += 1; | |
288 | if (tpm_nv_write_value(INDEX0, (uint8_t *)&index_0, sizeof(index_0) != | |
289 | TPM_SUCCESS)) { | |
9b643e31 | 290 | pr_err("\tcould not write index 0\n"); |
e76cb927 SG |
291 | } |
292 | tpm_nv_write_value_lock(INDEX0); | |
293 | if (tpm_nv_write_value(INDEX0, (uint8_t *)&index_0, sizeof(index_0)) == | |
294 | TPM_SUCCESS) | |
9b643e31 | 295 | pr_err("\tindex 0 is not locked\n"); |
e76cb927 SG |
296 | |
297 | printf("\tdone\n"); | |
298 | return 0; | |
299 | } | |
300 | ||
301 | static int test_redefine_unowned(void) | |
302 | { | |
303 | uint32_t perm; | |
304 | uint32_t result; | |
305 | uint32_t x; | |
306 | ||
307 | printf("Testing redefine_unowned ..."); | |
308 | tpm_init(); | |
309 | TPM_CHECK(TlclStartupIfNeeded()); | |
310 | TPM_CHECK(tpm_self_test_full()); | |
311 | TPM_CHECK(tpm_tsc_physical_presence(PRESENCE)); | |
312 | assert(!tpm_is_owned()); | |
313 | ||
314 | /* Ensures spaces exist. */ | |
315 | TPM_CHECK(tpm_nv_read_value(INDEX0, (uint8_t *)&x, sizeof(x))); | |
316 | TPM_CHECK(tpm_nv_read_value(INDEX1, (uint8_t *)&x, sizeof(x))); | |
317 | ||
318 | /* Redefines spaces a couple of times. */ | |
319 | perm = TPM_NV_PER_PPWRITE | TPM_NV_PER_GLOBALLOCK; | |
320 | TPM_CHECK(tpm_nv_define_space(INDEX0, perm, 2 * sizeof(uint32_t))); | |
321 | TPM_CHECK(tpm_nv_define_space(INDEX0, perm, sizeof(uint32_t))); | |
322 | perm = TPM_NV_PER_PPWRITE; | |
323 | TPM_CHECK(tpm_nv_define_space(INDEX1, perm, 2 * sizeof(uint32_t))); | |
324 | TPM_CHECK(tpm_nv_define_space(INDEX1, perm, sizeof(uint32_t))); | |
325 | ||
326 | /* Sets the global lock */ | |
327 | tpm_set_global_lock(); | |
328 | ||
329 | /* Verifies that index0 cannot be redefined */ | |
330 | result = tpm_nv_define_space(INDEX0, perm, sizeof(uint32_t)); | |
331 | assert(result == TPM_AREA_LOCKED); | |
332 | ||
333 | /* Checks that index1 can */ | |
334 | TPM_CHECK(tpm_nv_define_space(INDEX1, perm, 2 * sizeof(uint32_t))); | |
335 | TPM_CHECK(tpm_nv_define_space(INDEX1, perm, sizeof(uint32_t))); | |
336 | ||
337 | /* Turns off PP */ | |
338 | tpm_tsc_physical_presence(PHYS_PRESENCE); | |
339 | ||
340 | /* Verifies that neither index0 nor index1 can be redefined */ | |
341 | result = tpm_nv_define_space(INDEX0, perm, sizeof(uint32_t)); | |
342 | assert(result == TPM_BAD_PRESENCE); | |
343 | result = tpm_nv_define_space(INDEX1, perm, sizeof(uint32_t)); | |
344 | assert(result == TPM_BAD_PRESENCE); | |
345 | ||
346 | printf("done\n"); | |
347 | return 0; | |
348 | } | |
349 | ||
350 | #define PERMPPGL (TPM_NV_PER_PPWRITE | TPM_NV_PER_GLOBALLOCK) | |
351 | #define PERMPP TPM_NV_PER_PPWRITE | |
352 | ||
353 | static int test_space_perm(void) | |
354 | { | |
355 | uint32_t perm; | |
356 | ||
357 | printf("Testing spaceperm ..."); | |
358 | tpm_init(); | |
359 | TPM_CHECK(TlclStartupIfNeeded()); | |
360 | TPM_CHECK(tpm_continue_self_test()); | |
361 | TPM_CHECK(tpm_tsc_physical_presence(PRESENCE)); | |
362 | TPM_CHECK(tpm_get_permissions(INDEX0, &perm)); | |
363 | assert((perm & PERMPPGL) == PERMPPGL); | |
364 | TPM_CHECK(tpm_get_permissions(INDEX1, &perm)); | |
365 | assert((perm & PERMPP) == PERMPP); | |
366 | printf("done\n"); | |
367 | return 0; | |
368 | } | |
369 | ||
370 | static int test_startup(void) | |
371 | { | |
372 | uint32_t result; | |
373 | printf("Testing startup ...\n"); | |
374 | ||
375 | tpm_init(); | |
376 | result = tpm_startup(TPM_ST_CLEAR); | |
377 | if (result != 0 && result != TPM_INVALID_POSTINIT) | |
378 | printf("\ttpm startup failed with 0x%x\n", result); | |
379 | result = tpm_get_flags(NULL, NULL, NULL); | |
380 | if (result != 0) | |
381 | printf("\ttpm getflags failed with 0x%x\n", result); | |
382 | printf("\texecuting SelfTestFull\n"); | |
383 | tpm_self_test_full(); | |
384 | result = tpm_get_flags(NULL, NULL, NULL); | |
385 | if (result != 0) | |
386 | printf("\ttpm getflags failed with 0x%x\n", result); | |
387 | printf("\tdone\n"); | |
388 | return 0; | |
389 | } | |
390 | ||
391 | /* | |
392 | * Runs [op] and ensures it returns success and doesn't run longer than | |
393 | * [time_limit] in milliseconds. | |
394 | */ | |
395 | #define TTPM_CHECK(op, time_limit) do { \ | |
396 | ulong start, time; \ | |
397 | uint32_t __result; \ | |
398 | \ | |
399 | start = get_timer(0); \ | |
400 | __result = op; \ | |
401 | if (__result != TPM_SUCCESS) { \ | |
402 | printf("\t" #op ": error 0x%x\n", __result); \ | |
403 | return -1; \ | |
404 | } \ | |
405 | time = get_timer(start); \ | |
406 | printf("\t" #op ": %lu ms\n", time); \ | |
407 | if (time > (ulong)time_limit) { \ | |
408 | printf("\t" #op " exceeded " #time_limit " ms\n"); \ | |
409 | } \ | |
410 | } while (0) | |
411 | ||
412 | ||
413 | static int test_timing(void) | |
414 | { | |
415 | uint32_t x; | |
416 | uint8_t in[20], out[20]; | |
417 | ||
418 | printf("Testing timing ..."); | |
419 | tpm_init(); | |
420 | TTPM_CHECK(TlclStartupIfNeeded(), 50); | |
421 | TTPM_CHECK(tpm_continue_self_test(), 100); | |
422 | TTPM_CHECK(tpm_self_test_full(), 1000); | |
423 | TTPM_CHECK(tpm_tsc_physical_presence(PRESENCE), 100); | |
424 | TTPM_CHECK(tpm_nv_write_value(INDEX0, (uint8_t *)&x, sizeof(x)), 100); | |
425 | TTPM_CHECK(tpm_nv_read_value(INDEX0, (uint8_t *)&x, sizeof(x)), 100); | |
426 | TTPM_CHECK(tpm_extend(0, in, out), 200); | |
427 | TTPM_CHECK(tpm_set_global_lock(), 50); | |
428 | TTPM_CHECK(tpm_tsc_physical_presence(PHYS_PRESENCE), 100); | |
429 | printf("done\n"); | |
430 | return 0; | |
431 | } | |
432 | ||
433 | #define TPM_MAX_NV_WRITES_NOOWNER 64 | |
434 | ||
435 | static int test_write_limit(void) | |
436 | { | |
437 | printf("Testing writelimit ...\n"); | |
438 | int i; | |
439 | uint32_t result; | |
440 | ||
441 | tpm_init(); | |
442 | TPM_CHECK(TlclStartupIfNeeded()); | |
443 | TPM_CHECK(tpm_self_test_full()); | |
444 | TPM_CHECK(tpm_tsc_physical_presence(PRESENCE)); | |
445 | TPM_CHECK(tpm_force_clear()); | |
446 | TPM_CHECK(tpm_physical_enable()); | |
447 | TPM_CHECK(tpm_physical_set_deactivated(0)); | |
448 | ||
449 | for (i = 0; i < TPM_MAX_NV_WRITES_NOOWNER + 2; i++) { | |
450 | printf("\twriting %d\n", i); | |
451 | result = tpm_nv_write_value(INDEX0, (uint8_t *)&i, sizeof(i)); | |
452 | switch (result) { | |
453 | case TPM_SUCCESS: | |
454 | break; | |
455 | case TPM_MAXNVWRITES: | |
456 | assert(i >= TPM_MAX_NV_WRITES_NOOWNER); | |
457 | default: | |
9b643e31 | 458 | pr_err("\tunexpected error code %d (0x%x)\n", |
e76cb927 SG |
459 | result, result); |
460 | } | |
461 | } | |
462 | ||
463 | /* Reset write count */ | |
464 | TPM_CHECK(tpm_force_clear()); | |
465 | TPM_CHECK(tpm_physical_enable()); | |
466 | TPM_CHECK(tpm_physical_set_deactivated(0)); | |
467 | ||
468 | /* Try writing again. */ | |
469 | TPM_CHECK(tpm_nv_write_value(INDEX0, (uint8_t *)&i, sizeof(i))); | |
470 | printf("\tdone\n"); | |
471 | return 0; | |
472 | } | |
473 | ||
474 | #define VOIDTEST(XFUNC) \ | |
475 | int do_test_##XFUNC(cmd_tbl_t *cmd_tbl, int flag, int argc, \ | |
476 | char * const argv[]) \ | |
477 | { \ | |
478 | return test_##XFUNC(); \ | |
479 | } | |
480 | ||
481 | #define VOIDENT(XNAME) \ | |
482 | U_BOOT_CMD_MKENT(XNAME, 0, 1, do_test_##XNAME, "", ""), | |
483 | ||
484 | VOIDTEST(early_extend) | |
485 | VOIDTEST(early_nvram) | |
486 | VOIDTEST(early_nvram2) | |
487 | VOIDTEST(enable) | |
488 | VOIDTEST(fast_enable) | |
489 | VOIDTEST(global_lock) | |
490 | VOIDTEST(lock) | |
491 | VOIDTEST(readonly) | |
492 | VOIDTEST(redefine_unowned) | |
493 | VOIDTEST(space_perm) | |
494 | VOIDTEST(startup) | |
495 | VOIDTEST(timing) | |
496 | VOIDTEST(write_limit) | |
497 | VOIDTEST(timer) | |
498 | ||
499 | static cmd_tbl_t cmd_cros_tpm_sub[] = { | |
500 | VOIDENT(early_extend) | |
501 | VOIDENT(early_nvram) | |
502 | VOIDENT(early_nvram2) | |
503 | VOIDENT(enable) | |
504 | VOIDENT(fast_enable) | |
505 | VOIDENT(global_lock) | |
506 | VOIDENT(lock) | |
507 | VOIDENT(readonly) | |
508 | VOIDENT(redefine_unowned) | |
509 | VOIDENT(space_perm) | |
510 | VOIDENT(startup) | |
511 | VOIDENT(timing) | |
512 | VOIDENT(write_limit) | |
513 | VOIDENT(timer) | |
514 | }; | |
515 | ||
516 | static int do_tpmtest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
517 | { | |
518 | cmd_tbl_t *c; | |
0427b9c5 | 519 | int i; |
e76cb927 SG |
520 | |
521 | printf("argc = %d, argv = ", argc); | |
e76cb927 | 522 | |
0427b9c5 SB |
523 | for (i = 0; i < argc; i++) |
524 | printf(" %s", argv[i]); | |
525 | ||
526 | printf("\n------\n"); | |
527 | ||
e76cb927 SG |
528 | argc--; |
529 | argv++; | |
530 | c = find_cmd_tbl(argv[0], cmd_cros_tpm_sub, | |
531 | ARRAY_SIZE(cmd_cros_tpm_sub)); | |
532 | return c ? c->cmd(cmdtp, flag, argc, argv) : cmd_usage(cmdtp); | |
533 | } | |
534 | ||
535 | U_BOOT_CMD(tpmtest, 2, 1, do_tpmtest, "TPM tests", | |
536 | "\n\tearly_extend\n" | |
537 | "\tearly_nvram\n" | |
538 | "\tearly_nvram2\n" | |
539 | "\tenable\n" | |
540 | "\tfast_enable\n" | |
541 | "\tglobal_lock\n" | |
542 | "\tlock\n" | |
543 | "\treadonly\n" | |
544 | "\tredefine_unowned\n" | |
545 | "\tspace_perm\n" | |
546 | "\tstartup\n" | |
547 | "\ttiming\n" | |
548 | "\twrite_limit\n"); |