zynqmpbif.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008
  1. /*
  2. * Copyright (C) 2018 Alexander Graf <agraf@suse.de>
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include "imagetool.h"
  7. #include "mkimage.h"
  8. #include "zynqmpimage.h"
  9. #include <elf.h>
  10. #include <image.h>
  11. struct bif_entry {
  12. const char *filename;
  13. uint64_t flags;
  14. uint64_t dest_cpu;
  15. uint64_t exp_lvl;
  16. uint64_t dest_dev;
  17. uint64_t load;
  18. uint64_t entry;
  19. size_t offset;
  20. };
  21. enum bif_flag {
  22. BIF_FLAG_AESKEYFILE,
  23. BIF_FLAG_INIT,
  24. BIF_FLAG_UDF_BH,
  25. BIF_FLAG_HEADERSIGNATURE,
  26. BIF_FLAG_PPKFILE,
  27. BIF_FLAG_PSKFILE,
  28. BIF_FLAG_SPKFILE,
  29. BIF_FLAG_SSKFILE,
  30. BIF_FLAG_SPKSIGNATURE,
  31. BIF_FLAG_FSBL_CONFIG,
  32. BIF_FLAG_AUTH_PARAMS,
  33. BIF_FLAG_KEYSRC_ENCRYPTION,
  34. BIF_FLAG_PMUFW_IMAGE,
  35. BIF_FLAG_BOOTLOADER,
  36. BIF_FLAG_TZ,
  37. BIF_FLAG_BH_KEY_IV,
  38. BIF_FLAG_BH_KEYFILE,
  39. BIF_FLAG_PUF_FILE,
  40. BIF_FLAG_AARCH32,
  41. BIF_FLAG_PART_OWNER_UBOOT,
  42. /* Internal flags */
  43. BIF_FLAG_BIT_FILE,
  44. BIF_FLAG_ELF_FILE,
  45. BIF_FLAG_BIN_FILE,
  46. };
  47. struct bif_flags {
  48. const char name[32];
  49. uint64_t flag;
  50. char *(*parse)(char *line, struct bif_entry *bf);
  51. };
  52. struct bif_file_type {
  53. const char name[32];
  54. uint32_t header;
  55. int (*add)(struct bif_entry *bf);
  56. };
  57. struct bif_output {
  58. size_t data_len;
  59. char *data;
  60. struct image_header_table *imgheader;
  61. struct zynqmp_header *header;
  62. struct partition_header *last_part;
  63. };
  64. struct bif_output bif_output;
  65. static uint32_t zynqmp_csum(void *start, void *end)
  66. {
  67. uint32_t checksum = 0;
  68. uint32_t *ptr32 = start;
  69. while (ptr32 != end) {
  70. checksum += le32_to_cpu(*ptr32);
  71. ptr32++;
  72. }
  73. return ~checksum;
  74. }
  75. static int zynqmpbif_check_params(struct image_tool_params *params)
  76. {
  77. if (!params)
  78. return 0;
  79. if (params->addr != 0x0) {
  80. fprintf(stderr, "Error: Load Address can not be specified.\n");
  81. return -1;
  82. }
  83. if (params->eflag) {
  84. fprintf(stderr, "Error: Entry Point can not be specified.\n");
  85. return -1;
  86. }
  87. return !(params->lflag || params->dflag);
  88. }
  89. static int zynqmpbif_check_image_types(uint8_t type)
  90. {
  91. return (type == IH_TYPE_ZYNQMPBIF) ? EXIT_SUCCESS : EXIT_FAILURE;
  92. }
  93. static char *parse_dest_cpu(char *line, struct bif_entry *bf)
  94. {
  95. uint64_t i;
  96. for (i = 0; i < ARRAY_SIZE(dest_cpus); i++) {
  97. if (!strncmp(line, dest_cpus[i], strlen(dest_cpus[i]))) {
  98. bf->dest_cpu = i << PART_ATTR_DEST_CPU_SHIFT;
  99. return line + strlen(dest_cpus[i]);
  100. }
  101. /* a5x can also be written as a53 */
  102. if (!strncmp(dest_cpus[i], "a5x", 3)) {
  103. char a53[] = "a53-X";
  104. a53[4] = dest_cpus[i][4];
  105. if (!strncmp(line, a53, strlen(a53))) {
  106. bf->dest_cpu = i << PART_ATTR_DEST_CPU_SHIFT;
  107. return line + strlen(a53);
  108. }
  109. }
  110. }
  111. return line;
  112. }
  113. static char *parse_el(char *line, struct bif_entry *bf)
  114. {
  115. const char *dest_els[] = { "none", "el-0", "el-1", "el-2", "el-3" };
  116. int i;
  117. for (i = 0; i < ARRAY_SIZE(dest_els); i++) {
  118. if (!strncmp(line, dest_els[i], strlen(dest_els[i]))) {
  119. bf->exp_lvl = i;
  120. return line + strlen(dest_els[i]);
  121. }
  122. }
  123. return line;
  124. }
  125. static char *parse_load(char *line, struct bif_entry *bf)
  126. {
  127. char *endptr;
  128. bf->load = strtoll(line, &endptr, 0);
  129. return endptr;
  130. }
  131. static char *parse_entry(char *line, struct bif_entry *bf)
  132. {
  133. char *endptr;
  134. bf->entry = strtoll(line, &endptr, 0);
  135. return endptr;
  136. }
  137. static char *parse_offset(char *line, struct bif_entry *bf)
  138. {
  139. char *endptr;
  140. bf->offset = strtoll(line, &endptr, 0);
  141. return endptr;
  142. }
  143. static char *parse_partition_owner(char *line, struct bif_entry *bf)
  144. {
  145. char *endptr = NULL;
  146. if (!strncmp(line, "fsbl", 4)) {
  147. endptr = line + 4;
  148. } else if (!strncmp(line, "uboot", 5)) {
  149. bf->flags |= 1ULL << BIF_FLAG_PART_OWNER_UBOOT;
  150. endptr = line + 5;
  151. } else {
  152. printf("ERROR: Unknown partition type '%s'\n", line);
  153. }
  154. return endptr;
  155. }
  156. static const struct bif_flags bif_flags[] = {
  157. { "fsbl_config", BIF_FLAG_FSBL_CONFIG },
  158. { "trustzone", BIF_FLAG_TZ },
  159. { "pmufw_image", BIF_FLAG_PMUFW_IMAGE },
  160. { "bootloader", BIF_FLAG_BOOTLOADER },
  161. { "destination_cpu=", 0, parse_dest_cpu },
  162. { "exception_level=", 0, parse_el },
  163. { "load=", 0, parse_load },
  164. { "startup=", 0, parse_entry },
  165. { "offset=", 0, parse_offset },
  166. { "partition_owner=", 0, parse_partition_owner },
  167. };
  168. static char *read_full_file(const char *filename, size_t *size)
  169. {
  170. char *buf, *bufp;
  171. struct stat sbuf;
  172. int len = 0, r, fd;
  173. fd = open(filename, O_RDONLY);
  174. if (fd < 0)
  175. return NULL;
  176. if (fstat(fd, &sbuf) < 0)
  177. return NULL;
  178. if (size)
  179. *size = sbuf.st_size;
  180. buf = malloc(sbuf.st_size);
  181. if (!buf)
  182. return NULL;
  183. bufp = buf;
  184. while (len < sbuf.st_size) {
  185. r = read(fd, bufp, sbuf.st_size - len);
  186. if (r < 0)
  187. return NULL;
  188. len += r;
  189. bufp += r;
  190. }
  191. close(fd);
  192. return buf;
  193. }
  194. static int bif_add_blob(const void *data, size_t len, size_t *offset)
  195. {
  196. size_t new_size;
  197. uintptr_t header_off;
  198. uintptr_t last_part_off;
  199. uintptr_t imgheader_off;
  200. uintptr_t old_data = (uintptr_t)bif_output.data;
  201. void *new_data;
  202. header_off = (uintptr_t)bif_output.header - old_data;
  203. last_part_off = (uintptr_t)bif_output.last_part - old_data;
  204. imgheader_off = (uintptr_t)bif_output.imgheader - old_data;
  205. if (offset && *offset) {
  206. /* Pad to a given offset */
  207. if (bif_output.data_len > *offset) {
  208. printf("Can not pad to offset %zx\n", *offset);
  209. return -1;
  210. }
  211. bif_output.data_len = *offset;
  212. }
  213. new_size = ROUND(bif_output.data_len + len, 64);
  214. new_data = realloc(bif_output.data, new_size);
  215. memcpy(new_data + bif_output.data_len, data, len);
  216. if (offset)
  217. *offset = bif_output.data_len;
  218. bif_output.data = new_data;
  219. bif_output.data_len = new_size;
  220. /* Readjust internal pointers */
  221. if (bif_output.header)
  222. bif_output.header = new_data + header_off;
  223. if (bif_output.last_part)
  224. bif_output.last_part = new_data + last_part_off;
  225. if (bif_output.imgheader)
  226. bif_output.imgheader = new_data + imgheader_off;
  227. return 0;
  228. }
  229. static int bif_init(void)
  230. {
  231. struct zynqmp_header header = { { 0 } };
  232. int r;
  233. zynqmpimage_default_header(&header);
  234. r = bif_add_blob(&header, sizeof(header), NULL);
  235. if (r)
  236. return r;
  237. bif_output.header = (void *)bif_output.data;
  238. return 0;
  239. }
  240. static int bif_add_pmufw(struct bif_entry *bf, const char *data, size_t len)
  241. {
  242. int r;
  243. if (bif_output.header->image_offset) {
  244. printf("PMUFW expected before bootloader in your .bif file!\n");
  245. return -1;
  246. }
  247. r = bif_add_blob(data, len, &bf->offset);
  248. if (r)
  249. return r;
  250. len = ROUND(len, 64);
  251. bif_output.header->pfw_image_length = cpu_to_le32(len);
  252. bif_output.header->total_pfw_image_length = cpu_to_le32(len);
  253. bif_output.header->image_offset = cpu_to_le32(bf->offset);
  254. return 0;
  255. }
  256. static int bif_add_part(struct bif_entry *bf, const char *data, size_t len)
  257. {
  258. size_t parthdr_offset = 0;
  259. struct partition_header parthdr = {
  260. .len_enc = cpu_to_le32(len / 4),
  261. .len_unenc = cpu_to_le32(len / 4),
  262. .len = cpu_to_le32(len / 4),
  263. .entry_point = cpu_to_le64(bf->entry),
  264. .load_address = cpu_to_le64(bf->load),
  265. };
  266. int r;
  267. uint32_t csum;
  268. if (bf->flags & (1ULL << BIF_FLAG_PMUFW_IMAGE))
  269. return bif_add_pmufw(bf, data, len);
  270. r = bif_add_blob(data, len, &bf->offset);
  271. if (r)
  272. return r;
  273. parthdr.offset = cpu_to_le32(bf->offset / 4);
  274. if (bf->flags & (1ULL << BIF_FLAG_BOOTLOADER)) {
  275. if (bif_output.last_part) {
  276. printf("ERROR: Bootloader expected before others\n");
  277. return -1;
  278. }
  279. parthdr.offset = cpu_to_le32(bif_output.header->image_offset);
  280. parthdr.len = cpu_to_le32((bf->offset + len -
  281. bif_output.header->image_offset) / 4);
  282. parthdr.len_enc = parthdr.len;
  283. parthdr.len_unenc = parthdr.len;
  284. }
  285. /* Normalize EL */
  286. bf->exp_lvl = bf->exp_lvl ? bf->exp_lvl - 1 : 3;
  287. parthdr.attributes |= bf->exp_lvl << PART_ATTR_TARGET_EL_SHIFT;
  288. parthdr.attributes |= bf->dest_dev;
  289. parthdr.attributes |= bf->dest_cpu;
  290. if (bf->flags & (1ULL << BIF_FLAG_TZ))
  291. parthdr.attributes |= PART_ATTR_TZ_SECURE;
  292. if (bf->flags & (1ULL << BIF_FLAG_PART_OWNER_UBOOT))
  293. parthdr.attributes |= PART_ATTR_PART_OWNER_UBOOT;
  294. switch (bf->dest_cpu) {
  295. case PART_ATTR_DEST_CPU_NONE:
  296. case PART_ATTR_DEST_CPU_A53_0:
  297. case PART_ATTR_DEST_CPU_A53_1:
  298. case PART_ATTR_DEST_CPU_A53_2:
  299. case PART_ATTR_DEST_CPU_A53_3:
  300. if (bf->flags & (1ULL << BIF_FLAG_AARCH32))
  301. parthdr.attributes |= PART_ATTR_A53_EXEC_AARCH32;
  302. }
  303. csum = zynqmp_csum(&parthdr, &parthdr.checksum);
  304. parthdr.checksum = cpu_to_le32(csum);
  305. r = bif_add_blob(&parthdr, sizeof(parthdr), &parthdr_offset);
  306. if (r)
  307. return r;
  308. /* Add image header table if not there yet */
  309. if (!bif_output.imgheader) {
  310. size_t imghdr_off = 0;
  311. struct image_header_table imghdr = {
  312. .version = cpu_to_le32(0x01020000),
  313. .nr_parts = 0,
  314. };
  315. r = bif_add_blob(&imghdr, sizeof(imghdr), &imghdr_off);
  316. if (r)
  317. return r;
  318. bif_output.header->image_header_table_offset = imghdr_off;
  319. bif_output.imgheader = (void *)(bif_output.data + imghdr_off);
  320. }
  321. bif_output.imgheader->nr_parts = cpu_to_le32(le32_to_cpu(
  322. bif_output.imgheader->nr_parts) + 1);
  323. /* Link to this partition header */
  324. if (bif_output.last_part) {
  325. bif_output.last_part->next_partition_offset =
  326. cpu_to_le32(parthdr_offset / 4);
  327. /* Recalc checksum of last_part */
  328. csum = zynqmp_csum(bif_output.last_part,
  329. &bif_output.last_part->checksum);
  330. bif_output.last_part->checksum = cpu_to_le32(csum);
  331. } else {
  332. bif_output.imgheader->partition_header_offset =
  333. cpu_to_le32(parthdr_offset / 4);
  334. }
  335. bif_output.last_part = (void *)(bif_output.data + parthdr_offset);
  336. if (bf->flags & (1ULL << BIF_FLAG_BOOTLOADER)) {
  337. bif_output.header->image_load = cpu_to_le32(bf->load);
  338. if (!bif_output.header->image_offset)
  339. bif_output.header->image_offset =
  340. cpu_to_le32(bf->offset);
  341. bif_output.header->image_size = cpu_to_le32(len);
  342. bif_output.header->image_stored_size = cpu_to_le32(len);
  343. bif_output.header->image_attributes &= ~HEADER_CPU_SELECT_MASK;
  344. switch (bf->dest_cpu) {
  345. default:
  346. case PART_ATTR_DEST_CPU_A53_0:
  347. if (bf->flags & BIF_FLAG_AARCH32)
  348. bif_output.header->image_attributes |=
  349. HEADER_CPU_SELECT_A53_32BIT;
  350. else
  351. bif_output.header->image_attributes |=
  352. HEADER_CPU_SELECT_A53_64BIT;
  353. break;
  354. case PART_ATTR_DEST_CPU_R5_0:
  355. bif_output.header->image_attributes |=
  356. HEADER_CPU_SELECT_R5_SINGLE;
  357. break;
  358. case PART_ATTR_DEST_CPU_R5_L:
  359. bif_output.header->image_attributes |=
  360. HEADER_CPU_SELECT_R5_DUAL;
  361. break;
  362. }
  363. }
  364. return 0;
  365. }
  366. /* Add .bit bitstream */
  367. static int bif_add_bit(struct bif_entry *bf)
  368. {
  369. char *bit = read_full_file(bf->filename, NULL);
  370. char *bitbin;
  371. uint8_t initial_header[] = { 0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f,
  372. 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01, 0x61 };
  373. uint16_t len;
  374. uint32_t bitlen;
  375. int i;
  376. if (!bit)
  377. return -1;
  378. /* Skip initial header */
  379. if (memcmp(bit, initial_header, sizeof(initial_header)))
  380. return -1;
  381. bit += sizeof(initial_header);
  382. /* Design name */
  383. len = be16_to_cpu(*(uint16_t *)bit);
  384. bit += sizeof(uint16_t);
  385. debug("Design: %s\n", bit);
  386. bit += len;
  387. /* Device identifier */
  388. if (*bit != 'b')
  389. return -1;
  390. bit++;
  391. len = be16_to_cpu(*(uint16_t *)bit);
  392. bit += sizeof(uint16_t);
  393. debug("Device: %s\n", bit);
  394. bit += len;
  395. /* Date */
  396. if (*bit != 'c')
  397. return -1;
  398. bit++;
  399. len = be16_to_cpu(*(uint16_t *)bit);
  400. bit += sizeof(uint16_t);
  401. debug("Date: %s\n", bit);
  402. bit += len;
  403. /* Time */
  404. if (*bit != 'd')
  405. return -1;
  406. bit++;
  407. len = be16_to_cpu(*(uint16_t *)bit);
  408. bit += sizeof(uint16_t);
  409. debug("Time: %s\n", bit);
  410. bit += len;
  411. /* Bitstream length */
  412. if (*bit != 'e')
  413. return -1;
  414. bit++;
  415. bitlen = be32_to_cpu(*(uint32_t *)bit);
  416. bit += sizeof(uint32_t);
  417. bitbin = bit;
  418. debug("Bitstream Length: 0x%x\n", bitlen);
  419. for (i = 0; i < bitlen; i += sizeof(uint32_t)) {
  420. uint32_t *bitbin32 = (uint32_t *)&bitbin[i];
  421. *bitbin32 = __swab32(*bitbin32);
  422. }
  423. if (!bf->dest_dev)
  424. bf->dest_dev = PART_ATTR_DEST_DEVICE_PL;
  425. bf->load = 0xffffffff;
  426. bf->entry = 0;
  427. bf->flags |= 1ULL << BIF_FLAG_BIT_FILE;
  428. return bif_add_part(bf, bit, bitlen);
  429. }
  430. /* Add .bin bitstream */
  431. static int bif_add_bin(struct bif_entry *bf)
  432. {
  433. size_t size;
  434. char *bin = read_full_file(bf->filename, &size);
  435. if (!bf->dest_dev)
  436. bf->dest_dev = PART_ATTR_DEST_DEVICE_PS;
  437. bf->flags |= 1ULL << BIF_FLAG_BIN_FILE;
  438. return bif_add_part(bf, bin, size);
  439. }
  440. /* Add elf file */
  441. static char *elf2flat64(char *elf, size_t *flat_size, size_t *load_addr)
  442. {
  443. Elf64_Ehdr *ehdr;
  444. Elf64_Shdr *shdr;
  445. size_t min_addr = -1, max_addr = 0;
  446. char *flat;
  447. int i;
  448. ehdr = (void *)elf;
  449. shdr = (void *)(elf + le64_to_cpu(ehdr->e_shoff));
  450. /* Look for smallest / biggest address */
  451. for (i = 0; i < le64_to_cpu(ehdr->e_shnum); i++, shdr++) {
  452. if (!shdr->sh_size || !shdr->sh_addr ||
  453. !(shdr->sh_flags & SHF_ALLOC) ||
  454. (shdr->sh_type == SHT_NOBITS))
  455. continue;
  456. if (le64_to_cpu(shdr->sh_addr) < min_addr)
  457. min_addr = le64_to_cpu(shdr->sh_addr);
  458. if ((le64_to_cpu(shdr->sh_addr) + le64_to_cpu(shdr->sh_size)) >
  459. max_addr)
  460. max_addr = le64_to_cpu(shdr->sh_addr) +
  461. le64_to_cpu(shdr->sh_size);
  462. }
  463. *load_addr = min_addr;
  464. *flat_size = max_addr - min_addr;
  465. flat = calloc(1, *flat_size);
  466. if (!flat)
  467. return NULL;
  468. shdr = (void *)(elf + le64_to_cpu(ehdr->e_shoff));
  469. for (i = 0; i < le64_to_cpu(ehdr->e_shnum); i++, shdr++) {
  470. char *dst = flat + le64_to_cpu(shdr->sh_addr) - min_addr;
  471. char *src = elf + le64_to_cpu(shdr->sh_offset);
  472. if (!shdr->sh_size || !shdr->sh_addr ||
  473. !(shdr->sh_flags & SHF_ALLOC))
  474. continue;
  475. if (shdr->sh_type != SHT_NOBITS)
  476. memcpy(dst, src, le64_to_cpu(shdr->sh_size));
  477. }
  478. return flat;
  479. }
  480. static char *elf2flat32(char *elf, size_t *flat_size, size_t *load_addr)
  481. {
  482. Elf32_Ehdr *ehdr;
  483. Elf32_Shdr *shdr;
  484. size_t min_addr = -1, max_addr = 0;
  485. char *flat;
  486. int i;
  487. ehdr = (void *)elf;
  488. shdr = (void *)(elf + le32_to_cpu(ehdr->e_shoff));
  489. /* Look for smallest / biggest address */
  490. for (i = 0; i < le32_to_cpu(ehdr->e_shnum); i++, shdr++) {
  491. if (!shdr->sh_size || !shdr->sh_addr ||
  492. !(shdr->sh_flags & SHF_ALLOC) ||
  493. (shdr->sh_type == SHT_NOBITS))
  494. continue;
  495. if (le32_to_cpu(shdr->sh_addr) < min_addr)
  496. min_addr = le32_to_cpu(shdr->sh_addr);
  497. if ((le32_to_cpu(shdr->sh_addr) + le32_to_cpu(shdr->sh_size)) >
  498. max_addr)
  499. max_addr = le32_to_cpu(shdr->sh_addr) +
  500. le32_to_cpu(shdr->sh_size);
  501. }
  502. *load_addr = min_addr;
  503. *flat_size = max_addr - min_addr;
  504. flat = calloc(1, *flat_size);
  505. if (!flat)
  506. return NULL;
  507. shdr = (void *)(elf + le32_to_cpu(ehdr->e_shoff));
  508. for (i = 0; i < le32_to_cpu(ehdr->e_shnum); i++, shdr++) {
  509. char *dst = flat + le32_to_cpu(shdr->sh_addr) - min_addr;
  510. char *src = elf + le32_to_cpu(shdr->sh_offset);
  511. if (!shdr->sh_size || !shdr->sh_addr ||
  512. !(shdr->sh_flags & SHF_ALLOC))
  513. continue;
  514. if (shdr->sh_type != SHT_NOBITS)
  515. memcpy(dst, src, le32_to_cpu(shdr->sh_size));
  516. }
  517. return flat;
  518. }
  519. static int bif_add_elf(struct bif_entry *bf)
  520. {
  521. size_t size;
  522. size_t elf_size;
  523. char *elf;
  524. char *flat;
  525. size_t load_addr;
  526. Elf32_Ehdr *ehdr32;
  527. Elf64_Ehdr *ehdr64;
  528. elf = read_full_file(bf->filename, &elf_size);
  529. if (!elf)
  530. return -1;
  531. ehdr32 = (void *)elf;
  532. ehdr64 = (void *)elf;
  533. switch (ehdr32->e_ident[EI_CLASS]) {
  534. case ELFCLASS32:
  535. flat = elf2flat32(elf, &size, &load_addr);
  536. bf->entry = le32_to_cpu(ehdr32->e_entry);
  537. bf->flags |= 1ULL << BIF_FLAG_AARCH32;
  538. break;
  539. case ELFCLASS64:
  540. flat = elf2flat64(elf, &size, &load_addr);
  541. bf->entry = le64_to_cpu(ehdr64->e_entry);
  542. break;
  543. default:
  544. printf("Unknown ELF class: %d\n", ehdr32->e_ident[EI_CLASS]);
  545. return -1;
  546. }
  547. if (!flat)
  548. return -1;
  549. bf->load = load_addr;
  550. if (!bf->dest_dev)
  551. bf->dest_dev = PART_ATTR_DEST_DEVICE_PS;
  552. bf->flags |= 1ULL << BIF_FLAG_ELF_FILE;
  553. return bif_add_part(bf, flat, size);
  554. }
  555. static const struct bif_file_type bif_file_types[] = {
  556. {
  557. .name = "bitstream (.bit)",
  558. .header = 0x00090ff0,
  559. .add = bif_add_bit,
  560. },
  561. {
  562. .name = "ELF",
  563. .header = 0x7f454c46,
  564. .add = bif_add_elf,
  565. },
  566. /* Anything else is a .bin file */
  567. {
  568. .name = ".bin",
  569. .add = bif_add_bin,
  570. },
  571. };
  572. static int bif_fsbl_config(struct bif_entry *fsbl_config,
  573. struct bif_entry *entries, int nr_entries)
  574. {
  575. int i;
  576. int config_set = 0;
  577. struct {
  578. const char *name;
  579. uint64_t flags;
  580. uint64_t dest_cpu;
  581. } configs[] = {
  582. { .name = "a5x_x64", .dest_cpu = PART_ATTR_DEST_CPU_A53_0 },
  583. { .name = "a53_x64", .dest_cpu = PART_ATTR_DEST_CPU_A53_0 },
  584. { .name = "a5x_x32", .dest_cpu = PART_ATTR_DEST_CPU_A53_0,
  585. .flags = 1ULL << BIF_FLAG_AARCH32 },
  586. { .name = "a53_x32", .dest_cpu = PART_ATTR_DEST_CPU_A53_0,
  587. .flags = 1ULL << BIF_FLAG_AARCH32 },
  588. { .name = "r5_single", .dest_cpu = PART_ATTR_DEST_CPU_R5_0 },
  589. { .name = "r5_dual", .dest_cpu = PART_ATTR_DEST_CPU_R5_L },
  590. };
  591. /* Set target CPU of bootloader entry */
  592. for (i = 0; i < nr_entries; i++) {
  593. struct bif_entry *b = &entries[i];
  594. const char *config_attr = fsbl_config->filename;
  595. int j;
  596. if (!(b->flags & (1ULL << BIF_FLAG_BOOTLOADER)))
  597. continue;
  598. for (j = 0; j < ARRAY_SIZE(configs); j++) {
  599. if (!strncmp(config_attr, configs[j].name,
  600. strlen(configs[j].name))) {
  601. b->dest_cpu = configs[j].dest_cpu;
  602. b->flags |= configs[j].flags;
  603. config_set = 1;
  604. }
  605. }
  606. if (!config_set) {
  607. printf("ERROR: Unsupported fsbl_config: %s\n",
  608. config_attr);
  609. return -1;
  610. }
  611. }
  612. if (!config_set) {
  613. printf("ERROR: fsbl_config w/o bootloader\n");
  614. return -1;
  615. }
  616. return 0;
  617. }
  618. static const struct bif_flags *find_flag(char *str)
  619. {
  620. const struct bif_flags *bf;
  621. int i;
  622. for (i = 0; i < ARRAY_SIZE(bif_flags); i++) {
  623. bf = &bif_flags[i];
  624. if (!strncmp(bf->name, str, strlen(bf->name)))
  625. return bf;
  626. }
  627. printf("ERROR: Flag '%s' not found\n", str);
  628. return NULL;
  629. }
  630. static int bif_open_file(struct bif_entry *entry)
  631. {
  632. int fd = open(entry->filename, O_RDONLY);
  633. if (fd < 0)
  634. printf("Error opening file %s\n", entry->filename);
  635. return fd;
  636. }
  637. static const struct bif_file_type *get_file_type(struct bif_entry *entry)
  638. {
  639. int fd = bif_open_file(entry);
  640. uint32_t header;
  641. int i;
  642. if (fd < 0)
  643. return NULL;
  644. if (read(fd, &header, sizeof(header)) != sizeof(header)) {
  645. printf("Error reading file %s", entry->filename);
  646. return NULL;
  647. }
  648. close(fd);
  649. for (i = 0; i < ARRAY_SIZE(bif_file_types); i++) {
  650. const struct bif_file_type *type = &bif_file_types[i];
  651. if (!type->header)
  652. return type;
  653. if (type->header == be32_to_cpu(header))
  654. return type;
  655. }
  656. return NULL;
  657. }
  658. #define NEXT_CHAR(str, chr) ({ \
  659. char *_n = strchr(str, chr); \
  660. if (!_n) \
  661. goto err; \
  662. _n; \
  663. })
  664. static char *skip_whitespace(char *str)
  665. {
  666. while (*str == ' ' || *str == '\t')
  667. str++;
  668. return str;
  669. }
  670. int zynqmpbif_copy_image(int outfd, struct image_tool_params *mparams)
  671. {
  672. char *bif, *bifp, *bifpn;
  673. char *line;
  674. struct bif_entry entries[32] = { { 0 } };
  675. int nr_entries = 0;
  676. struct bif_entry *entry = entries;
  677. size_t len;
  678. int i;
  679. uint32_t csum;
  680. int bldr = -1;
  681. bif_init();
  682. /* Read .bif input file */
  683. bif = read_full_file(mparams->datafile, NULL);
  684. if (!bif)
  685. goto err;
  686. /* Interpret .bif file */
  687. bifp = bif;
  688. /* A bif description starts with a { section */
  689. bifp = NEXT_CHAR(bifp, '{') + 1;
  690. /* Read every line */
  691. while (1) {
  692. bifpn = NEXT_CHAR(bifp, '\n');
  693. if (bifpn[-1] == '\r')
  694. bifpn[-1] = '\0';
  695. *bifpn = '\0';
  696. bifpn++;
  697. line = bifp;
  698. line = skip_whitespace(line);
  699. /* Attributes? */
  700. if (*line == '[') {
  701. line++;
  702. while (1) {
  703. const struct bif_flags *bf;
  704. line = skip_whitespace(line);
  705. bf = find_flag(line);
  706. if (!bf)
  707. goto err;
  708. line += strlen(bf->name);
  709. if (bf->parse)
  710. line = bf->parse(line, entry);
  711. else
  712. entry->flags |= 1ULL << bf->flag;
  713. if (!line)
  714. goto err;
  715. /* Go to next attribute or quit */
  716. if (*line == ']') {
  717. line++;
  718. break;
  719. }
  720. if (*line == ',')
  721. line++;
  722. }
  723. }
  724. /* End of image description */
  725. if (*line == '}')
  726. break;
  727. if (*line) {
  728. line = skip_whitespace(line);
  729. entry->filename = line;
  730. nr_entries++;
  731. entry++;
  732. }
  733. /* Use next line */
  734. bifp = bifpn;
  735. }
  736. for (i = 0; i < nr_entries; i++) {
  737. debug("Entry flags=%#lx name=%s\n", entries[i].flags,
  738. entries[i].filename);
  739. }
  740. /*
  741. * Some entries are actually configuration option for other ones,
  742. * let's apply them in an intermediate step.
  743. */
  744. for (i = 0; i < nr_entries; i++) {
  745. struct bif_entry *entry = &entries[i];
  746. if (entry->flags & (1ULL << BIF_FLAG_FSBL_CONFIG))
  747. if (bif_fsbl_config(entry, entries, nr_entries))
  748. goto err;
  749. }
  750. /* Make sure PMUFW comes before bootloader */
  751. for (i = 0; i < nr_entries; i++) {
  752. struct bif_entry *entry = &entries[i];
  753. if (entry->flags & (1ULL << BIF_FLAG_BOOTLOADER))
  754. bldr = i;
  755. if (entry->flags & (1ULL << BIF_FLAG_PMUFW_IMAGE)) {
  756. if (bldr >= 0) {
  757. struct bif_entry tmp = *entry;
  758. *entry = entries[bldr];
  759. entries[bldr] = tmp;
  760. }
  761. }
  762. }
  763. for (i = 0; i < nr_entries; i++) {
  764. struct bif_entry *entry = &entries[i];
  765. const struct bif_file_type *type;
  766. int r;
  767. if (entry->flags & (1ULL << BIF_FLAG_FSBL_CONFIG))
  768. continue;
  769. type = get_file_type(entry);
  770. if (!type)
  771. goto err;
  772. debug("type=%s file=%s\n", type->name, entry->filename);
  773. r = type->add(entry);
  774. if (r)
  775. goto err;
  776. }
  777. /* Calculate checksums */
  778. csum = zynqmp_csum(&bif_output.header->width_detection,
  779. &bif_output.header->checksum);
  780. bif_output.header->checksum = cpu_to_le32(csum);
  781. if (bif_output.imgheader) {
  782. csum = zynqmp_csum(bif_output.imgheader,
  783. &bif_output.imgheader->checksum);
  784. bif_output.imgheader->checksum = cpu_to_le32(csum);
  785. }
  786. /* Write headers and components */
  787. if (lseek(outfd, 0, SEEK_SET) != 0)
  788. goto err;
  789. len = bif_output.data_len;
  790. bifp = bif_output.data;
  791. while (len) {
  792. int r;
  793. r = write(outfd, bifp, len);
  794. if (r < 0)
  795. goto err;
  796. len -= r;
  797. bifp += r;
  798. }
  799. return 0;
  800. err:
  801. fprintf(stderr, "Error: Failed to create image.\n");
  802. return -1;
  803. }
  804. /* Needs to be stubbed out so we can print after creation */
  805. static void zynqmpbif_set_header(void *ptr, struct stat *sbuf, int ifd,
  806. struct image_tool_params *params)
  807. {
  808. }
  809. static struct zynqmp_header zynqmpimage_header;
  810. U_BOOT_IMAGE_TYPE(
  811. zynqmpbif,
  812. "Xilinx ZynqMP Boot Image support (bif)",
  813. sizeof(struct zynqmp_header),
  814. (void *)&zynqmpimage_header,
  815. zynqmpbif_check_params,
  816. NULL,
  817. zynqmpimage_print_header,
  818. zynqmpbif_set_header,
  819. NULL,
  820. zynqmpbif_check_image_types,
  821. NULL,
  822. NULL
  823. );