tpm_test.c 15 KB

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