zynqmpbif.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017
  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. size_t len_padded = ROUND(len, 4);
  260. struct partition_header parthdr = {
  261. .len_enc = cpu_to_le32(len_padded / 4),
  262. .len_unenc = cpu_to_le32(len_padded / 4),
  263. .len = cpu_to_le32(len_padded / 4),
  264. .entry_point = cpu_to_le64(bf->entry),
  265. .load_address = cpu_to_le64(bf->load),
  266. };
  267. int r;
  268. uint32_t csum;
  269. if (len < len_padded) {
  270. char *newdata = malloc(len_padded);
  271. memcpy(newdata, data, len);
  272. memset(newdata + len, 0, len_padded - len);
  273. data = newdata;
  274. }
  275. if (bf->flags & (1ULL << BIF_FLAG_PMUFW_IMAGE))
  276. return bif_add_pmufw(bf, data, len);
  277. r = bif_add_blob(data, len, &bf->offset);
  278. if (r)
  279. return r;
  280. parthdr.offset = cpu_to_le32(bf->offset / 4);
  281. if (bf->flags & (1ULL << BIF_FLAG_BOOTLOADER)) {
  282. if (bif_output.last_part) {
  283. printf("ERROR: Bootloader expected before others\n");
  284. return -1;
  285. }
  286. parthdr.offset = cpu_to_le32(bif_output.header->image_offset);
  287. parthdr.len = cpu_to_le32((bf->offset + len -
  288. bif_output.header->image_offset) / 4);
  289. parthdr.len_enc = parthdr.len;
  290. parthdr.len_unenc = parthdr.len;
  291. }
  292. /* Normalize EL */
  293. bf->exp_lvl = bf->exp_lvl ? bf->exp_lvl - 1 : 3;
  294. parthdr.attributes |= bf->exp_lvl << PART_ATTR_TARGET_EL_SHIFT;
  295. parthdr.attributes |= bf->dest_dev;
  296. parthdr.attributes |= bf->dest_cpu;
  297. if (bf->flags & (1ULL << BIF_FLAG_TZ))
  298. parthdr.attributes |= PART_ATTR_TZ_SECURE;
  299. if (bf->flags & (1ULL << BIF_FLAG_PART_OWNER_UBOOT))
  300. parthdr.attributes |= PART_ATTR_PART_OWNER_UBOOT;
  301. switch (bf->dest_cpu) {
  302. case PART_ATTR_DEST_CPU_NONE:
  303. case PART_ATTR_DEST_CPU_A53_0:
  304. case PART_ATTR_DEST_CPU_A53_1:
  305. case PART_ATTR_DEST_CPU_A53_2:
  306. case PART_ATTR_DEST_CPU_A53_3:
  307. if (bf->flags & (1ULL << BIF_FLAG_AARCH32))
  308. parthdr.attributes |= PART_ATTR_A53_EXEC_AARCH32;
  309. }
  310. csum = zynqmp_csum(&parthdr, &parthdr.checksum);
  311. parthdr.checksum = cpu_to_le32(csum);
  312. r = bif_add_blob(&parthdr, sizeof(parthdr), &parthdr_offset);
  313. if (r)
  314. return r;
  315. /* Add image header table if not there yet */
  316. if (!bif_output.imgheader) {
  317. size_t imghdr_off = 0;
  318. struct image_header_table imghdr = {
  319. .version = cpu_to_le32(0x01020000),
  320. .nr_parts = 0,
  321. };
  322. r = bif_add_blob(&imghdr, sizeof(imghdr), &imghdr_off);
  323. if (r)
  324. return r;
  325. bif_output.header->image_header_table_offset = imghdr_off;
  326. bif_output.imgheader = (void *)(bif_output.data + imghdr_off);
  327. }
  328. bif_output.imgheader->nr_parts = cpu_to_le32(le32_to_cpu(
  329. bif_output.imgheader->nr_parts) + 1);
  330. /* Link to this partition header */
  331. if (bif_output.last_part) {
  332. bif_output.last_part->next_partition_offset =
  333. cpu_to_le32(parthdr_offset / 4);
  334. /* Recalc checksum of last_part */
  335. csum = zynqmp_csum(bif_output.last_part,
  336. &bif_output.last_part->checksum);
  337. bif_output.last_part->checksum = cpu_to_le32(csum);
  338. } else {
  339. bif_output.imgheader->partition_header_offset =
  340. cpu_to_le32(parthdr_offset / 4);
  341. }
  342. bif_output.last_part = (void *)(bif_output.data + parthdr_offset);
  343. if (bf->flags & (1ULL << BIF_FLAG_BOOTLOADER)) {
  344. bif_output.header->image_load = cpu_to_le32(bf->load);
  345. if (!bif_output.header->image_offset)
  346. bif_output.header->image_offset =
  347. cpu_to_le32(bf->offset);
  348. bif_output.header->image_size = cpu_to_le32(len_padded);
  349. bif_output.header->image_stored_size = cpu_to_le32(len_padded);
  350. bif_output.header->image_attributes &= ~HEADER_CPU_SELECT_MASK;
  351. switch (bf->dest_cpu) {
  352. default:
  353. case PART_ATTR_DEST_CPU_A53_0:
  354. if (bf->flags & BIF_FLAG_AARCH32)
  355. bif_output.header->image_attributes |=
  356. HEADER_CPU_SELECT_A53_32BIT;
  357. else
  358. bif_output.header->image_attributes |=
  359. HEADER_CPU_SELECT_A53_64BIT;
  360. break;
  361. case PART_ATTR_DEST_CPU_R5_0:
  362. bif_output.header->image_attributes |=
  363. HEADER_CPU_SELECT_R5_SINGLE;
  364. break;
  365. case PART_ATTR_DEST_CPU_R5_L:
  366. bif_output.header->image_attributes |=
  367. HEADER_CPU_SELECT_R5_DUAL;
  368. break;
  369. }
  370. }
  371. return 0;
  372. }
  373. /* Add .bit bitstream */
  374. static int bif_add_bit(struct bif_entry *bf)
  375. {
  376. char *bit = read_full_file(bf->filename, NULL);
  377. char *bitbin;
  378. uint8_t initial_header[] = { 0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f,
  379. 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01, 0x61 };
  380. uint16_t len;
  381. uint32_t bitlen;
  382. int i;
  383. if (!bit)
  384. return -1;
  385. /* Skip initial header */
  386. if (memcmp(bit, initial_header, sizeof(initial_header)))
  387. return -1;
  388. bit += sizeof(initial_header);
  389. /* Design name */
  390. len = be16_to_cpu(*(uint16_t *)bit);
  391. bit += sizeof(uint16_t);
  392. debug("Design: %s\n", bit);
  393. bit += len;
  394. /* Device identifier */
  395. if (*bit != 'b')
  396. return -1;
  397. bit++;
  398. len = be16_to_cpu(*(uint16_t *)bit);
  399. bit += sizeof(uint16_t);
  400. debug("Device: %s\n", bit);
  401. bit += len;
  402. /* Date */
  403. if (*bit != 'c')
  404. return -1;
  405. bit++;
  406. len = be16_to_cpu(*(uint16_t *)bit);
  407. bit += sizeof(uint16_t);
  408. debug("Date: %s\n", bit);
  409. bit += len;
  410. /* Time */
  411. if (*bit != 'd')
  412. return -1;
  413. bit++;
  414. len = be16_to_cpu(*(uint16_t *)bit);
  415. bit += sizeof(uint16_t);
  416. debug("Time: %s\n", bit);
  417. bit += len;
  418. /* Bitstream length */
  419. if (*bit != 'e')
  420. return -1;
  421. bit++;
  422. bitlen = be32_to_cpu(*(uint32_t *)bit);
  423. bit += sizeof(uint32_t);
  424. bitbin = bit;
  425. debug("Bitstream Length: 0x%x\n", bitlen);
  426. for (i = 0; i < bitlen; i += sizeof(uint32_t)) {
  427. uint32_t *bitbin32 = (uint32_t *)&bitbin[i];
  428. *bitbin32 = __builtin_bswap32(*bitbin32);
  429. }
  430. if (!bf->dest_dev)
  431. bf->dest_dev = PART_ATTR_DEST_DEVICE_PL;
  432. bf->load = 0xffffffff;
  433. bf->entry = 0;
  434. bf->flags |= 1ULL << BIF_FLAG_BIT_FILE;
  435. return bif_add_part(bf, bit, bitlen);
  436. }
  437. /* Add .bin bitstream */
  438. static int bif_add_bin(struct bif_entry *bf)
  439. {
  440. size_t size;
  441. char *bin = read_full_file(bf->filename, &size);
  442. if (!bf->dest_dev)
  443. bf->dest_dev = PART_ATTR_DEST_DEVICE_PS;
  444. bf->flags |= 1ULL << BIF_FLAG_BIN_FILE;
  445. return bif_add_part(bf, bin, size);
  446. }
  447. /* Add elf file */
  448. static char *elf2flat64(char *elf, size_t *flat_size, size_t *load_addr)
  449. {
  450. Elf64_Ehdr *ehdr;
  451. Elf64_Shdr *shdr;
  452. size_t min_addr = -1, max_addr = 0;
  453. char *flat;
  454. int i;
  455. ehdr = (void *)elf;
  456. shdr = (void *)(elf + le64_to_cpu(ehdr->e_shoff));
  457. /* Look for smallest / biggest address */
  458. for (i = 0; i < le64_to_cpu(ehdr->e_shnum); i++, shdr++) {
  459. if (!shdr->sh_size || !shdr->sh_addr ||
  460. !(shdr->sh_flags & SHF_ALLOC) ||
  461. (shdr->sh_type == SHT_NOBITS))
  462. continue;
  463. if (le64_to_cpu(shdr->sh_addr) < min_addr)
  464. min_addr = le64_to_cpu(shdr->sh_addr);
  465. if ((le64_to_cpu(shdr->sh_addr) + le64_to_cpu(shdr->sh_size)) >
  466. max_addr)
  467. max_addr = le64_to_cpu(shdr->sh_addr) +
  468. le64_to_cpu(shdr->sh_size);
  469. }
  470. *load_addr = min_addr;
  471. *flat_size = max_addr - min_addr;
  472. flat = calloc(1, *flat_size);
  473. if (!flat)
  474. return NULL;
  475. shdr = (void *)(elf + le64_to_cpu(ehdr->e_shoff));
  476. for (i = 0; i < le64_to_cpu(ehdr->e_shnum); i++, shdr++) {
  477. char *dst = flat + le64_to_cpu(shdr->sh_addr) - min_addr;
  478. char *src = elf + le64_to_cpu(shdr->sh_offset);
  479. if (!shdr->sh_size || !shdr->sh_addr ||
  480. !(shdr->sh_flags & SHF_ALLOC))
  481. continue;
  482. if (shdr->sh_type != SHT_NOBITS)
  483. memcpy(dst, src, le64_to_cpu(shdr->sh_size));
  484. }
  485. return flat;
  486. }
  487. static char *elf2flat32(char *elf, size_t *flat_size, size_t *load_addr)
  488. {
  489. Elf32_Ehdr *ehdr;
  490. Elf32_Shdr *shdr;
  491. size_t min_addr = -1, max_addr = 0;
  492. char *flat;
  493. int i;
  494. ehdr = (void *)elf;
  495. shdr = (void *)(elf + le32_to_cpu(ehdr->e_shoff));
  496. /* Look for smallest / biggest address */
  497. for (i = 0; i < le32_to_cpu(ehdr->e_shnum); i++, shdr++) {
  498. if (!shdr->sh_size || !shdr->sh_addr ||
  499. !(shdr->sh_flags & SHF_ALLOC) ||
  500. (shdr->sh_type == SHT_NOBITS))
  501. continue;
  502. if (le32_to_cpu(shdr->sh_addr) < min_addr)
  503. min_addr = le32_to_cpu(shdr->sh_addr);
  504. if ((le32_to_cpu(shdr->sh_addr) + le32_to_cpu(shdr->sh_size)) >
  505. max_addr)
  506. max_addr = le32_to_cpu(shdr->sh_addr) +
  507. le32_to_cpu(shdr->sh_size);
  508. }
  509. *load_addr = min_addr;
  510. *flat_size = max_addr - min_addr;
  511. flat = calloc(1, *flat_size);
  512. if (!flat)
  513. return NULL;
  514. shdr = (void *)(elf + le32_to_cpu(ehdr->e_shoff));
  515. for (i = 0; i < le32_to_cpu(ehdr->e_shnum); i++, shdr++) {
  516. char *dst = flat + le32_to_cpu(shdr->sh_addr) - min_addr;
  517. char *src = elf + le32_to_cpu(shdr->sh_offset);
  518. if (!shdr->sh_size || !shdr->sh_addr ||
  519. !(shdr->sh_flags & SHF_ALLOC))
  520. continue;
  521. if (shdr->sh_type != SHT_NOBITS)
  522. memcpy(dst, src, le32_to_cpu(shdr->sh_size));
  523. }
  524. return flat;
  525. }
  526. static int bif_add_elf(struct bif_entry *bf)
  527. {
  528. size_t size;
  529. size_t elf_size;
  530. char *elf;
  531. char *flat;
  532. size_t load_addr;
  533. Elf32_Ehdr *ehdr32;
  534. Elf64_Ehdr *ehdr64;
  535. elf = read_full_file(bf->filename, &elf_size);
  536. if (!elf)
  537. return -1;
  538. ehdr32 = (void *)elf;
  539. ehdr64 = (void *)elf;
  540. switch (ehdr32->e_ident[EI_CLASS]) {
  541. case ELFCLASS32:
  542. flat = elf2flat32(elf, &size, &load_addr);
  543. bf->entry = le32_to_cpu(ehdr32->e_entry);
  544. bf->flags |= 1ULL << BIF_FLAG_AARCH32;
  545. break;
  546. case ELFCLASS64:
  547. flat = elf2flat64(elf, &size, &load_addr);
  548. bf->entry = le64_to_cpu(ehdr64->e_entry);
  549. break;
  550. default:
  551. printf("Unknown ELF class: %d\n", ehdr32->e_ident[EI_CLASS]);
  552. return -1;
  553. }
  554. if (!flat)
  555. return -1;
  556. bf->load = load_addr;
  557. if (!bf->dest_dev)
  558. bf->dest_dev = PART_ATTR_DEST_DEVICE_PS;
  559. bf->flags |= 1ULL << BIF_FLAG_ELF_FILE;
  560. return bif_add_part(bf, flat, size);
  561. }
  562. static const struct bif_file_type bif_file_types[] = {
  563. {
  564. .name = "bitstream (.bit)",
  565. .header = 0x00090ff0,
  566. .add = bif_add_bit,
  567. },
  568. {
  569. .name = "ELF",
  570. .header = 0x7f454c46,
  571. .add = bif_add_elf,
  572. },
  573. /* Anything else is a .bin file */
  574. {
  575. .name = ".bin",
  576. .add = bif_add_bin,
  577. },
  578. };
  579. static int bif_fsbl_config(struct bif_entry *fsbl_config,
  580. struct bif_entry *entries, int nr_entries)
  581. {
  582. int i;
  583. int config_set = 0;
  584. struct {
  585. const char *name;
  586. uint64_t flags;
  587. uint64_t dest_cpu;
  588. } configs[] = {
  589. { .name = "a5x_x64", .dest_cpu = PART_ATTR_DEST_CPU_A53_0 },
  590. { .name = "a53_x64", .dest_cpu = PART_ATTR_DEST_CPU_A53_0 },
  591. { .name = "a5x_x32", .dest_cpu = PART_ATTR_DEST_CPU_A53_0,
  592. .flags = 1ULL << BIF_FLAG_AARCH32 },
  593. { .name = "a53_x32", .dest_cpu = PART_ATTR_DEST_CPU_A53_0,
  594. .flags = 1ULL << BIF_FLAG_AARCH32 },
  595. { .name = "r5_single", .dest_cpu = PART_ATTR_DEST_CPU_R5_0 },
  596. { .name = "r5_dual", .dest_cpu = PART_ATTR_DEST_CPU_R5_L },
  597. };
  598. /* Set target CPU of bootloader entry */
  599. for (i = 0; i < nr_entries; i++) {
  600. struct bif_entry *b = &entries[i];
  601. const char *config_attr = fsbl_config->filename;
  602. int j;
  603. if (!(b->flags & (1ULL << BIF_FLAG_BOOTLOADER)))
  604. continue;
  605. for (j = 0; j < ARRAY_SIZE(configs); j++) {
  606. if (!strncmp(config_attr, configs[j].name,
  607. strlen(configs[j].name))) {
  608. b->dest_cpu = configs[j].dest_cpu;
  609. b->flags |= configs[j].flags;
  610. config_set = 1;
  611. }
  612. }
  613. if (!config_set) {
  614. printf("ERROR: Unsupported fsbl_config: %s\n",
  615. config_attr);
  616. return -1;
  617. }
  618. }
  619. if (!config_set) {
  620. printf("ERROR: fsbl_config w/o bootloader\n");
  621. return -1;
  622. }
  623. return 0;
  624. }
  625. static const struct bif_flags *find_flag(char *str)
  626. {
  627. const struct bif_flags *bf;
  628. int i;
  629. for (i = 0; i < ARRAY_SIZE(bif_flags); i++) {
  630. bf = &bif_flags[i];
  631. if (!strncmp(bf->name, str, strlen(bf->name)))
  632. return bf;
  633. }
  634. printf("ERROR: Flag '%s' not found\n", str);
  635. return NULL;
  636. }
  637. static int bif_open_file(struct bif_entry *entry)
  638. {
  639. int fd = open(entry->filename, O_RDONLY);
  640. if (fd < 0)
  641. printf("Error opening file %s\n", entry->filename);
  642. return fd;
  643. }
  644. static const struct bif_file_type *get_file_type(struct bif_entry *entry)
  645. {
  646. int fd = bif_open_file(entry);
  647. uint32_t header;
  648. int i;
  649. if (fd < 0)
  650. return NULL;
  651. if (read(fd, &header, sizeof(header)) != sizeof(header)) {
  652. printf("Error reading file %s", entry->filename);
  653. return NULL;
  654. }
  655. close(fd);
  656. for (i = 0; i < ARRAY_SIZE(bif_file_types); i++) {
  657. const struct bif_file_type *type = &bif_file_types[i];
  658. if (!type->header)
  659. return type;
  660. if (type->header == be32_to_cpu(header))
  661. return type;
  662. }
  663. return NULL;
  664. }
  665. #define NEXT_CHAR(str, chr) ({ \
  666. char *_n = strchr(str, chr); \
  667. if (!_n) \
  668. goto err; \
  669. _n; \
  670. })
  671. static char *skip_whitespace(char *str)
  672. {
  673. while (*str == ' ' || *str == '\t')
  674. str++;
  675. return str;
  676. }
  677. int zynqmpbif_copy_image(int outfd, struct image_tool_params *mparams)
  678. {
  679. char *bif, *bifp, *bifpn;
  680. char *line;
  681. struct bif_entry entries[32] = { { 0 } };
  682. int nr_entries = 0;
  683. struct bif_entry *entry = entries;
  684. size_t len;
  685. int i;
  686. uint32_t csum;
  687. int bldr = -1;
  688. bif_init();
  689. /* Read .bif input file */
  690. bif = read_full_file(mparams->datafile, NULL);
  691. if (!bif)
  692. goto err;
  693. /* Interpret .bif file */
  694. bifp = bif;
  695. /* A bif description starts with a { section */
  696. bifp = NEXT_CHAR(bifp, '{') + 1;
  697. /* Read every line */
  698. while (1) {
  699. bifpn = NEXT_CHAR(bifp, '\n');
  700. if (bifpn[-1] == '\r')
  701. bifpn[-1] = '\0';
  702. *bifpn = '\0';
  703. bifpn++;
  704. line = bifp;
  705. line = skip_whitespace(line);
  706. /* Attributes? */
  707. if (*line == '[') {
  708. line++;
  709. while (1) {
  710. const struct bif_flags *bf;
  711. line = skip_whitespace(line);
  712. bf = find_flag(line);
  713. if (!bf)
  714. goto err;
  715. line += strlen(bf->name);
  716. if (bf->parse)
  717. line = bf->parse(line, entry);
  718. else
  719. entry->flags |= 1ULL << bf->flag;
  720. if (!line)
  721. goto err;
  722. /* Go to next attribute or quit */
  723. if (*line == ']') {
  724. line++;
  725. break;
  726. }
  727. if (*line == ',')
  728. line++;
  729. }
  730. }
  731. /* End of image description */
  732. if (*line == '}')
  733. break;
  734. if (*line) {
  735. line = skip_whitespace(line);
  736. entry->filename = line;
  737. nr_entries++;
  738. entry++;
  739. }
  740. /* Use next line */
  741. bifp = bifpn;
  742. }
  743. for (i = 0; i < nr_entries; i++) {
  744. debug("Entry flags=%#lx name=%s\n", entries[i].flags,
  745. entries[i].filename);
  746. }
  747. /*
  748. * Some entries are actually configuration option for other ones,
  749. * let's apply them in an intermediate step.
  750. */
  751. for (i = 0; i < nr_entries; i++) {
  752. struct bif_entry *entry = &entries[i];
  753. if (entry->flags & (1ULL << BIF_FLAG_FSBL_CONFIG))
  754. if (bif_fsbl_config(entry, entries, nr_entries))
  755. goto err;
  756. }
  757. /* Make sure PMUFW comes before bootloader */
  758. for (i = 0; i < nr_entries; i++) {
  759. struct bif_entry *entry = &entries[i];
  760. if (entry->flags & (1ULL << BIF_FLAG_BOOTLOADER))
  761. bldr = i;
  762. if (entry->flags & (1ULL << BIF_FLAG_PMUFW_IMAGE)) {
  763. if (bldr >= 0) {
  764. struct bif_entry tmp = *entry;
  765. *entry = entries[bldr];
  766. entries[bldr] = tmp;
  767. }
  768. }
  769. }
  770. for (i = 0; i < nr_entries; i++) {
  771. struct bif_entry *entry = &entries[i];
  772. const struct bif_file_type *type;
  773. int r;
  774. if (entry->flags & (1ULL << BIF_FLAG_FSBL_CONFIG))
  775. continue;
  776. type = get_file_type(entry);
  777. if (!type)
  778. goto err;
  779. debug("type=%s file=%s\n", type->name, entry->filename);
  780. r = type->add(entry);
  781. if (r)
  782. goto err;
  783. }
  784. /* Calculate checksums */
  785. csum = zynqmp_csum(&bif_output.header->width_detection,
  786. &bif_output.header->checksum);
  787. bif_output.header->checksum = cpu_to_le32(csum);
  788. if (bif_output.imgheader) {
  789. csum = zynqmp_csum(bif_output.imgheader,
  790. &bif_output.imgheader->checksum);
  791. bif_output.imgheader->checksum = cpu_to_le32(csum);
  792. }
  793. /* Write headers and components */
  794. if (lseek(outfd, 0, SEEK_SET) != 0)
  795. goto err;
  796. len = bif_output.data_len;
  797. bifp = bif_output.data;
  798. while (len) {
  799. int r;
  800. r = write(outfd, bifp, len);
  801. if (r < 0)
  802. goto err;
  803. len -= r;
  804. bifp += r;
  805. }
  806. return 0;
  807. err:
  808. fprintf(stderr, "Error: Failed to create image.\n");
  809. return -1;
  810. }
  811. /* Needs to be stubbed out so we can print after creation */
  812. static void zynqmpbif_set_header(void *ptr, struct stat *sbuf, int ifd,
  813. struct image_tool_params *params)
  814. {
  815. }
  816. static struct zynqmp_header zynqmpimage_header;
  817. U_BOOT_IMAGE_TYPE(
  818. zynqmpbif,
  819. "Xilinx ZynqMP Boot Image support (bif)",
  820. sizeof(struct zynqmp_header),
  821. (void *)&zynqmpimage_header,
  822. zynqmpbif_check_params,
  823. NULL,
  824. zynqmpimage_print_header,
  825. zynqmpbif_set_header,
  826. NULL,
  827. zynqmpbif_check_image_types,
  828. NULL,
  829. NULL
  830. );