boot.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. // SPDX-License-Identifier: GPL-2.0+
  2. #include <common.h>
  3. #include <command.h>
  4. #include <net.h>
  5. #include <asm/io.h>
  6. #include <dm.h>
  7. #include <fdt_support.h>
  8. #include <fdtdec.h>
  9. #include <opensbi.h>
  10. #include <asm/csr.h>
  11. #include <asm/arch-thead/boot_mode.h>
  12. #include "../../../lib/sec_library/include/csi_efuse_api.h"
  13. #if CONFIG_IS_ENABLED(LIGHT_SEC_UPGRADE)
  14. /* The micro is used to enable NON-COT boot with non-signed image */
  15. #define LIGHT_NON_COT_BOOT 1
  16. /* The micro is used to enable uboot version in efuse */
  17. #define LIGHT_UBOOT_VERSION_IN_ENV 1
  18. /* The micro is used to enble RPMB ACCESS KEY from KDF */
  19. //#define LIGHT_KDF_RPMB_KEY 1
  20. /* the sample rpmb key is only used for testing */
  21. #ifndef LIGHT_KDF_RPMB_KEY
  22. static const unsigned char emmc_rpmb_key_sample[32] = {0x33, 0x22, 0x11, 0x00, 0x77, 0x66, 0x55, 0x44, \
  23. 0xbb, 0xaa, 0x99, 0x88, 0xff, 0xee, 0xdd, 0xcc, \
  24. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
  25. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
  26. #endif
  27. static unsigned int upgrade_image_version = 0;
  28. int csi_rpmb_write_access_key(void)
  29. {
  30. unsigned long *temp_rpmb_key_addr = NULL;
  31. char runcmd[64] = {0};
  32. uint8_t blkdata[256] = {0};
  33. uint8_t kdf_rpmb_key[32];
  34. uint32_t kdf_rpmb_key_length = 0;
  35. int ret = 0;
  36. #ifdef LIGHT_KDF_RPMB_KEY
  37. /* Step1: retrive RPMB key from KDF function */
  38. ret = csi_kdf_gen_hmac_key(kdf_rpmb_key, &kdf_rpmb_key_length);
  39. if (ret != 0) {
  40. return -1;
  41. }
  42. /* Make sure rpmb key length must be 32*/
  43. if (kdf_rpmb_key_length != 32) {
  44. return -1;
  45. }
  46. temp_rpmb_key_addr = (unsigned long *)kdf_rpmb_key;
  47. /* Step2: check whether RPMB key is available */
  48. sprintf(runcmd, "mmc rpmb read 0x%lx 0 1 0x%lx", (unsigned long)blkdata, (unsigned long)temp_rpmb_key_addr);
  49. ret = run_command(runcmd, 0);
  50. if (ret == CMD_RET_SUCCESS) {
  51. return -1;
  52. }
  53. /* Step3: Write RPMB key at once */
  54. sprintf(runcmd, "mmc rpmb key 0x%lx", (unsigned long)temp_rpmb_key_addr);
  55. ret = run_command(runcmd, 0);
  56. if (ret != CMD_RET_SUCCESS) {
  57. return -1;
  58. }
  59. return 0;
  60. #else
  61. return 1;
  62. #endif
  63. }
  64. int csi_tf_get_image_version(unsigned int *ver)
  65. {
  66. char runcmd[64] = {0};
  67. unsigned char blkdata[256];
  68. /* tf version reside in RPMB block#0, offset#16*/
  69. sprintf(runcmd, "mmc rpmb read 0x%lx 0 1", (unsigned long)blkdata);
  70. run_command(runcmd, 0);
  71. *ver = (blkdata[16] << 8) + blkdata[17];
  72. return 0;
  73. }
  74. int csi_tf_set_image_version(unsigned int ver)
  75. {
  76. char runcmd[64] = {0};
  77. unsigned char blkdata[256];
  78. unsigned long *temp_rpmb_key_addr = NULL;
  79. /* tf version reside in RPMB block#0, offset#16*/
  80. sprintf(runcmd, "mmc rpmb read 0x%lx 0 1", (unsigned long)blkdata);
  81. run_command(runcmd, 0);
  82. blkdata[16] = (ver & 0xFF00) >> 8;
  83. blkdata[17] = ver & 0xFF;
  84. /* tf version reside in RPMB block#0, offset#16*/
  85. #ifndef LIGHT_KDF_RPMB_KEY
  86. temp_rpmb_key_addr = (unsigned long *)emmc_rpmb_key_sample;
  87. #else
  88. uint8_t kdf_rpmb_key[32];
  89. uint32_t kdf_rpmb_key_length = 0;
  90. int ret = 0;
  91. ret = csi_kdf_gen_hmac_key(kdf_rpmb_key, &kdf_rpmb_key_length);
  92. if (ret != 0) {
  93. return -1;
  94. }
  95. temp_rpmb_key_addr = (unsigned long *)kdf_rpmb_key;
  96. #endif
  97. sprintf(runcmd, "mmc rpmb write 0x%lx 0 1 0x%lx", (unsigned long)blkdata, (unsigned long)temp_rpmb_key_addr);
  98. run_command(runcmd, 0);
  99. return 0;
  100. }
  101. int csi_tf_set_upgrade_version(void)
  102. {
  103. return csi_tf_set_image_version(upgrade_image_version);
  104. }
  105. int csi_tee_get_image_version(unsigned int *ver)
  106. {
  107. char runcmd[64] = {0};
  108. unsigned char blkdata[256];
  109. /* tf version reside in RPMB block#0, offset#0*/
  110. sprintf(runcmd, "mmc rpmb read 0x%lx 0 1", (unsigned long)blkdata);
  111. run_command(runcmd, 0);
  112. *ver = (blkdata[0] << 8) + blkdata[1];
  113. return 0;
  114. }
  115. int csi_kernel_get_image_version(unsigned int *ver)
  116. {
  117. char runcmd[64] = {0};
  118. unsigned char blkdata[256];
  119. /* kernel version reside in RPMB block#0, offset#32*/
  120. sprintf(runcmd, "mmc rpmb read 0x%lx 0 1", (unsigned long)blkdata);
  121. run_command(runcmd, 0);
  122. *ver = (blkdata[32] << 8) + blkdata[33];
  123. return 0;
  124. }
  125. int csi_tee_set_image_version(unsigned int ver)
  126. {
  127. char runcmd[64] = {0};
  128. unsigned char blkdata[256];
  129. unsigned long *temp_rpmb_key_addr = NULL;
  130. /* tf version reside in RPMB block#0, offset#0*/
  131. sprintf(runcmd, "mmc rpmb read 0x%lx 0 1", (unsigned long)blkdata);
  132. run_command(runcmd, 0);
  133. blkdata[0] = (ver & 0xFF00) >> 8;
  134. blkdata[1] = ver & 0xFF;
  135. /* tf version reside in RPMB block#0, offset#16*/
  136. #ifndef LIGHT_KDF_RPMB_KEY
  137. temp_rpmb_key_addr = (unsigned long *)emmc_rpmb_key_sample;
  138. #else
  139. uint8_t kdf_rpmb_key[32];
  140. uint32_t kdf_rpmb_key_length = 0;
  141. int ret = 0;
  142. ret = csi_kdf_gen_hmac_key(kdf_rpmb_key, &kdf_rpmb_key_length);
  143. if (ret != 0) {
  144. return -1;
  145. }
  146. temp_rpmb_key_addr = (unsigned long *)kdf_rpmb_key;
  147. #endif
  148. sprintf(runcmd, "mmc rpmb write 0x%lx 0 1 0x%lx", (unsigned long)blkdata, (unsigned long)temp_rpmb_key_addr);
  149. run_command(runcmd, 0);
  150. return 0;
  151. }
  152. int csi_tee_set_upgrade_version(void)
  153. {
  154. return csi_tee_set_image_version(upgrade_image_version);
  155. }
  156. int csi_uboot_get_image_version(unsigned int *ver)
  157. {
  158. #ifdef LIGHT_UBOOT_VERSION_IN_ENV
  159. long long uboot_ver = 0;
  160. unsigned char ver_x = 1;
  161. int i;
  162. // TODO
  163. // To avoid waste efuse resource, we define uboot_version env parameter to standd for BL1_VERSION in efuse
  164. uboot_ver = env_get_hex("uboot_version", 0xffffffffffffffff);
  165. // Add getting uboot version here.
  166. for (i = 0; i < (UBOOT_MAX_VER-1); i++) {
  167. if ((uboot_ver >> i) & 0x1) {
  168. ver_x ++;
  169. } else {
  170. break;
  171. }
  172. }
  173. if ( i <= (UBOOT_MAX_VER-1) ) {
  174. *ver = ver_x << 8;
  175. } else {
  176. *ver = 1 << 8;
  177. }
  178. #else
  179. unsigned int ver_x = 0;
  180. int ret = 0;
  181. ret = csi_efuse_api_int();
  182. if (ret) {
  183. printf("efuse api init fail \n");
  184. return -1;
  185. }
  186. ret = csi_efuse_get_bl1_version(&ver_x);
  187. if (ret) {
  188. printf("csi_efuse_get_bl1_version fail\n");
  189. return -1;
  190. }
  191. csi_efuse_api_uninit();
  192. *ver = (ver_x + 1) << 8;
  193. #endif
  194. return 0;
  195. }
  196. int csi_uboot_set_image_version(unsigned int ver)
  197. {
  198. #ifdef LIGHT_UBOOT_VERSION_IN_ENV
  199. //TODO
  200. unsigned long long uboot_ver = 0;
  201. unsigned char ver_x = (ver & 0xff00) >> 8;
  202. char ver_str[32] = {0};
  203. uboot_ver = env_get_hex("uboot_version", 0xffffffffffffffff);
  204. // Add getting uboot version here.
  205. if (ver_x == 1) {
  206. printf("This is initial version !");
  207. return 0;
  208. }
  209. uboot_ver |= ((unsigned long long)1 << (ver_x - 2));
  210. // To avoid waste efuse resource, we define uboot_version env parameter to stand for BL1_VERSION in efuse
  211. env_set_hex("uboot_version", uboot_ver);
  212. #else
  213. unsigned int ver_x = 0;
  214. int ret = 0;
  215. ver_x = (ver & 0xff00) >> 8;
  216. if (ver_x == 1) {
  217. printf("This is initial version !");
  218. return 0;
  219. }
  220. ret = csi_efuse_api_int();
  221. if (ret) {
  222. printf("efuse api init fail \n");
  223. return -1;
  224. }
  225. ver_x = ver_x - 1;
  226. ret = csi_efuse_set_bl1_version(ver_x);
  227. if (ret) {
  228. printf("csi_efuse_set_bl1_version fail \n");
  229. return -1;
  230. }
  231. csi_efuse_api_uninit();
  232. #endif
  233. return 0;
  234. }
  235. int csi_uboot_set_upgrade_version(void)
  236. {
  237. return csi_uboot_set_image_version(upgrade_image_version);
  238. }
  239. int verify_image_version_rule(unsigned int new_ver, unsigned int cur_ver)
  240. {
  241. unsigned char new_ver_x = 0, new_ver_y = 0;
  242. unsigned char cur_ver_x = 0, cur_ver_y = 0;
  243. /* Get secure version X from image version X.Y */
  244. new_ver_x = (new_ver & 0xFF00) >> 8;
  245. new_ver_y = new_ver & 0xFF;
  246. cur_ver_x = (cur_ver & 0xFF00) >> 8;
  247. cur_ver_y = cur_ver & 0xFF;
  248. printf("\n\n");
  249. printf("cur image version: %d.%d\n", cur_ver_x, cur_ver_y);
  250. printf("new image version: %d.%d\n", new_ver_x, new_ver_y);
  251. /* According the version rule, the X value must increase by 1 */
  252. if ((new_ver_x - cur_ver_x) == 0) {
  253. /* This is unsecure function */
  254. if ((new_ver_y - cur_ver_y) == 0) {
  255. printf("New version is equal to Current version, upgrade process terminates \n\n\n");
  256. return -1;
  257. }
  258. printf("This is unsecure function upgrade, going on uprade anyway\n");
  259. } else if ((new_ver_x - cur_ver_x) != 1) {
  260. /* Check the seure version rule */
  261. printf("The upgrade version(X) breaks against the rule\n\n\n");
  262. return -1;
  263. }
  264. printf("check image verison rule pass\n\n\n");
  265. return 0;
  266. }
  267. int light_vimage(int argc, char *const argv[])
  268. {
  269. int ret = 0;
  270. unsigned long vimage_addr = 0;
  271. unsigned int new_img_version = 0;
  272. unsigned int cur_img_version = 0;
  273. char imgname[32] = {0};
  274. if (argc < 3)
  275. return CMD_RET_USAGE;
  276. /* Parse input parameters */
  277. vimage_addr = simple_strtoul(argv[1], NULL, 16);
  278. strcpy(imgname, argv[2]);
  279. /* Retrieve desired information from image header */
  280. new_img_version = get_image_version(vimage_addr);
  281. if (new_img_version == 0) {
  282. printf("get new img version fail\n");
  283. return CMD_RET_FAILURE;
  284. }
  285. if (strcmp(imgname, UBOOT_PART_NAME) == 0) {
  286. new_img_version = (((new_img_version & 0xff )+1) << 8) | ((new_img_version & 0xff00)>>8);
  287. }
  288. printf("Get new image version from image header: v%d.%d\n", (new_img_version & 0xff00)>>8, new_img_version & 0xff);
  289. /* Check image version for ROLLBACK resisance */
  290. if (strcmp(imgname, TF_PART_NAME) == 0) {
  291. ret = csi_tf_get_image_version(&cur_img_version);
  292. if (ret != 0) {
  293. printf("Get tf img version fail\n");
  294. return CMD_RET_FAILURE;
  295. }
  296. } else if (strcmp(imgname, TEE_PART_NAME) == 0){
  297. ret = csi_tee_get_image_version(&cur_img_version);
  298. if (ret != 0) {
  299. printf("Get tee img version fail\n");
  300. return CMD_RET_FAILURE;
  301. }
  302. } else if (strcmp(imgname, KERNEL_PART_NAME) == 0){
  303. ret = csi_kernel_get_image_version(&cur_img_version);
  304. if (ret != 0) {
  305. printf("Get kernel img version fail\n");
  306. return CMD_RET_FAILURE;
  307. }
  308. } else if (strcmp(imgname, UBOOT_PART_NAME) == 0) {
  309. ret = csi_uboot_get_image_version(&cur_img_version);
  310. if (ret != 0) {
  311. printf("Get uboot img version fail\n");
  312. return CMD_RET_FAILURE;
  313. }
  314. // Check uboot maximization version > 64
  315. if (((new_img_version & 0xFF00) >> 8) > UBOOT_MAX_VER) {
  316. printf("UBOOT Image version has reached to max-version\n");
  317. return CMD_RET_FAILURE;
  318. }
  319. } else {
  320. printf("unsupport image file\n");
  321. return CMD_RET_FAILURE;
  322. }
  323. /* Verify image version rule */
  324. ret = verify_image_version_rule(new_img_version, cur_img_version);
  325. if (ret != 0) {
  326. return CMD_RET_FAILURE;
  327. }
  328. /* Save new image version to allow caller upgrade image version */
  329. upgrade_image_version = new_img_version;
  330. /* Initialize secure basis of functions */
  331. ret = csi_sec_init();
  332. if (ret != 0) {
  333. return CMD_RET_FAILURE;
  334. }
  335. /* Do image verification for TF and TEE */
  336. if (strcmp(imgname, TF_PART_NAME) == 0) {
  337. ret = verify_customer_image(T_TF, vimage_addr);
  338. if (ret != 0) {
  339. return CMD_RET_FAILURE;
  340. }
  341. } else if (strcmp(imgname, TEE_PART_NAME) == 0) {
  342. ret = verify_customer_image(T_TEE, vimage_addr);
  343. if (ret != 0) {
  344. return CMD_RET_FAILURE;
  345. }
  346. } else if (strcmp(imgname, KERNEL_PART_NAME) == 0) {
  347. ret = verify_customer_image(T_KRLIMG, vimage_addr);
  348. if (ret != 0) {
  349. return CMD_RET_FAILURE;
  350. }
  351. } else if (strcmp(imgname, UBOOT_PART_NAME) == 0) {
  352. ret = verify_customer_image(T_UBOOT, vimage_addr);
  353. if (ret != 0) {
  354. return CMD_RET_FAILURE;
  355. }
  356. } else {
  357. printf("Error: unknow image name\n");
  358. return CMD_RET_FAILURE;
  359. }
  360. return 0;
  361. }
  362. int light_secboot(int argc, char * const argv[])
  363. {
  364. int ret = 0;
  365. unsigned long tf_addr = LIGHT_TF_FW_ADDR;
  366. unsigned long tee_addr = LIGHT_TEE_FW_ADDR;
  367. unsigned long kernel_addr = LIGHT_KERNEL_ADDR;
  368. unsigned int tf_image_size = 0;
  369. unsigned int tee_image_size = 0;
  370. unsigned int kernel_image_size = 0;
  371. printf("\n\n");
  372. printf("Now, we start to verify all trust firmware before boot kernel !\n");
  373. /* Enject RPMB KEY directly in startup */
  374. csi_rpmb_write_access_key();
  375. /* Initialize secure basis of functions */
  376. ret = csi_sec_init();
  377. if (ret != 0) {
  378. return CMD_RET_FAILURE;
  379. }
  380. /* Step1. Check and verify TF image */
  381. if (image_have_head(LIGHT_TF_FW_TMP_ADDR) == 1) {
  382. printf("Process TF image verification ...\n");
  383. ret = verify_customer_image(T_TF, LIGHT_TF_FW_TMP_ADDR);
  384. if (ret != 0) {
  385. return CMD_RET_FAILURE;
  386. }
  387. tf_image_size = get_image_size(LIGHT_TF_FW_TMP_ADDR);
  388. printf("TF image size: %d\n", tf_image_size);
  389. if (tf_image_size < 0) {
  390. printf("GET TF image size error\n");
  391. return CMD_RET_FAILURE;
  392. }
  393. memmove((void *)tf_addr, (const void *)(LIGHT_TF_FW_TMP_ADDR + HEADER_SIZE), tf_image_size);
  394. } else {
  395. #ifdef LIGHT_NON_COT_BOOT
  396. run_command("ext4load mmc 0:3 0x0 trust_firmware.bin", 0);
  397. #else
  398. return CMD_RET_FAILURE;
  399. #endif
  400. }
  401. /* Step2. Check and verify TEE image */
  402. if (image_have_head(tee_addr) == 1) {
  403. printf("Process TEE image verification ...\n");
  404. ret = verify_customer_image(T_TEE, tee_addr);
  405. if (ret != 0) {
  406. return CMD_RET_FAILURE;
  407. }
  408. tee_image_size = get_image_size(tee_addr);
  409. printf("TEE image size: %d\n", tee_image_size);
  410. if (tee_image_size < 0) {
  411. printf("GET TEE image size error\n");
  412. return CMD_RET_FAILURE;
  413. }
  414. memmove((void *)tee_addr, (const void *)(tee_addr + HEADER_SIZE), tee_image_size);
  415. } else {
  416. #ifndef LIGHT_NON_COT_BOOT
  417. return CMD_RET_FAILURE;
  418. #endif
  419. }
  420. // /* Step3. Check and verify light kernel image */
  421. // if (image_have_head(kernel_addr) == 1) {
  422. // printf("Process kernel image verification ...\n");
  423. // ret = verify_customer_image(T_KRLIMG, kernel_addr);
  424. // if (ret != 0) {
  425. // return CMD_RET_FAILURE;
  426. // }
  427. // kernel_image_size = get_image_size(kernel_addr);
  428. // printf("Kernel image size: %d\n", kernel_image_size);
  429. // if (kernel_image_size < 0) {
  430. // printf("GET kernel image size error\n");
  431. // return CMD_RET_FAILURE;
  432. // }
  433. // memmove((void *)kernel_addr, (const void *)(kernel_addr + HEADER_SIZE), kernel_image_size);
  434. // } else {
  435. // #ifndef LIGHT_NON_COT_BOOT
  436. // return CMD_RET_FAILURE;
  437. // #endif
  438. // }
  439. return 0;
  440. }
  441. void sec_firmware_version_dump(void)
  442. {
  443. unsigned int tf_ver = 0;
  444. unsigned int tee_ver = 0;
  445. unsigned int uboot_ver = 0;
  446. csi_uboot_get_image_version(&uboot_ver);
  447. csi_tf_get_image_version(&tf_ver);
  448. csi_tee_get_image_version(&tee_ver);
  449. printf("\n\n");
  450. printf("Secure Firmware image version info: \n");
  451. printf("uboot Firmware v%d.0\n", (uboot_ver & 0xff00) >> 8);
  452. printf("Trust Firmware v%d.%d\n", (tf_ver & 0xff00) >> 8, tf_ver & 0xff);
  453. printf("TEE OS v%d.%d\n", (tee_ver & 0xff00) >> 8, tee_ver & 0xff);
  454. printf("\n\n");
  455. }
  456. void sec_upgrade_thread(void)
  457. {
  458. const unsigned long temp_addr=0x200000;
  459. char runcmd[80];
  460. int ret = 0;
  461. unsigned int sec_upgrade_flag = 0;
  462. unsigned int upgrade_file_size = 0;
  463. sec_upgrade_flag = env_get_hex("sec_upgrade_mode", 0);
  464. if (sec_upgrade_flag == 0)
  465. return;
  466. printf("bootstrap: sec_upgrade_flag: %x\n", sec_upgrade_flag);
  467. if (sec_upgrade_flag == TF_SEC_UPGRADE_FLAG) {
  468. /* STEP 1: read upgrade image (trust_firmware.bin) from stash partition */
  469. printf("read upgrade image (trust_firmware.bin) from stash partition \n");
  470. sprintf(runcmd, "ext4load mmc 0:5 0x%p trust_firmware.bin", (void *)temp_addr);
  471. printf("runcmd:%s\n", runcmd);
  472. ret = run_command(runcmd, 0);
  473. if (ret != 0) {
  474. printf("TF upgrade process is terminated due to some reason\n");
  475. goto _upgrade_tf_exit;
  476. }
  477. /* Fetch the total file size after read out operation end */
  478. upgrade_file_size = env_get_hex("filesize", 0);
  479. printf("upgrade file size: %d\n", upgrade_file_size);
  480. /* STEP 2: verify its authentiticy here */
  481. sprintf(runcmd, "vimage 0x%p tf", (void *)temp_addr);
  482. printf("runcmd:%s\n", runcmd);
  483. ret = run_command(runcmd, 0);
  484. if (ret != 0) {
  485. printf("TF Image verification fail and upgrade process terminates\n");
  486. goto _upgrade_tf_exit;
  487. }
  488. /* STEP 3: update tf partition */
  489. printf("read upgrade image (trust_firmware.bin) into tf partition \n");
  490. sprintf(runcmd, "ext4write mmc 0:3 0x%p /trust_firmware.bin 0x%x", (void *)temp_addr, upgrade_file_size);
  491. printf("runcmd:%s\n", runcmd);
  492. ret = run_command(runcmd, 0);
  493. if (ret != 0) {
  494. printf("TF upgrade process is terminated due to some reason\n");
  495. goto _upgrade_tf_exit;
  496. }
  497. /* STEP 4: update tf version */
  498. ret = csi_tf_set_upgrade_version();
  499. if (ret != 0) {
  500. printf("Set trustfirmware upgrade version fail\n");
  501. goto _upgrade_tf_exit;
  502. }
  503. printf("\n\nTF image ugprade process is successful\n\n");
  504. _upgrade_tf_exit:
  505. /* set secure upgrade flag to 0 that indicate upgrade over */
  506. run_command("env set sec_upgrade_mode 0", 0);
  507. run_command("saveenv", 0);
  508. run_command("reset", 0);
  509. } else if (sec_upgrade_flag == TEE_SEC_UPGRADE_FLAG) {
  510. /* STEP 1: read upgrade image (tee.bin) from stash partition */
  511. printf("read upgrade image (tee.bin) from stash partition \n");
  512. sprintf(runcmd, "ext4load mmc 0:5 0x%p tee.bin", (void *)temp_addr);
  513. printf("runcmd:%s\n", runcmd);
  514. ret = run_command(runcmd, 0);
  515. if (ret != 0) {
  516. printf("TEE Upgrade process is terminated due to some reason\n");
  517. goto _upgrade_tee_exit;
  518. }
  519. /* Fetch the total file size after read out operation end */
  520. upgrade_file_size = env_get_hex("filesize", 0);
  521. printf("TEE upgrade file size: %d\n", upgrade_file_size);
  522. /* STEP 2: verify its authentiticy here */
  523. sprintf(runcmd, "vimage 0x%p tee", (void *)temp_addr);
  524. printf("runcmd:%s\n", runcmd);
  525. ret = run_command(runcmd, 0);
  526. if (ret != 0) {
  527. printf("TEE Image verification fail and upgrade process terminates\n");
  528. goto _upgrade_tee_exit;
  529. }
  530. /* STEP 3: update tee partition */
  531. printf("read upgrade image (tee.bin) into tf partition \n");
  532. sprintf(runcmd, "ext4write mmc 0:4 0x%p /tee.bin 0x%x", (void *)temp_addr, upgrade_file_size);
  533. printf("runcmd:%s\n", runcmd);
  534. ret = run_command(runcmd, 0);
  535. if (ret != 0) {
  536. printf("TEE upgrade process is terminated due to some reason\n");
  537. goto _upgrade_tee_exit;
  538. }
  539. /* STEP 4: update tee version */
  540. ret = csi_tee_set_upgrade_version();
  541. if (ret != 0) {
  542. printf("Set tee upgrade version fail\n");
  543. goto _upgrade_tee_exit;
  544. }
  545. printf("\n\nTEE image ugprade process is successful\n\n");
  546. _upgrade_tee_exit:
  547. /* set secure upgrade flag to 0 that indicate upgrade over */
  548. run_command("env set sec_upgrade_mode 0", 0);
  549. run_command("saveenv", 0);
  550. run_command("reset", 0);
  551. } else if (sec_upgrade_flag == UBOOT_SEC_UPGRADE_FLAG) {
  552. unsigned int block_cnt;
  553. struct blk_desc *dev_desc;
  554. const unsigned long uboot_temp_addr=0x80000000;
  555. #define BLOCK_SIZE 512
  556. #define PUBKEY_HEADER_SIZE 0x1000
  557. /* STEP 1: read upgrade image (u-boot-with-spl.bin) from stash partition */
  558. printf("read upgrade image (u-boot-with-spl.bin) from stash partition \n");
  559. sprintf(runcmd, "ext4load mmc 0:5 0x%p u-boot-with-spl.bin", (void *)temp_addr);
  560. printf("runcmd:%s\n", runcmd);
  561. ret = run_command(runcmd, 0);
  562. if (ret != 0) {
  563. printf("UBOOT Upgrade process is terminated due to some reason\n");
  564. goto _upgrade_uboot_exit;
  565. }
  566. /* Fetch the total file size after read out operation end */
  567. upgrade_file_size = env_get_hex("filesize", 0);
  568. printf("uboot upgrade file size: %d\n", upgrade_file_size);
  569. /* STEP 2: verify its authentiticy here */
  570. memmove((void *)uboot_temp_addr, (const void *)temp_addr, upgrade_file_size);
  571. sprintf(runcmd, "vimage 0x%p uboot", (void *)(uboot_temp_addr+PUBKEY_HEADER_SIZE));
  572. printf("runcmd:%s\n", runcmd);
  573. ret = run_command(runcmd, 0);
  574. if (ret != 0) {
  575. printf("UBOOT Image verification fail and upgrade process terminates\n");
  576. goto _upgrade_uboot_exit;
  577. }
  578. /* STEP 3: update uboot partition */
  579. printf("write upgrade image (u-boot-with-spl.bin) into boot partition \n");
  580. dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
  581. if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
  582. printf("Invalid mmc device\n");
  583. goto _upgrade_uboot_exit;
  584. }
  585. block_cnt = upgrade_file_size / BLOCK_SIZE;
  586. if (upgrade_file_size % BLOCK_SIZE) {
  587. block_cnt = block_cnt +1;
  588. }
  589. run_command("mmc partconf 0 1 0 1", 0);
  590. sprintf(runcmd, "mmc write 0x%p 0 %x", (void *)temp_addr, block_cnt);
  591. printf("runcmd:%s\n", runcmd);
  592. ret = run_command(runcmd, 0);
  593. run_command("mmc partconf 0 1 0 0", 0);
  594. if (ret != 0) {
  595. printf("UBOOT upgrade process is terminated due to some reason\n");
  596. goto _upgrade_uboot_exit;
  597. }
  598. /* STEP 4: update tee version */
  599. ret = csi_uboot_set_upgrade_version();
  600. if (ret != 0) {
  601. printf("Set uboot upgrade version fail\n");
  602. goto _upgrade_uboot_exit;
  603. }
  604. printf("\n\nUBOOT image ugprade process is successful\n\n");
  605. _upgrade_uboot_exit:
  606. /* set secure upgrade flag to 0 that indicate upgrade over */
  607. run_command("env set sec_upgrade_mode 0", 0);
  608. run_command("saveenv", 0);
  609. run_command("reset", 0);
  610. } else {
  611. printf("Unknown bootstrap, Force sysem reboot\n");
  612. run_command("reset", 0);
  613. }
  614. }
  615. #endif