|
@@ -43,6 +43,21 @@ void EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+/* fls - find last (most-significant) bit set in 4-bit integer */
|
|
|
+static inline int fls4(int num)
|
|
|
+{
|
|
|
+ if (num & 0x8)
|
|
|
+ return 4;
|
|
|
+ else if (num & 0x4)
|
|
|
+ return 3;
|
|
|
+ else if (num & 0x2)
|
|
|
+ return 2;
|
|
|
+ else if (num & 0x1)
|
|
|
+ return 1;
|
|
|
+ else
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static struct image_cfg_element *image_cfg;
|
|
|
static int cfgn;
|
|
|
static int verbose_mode;
|
|
@@ -1898,6 +1913,7 @@ static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd,
|
|
|
static void kwbimage_print_header(const void *ptr)
|
|
|
{
|
|
|
struct main_hdr_v0 *mhdr = (struct main_hdr_v0 *)ptr;
|
|
|
+ struct bin_hdr_v0 *bhdr;
|
|
|
struct opt_hdr_v1 *ohdr;
|
|
|
|
|
|
printf("Image Type: MVEBU Boot from %s Image\n",
|
|
@@ -1915,6 +1931,13 @@ static void kwbimage_print_header(const void *ptr)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ for_each_bin_hdr_v0(bhdr, mhdr) {
|
|
|
+ printf("BIN Img Size: ");
|
|
|
+ genimg_print_size(le32_to_cpu(bhdr->size));
|
|
|
+ printf("BIN Img Addr: %08x\n", le32_to_cpu(bhdr->destaddr));
|
|
|
+ printf("BIN Img Entr: %08x\n", le32_to_cpu(bhdr->execaddr));
|
|
|
+ }
|
|
|
+
|
|
|
printf("Data Size: ");
|
|
|
genimg_print_size(mhdr->blocksize - sizeof(uint32_t));
|
|
|
printf("Load Address: %08x\n", mhdr->destaddr);
|
|
@@ -1947,15 +1970,31 @@ static int kwbimage_verify_header(unsigned char *ptr, int image_size,
|
|
|
/* Only version 0 extended header has checksum */
|
|
|
if (kwbimage_version(ptr) == 0) {
|
|
|
struct main_hdr_v0 *mhdr = (struct main_hdr_v0 *)ptr;
|
|
|
+ struct ext_hdr_v0 *ext_hdr;
|
|
|
+ struct bin_hdr_v0 *bhdr;
|
|
|
|
|
|
- if (mhdr->ext) {
|
|
|
- struct ext_hdr_v0 *ext_hdr = (void *)(mhdr + 1);
|
|
|
-
|
|
|
+ for_each_ext_hdr_v0(ext_hdr, ptr) {
|
|
|
csum = image_checksum8(ext_hdr, sizeof(*ext_hdr) - 1);
|
|
|
if (csum != ext_hdr->checksum)
|
|
|
return -FDT_ERR_BADSTRUCTURE;
|
|
|
}
|
|
|
|
|
|
+ for_each_bin_hdr_v0(bhdr, ptr) {
|
|
|
+ csum = image_checksum8(bhdr, (uint8_t *)&bhdr->checksum - (uint8_t *)bhdr - 1);
|
|
|
+ if (csum != bhdr->checksum)
|
|
|
+ return -FDT_ERR_BADSTRUCTURE;
|
|
|
+
|
|
|
+ if (bhdr->offset > sizeof(*bhdr) || bhdr->offset % 4 != 0)
|
|
|
+ return -FDT_ERR_BADSTRUCTURE;
|
|
|
+
|
|
|
+ if (bhdr->offset + bhdr->size + 4 > sizeof(*bhdr) || bhdr->size % 4 != 0)
|
|
|
+ return -FDT_ERR_BADSTRUCTURE;
|
|
|
+
|
|
|
+ if (image_checksum32((uint8_t *)bhdr + bhdr->offset, bhdr->size) !=
|
|
|
+ *(uint32_t *)((uint8_t *)bhdr + bhdr->offset + bhdr->size))
|
|
|
+ return -FDT_ERR_BADSTRUCTURE;
|
|
|
+ }
|
|
|
+
|
|
|
blockid = mhdr->blockid;
|
|
|
offset = le32_to_cpu(mhdr->srcaddr);
|
|
|
size = le32_to_cpu(mhdr->blocksize);
|
|
@@ -2130,8 +2169,11 @@ static int kwbimage_generate_config(void *ptr, struct image_tool_params *params)
|
|
|
struct register_set_hdr_v1 *regset_hdr;
|
|
|
struct ext_hdr_v0_reg *regdata;
|
|
|
struct ext_hdr_v0 *ehdr0;
|
|
|
+ struct bin_hdr_v0 *bhdr0;
|
|
|
struct opt_hdr_v1 *ohdr;
|
|
|
+ int params_count;
|
|
|
unsigned offset;
|
|
|
+ int is_v0_ext;
|
|
|
int cur_idx;
|
|
|
int version;
|
|
|
FILE *f;
|
|
@@ -2145,6 +2187,14 @@ static int kwbimage_generate_config(void *ptr, struct image_tool_params *params)
|
|
|
|
|
|
version = kwbimage_version(ptr);
|
|
|
|
|
|
+ is_v0_ext = 0;
|
|
|
+ if (version == 0) {
|
|
|
+ if (mhdr0->ext > 1 || mhdr0->bin ||
|
|
|
+ ((ehdr0 = ext_hdr_v0_first(ptr)) &&
|
|
|
+ (ehdr0->match_addr || ehdr0->match_mask || ehdr0->match_value)))
|
|
|
+ is_v0_ext = 1;
|
|
|
+ }
|
|
|
+
|
|
|
if (version != 0)
|
|
|
fprintf(f, "VERSION %d\n", version);
|
|
|
|
|
@@ -2156,10 +2206,11 @@ static int kwbimage_generate_config(void *ptr, struct image_tool_params *params)
|
|
|
if (mhdr->blockid == IBR_HDR_NAND_ID)
|
|
|
fprintf(f, "NAND_PAGE_SIZE 0x%x\n", (unsigned)mhdr->nandpagesize);
|
|
|
|
|
|
- if (version != 0 && mhdr->blockid == IBR_HDR_NAND_ID) {
|
|
|
+ if (version != 0 && mhdr->blockid == IBR_HDR_NAND_ID)
|
|
|
fprintf(f, "NAND_BLKSZ 0x%x\n", (unsigned)mhdr->nandblocksize);
|
|
|
+
|
|
|
+ if (mhdr->blockid == IBR_HDR_NAND_ID && (mhdr->nandbadblklocation != 0 || is_v0_ext))
|
|
|
fprintf(f, "NAND_BADBLK_LOCATION 0x%x\n", (unsigned)mhdr->nandbadblklocation);
|
|
|
- }
|
|
|
|
|
|
if (version == 0 && mhdr->blockid == IBR_HDR_SATA_ID)
|
|
|
fprintf(f, "SATA_PIO_MODE %u\n", (unsigned)mhdr0->satapiomode);
|
|
@@ -2222,8 +2273,39 @@ static int kwbimage_generate_config(void *ptr, struct image_tool_params *params)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (version == 0 && mhdr0->ext) {
|
|
|
- ehdr0 = (struct ext_hdr_v0 *)(mhdr0 + 1);
|
|
|
+ if (version == 0 && !is_v0_ext && le16_to_cpu(mhdr0->ddrinitdelay))
|
|
|
+ fprintf(f, "DDR_INIT_DELAY %u\n", (unsigned)le16_to_cpu(mhdr0->ddrinitdelay));
|
|
|
+
|
|
|
+ for_each_ext_hdr_v0(ehdr0, ptr) {
|
|
|
+ if (is_v0_ext) {
|
|
|
+ fprintf(f, "\nMATCH ADDRESS 0x%08x MASK 0x%08x VALUE 0x%08x\n",
|
|
|
+ le32_to_cpu(ehdr0->match_addr),
|
|
|
+ le32_to_cpu(ehdr0->match_mask),
|
|
|
+ le32_to_cpu(ehdr0->match_value));
|
|
|
+ if (ehdr0->rsvd1[0] || ehdr0->rsvd1[1] || ehdr0->rsvd1[2] ||
|
|
|
+ ehdr0->rsvd1[3] || ehdr0->rsvd1[4] || ehdr0->rsvd1[5] ||
|
|
|
+ ehdr0->rsvd1[6] || ehdr0->rsvd1[7])
|
|
|
+ fprintf(f, "#DDR_RSVD1 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
|
|
|
+ ehdr0->rsvd1[0], ehdr0->rsvd1[1], ehdr0->rsvd1[2],
|
|
|
+ ehdr0->rsvd1[3], ehdr0->rsvd1[4], ehdr0->rsvd1[5],
|
|
|
+ ehdr0->rsvd1[6], ehdr0->rsvd1[7]);
|
|
|
+ if (ehdr0->rsvd2[0] || ehdr0->rsvd2[1] || ehdr0->rsvd2[2] ||
|
|
|
+ ehdr0->rsvd2[3] || ehdr0->rsvd2[4] || ehdr0->rsvd2[5] ||
|
|
|
+ ehdr0->rsvd2[6])
|
|
|
+ fprintf(f, "#DDR_RSVD2 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
|
|
|
+ ehdr0->rsvd2[0], ehdr0->rsvd2[1], ehdr0->rsvd2[2],
|
|
|
+ ehdr0->rsvd2[3], ehdr0->rsvd2[4], ehdr0->rsvd2[5],
|
|
|
+ ehdr0->rsvd2[6]);
|
|
|
+ if (ehdr0->ddrwritetype)
|
|
|
+ fprintf(f, "DDR_WRITE_TYPE %u\n", (unsigned)ehdr0->ddrwritetype);
|
|
|
+ if (ehdr0->ddrresetmpp)
|
|
|
+ fprintf(f, "DDR_RESET_MPP 0x%x\n", (unsigned)ehdr0->ddrresetmpp);
|
|
|
+ if (ehdr0->ddrclkenmpp)
|
|
|
+ fprintf(f, "DDR_CLKEN_MPP 0x%x\n", (unsigned)ehdr0->ddrclkenmpp);
|
|
|
+ if (ehdr0->ddrinitdelay)
|
|
|
+ fprintf(f, "DDR_INIT_DELAY %u\n", (unsigned)ehdr0->ddrinitdelay);
|
|
|
+ }
|
|
|
+
|
|
|
if (ehdr0->offset) {
|
|
|
for (regdata = (struct ext_hdr_v0_reg *)((uint8_t *)ptr + ehdr0->offset);
|
|
|
(uint8_t *)regdata < (uint8_t *)ptr + header_size &&
|
|
@@ -2234,10 +2316,38 @@ static int kwbimage_generate_config(void *ptr, struct image_tool_params *params)
|
|
|
if ((uint8_t *)regdata != (uint8_t *)ptr + ehdr0->offset)
|
|
|
fprintf(f, "DATA 0x0 0x0\n");
|
|
|
}
|
|
|
+
|
|
|
+ if (le32_to_cpu(ehdr0->enddelay))
|
|
|
+ fprintf(f, "DATA_DELAY %u\n", le32_to_cpu(ehdr0->enddelay));
|
|
|
+ else if (is_v0_ext)
|
|
|
+ fprintf(f, "DATA_DELAY SDRAM_SETUP\n");
|
|
|
}
|
|
|
|
|
|
- if (version == 0 && le16_to_cpu(mhdr0->ddrinitdelay))
|
|
|
- fprintf(f, "DDR_INIT_DELAY %u\n", (unsigned)le16_to_cpu(mhdr0->ddrinitdelay));
|
|
|
+ cur_idx = 1;
|
|
|
+ for_each_bin_hdr_v0(bhdr0, ptr) {
|
|
|
+ fprintf(f, "\nMATCH ADDRESS 0x%08x MASK 0x%08x VALUE 0x%08x\n",
|
|
|
+ le32_to_cpu(bhdr0->match_addr),
|
|
|
+ le32_to_cpu(bhdr0->match_mask),
|
|
|
+ le32_to_cpu(bhdr0->match_value));
|
|
|
+
|
|
|
+ fprintf(f, "BINARY binary%d.bin", cur_idx);
|
|
|
+ params_count = fls4(bhdr0->params_flags & 0xF);
|
|
|
+ for (i = 0; i < params_count; i++)
|
|
|
+ fprintf(f, " 0x%x", (bhdr0->params[i] & (1 << i)) ? bhdr0->params[i] : 0);
|
|
|
+ fprintf(f, " LOAD_ADDRESS 0x%08x", le32_to_cpu(bhdr0->destaddr));
|
|
|
+ fprintf(f, " EXEC_ADDRESS 0x%08x", le32_to_cpu(bhdr0->execaddr));
|
|
|
+ fprintf(f, "\n");
|
|
|
+
|
|
|
+ fprintf(f, "#BINARY_OFFSET 0x%x\n", le32_to_cpu(bhdr0->offset));
|
|
|
+ fprintf(f, "#BINARY_SIZE 0x%x\n", le32_to_cpu(bhdr0->size));
|
|
|
+
|
|
|
+ if (bhdr0->rsvd1)
|
|
|
+ fprintf(f, "#BINARY_RSVD1 0x%x\n", (unsigned)bhdr0->rsvd1);
|
|
|
+ if (bhdr0->rsvd2)
|
|
|
+ fprintf(f, "#BINARY_RSVD2 0x%x\n", (unsigned)bhdr0->rsvd2);
|
|
|
+
|
|
|
+ cur_idx++;
|
|
|
+ }
|
|
|
|
|
|
/* Undocumented reserved fields */
|
|
|
|
|
@@ -2245,9 +2355,6 @@ static int kwbimage_generate_config(void *ptr, struct image_tool_params *params)
|
|
|
fprintf(f, "#RSVD1 0x%x 0x%x 0x%x\n", (unsigned)mhdr0->rsvd1[0],
|
|
|
(unsigned)mhdr0->rsvd1[1], (unsigned)mhdr0->rsvd1[2]);
|
|
|
|
|
|
- if (version == 0 && mhdr0->rsvd3)
|
|
|
- fprintf(f, "#RSVD3 0x%x\n", (unsigned)mhdr0->rsvd3);
|
|
|
-
|
|
|
if (version == 0 && le16_to_cpu(mhdr0->rsvd2))
|
|
|
fprintf(f, "#RSVD2 0x%x\n", (unsigned)le16_to_cpu(mhdr0->rsvd2));
|
|
|
|
|
@@ -2266,6 +2373,7 @@ static int kwbimage_extract_subimage(void *ptr, struct image_tool_params *params
|
|
|
{
|
|
|
struct main_hdr_v1 *mhdr = (struct main_hdr_v1 *)ptr;
|
|
|
size_t header_size = kwbheader_size(ptr);
|
|
|
+ struct bin_hdr_v0 *bhdr;
|
|
|
struct opt_hdr_v1 *ohdr;
|
|
|
int idx = params->pflag;
|
|
|
int cur_idx;
|
|
@@ -2312,6 +2420,14 @@ static int kwbimage_extract_subimage(void *ptr, struct image_tool_params *params
|
|
|
|
|
|
++cur_idx;
|
|
|
}
|
|
|
+ for_each_bin_hdr_v0(bhdr, ptr) {
|
|
|
+ if (idx == cur_idx) {
|
|
|
+ image = (ulong)bhdr + bhdr->offset;
|
|
|
+ size = bhdr->size;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ ++cur_idx;
|
|
|
+ }
|
|
|
|
|
|
if (!image) {
|
|
|
fprintf(stderr, "Argument -p %d is invalid\n", idx);
|