diff mbox

[U-Boot] tools: mkimage: Add support for initialization table for Zynq and ZynqMP

Message ID e716cc4f25be67540c98e24a27d71fe4a8a8b3c7.1474536348.git.michal.simek@xilinx.com
State Accepted
Delegated to: Michal Simek
Headers show

Commit Message

Michal Simek Sept. 22, 2016, 9:25 a.m. UTC
From: Mike Looijmans <mike.looijmans@topic.nl>

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>
---

 arch/arm/cpu/armv8/zynqmp/Kconfig |  7 +++++++
 arch/arm/mach-zynq/Kconfig        |  7 +++++++
 scripts/Makefile.spl              |  4 ++--
 tools/zynqimage.c                 | 28 ++++++++++++++++++++++++++++
 tools/zynqmpimage.c               | 28 ++++++++++++++++++++++++++++
 5 files changed, 72 insertions(+), 2 deletions(-)

Comments

Mike Looijmans Sept. 26, 2016, 6:12 a.m. UTC | #1
On 22-09-16 11:25, Michal Simek wrote:
> From: Mike Looijmans <mike.looijmans@topic.nl>
>
> 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>
> ---
>
>   arch/arm/cpu/armv8/zynqmp/Kconfig |  7 +++++++
>   arch/arm/mach-zynq/Kconfig        |  7 +++++++
>   scripts/Makefile.spl              |  4 ++--
>   tools/zynqimage.c                 | 28 ++++++++++++++++++++++++++++
>   tools/zynqmpimage.c               | 28 ++++++++++++++++++++++++++++
>   5 files changed, 72 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/cpu/armv8/zynqmp/Kconfig b/arch/arm/cpu/armv8/zynqmp/Kconfig
> index 1eedb39aa5a8..a3baae4f740c 100644
> --- a/arch/arm/cpu/armv8/zynqmp/Kconfig
> +++ b/arch/arm/cpu/armv8/zynqmp/Kconfig
> @@ -41,6 +41,13 @@ config SYS_CONFIG_NAME
>   	  Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header
>   	  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
>   	bool "Configure ZynqMP USB"
>
> diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig
> index a1175eea6ebb..44e16af863d7 100644
> --- a/arch/arm/mach-zynq/Kconfig
> +++ b/arch/arm/mach-zynq/Kconfig
> @@ -44,4 +44,11 @@ config SYS_CONFIG_NAME
>   config SYS_MALLOC_F_LEN
>   	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
> diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
> index 4994fa887ba3..b12b0c27dfe9 100644
> --- a/scripts/Makefile.spl
> +++ b/scripts/Makefile.spl
> @@ -142,10 +142,10 @@ boot.bin: $(obj)/u-boot-spl.bin FORCE
>   	$(call if_changed,mkimage)
>   else
>   ifdef CONFIG_ARCH_ZYNQ
> -MKIMAGEFLAGS_boot.bin = -T zynqimage
> +MKIMAGEFLAGS_boot.bin = -T zynqimage -R $(CONFIG_BOOT_INIT_FILE)

This should be:

MKIMAGEFLAGS_boot.bin = -T zynqimage -R $(srctree)/$(CONFIG_BOOT_INIT_FILE)

Without the "$(srctree)", out-of-tree builds will fail.

>   endif
>   ifdef CONFIG_ARCH_ZYNQMP
> -MKIMAGEFLAGS_boot.bin = -T zynqmpimage
> +MKIMAGEFLAGS_boot.bin = -T zynqmpimage -R $(CONFIG_BOOT_INIT_FILE)

Same here:
MKIMAGEFLAGS_boot.bin = -T zynqmpimage -R $(srctree)/$(CONFIG_BOOT_INIT_FILE)

>   endif
>
>   spl/boot.bin: $(obj)/u-boot-spl.bin FORCE
> diff --git a/tools/zynqimage.c b/tools/zynqimage.c
> index c43bd5d48820..43876e7a3024 100644
> --- a/tools/zynqimage.c
> +++ b/tools/zynqimage.c
> @@ -222,6 +222,30 @@ static int zynqimage_check_image_types(uint8_t type)
>   	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,
>   		struct image_tool_params *params)
>   {
> @@ -237,6 +261,10 @@ static void zynqimage_set_header(void *ptr, struct stat *sbuf, int ifd,
>   	if (params->eflag)
>   		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);
>   }
>
> diff --git a/tools/zynqmpimage.c b/tools/zynqmpimage.c
> index 3f28eb401d9b..d08144c2bdfd 100644
> --- a/tools/zynqmpimage.c
> +++ b/tools/zynqmpimage.c
> @@ -234,6 +234,30 @@ static int zynqmpimage_check_image_types(uint8_t type)
>   	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,
>   		struct image_tool_params *params)
>   {
> @@ -250,6 +274,10 @@ static void zynqmpimage_set_header(void *ptr, struct stat *sbuf, int ifd,
>   	if (params->eflag)
>   		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);
>   }
>
>



Kind regards,

Mike Looijmans
System Expert

TOPIC Products
Materiaalweg 4, NL-5681 RJ Best
Postbus 440, NL-5680 AK Best
Telefoon: +31 (0) 499 33 69 79
E-mail: mike.looijmans@topicproducts.com
Website: www.topicproducts.com

Please consider the environment before printing this e-mail

Topic zoekt gedreven (embedded) software specialisten!
http://topic.nl/vacancy/topic-zoekt-technische-software-engineers/
Michal Simek Sept. 26, 2016, 6:17 a.m. UTC | #2
On 26.9.2016 08:12, Mike Looijmans wrote:
> On 22-09-16 11:25, Michal Simek wrote:
>> From: Mike Looijmans <mike.looijmans@topic.nl>
>>
>> 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>
>> ---
>>
>>   arch/arm/cpu/armv8/zynqmp/Kconfig |  7 +++++++
>>   arch/arm/mach-zynq/Kconfig        |  7 +++++++
>>   scripts/Makefile.spl              |  4 ++--
>>   tools/zynqimage.c                 | 28 ++++++++++++++++++++++++++++
>>   tools/zynqmpimage.c               | 28 ++++++++++++++++++++++++++++
>>   5 files changed, 72 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/cpu/armv8/zynqmp/Kconfig
>> b/arch/arm/cpu/armv8/zynqmp/Kconfig
>> index 1eedb39aa5a8..a3baae4f740c 100644
>> --- a/arch/arm/cpu/armv8/zynqmp/Kconfig
>> +++ b/arch/arm/cpu/armv8/zynqmp/Kconfig
>> @@ -41,6 +41,13 @@ config SYS_CONFIG_NAME
>>         Based on this option
>> include/configs/<CONFIG_SYS_CONFIG_NAME>.h header
>>         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
>>       bool "Configure ZynqMP USB"
>>
>> diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig
>> index a1175eea6ebb..44e16af863d7 100644
>> --- a/arch/arm/mach-zynq/Kconfig
>> +++ b/arch/arm/mach-zynq/Kconfig
>> @@ -44,4 +44,11 @@ config SYS_CONFIG_NAME
>>   config SYS_MALLOC_F_LEN
>>       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
>> diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
>> index 4994fa887ba3..b12b0c27dfe9 100644
>> --- a/scripts/Makefile.spl
>> +++ b/scripts/Makefile.spl
>> @@ -142,10 +142,10 @@ boot.bin: $(obj)/u-boot-spl.bin FORCE
>>       $(call if_changed,mkimage)
>>   else
>>   ifdef CONFIG_ARCH_ZYNQ
>> -MKIMAGEFLAGS_boot.bin = -T zynqimage
>> +MKIMAGEFLAGS_boot.bin = -T zynqimage -R $(CONFIG_BOOT_INIT_FILE)
> 
> This should be:
> 
> MKIMAGEFLAGS_boot.bin = -T zynqimage -R $(srctree)/$(CONFIG_BOOT_INIT_FILE)
> 
> Without the "$(srctree)", out-of-tree builds will fail.
> 
>>   endif
>>   ifdef CONFIG_ARCH_ZYNQMP
>> -MKIMAGEFLAGS_boot.bin = -T zynqmpimage
>> +MKIMAGEFLAGS_boot.bin = -T zynqmpimage -R $(CONFIG_BOOT_INIT_FILE)
> 
> Same here:
> MKIMAGEFLAGS_boot.bin = -T zynqmpimage -R
> $(srctree)/$(CONFIG_BOOT_INIT_FILE)

Good. Will be fixed in v2.

Thanks,
Michal
diff mbox

Patch

diff --git a/arch/arm/cpu/armv8/zynqmp/Kconfig b/arch/arm/cpu/armv8/zynqmp/Kconfig
index 1eedb39aa5a8..a3baae4f740c 100644
--- a/arch/arm/cpu/armv8/zynqmp/Kconfig
+++ b/arch/arm/cpu/armv8/zynqmp/Kconfig
@@ -41,6 +41,13 @@  config SYS_CONFIG_NAME
 	  Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header
 	  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
 	bool "Configure ZynqMP USB"
 
diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig
index a1175eea6ebb..44e16af863d7 100644
--- a/arch/arm/mach-zynq/Kconfig
+++ b/arch/arm/mach-zynq/Kconfig
@@ -44,4 +44,11 @@  config SYS_CONFIG_NAME
 config SYS_MALLOC_F_LEN
 	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
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index 4994fa887ba3..b12b0c27dfe9 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -142,10 +142,10 @@  boot.bin: $(obj)/u-boot-spl.bin FORCE
 	$(call if_changed,mkimage)
 else
 ifdef CONFIG_ARCH_ZYNQ
-MKIMAGEFLAGS_boot.bin = -T zynqimage
+MKIMAGEFLAGS_boot.bin = -T zynqimage -R $(CONFIG_BOOT_INIT_FILE)
 endif
 ifdef CONFIG_ARCH_ZYNQMP
-MKIMAGEFLAGS_boot.bin = -T zynqmpimage
+MKIMAGEFLAGS_boot.bin = -T zynqmpimage -R $(CONFIG_BOOT_INIT_FILE)
 endif
 
 spl/boot.bin: $(obj)/u-boot-spl.bin FORCE
diff --git a/tools/zynqimage.c b/tools/zynqimage.c
index c43bd5d48820..43876e7a3024 100644
--- a/tools/zynqimage.c
+++ b/tools/zynqimage.c
@@ -222,6 +222,30 @@  static int zynqimage_check_image_types(uint8_t type)
 	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,
 		struct image_tool_params *params)
 {
@@ -237,6 +261,10 @@  static void zynqimage_set_header(void *ptr, struct stat *sbuf, int ifd,
 	if (params->eflag)
 		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);
 }
 
diff --git a/tools/zynqmpimage.c b/tools/zynqmpimage.c
index 3f28eb401d9b..d08144c2bdfd 100644
--- a/tools/zynqmpimage.c
+++ b/tools/zynqmpimage.c
@@ -234,6 +234,30 @@  static int zynqmpimage_check_image_types(uint8_t type)
 	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,
 		struct image_tool_params *params)
 {
@@ -250,6 +274,10 @@  static void zynqmpimage_set_header(void *ptr, struct stat *sbuf, int ifd,
 	if (params->eflag)
 		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);
 }