trng_cmd.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2021 Alibaba Group Holding Limited.
  4. */
  5. #include <common.h>
  6. #include <autoboot.h>
  7. #include <bootretry.h>
  8. #include <cli.h>
  9. #include <command.h>
  10. #include <console.h>
  11. #include <env.h>
  12. #include <fdtdec.h>
  13. #include <hash.h>
  14. #include <memalign.h>
  15. #include <menu.h>
  16. #include <post.h>
  17. #include <time.h>
  18. #include <u-boot/sha256.h>
  19. #include <bootcount.h>
  20. extern int csi_rng_get_multi_word(uint32_t *data, uint32_t num);
  21. #define CSI_OK 0
  22. void
  23. trng_hexdump(
  24. const char * szPrefix_p,
  25. const unsigned int PrintOffset,
  26. const uint8_t * Buffer_p,
  27. const unsigned int ByteCount)
  28. {
  29. unsigned int i;
  30. char Format[] = "%s %08d:";
  31. for(i = 0; i < ByteCount; i += 16)
  32. {
  33. unsigned int j, Limit;
  34. // if we do not have enough data for a full line
  35. if (i + 16 > ByteCount)
  36. Limit = ByteCount - i;
  37. else
  38. Limit = 16;
  39. // printf(Format, szPrefix_p, PrintOffset + i);
  40. for (j = 0; j < Limit; j++)
  41. //printf(" %02X", Buffer_p[i+j]);
  42. printf("%02X", Buffer_p[i+j]);
  43. //printf("\n");
  44. } // for
  45. }
  46. //128M
  47. #define RB_TRNG_SYS_TEST_LEN_IN_BYTE (1024 * 1024 * 128)
  48. //#define RB_TRNG_SYS_TEST_LEN_IN_BYTE (1024)
  49. #define RB_TRNG_SYS_TEST_BLOCK_IN_BYTE (1024)
  50. static uint32_t g_sys_buf[RB_TRNG_SYS_TEST_BLOCK_IN_BYTE] = {0x0};
  51. uint32_t g_rb_trng_reseed_cur = 0;
  52. /* config */
  53. uint32_t g_rb_trng_ctrl = 0;
  54. /* MAX reseed count in block */
  55. uint32_t g_rb_trng_reseed_max = 4195;
  56. /* 1:enable, 0:disable */
  57. uint32_t g_rb_trng_reseed_enable = 1;
  58. /* request times in block */
  59. uint32_t g_rb_trng_request_block = 0;
  60. /* 1:enable, 0:disable */
  61. uint32_t g_rb_trng_auto_detune = 1;
  62. /* EIP76_ALARM_THRESHOLD */
  63. uint32_t g_alarm_threshold = 255;
  64. /* EIP76_SHUTDOWN_THRESHOLD */
  65. uint32_t g_shutdown_threshold = 6;
  66. /* mode 4 in docdument */
  67. uint32_t g_long_request_mode = 0;
  68. static int rb_trng_sys_test(uint32_t times)
  69. {
  70. printf("===%s, %d\n", __FUNCTION__, __LINE__);
  71. printf("===%s, %d\n", __FUNCTION__, times);
  72. printf("===config %s, %x\n", __FUNCTION__, g_rb_trng_ctrl);
  73. printf("===max %s, %d\n", __FUNCTION__, g_rb_trng_reseed_max);
  74. printf("===resedd en %s, %d\n", __FUNCTION__, g_rb_trng_reseed_enable);
  75. printf("===r block %s, %d\n", __FUNCTION__, g_rb_trng_request_block);
  76. printf("===auto d %s, %d\n", __FUNCTION__, g_rb_trng_auto_detune);
  77. printf("===alarm threshold %s, %d\n", __FUNCTION__, g_alarm_threshold);
  78. printf("===shutdown threshold %s, %d\n", __FUNCTION__, g_shutdown_threshold);
  79. uint32_t ret = trng_init();
  80. if (ret != CSI_OK) {
  81. // LOG_INFO("fail to get trng multi data\n");
  82. // finish(FAIL);
  83. return ret;
  84. }
  85. g_rb_trng_reseed_cur = 0;
  86. /* delay */
  87. mdelay(200);
  88. //CHECK_RET_WITH_RET(ret == CSI_OK, ret);
  89. printf("===%s, 0x%x\n", "rb_trng_sys_test bytes:", 16 * g_rb_trng_request_block);
  90. if ((16 * g_rb_trng_request_block % 1024) != 0) {
  91. printf("===error length must ali to K Byte %s, %d\n", __FUNCTION__, __LINE__);
  92. return 0;
  93. }
  94. for (int i = 0; i < ((16 * g_rb_trng_request_block) /
  95. RB_TRNG_SYS_TEST_BLOCK_IN_BYTE);
  96. i++) {
  97. ret = csi_rng_get_multi_word(
  98. g_sys_buf, RB_TRNG_SYS_TEST_BLOCK_IN_BYTE / 4);
  99. if (ret != CSI_OK) {
  100. // LOG_INFO("fail to get trng multi data\n");
  101. // finish(FAIL);
  102. return ret;
  103. }
  104. memcpy(0x80000000 + i*1024 + (16 * g_rb_trng_request_block) * times, g_sys_buf, 1024);
  105. // trng_hexdump("", i * RB_TRNG_SYS_TEST_BLOCK_IN_BYTE, g_sys_buf, RB_TRNG_SYS_TEST_BLOCK_IN_BYTE);
  106. }
  107. // finish(PASS);
  108. return 0;
  109. }
  110. // static int rb_trng_sys_test_long_request(uint32_t times)
  111. // {
  112. // printf("===%s, %d\n", __FUNCTION__, __LINE__);
  113. // printf("===%s, %d\n", __FUNCTION__, times);
  114. // printf("===config %s, %x\n", __FUNCTION__, g_rb_trng_ctrl);
  115. // printf("===max %s, %d\n", __FUNCTION__, g_rb_trng_reseed_max);
  116. // printf("===resedd en %s, %d\n", __FUNCTION__, g_rb_trng_reseed_enable);
  117. // printf("===r block %s, %d\n", __FUNCTION__, g_rb_trng_request_block);
  118. // printf("===auto d %s, %d\n", __FUNCTION__, g_rb_trng_auto_detune);
  119. // printf("===alarm threshold %s, %d\n", __FUNCTION__, g_alarm_threshold);
  120. // printf("===shutdown threshold %s, %d\n", __FUNCTION__,
  121. // g_shutdown_threshold);
  122. // uint32_t ret = trng_init();
  123. // if (ret != CSI_OK) {
  124. // // LOG_INFO("fail to get trng multi data\n");
  125. // // finish(FAIL);
  126. // return ret;
  127. // }
  128. // g_rb_trng_reseed_cur = 0;
  129. // /* delay */
  130. // mdelay(200);
  131. // //CHECK_RET_WITH_RET(ret == CSI_OK, ret);
  132. // printf("===%s, 0x%x\n",
  133. // "rb_trng_sys_test bytes:", 16 * g_rb_trng_request_block);
  134. // if ((16 * g_rb_trng_request_block % 1024) != 0) {
  135. // printf("===error length must ali to K Byte %s, %d\n",
  136. // __FUNCTION__, __LINE__);
  137. // return 0;
  138. // }
  139. // for (int i = 0; i < ((16 * g_rb_trng_request_block) /
  140. // RB_TRNG_SYS_TEST_BLOCK_IN_BYTE);
  141. // i++) {
  142. // #if 0
  143. // ret = csi_rng_get_multi_word(
  144. // g_sys_buf, RB_TRNG_SYS_TEST_BLOCK_IN_BYTE / 4);
  145. // if (ret != CSI_OK) {
  146. // // LOG_INFO("fail to get trng multi data\n");
  147. // // finish(FAIL);
  148. // return ret;
  149. // }
  150. // #else
  151. // /* 1 */
  152. // EIP76_Write32(NULL, EIP76_REG_CONTROL,
  153. // 0x10000 | (g_rb_trng_reseed_max << 20));
  154. // /* 2 */
  155. // while ((EIP76_Read32(NULL, EIP76_REG_STATUS) & 0x00000001) != 1)
  156. // ;
  157. // /* 3 read 1k byte data*/
  158. // int *p = g_sys_buf;
  159. // for (int i = 0; i < (1024 / 16); i++) {
  160. // *p = EIP76_Read32(NULL, EIP76_REG_OUTPUT_0);
  161. // p++;
  162. // *p = EIP76_Read32(NULL, EIP76_REG_OUTPUT_1);
  163. // p++;
  164. // *p = EIP76_Read32(NULL, EIP76_REG_OUTPUT_2);
  165. // p++;
  166. // *p = EIP76_Read32(NULL, EIP76_REG_OUTPUT_3);
  167. // p++;
  168. // }
  169. // /* 4 */
  170. // /* 5 */
  171. // /* 6 */
  172. // /* 7 */
  173. // /* 8 */
  174. // /* 9 */
  175. // /* 10 */
  176. // /* 11 */
  177. // /* 12*/
  178. // /* 13 */
  179. // #endif
  180. // memcpy(0x80000000 + i * 1024 +
  181. // (16 * g_rb_trng_request_block) * times,
  182. // g_sys_buf, 1024);
  183. // // trng_hexdump("", i * RB_TRNG_SYS_TEST_BLOCK_IN_BYTE, g_sys_buf, RB_TRNG_SYS_TEST_BLOCK_IN_BYTE);
  184. // }
  185. // // finish(PASS);
  186. // return 0;
  187. // }
  188. extern int rb_trng_sys_test_entropy();
  189. static int do_rb_trng_sampling(cmd_tbl_t *cmdtp, int flag, int argc,
  190. char * const argv[])
  191. {
  192. ulong ctrl, times;
  193. ulong reseed_max, reseed_enable, request_block, auto_detune, alarm_threshold, shutdown_threshold;
  194. ulong entropy_mode = 0;
  195. ulong long_request_mode = 0;
  196. int ret;
  197. ctrl = 0x0011034C;
  198. times = 1;
  199. if (argc > 1)
  200. if (strict_strtoul(argv[1], 16, &ctrl) < 0)
  201. return CMD_RET_USAGE;
  202. if (argc > 2)
  203. if (strict_strtoul(argv[2], 16, &times) < 0)
  204. return CMD_RET_USAGE;
  205. if (argc > 3) {
  206. if (strict_strtoul(argv[3], 16, &reseed_max) < 0)
  207. return CMD_RET_USAGE;
  208. g_rb_trng_reseed_max = (uint32_t)reseed_max;
  209. }
  210. if (argc > 4) {
  211. if (strict_strtoul(argv[4], 16, &reseed_enable) < 0)
  212. return CMD_RET_USAGE;
  213. g_rb_trng_reseed_enable = (uint32_t)reseed_enable;
  214. }
  215. if (argc > 5) {
  216. if (strict_strtoul(argv[5], 16, &request_block) < 0)
  217. return CMD_RET_USAGE;
  218. g_rb_trng_request_block = (uint32_t)request_block;
  219. }
  220. if (argc > 6) {
  221. if (strict_strtoul(argv[6], 16, &auto_detune) < 0)
  222. return CMD_RET_USAGE;
  223. g_rb_trng_auto_detune = (uint32_t)auto_detune;
  224. }
  225. if (argc > 7) {
  226. if (strict_strtoul(argv[7], 16, &alarm_threshold) < 0)
  227. return CMD_RET_USAGE;
  228. g_alarm_threshold = (uint32_t)alarm_threshold;
  229. }
  230. if (argc > 8) {
  231. if (strict_strtoul(argv[8], 16, &shutdown_threshold) < 0)
  232. return CMD_RET_USAGE;
  233. g_shutdown_threshold = (uint32_t)shutdown_threshold;
  234. }
  235. if (argc > 9) {
  236. if (strict_strtoul(argv[9], 16, &entropy_mode) < 0)
  237. return CMD_RET_USAGE;
  238. }
  239. if (argc > 10) {
  240. if (strict_strtoul(argv[10], 16, &long_request_mode) < 0)
  241. return CMD_RET_USAGE;
  242. }
  243. printf(
  244. "Sampling TRNG raw data with ctrl:%08lx, sampling times:%08lx:\n",
  245. ctrl, times);
  246. g_rb_trng_ctrl = (uint32_t)ctrl;
  247. for (int i = 0; i < times; i++) {
  248. /* TODO laoduan add switch to rb_trng_sys_test or rb_trng_sys_test_entropy */
  249. if (!entropy_mode) {
  250. if (long_request_mode) {
  251. g_long_request_mode = 1;
  252. }
  253. rb_trng_sys_test(i);
  254. }
  255. else
  256. rb_trng_sys_test_entropy();
  257. }
  258. return 0;
  259. }
  260. U_BOOT_CMD(rb_trng_sampling, 11, 1, do_rb_trng_sampling,
  261. "Light MPW TRNG sampling",
  262. "[ctrl times reseed_max reseed_enable request_block auto_detune "
  263. "alarm_threshold shutdown_threshold mode long_request_mode]");