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