tools: mkimage: Add support for initialization table for Zynq and ZynqMP

The Zynq/ZynqMP boot.bin file contains a region for register initialization
data. Filling in proper values in this table can reduce boot time
(e.g. about 50ms faster on QSPI boot) and also reduce the size of
the SPL binary.

The table is a simple text file with register+data on each line. Other
lines are simply skipped. The file can be passed to mkimage using the
"-R" parameter.

It is recommended to add reg init file to board folder.
For example:
CONFIG_BOOT_INIT_FILE="board/xilinx/zynqmp/xilinx_zynqmp_zcu102/reg.int

Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
master
Mike Looijmans 8 years ago committed by Michal Simek
parent 29e0cfb4f7
commit 3b6460809c
  1. 7
      arch/arm/cpu/armv8/zynqmp/Kconfig
  2. 7
      arch/arm/mach-zynq/Kconfig
  3. 4
      scripts/Makefile.spl
  4. 28
      tools/zynqimage.c
  5. 28
      tools/zynqmpimage.c

@ -41,6 +41,13 @@ config SYS_CONFIG_NAME
Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header
will be used for board configuration. will be used for board configuration.
config BOOT_INIT_FILE
string "boot.bin init register filename"
default ""
help
Add register writes to boot.bin format (max 256 pairs).
Expect a table of register-value pairs, e.g. "0x12345678 0x4321"
config ZYNQMP_USB config ZYNQMP_USB
bool "Configure ZynqMP USB" bool "Configure ZynqMP USB"

@ -44,4 +44,11 @@ config SYS_CONFIG_NAME
config SYS_MALLOC_F_LEN config SYS_MALLOC_F_LEN
default 0x600 default 0x600
config BOOT_INIT_FILE
string "boot.bin init register filename"
default ""
help
Add register writes to boot.bin format (max 256 pairs).
Expect a table of register-value pairs, e.g. "0x12345678 0x4321"
endif endif

@ -146,10 +146,10 @@ boot.bin: $(obj)/u-boot-spl.bin FORCE
$(call if_changed,mkimage) $(call if_changed,mkimage)
else else
ifdef CONFIG_ARCH_ZYNQ ifdef CONFIG_ARCH_ZYNQ
MKIMAGEFLAGS_boot.bin = -T zynqimage MKIMAGEFLAGS_boot.bin = -T zynqimage -R $(srctree)/$(CONFIG_BOOT_INIT_FILE)
endif endif
ifdef CONFIG_ARCH_ZYNQMP ifdef CONFIG_ARCH_ZYNQMP
MKIMAGEFLAGS_boot.bin = -T zynqmpimage MKIMAGEFLAGS_boot.bin = -T zynqmpimage -R $(srctree)/$(CONFIG_BOOT_INIT_FILE)
endif endif
spl/boot.bin: $(obj)/u-boot-spl.bin FORCE spl/boot.bin: $(obj)/u-boot-spl.bin FORCE

@ -222,6 +222,30 @@ static int zynqimage_check_image_types(uint8_t type)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
static void zynqimage_parse_initparams(struct zynq_header *zynqhdr,
const char *filename)
{
/* Expect a table of register-value pairs, e.g. "0x12345678 0x4321" */
FILE *fp = fopen(filename, "r");
struct zynq_reginit reginit;
unsigned int reg_count = 0;
int r;
if (!fp) {
fprintf(stderr, "Cannot open initparams file: %s\n", filename);
exit(1);
}
do {
r = fscanf(fp, "%x %x", &reginit.address, &reginit.data);
if (r == 2) {
zynqhdr->register_init[reg_count] = reginit;
++reg_count;
}
r = fscanf(fp, "%*[^\n]\n"); /* Skip to next line */
} while ((r != EOF) && (reg_count < HEADER_REGINITS));
fclose(fp);
}
static void zynqimage_set_header(void *ptr, struct stat *sbuf, int ifd, static void zynqimage_set_header(void *ptr, struct stat *sbuf, int ifd,
struct image_tool_params *params) struct image_tool_params *params)
{ {
@ -237,6 +261,10 @@ static void zynqimage_set_header(void *ptr, struct stat *sbuf, int ifd,
if (params->eflag) if (params->eflag)
zynqhdr->image_load = cpu_to_le32((uint32_t)params->ep); zynqhdr->image_load = cpu_to_le32((uint32_t)params->ep);
/* User can pass in text file with init list */
if (strlen(params->imagename2))
zynqimage_parse_initparams(zynqhdr, params->imagename2);
zynqhdr->checksum = zynqimage_checksum(zynqhdr); zynqhdr->checksum = zynqimage_checksum(zynqhdr);
} }

@ -234,6 +234,30 @@ static int zynqmpimage_check_image_types(uint8_t type)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
static void zynqmpimage_parse_initparams(struct zynqmp_header *zynqhdr,
const char *filename)
{
/* Expect a table of register-value pairs, e.g. "0x12345678 0x4321" */
FILE *fp = fopen(filename, "r");
struct zynqmp_reginit reginit;
unsigned int reg_count = 0;
int r;
if (!fp) {
fprintf(stderr, "Cannot open initparams file: %s\n", filename);
exit(1);
}
do {
r = fscanf(fp, "%x %x", &reginit.address, &reginit.data);
if (r == 2) {
zynqhdr->register_init[reg_count] = reginit;
++reg_count;
}
r = fscanf(fp, "%*[^\n]\n"); /* Skip to next line */
} while ((r != EOF) && (reg_count < HEADER_REGINITS));
fclose(fp);
}
static void zynqmpimage_set_header(void *ptr, struct stat *sbuf, int ifd, static void zynqmpimage_set_header(void *ptr, struct stat *sbuf, int ifd,
struct image_tool_params *params) struct image_tool_params *params)
{ {
@ -250,6 +274,10 @@ static void zynqmpimage_set_header(void *ptr, struct stat *sbuf, int ifd,
if (params->eflag) if (params->eflag)
zynqhdr->image_load = cpu_to_le32((uint32_t)params->ep); zynqhdr->image_load = cpu_to_le32((uint32_t)params->ep);
/* User can pass in text file with init list */
if (strlen(params->imagename2))
zynqmpimage_parse_initparams(zynqhdr, params->imagename2);
zynqhdr->checksum = zynqmpimage_checksum(zynqhdr); zynqhdr->checksum = zynqmpimage_checksum(zynqhdr);
} }

Loading…
Cancel
Save