tpm_test.c 15 KB

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