xref: /openbmc/u-boot/tools/lpc32xximage.c (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
239f520bbSAlbert ARIBAUD \(3ADEV\) /*
339f520bbSAlbert ARIBAUD \(3ADEV\)  * Image manipulator for LPC32XX SoCs
439f520bbSAlbert ARIBAUD \(3ADEV\)  *
539f520bbSAlbert ARIBAUD \(3ADEV\)  * (C) Copyright 2015  DENX Software Engineering GmbH
639f520bbSAlbert ARIBAUD \(3ADEV\)  * Written-by: Albert ARIBAUD <albert.aribaud@3adev.fr>
739f520bbSAlbert ARIBAUD \(3ADEV\)  *
839f520bbSAlbert ARIBAUD \(3ADEV\)  * Derived from omapimage.c:
939f520bbSAlbert ARIBAUD \(3ADEV\)  *
1039f520bbSAlbert ARIBAUD \(3ADEV\)  * (C) Copyright 2010
1139f520bbSAlbert ARIBAUD \(3ADEV\)  * Linaro LTD, www.linaro.org
1239f520bbSAlbert ARIBAUD \(3ADEV\)  * Author: John Rigby <john.rigby@linaro.org>
1339f520bbSAlbert ARIBAUD \(3ADEV\)  * Based on TI's signGP.c
1439f520bbSAlbert ARIBAUD \(3ADEV\)  *
1539f520bbSAlbert ARIBAUD \(3ADEV\)  * (C) Copyright 2009
1639f520bbSAlbert ARIBAUD \(3ADEV\)  * Stefano Babic, DENX Software Engineering, sbabic@denx.de.
1739f520bbSAlbert ARIBAUD \(3ADEV\)  *
1839f520bbSAlbert ARIBAUD \(3ADEV\)  * (C) Copyright 2008
1939f520bbSAlbert ARIBAUD \(3ADEV\)  * Marvell Semiconductor <www.marvell.com>
2039f520bbSAlbert ARIBAUD \(3ADEV\)  * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
2139f520bbSAlbert ARIBAUD \(3ADEV\)  */
2239f520bbSAlbert ARIBAUD \(3ADEV\) 
2339f520bbSAlbert ARIBAUD \(3ADEV\) #include "imagetool.h"
2439f520bbSAlbert ARIBAUD \(3ADEV\) #include <compiler.h>
2539f520bbSAlbert ARIBAUD \(3ADEV\) #include <image.h>
2639f520bbSAlbert ARIBAUD \(3ADEV\) 
2739f520bbSAlbert ARIBAUD \(3ADEV\) /*
2839f520bbSAlbert ARIBAUD \(3ADEV\)  * NAND page 0 boot header
2939f520bbSAlbert ARIBAUD \(3ADEV\)  */
3039f520bbSAlbert ARIBAUD \(3ADEV\) 
3139f520bbSAlbert ARIBAUD \(3ADEV\) struct nand_page_0_boot_header {
3239f520bbSAlbert ARIBAUD \(3ADEV\) 	uint32_t data[129];
3339f520bbSAlbert ARIBAUD \(3ADEV\) 	uint32_t pad[383];
3439f520bbSAlbert ARIBAUD \(3ADEV\) };
3539f520bbSAlbert ARIBAUD \(3ADEV\) 
3639f520bbSAlbert ARIBAUD \(3ADEV\) /*
3739f520bbSAlbert ARIBAUD \(3ADEV\)  * Default ICC (interface configuration data [sic]) if none specified
3839f520bbSAlbert ARIBAUD \(3ADEV\)  * in board config
3939f520bbSAlbert ARIBAUD \(3ADEV\)  */
4039f520bbSAlbert ARIBAUD \(3ADEV\) 
4139f520bbSAlbert ARIBAUD \(3ADEV\) #ifndef LPC32XX_BOOT_ICR
4239f520bbSAlbert ARIBAUD \(3ADEV\) #define LPC32XX_BOOT_ICR 0x00000096
4339f520bbSAlbert ARIBAUD \(3ADEV\) #endif
4439f520bbSAlbert ARIBAUD \(3ADEV\) 
4539f520bbSAlbert ARIBAUD \(3ADEV\) /*
4639f520bbSAlbert ARIBAUD \(3ADEV\)  * Default boot NAND page size if none specified in board config
4739f520bbSAlbert ARIBAUD \(3ADEV\)  */
4839f520bbSAlbert ARIBAUD \(3ADEV\) 
4939f520bbSAlbert ARIBAUD \(3ADEV\) #ifndef LPC32XX_BOOT_NAND_PAGESIZE
5039f520bbSAlbert ARIBAUD \(3ADEV\) #define LPC32XX_BOOT_NAND_PAGESIZE 2048
5139f520bbSAlbert ARIBAUD \(3ADEV\) #endif
5239f520bbSAlbert ARIBAUD \(3ADEV\) 
5339f520bbSAlbert ARIBAUD \(3ADEV\) /*
5439f520bbSAlbert ARIBAUD \(3ADEV\)  * Default boot NAND pages per sector if none specified in board config
5539f520bbSAlbert ARIBAUD \(3ADEV\)  */
5639f520bbSAlbert ARIBAUD \(3ADEV\) 
5739f520bbSAlbert ARIBAUD \(3ADEV\) #ifndef LPC32XX_BOOT_NAND_PAGES_PER_SECTOR
5839f520bbSAlbert ARIBAUD \(3ADEV\) #define LPC32XX_BOOT_NAND_PAGES_PER_SECTOR 64
5939f520bbSAlbert ARIBAUD \(3ADEV\) #endif
6039f520bbSAlbert ARIBAUD \(3ADEV\) 
6139f520bbSAlbert ARIBAUD \(3ADEV\) /*
6239f520bbSAlbert ARIBAUD \(3ADEV\)  * Maximum size for boot code is 56K unless defined in board config
6339f520bbSAlbert ARIBAUD \(3ADEV\)  */
6439f520bbSAlbert ARIBAUD \(3ADEV\) 
6539f520bbSAlbert ARIBAUD \(3ADEV\) #ifndef LPC32XX_BOOT_CODESIZE
6639f520bbSAlbert ARIBAUD \(3ADEV\) #define LPC32XX_BOOT_CODESIZE (56*1024)
6739f520bbSAlbert ARIBAUD \(3ADEV\) #endif
6839f520bbSAlbert ARIBAUD \(3ADEV\) 
6939f520bbSAlbert ARIBAUD \(3ADEV\) /* signature byte for a readable block */
7039f520bbSAlbert ARIBAUD \(3ADEV\) 
7139f520bbSAlbert ARIBAUD \(3ADEV\) #define LPC32XX_BOOT_BLOCK_OK 0xaa
7239f520bbSAlbert ARIBAUD \(3ADEV\) 
7339f520bbSAlbert ARIBAUD \(3ADEV\) static struct nand_page_0_boot_header lpc32xximage_header;
7439f520bbSAlbert ARIBAUD \(3ADEV\) 
lpc32xximage_check_image_types(uint8_t type)7539f520bbSAlbert ARIBAUD \(3ADEV\) static int lpc32xximage_check_image_types(uint8_t type)
7639f520bbSAlbert ARIBAUD \(3ADEV\) {
7739f520bbSAlbert ARIBAUD \(3ADEV\) 	if (type == IH_TYPE_LPC32XXIMAGE)
7839f520bbSAlbert ARIBAUD \(3ADEV\) 		return EXIT_SUCCESS;
7939f520bbSAlbert ARIBAUD \(3ADEV\) 	return EXIT_FAILURE;
8039f520bbSAlbert ARIBAUD \(3ADEV\) }
8139f520bbSAlbert ARIBAUD \(3ADEV\) 
lpc32xximage_verify_header(unsigned char * ptr,int image_size,struct image_tool_params * params)8239f520bbSAlbert ARIBAUD \(3ADEV\) static int lpc32xximage_verify_header(unsigned char *ptr, int image_size,
8339f520bbSAlbert ARIBAUD \(3ADEV\) 			struct image_tool_params *params)
8439f520bbSAlbert ARIBAUD \(3ADEV\) {
8539f520bbSAlbert ARIBAUD \(3ADEV\) 	struct nand_page_0_boot_header *hdr =
8639f520bbSAlbert ARIBAUD \(3ADEV\) 		(struct nand_page_0_boot_header *)ptr;
8739f520bbSAlbert ARIBAUD \(3ADEV\) 
8839f520bbSAlbert ARIBAUD \(3ADEV\) 	/* turn image size from bytes to NAND pages, page 0 included */
8939f520bbSAlbert ARIBAUD \(3ADEV\) 	int image_size_in_pages = ((image_size - 1)
9039f520bbSAlbert ARIBAUD \(3ADEV\) 				  / LPC32XX_BOOT_NAND_PAGESIZE);
9139f520bbSAlbert ARIBAUD \(3ADEV\) 
9239f520bbSAlbert ARIBAUD \(3ADEV\) 	if (hdr->data[0] != (0xff & LPC32XX_BOOT_ICR))
9339f520bbSAlbert ARIBAUD \(3ADEV\) 		return -1;
9439f520bbSAlbert ARIBAUD \(3ADEV\) 	if (hdr->data[1] != (0xff & ~LPC32XX_BOOT_ICR))
9539f520bbSAlbert ARIBAUD \(3ADEV\) 		return -1;
9639f520bbSAlbert ARIBAUD \(3ADEV\) 	if (hdr->data[2] != (0xff & LPC32XX_BOOT_ICR))
9739f520bbSAlbert ARIBAUD \(3ADEV\) 		return -1;
9839f520bbSAlbert ARIBAUD \(3ADEV\) 	if (hdr->data[3] != (0xff & ~LPC32XX_BOOT_ICR))
9939f520bbSAlbert ARIBAUD \(3ADEV\) 		return -1;
10039f520bbSAlbert ARIBAUD \(3ADEV\) 	if (hdr->data[4] != (0xff & image_size_in_pages))
10139f520bbSAlbert ARIBAUD \(3ADEV\) 		return -1;
10239f520bbSAlbert ARIBAUD \(3ADEV\) 	if (hdr->data[5] != (0xff & ~image_size_in_pages))
10339f520bbSAlbert ARIBAUD \(3ADEV\) 		return -1;
10439f520bbSAlbert ARIBAUD \(3ADEV\) 	if (hdr->data[6] != (0xff & image_size_in_pages))
10539f520bbSAlbert ARIBAUD \(3ADEV\) 		return -1;
10639f520bbSAlbert ARIBAUD \(3ADEV\) 	if (hdr->data[7] != (0xff & ~image_size_in_pages))
10739f520bbSAlbert ARIBAUD \(3ADEV\) 		return -1;
10839f520bbSAlbert ARIBAUD \(3ADEV\) 	if (hdr->data[8] != (0xff & image_size_in_pages))
10939f520bbSAlbert ARIBAUD \(3ADEV\) 		return -1;
11039f520bbSAlbert ARIBAUD \(3ADEV\) 	if (hdr->data[9] != (0xff & ~image_size_in_pages))
11139f520bbSAlbert ARIBAUD \(3ADEV\) 		return -1;
11239f520bbSAlbert ARIBAUD \(3ADEV\) 	if (hdr->data[10] != (0xff & image_size_in_pages))
11339f520bbSAlbert ARIBAUD \(3ADEV\) 		return -1;
11439f520bbSAlbert ARIBAUD \(3ADEV\) 	if (hdr->data[11] != (0xff & ~image_size_in_pages))
11539f520bbSAlbert ARIBAUD \(3ADEV\) 		return -1;
11639f520bbSAlbert ARIBAUD \(3ADEV\) 	if (hdr->data[12] != LPC32XX_BOOT_BLOCK_OK)
11739f520bbSAlbert ARIBAUD \(3ADEV\) 		return -1;
11839f520bbSAlbert ARIBAUD \(3ADEV\) 	if (hdr->data[128] != LPC32XX_BOOT_BLOCK_OK)
11939f520bbSAlbert ARIBAUD \(3ADEV\) 		return -1;
12039f520bbSAlbert ARIBAUD \(3ADEV\) 	return 0;
12139f520bbSAlbert ARIBAUD \(3ADEV\) }
12239f520bbSAlbert ARIBAUD \(3ADEV\) 
print_hdr_byte(struct nand_page_0_boot_header * hdr,int ofs)12339f520bbSAlbert ARIBAUD \(3ADEV\) static void print_hdr_byte(struct nand_page_0_boot_header *hdr, int ofs)
12439f520bbSAlbert ARIBAUD \(3ADEV\) {
12539f520bbSAlbert ARIBAUD \(3ADEV\) 	printf("header[%d] = %02x\n", ofs, hdr->data[ofs]);
12639f520bbSAlbert ARIBAUD \(3ADEV\) }
12739f520bbSAlbert ARIBAUD \(3ADEV\) 
lpc32xximage_print_header(const void * ptr)12839f520bbSAlbert ARIBAUD \(3ADEV\) static void lpc32xximage_print_header(const void *ptr)
12939f520bbSAlbert ARIBAUD \(3ADEV\) {
13039f520bbSAlbert ARIBAUD \(3ADEV\) 	struct nand_page_0_boot_header *hdr =
13139f520bbSAlbert ARIBAUD \(3ADEV\) 		(struct nand_page_0_boot_header *)ptr;
13239f520bbSAlbert ARIBAUD \(3ADEV\) 	int ofs;
13339f520bbSAlbert ARIBAUD \(3ADEV\) 
13439f520bbSAlbert ARIBAUD \(3ADEV\) 	for (ofs = 0; ofs <= 12; ofs++)
13539f520bbSAlbert ARIBAUD \(3ADEV\) 		print_hdr_byte(hdr, ofs);
13639f520bbSAlbert ARIBAUD \(3ADEV\) 	print_hdr_byte(hdr, 128);
13739f520bbSAlbert ARIBAUD \(3ADEV\) }
13839f520bbSAlbert ARIBAUD \(3ADEV\) 
lpc32xximage_set_header(void * ptr,struct stat * sbuf,int ifd,struct image_tool_params * params)13939f520bbSAlbert ARIBAUD \(3ADEV\) static void lpc32xximage_set_header(void *ptr, struct stat *sbuf, int ifd,
14039f520bbSAlbert ARIBAUD \(3ADEV\) 				struct image_tool_params *params)
14139f520bbSAlbert ARIBAUD \(3ADEV\) {
14239f520bbSAlbert ARIBAUD \(3ADEV\) 	struct nand_page_0_boot_header *hdr =
14339f520bbSAlbert ARIBAUD \(3ADEV\) 		(struct nand_page_0_boot_header *)ptr;
14439f520bbSAlbert ARIBAUD \(3ADEV\) 
14539f520bbSAlbert ARIBAUD \(3ADEV\) 	/* turn image size from bytes to NAND pages, page 0 included */
14639f520bbSAlbert ARIBAUD \(3ADEV\) 	int image_size_in_pages = ((sbuf->st_size
14739f520bbSAlbert ARIBAUD \(3ADEV\) 				  + LPC32XX_BOOT_NAND_PAGESIZE - 1)
14839f520bbSAlbert ARIBAUD \(3ADEV\) 				  / LPC32XX_BOOT_NAND_PAGESIZE);
14939f520bbSAlbert ARIBAUD \(3ADEV\) 
15039f520bbSAlbert ARIBAUD \(3ADEV\) 	/* fill header -- default byte value is 0x00, not 0xFF */
15139f520bbSAlbert ARIBAUD \(3ADEV\) 	memset((void *)hdr, 0, sizeof(*hdr));
15239f520bbSAlbert ARIBAUD \(3ADEV\) 	hdr->data[0] = (hdr->data[2] = 0xff & LPC32XX_BOOT_ICR);
15339f520bbSAlbert ARIBAUD \(3ADEV\) 	hdr->data[1] = (hdr->data[3] = 0xff & ~LPC32XX_BOOT_ICR);
15439f520bbSAlbert ARIBAUD \(3ADEV\) 	hdr->data[4] = (hdr->data[6] = (hdr->data[8]
15539f520bbSAlbert ARIBAUD \(3ADEV\) 		       = (hdr->data[10] = 0xff & image_size_in_pages)));
15639f520bbSAlbert ARIBAUD \(3ADEV\) 	hdr->data[5] = (hdr->data[7] = (hdr->data[9]
15739f520bbSAlbert ARIBAUD \(3ADEV\) 		       = (hdr->data[11] = 0xff & ~image_size_in_pages)));
15839f520bbSAlbert ARIBAUD \(3ADEV\) 	hdr->data[12] = (hdr->data[128] = LPC32XX_BOOT_BLOCK_OK);
15939f520bbSAlbert ARIBAUD \(3ADEV\) }
16039f520bbSAlbert ARIBAUD \(3ADEV\) 
16139f520bbSAlbert ARIBAUD \(3ADEV\) /*
16239f520bbSAlbert ARIBAUD \(3ADEV\)  * lpc32xximage parameters
16339f520bbSAlbert ARIBAUD \(3ADEV\)  */
16439f520bbSAlbert ARIBAUD \(3ADEV\) U_BOOT_IMAGE_TYPE(
16539f520bbSAlbert ARIBAUD \(3ADEV\) 	lpc32xximage,
16639f520bbSAlbert ARIBAUD \(3ADEV\) 	"LPC32XX Boot Image",
16739f520bbSAlbert ARIBAUD \(3ADEV\) 	sizeof(lpc32xximage_header),
16839f520bbSAlbert ARIBAUD \(3ADEV\) 	(void *)&lpc32xximage_header,
16939f520bbSAlbert ARIBAUD \(3ADEV\) 	NULL,
17039f520bbSAlbert ARIBAUD \(3ADEV\) 	lpc32xximage_verify_header,
17139f520bbSAlbert ARIBAUD \(3ADEV\) 	lpc32xximage_print_header,
17239f520bbSAlbert ARIBAUD \(3ADEV\) 	lpc32xximage_set_header,
17339f520bbSAlbert ARIBAUD \(3ADEV\) 	NULL,
17439f520bbSAlbert ARIBAUD \(3ADEV\) 	lpc32xximage_check_image_types,
17539f520bbSAlbert ARIBAUD \(3ADEV\) 	NULL,
17639f520bbSAlbert ARIBAUD \(3ADEV\) 	NULL
17739f520bbSAlbert ARIBAUD \(3ADEV\) );
178