001-mtk-0024-tools-mtk_image-add-support-for-MT7621-NAND-images.patch 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. From 18dd1ef9417d0880f2f492b55bd4d9ede499f137 Mon Sep 17 00:00:00 2001
  2. From: Weijie Gao <[email protected]>
  3. Date: Fri, 20 May 2022 11:24:10 +0800
  4. Subject: [PATCH 24/25] tools: mtk_image: add support for MT7621 NAND images
  5. The BootROM of MT7621 requires a image header for SPL to record its size
  6. and load address when booting from NAND.
  7. To create such an image, one can use the following command line:
  8. mkimage -T mtk_image -a 0x80200000 -e 0x80200000 -n "mt7621=1"
  9. -d u-boot-spl-ddr.bin u-boot-spl-ddr.img
  10. Reviewed-by: Daniel Schwierzeck <[email protected]>
  11. Signed-off-by: Weijie Gao <[email protected]>
  12. ---
  13. tools/mtk_image.c | 182 ++++++++++++++++++++++++++++++++++++++++++++++
  14. tools/mtk_image.h | 24 ++++++
  15. 2 files changed, 206 insertions(+)
  16. diff --git a/tools/mtk_image.c b/tools/mtk_image.c
  17. index 418c5fd54b..de5ce4d964 100644
  18. --- a/tools/mtk_image.c
  19. +++ b/tools/mtk_image.c
  20. @@ -6,7 +6,9 @@
  21. * Author: Weijie Gao <[email protected]>
  22. */
  23. +#include <time.h>
  24. #include <image.h>
  25. +#include <u-boot/crc.h>
  26. #include <u-boot/sha256.h>
  27. #include "imagetool.h"
  28. #include "mtk_image.h"
  29. @@ -251,17 +253,45 @@ static uint32_t img_size;
  30. static enum brlyt_img_type hdr_media;
  31. static uint32_t hdr_offset;
  32. static int use_lk_hdr;
  33. +static int use_mt7621_hdr;
  34. static bool is_arm64_image;
  35. /* LK image name */
  36. static char lk_name[32] = "U-Boot";
  37. +/* CRC32 normal table required by MT7621 image */
  38. +static uint32_t crc32tbl[256];
  39. +
  40. /* NAND header selected by user */
  41. static const union nand_boot_header *hdr_nand;
  42. /* GFH header + 2 * 4KB pages of NAND */
  43. static char hdr_tmp[sizeof(struct gfh_header) + 0x2000];
  44. +static uint32_t crc32_normal_cal(uint32_t crc, const void *data, size_t length,
  45. + const uint32_t *crc32c_table)
  46. +{
  47. + const uint8_t *p = data;
  48. +
  49. + while (length--)
  50. + crc = crc32c_table[(uint8_t)((crc >> 24) ^ *p++)] ^ (crc << 8);
  51. +
  52. + return crc;
  53. +}
  54. +
  55. +static void crc32_normal_init(uint32_t *crc32c_table, uint32_t poly)
  56. +{
  57. + uint32_t v, i, j;
  58. +
  59. + for (i = 0; i < 256; i++) {
  60. + v = i << 24;
  61. + for (j = 0; j < 8; j++)
  62. + v = (v << 1) ^ ((v & (1 << 31)) ? poly : 0);
  63. +
  64. + crc32c_table[i] = v;
  65. + }
  66. +}
  67. +
  68. static int mtk_image_check_image_types(uint8_t type)
  69. {
  70. if (type == IH_TYPE_MTKIMAGE)
  71. @@ -283,6 +313,7 @@ static int mtk_brom_parse_imagename(const char *imagename)
  72. static const char *hdr_offs = "";
  73. static const char *nandinfo = "";
  74. static const char *lk = "";
  75. + static const char *mt7621 = "";
  76. static const char *arm64_param = "";
  77. key = buf;
  78. @@ -332,6 +363,9 @@ static int mtk_brom_parse_imagename(const char *imagename)
  79. if (!strcmp(key, "lk"))
  80. lk = val;
  81. + if (!strcmp(key, "mt7621"))
  82. + mt7621 = val;
  83. +
  84. if (!strcmp(key, "lkname"))
  85. snprintf(lk_name, sizeof(lk_name), "%s", val);
  86. @@ -352,6 +386,13 @@ static int mtk_brom_parse_imagename(const char *imagename)
  87. return 0;
  88. }
  89. + /* if user specified MT7621 image header, skip following checks */
  90. + if (mt7621 && mt7621[0] == '1') {
  91. + use_mt7621_hdr = 1;
  92. + free(buf);
  93. + return 0;
  94. + }
  95. +
  96. /* parse media type */
  97. for (i = 0; i < ARRAY_SIZE(brom_images); i++) {
  98. if (!strcmp(brom_images[i].name, media)) {
  99. @@ -419,6 +460,13 @@ static int mtk_image_vrec_header(struct image_tool_params *params,
  100. return 0;
  101. }
  102. + if (use_mt7621_hdr) {
  103. + tparams->header_size = image_get_header_size();
  104. + tparams->hdr = &hdr_tmp;
  105. + memset(&hdr_tmp, 0, tparams->header_size);
  106. + return 0;
  107. + }
  108. +
  109. if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
  110. tparams->header_size = 2 * le16_to_cpu(hdr_nand->pagesize);
  111. else
  112. @@ -579,9 +627,90 @@ static int mtk_image_verify_nand_header(const uint8_t *ptr, int print)
  113. return 0;
  114. }
  115. +static uint32_t crc32be_cal(const void *data, size_t length)
  116. +{
  117. + uint32_t crc = 0;
  118. + uint8_t c;
  119. +
  120. + if (crc32tbl[1] != MT7621_IH_CRC_POLYNOMIAL)
  121. + crc32_normal_init(crc32tbl, MT7621_IH_CRC_POLYNOMIAL);
  122. +
  123. + crc = crc32_normal_cal(crc, data, length, crc32tbl);
  124. +
  125. + for (; length; length >>= 8) {
  126. + c = length & 0xff;
  127. + crc = crc32_normal_cal(crc, &c, 1, crc32tbl);
  128. + }
  129. +
  130. + return ~crc;
  131. +}
  132. +
  133. +static int mtk_image_verify_mt7621_header(const uint8_t *ptr, int print)
  134. +{
  135. + const image_header_t *hdr = (const image_header_t *)ptr;
  136. + struct mt7621_nand_header *nhdr;
  137. + uint32_t spl_size, crcval;
  138. + image_header_t header;
  139. + int ret;
  140. +
  141. + spl_size = image_get_size(hdr);
  142. +
  143. + if (spl_size > img_size) {
  144. + if (print)
  145. + printf("Incomplete SPL image\n");
  146. + return -1;
  147. + }
  148. +
  149. + ret = image_check_hcrc(hdr);
  150. + if (!ret) {
  151. + if (print)
  152. + printf("Bad header CRC\n");
  153. + return -1;
  154. + }
  155. +
  156. + ret = image_check_dcrc(hdr);
  157. + if (!ret) {
  158. + if (print)
  159. + printf("Bad data CRC\n");
  160. + return -1;
  161. + }
  162. +
  163. + /* Copy header so we can blank CRC field for re-calculation */
  164. + memmove(&header, hdr, image_get_header_size());
  165. + image_set_hcrc(&header, 0);
  166. +
  167. + nhdr = (struct mt7621_nand_header *)header.ih_name;
  168. + crcval = be32_to_cpu(nhdr->crc);
  169. + nhdr->crc = 0;
  170. +
  171. + if (crcval != crc32be_cal(&header, image_get_header_size())) {
  172. + if (print)
  173. + printf("Bad NAND header CRC\n");
  174. + return -1;
  175. + }
  176. +
  177. + if (print) {
  178. + printf("Load Address: %08x\n", image_get_load(hdr));
  179. +
  180. + printf("Image Name: %.*s\n", MT7621_IH_NMLEN,
  181. + image_get_name(hdr));
  182. +
  183. + if (IMAGE_ENABLE_TIMESTAMP) {
  184. + printf("Created: ");
  185. + genimg_print_time((time_t)image_get_time(hdr));
  186. + }
  187. +
  188. + printf("Data Size: ");
  189. + genimg_print_size(image_get_data_size(hdr));
  190. + }
  191. +
  192. + return 0;
  193. +}
  194. +
  195. static int mtk_image_verify_header(unsigned char *ptr, int image_size,
  196. struct image_tool_params *params)
  197. {
  198. + image_header_t *hdr = (image_header_t *)ptr;
  199. union lk_hdr *lk = (union lk_hdr *)ptr;
  200. /* nothing to verify for LK image header */
  201. @@ -590,6 +719,9 @@ static int mtk_image_verify_header(unsigned char *ptr, int image_size,
  202. img_size = image_size;
  203. + if (image_get_magic(hdr) == IH_MAGIC)
  204. + return mtk_image_verify_mt7621_header(ptr, 0);
  205. +
  206. if (!strcmp((char *)ptr, NAND_BOOT_NAME))
  207. return mtk_image_verify_nand_header(ptr, 0);
  208. else
  209. @@ -600,6 +732,7 @@ static int mtk_image_verify_header(unsigned char *ptr, int image_size,
  210. static void mtk_image_print_header(const void *ptr)
  211. {
  212. + image_header_t *hdr = (image_header_t *)ptr;
  213. union lk_hdr *lk = (union lk_hdr *)ptr;
  214. if (le32_to_cpu(lk->magic) == LK_PART_MAGIC) {
  215. @@ -610,6 +743,11 @@ static void mtk_image_print_header(const void *ptr)
  216. printf("Image Type: MediaTek BootROM Loadable Image\n");
  217. + if (image_get_magic(hdr) == IH_MAGIC) {
  218. + mtk_image_verify_mt7621_header(ptr, 1);
  219. + return;
  220. + }
  221. +
  222. if (!strcmp((char *)ptr, NAND_BOOT_NAME))
  223. mtk_image_verify_nand_header(ptr, 1);
  224. else
  225. @@ -773,6 +911,45 @@ static void mtk_image_set_nand_header(void *ptr, off_t filesize,
  226. filesize - 2 * le16_to_cpu(hdr_nand->pagesize) - SHA256_SUM_LEN);
  227. }
  228. +static void mtk_image_set_mt7621_header(void *ptr, off_t filesize,
  229. + uint32_t loadaddr)
  230. +{
  231. + image_header_t *hdr = (image_header_t *)ptr;
  232. + struct mt7621_stage1_header *shdr;
  233. + struct mt7621_nand_header *nhdr;
  234. + uint32_t datasize, crcval;
  235. +
  236. + datasize = filesize - image_get_header_size();
  237. + nhdr = (struct mt7621_nand_header *)hdr->ih_name;
  238. + shdr = (struct mt7621_stage1_header *)(ptr + image_get_header_size());
  239. +
  240. + shdr->ep = cpu_to_be32(loadaddr);
  241. + shdr->stage_size = cpu_to_be32(datasize);
  242. +
  243. + image_set_magic(hdr, IH_MAGIC);
  244. + image_set_time(hdr, time(NULL));
  245. + image_set_size(hdr, datasize);
  246. + image_set_load(hdr, loadaddr);
  247. + image_set_ep(hdr, loadaddr);
  248. + image_set_os(hdr, IH_OS_U_BOOT);
  249. + image_set_arch(hdr, IH_ARCH_MIPS);
  250. + image_set_type(hdr, IH_TYPE_STANDALONE);
  251. + image_set_comp(hdr, IH_COMP_NONE);
  252. +
  253. + crcval = crc32(0, (uint8_t *)shdr, datasize);
  254. + image_set_dcrc(hdr, crcval);
  255. +
  256. + strncpy(nhdr->ih_name, "MT7621 NAND", MT7621_IH_NMLEN);
  257. +
  258. + nhdr->ih_stage_offset = cpu_to_be32(image_get_header_size());
  259. +
  260. + crcval = crc32be_cal(hdr, image_get_header_size());
  261. + nhdr->crc = cpu_to_be32(crcval);
  262. +
  263. + crcval = crc32(0, (uint8_t *)hdr, image_get_header_size());
  264. + image_set_hcrc(hdr, crcval);
  265. +}
  266. +
  267. static void mtk_image_set_header(void *ptr, struct stat *sbuf, int ifd,
  268. struct image_tool_params *params)
  269. {
  270. @@ -791,6 +968,11 @@ static void mtk_image_set_header(void *ptr, struct stat *sbuf, int ifd,
  271. img_gen = true;
  272. img_size = sbuf->st_size;
  273. + if (use_mt7621_hdr) {
  274. + mtk_image_set_mt7621_header(ptr, sbuf->st_size, params->addr);
  275. + return;
  276. + }
  277. +
  278. if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
  279. mtk_image_set_nand_header(ptr, sbuf->st_size, params->addr);
  280. else
  281. diff --git a/tools/mtk_image.h b/tools/mtk_image.h
  282. index 7dda71ce88..d868545a33 100644
  283. --- a/tools/mtk_image.h
  284. +++ b/tools/mtk_image.h
  285. @@ -200,4 +200,28 @@ union lk_hdr {
  286. #define LK_PART_MAGIC 0x58881688
  287. +/* MT7621 NAND SPL image header */
  288. +
  289. +#define MT7621_IH_NMLEN 12
  290. +#define MT7621_IH_CRC_POLYNOMIAL 0x04c11db7
  291. +
  292. +struct mt7621_nand_header {
  293. + char ih_name[MT7621_IH_NMLEN];
  294. + uint32_t nand_ac_timing;
  295. + uint32_t ih_stage_offset;
  296. + uint32_t ih_bootloader_offset;
  297. + uint32_t nand_info_1_data;
  298. + uint32_t crc;
  299. +};
  300. +
  301. +struct mt7621_stage1_header {
  302. + uint32_t jump_insn[2];
  303. + uint32_t ep;
  304. + uint32_t stage_size;
  305. + uint32_t has_stage2;
  306. + uint32_t next_ep;
  307. + uint32_t next_size;
  308. + uint32_t next_offset;
  309. +};
  310. +
  311. #endif /* _MTK_IMAGE_H */
  312. --
  313. 2.36.1