xref: /openbmc/u-boot/tools/omapimage.c (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
23decb14aSJohn Rigby /*
33decb14aSJohn Rigby  * (C) Copyright 2010
43decb14aSJohn Rigby  * Linaro LTD, www.linaro.org
53decb14aSJohn Rigby  * Author: John Rigby <john.rigby@linaro.org>
63decb14aSJohn Rigby  * Based on TI's signGP.c
73decb14aSJohn Rigby  *
83decb14aSJohn Rigby  * (C) Copyright 2009
93decb14aSJohn Rigby  * Stefano Babic, DENX Software Engineering, sbabic@denx.de.
103decb14aSJohn Rigby  *
113decb14aSJohn Rigby  * (C) Copyright 2008
123decb14aSJohn Rigby  * Marvell Semiconductor <www.marvell.com>
133decb14aSJohn Rigby  * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
143decb14aSJohn Rigby  */
153decb14aSJohn Rigby 
16f86ed6a8SGuilherme Maciel Ferreira #include "imagetool.h"
17bf411ea9SKaricheri, Muralidharan #include <compiler.h>
183decb14aSJohn Rigby #include <image.h>
19bf411ea9SKaricheri, Muralidharan #include "gpheader.h"
203decb14aSJohn Rigby #include "omapimage.h"
213decb14aSJohn Rigby 
22c8e1ca3eSPhilipp Tomsich #define DIV_ROUND_UP(n, d)     (((n) + (d) - 1) / (d))
23c8e1ca3eSPhilipp Tomsich 
243decb14aSJohn Rigby /* Header size is CH header rounded up to 512 bytes plus GP header */
253decb14aSJohn Rigby #define OMAP_CH_HDR_SIZE 512
26bf411ea9SKaricheri, Muralidharan #define OMAP_FILE_HDR_SIZE (OMAP_CH_HDR_SIZE + GPIMAGE_HDR_SIZE)
273decb14aSJohn Rigby 
2879b9ebb7STom Rini static int do_swap32 = 0;
2979b9ebb7STom Rini 
303decb14aSJohn Rigby static uint8_t omapimage_header[OMAP_FILE_HDR_SIZE];
313decb14aSJohn Rigby 
omapimage_check_image_types(uint8_t type)323decb14aSJohn Rigby static int omapimage_check_image_types(uint8_t type)
333decb14aSJohn Rigby {
343decb14aSJohn Rigby 	if (type == IH_TYPE_OMAPIMAGE)
353decb14aSJohn Rigby 		return EXIT_SUCCESS;
363decb14aSJohn Rigby 	return EXIT_FAILURE;
373decb14aSJohn Rigby }
383decb14aSJohn Rigby 
omapimage_verify_header(unsigned char * ptr,int image_size,struct image_tool_params * params)393decb14aSJohn Rigby static int omapimage_verify_header(unsigned char *ptr, int image_size,
40f86ed6a8SGuilherme Maciel Ferreira 			struct image_tool_params *params)
413decb14aSJohn Rigby {
423decb14aSJohn Rigby 	struct ch_toc *toc = (struct ch_toc *)ptr;
433decb14aSJohn Rigby 	struct gp_header *gph = (struct gp_header *)(ptr+OMAP_CH_HDR_SIZE);
44bf411ea9SKaricheri, Muralidharan 	uint32_t offset, size;
453decb14aSJohn Rigby 
463decb14aSJohn Rigby 	while (toc->section_offset != 0xffffffff
473decb14aSJohn Rigby 			&& toc->section_size != 0xffffffff) {
4879b9ebb7STom Rini 		if (do_swap32) {
49bf411ea9SKaricheri, Muralidharan 			offset = cpu_to_be32(toc->section_offset);
50bf411ea9SKaricheri, Muralidharan 			size = cpu_to_be32(toc->section_size);
5179b9ebb7STom Rini 		} else {
523decb14aSJohn Rigby 			offset = toc->section_offset;
533decb14aSJohn Rigby 			size = toc->section_size;
5479b9ebb7STom Rini 		}
553decb14aSJohn Rigby 		if (!offset || !size)
563decb14aSJohn Rigby 			return -1;
573decb14aSJohn Rigby 		if (offset >= OMAP_CH_HDR_SIZE ||
583decb14aSJohn Rigby 		    offset+size >= OMAP_CH_HDR_SIZE)
593decb14aSJohn Rigby 			return -1;
603decb14aSJohn Rigby 		toc++;
613decb14aSJohn Rigby 	}
6279b9ebb7STom Rini 
63bf411ea9SKaricheri, Muralidharan 	return gph_verify_header(gph, do_swap32);
643decb14aSJohn Rigby }
653decb14aSJohn Rigby 
omapimage_print_section(struct ch_settings * chs)663decb14aSJohn Rigby static void omapimage_print_section(struct ch_settings *chs)
673decb14aSJohn Rigby {
683decb14aSJohn Rigby 	const char *section_name;
693decb14aSJohn Rigby 
703decb14aSJohn Rigby 	if (chs->section_key)
713decb14aSJohn Rigby 		section_name = "CHSETTINGS";
723decb14aSJohn Rigby 	else
733decb14aSJohn Rigby 		section_name = "UNKNOWNKEY";
743decb14aSJohn Rigby 
753decb14aSJohn Rigby 	printf("%s (%x) "
763decb14aSJohn Rigby 		"valid:%x "
773decb14aSJohn Rigby 		"version:%x "
783decb14aSJohn Rigby 		"reserved:%x "
793decb14aSJohn Rigby 		"flags:%x\n",
803decb14aSJohn Rigby 		section_name,
813decb14aSJohn Rigby 		chs->section_key,
823decb14aSJohn Rigby 		chs->valid,
833decb14aSJohn Rigby 		chs->version,
843decb14aSJohn Rigby 		chs->reserved,
853decb14aSJohn Rigby 		chs->flags);
863decb14aSJohn Rigby }
873decb14aSJohn Rigby 
omapimage_print_header(const void * ptr)883decb14aSJohn Rigby static void omapimage_print_header(const void *ptr)
893decb14aSJohn Rigby {
903decb14aSJohn Rigby 	const struct ch_toc *toc = (struct ch_toc *)ptr;
913decb14aSJohn Rigby 	const struct gp_header *gph =
923decb14aSJohn Rigby 			(struct gp_header *)(ptr+OMAP_CH_HDR_SIZE);
93bf411ea9SKaricheri, Muralidharan 	uint32_t offset, size;
943decb14aSJohn Rigby 
953decb14aSJohn Rigby 	while (toc->section_offset != 0xffffffff
963decb14aSJohn Rigby 			&& toc->section_size != 0xffffffff) {
9779b9ebb7STom Rini 		if (do_swap32) {
98bf411ea9SKaricheri, Muralidharan 			offset = cpu_to_be32(toc->section_offset);
99bf411ea9SKaricheri, Muralidharan 			size = cpu_to_be32(toc->section_size);
10079b9ebb7STom Rini 		} else {
1013decb14aSJohn Rigby 			offset = toc->section_offset;
1023decb14aSJohn Rigby 			size = toc->section_size;
10379b9ebb7STom Rini 		}
1043decb14aSJohn Rigby 
1053decb14aSJohn Rigby 		if (offset >= OMAP_CH_HDR_SIZE ||
1063decb14aSJohn Rigby 		    offset+size >= OMAP_CH_HDR_SIZE)
1073decb14aSJohn Rigby 			exit(EXIT_FAILURE);
1083decb14aSJohn Rigby 
1093decb14aSJohn Rigby 		printf("Section %s offset %x length %x\n",
1103decb14aSJohn Rigby 			toc->section_name,
1113decb14aSJohn Rigby 			toc->section_offset,
1123decb14aSJohn Rigby 			toc->section_size);
1133decb14aSJohn Rigby 
1143decb14aSJohn Rigby 		omapimage_print_section((struct ch_settings *)(ptr+offset));
1153decb14aSJohn Rigby 		toc++;
1163decb14aSJohn Rigby 	}
1173decb14aSJohn Rigby 
118bf411ea9SKaricheri, Muralidharan 	gph_print_header(gph, do_swap32);
1193decb14aSJohn Rigby }
1203decb14aSJohn Rigby 
toc_offset(void * hdr,void * member)1213decb14aSJohn Rigby static int toc_offset(void *hdr, void *member)
1223decb14aSJohn Rigby {
1233decb14aSJohn Rigby 	return member - hdr;
1243decb14aSJohn Rigby }
1253decb14aSJohn Rigby 
omapimage_set_header(void * ptr,struct stat * sbuf,int ifd,struct image_tool_params * params)1263decb14aSJohn Rigby static void omapimage_set_header(void *ptr, struct stat *sbuf, int ifd,
127f86ed6a8SGuilherme Maciel Ferreira 				struct image_tool_params *params)
1283decb14aSJohn Rigby {
1293decb14aSJohn Rigby 	struct ch_toc *toc = (struct ch_toc *)ptr;
1303decb14aSJohn Rigby 	struct ch_settings *chs = (struct ch_settings *)
1313decb14aSJohn Rigby 					(ptr + 2 * sizeof(*toc));
1323decb14aSJohn Rigby 	struct gp_header *gph = (struct gp_header *)(ptr + OMAP_CH_HDR_SIZE);
1333decb14aSJohn Rigby 
1343decb14aSJohn Rigby 	toc->section_offset = toc_offset(ptr, chs);
1353decb14aSJohn Rigby 	toc->section_size = sizeof(struct ch_settings);
1363decb14aSJohn Rigby 	strcpy((char *)toc->section_name, "CHSETTINGS");
1373decb14aSJohn Rigby 
1383decb14aSJohn Rigby 	chs->section_key = KEY_CHSETTINGS;
1393decb14aSJohn Rigby 	chs->valid = 0;
1403decb14aSJohn Rigby 	chs->version = 1;
1413decb14aSJohn Rigby 	chs->reserved = 0;
1423decb14aSJohn Rigby 	chs->flags = 0;
1433decb14aSJohn Rigby 
1443decb14aSJohn Rigby 	toc++;
1453decb14aSJohn Rigby 	memset(toc, 0xff, sizeof(*toc));
1463decb14aSJohn Rigby 
1473a0e70f1SLokesh Vutla 	gph_set_header(gph, sbuf->st_size - OMAP_CH_HDR_SIZE,
148bf411ea9SKaricheri, Muralidharan 		       params->addr, 0);
14979b9ebb7STom Rini 
15079b9ebb7STom Rini 	if (strncmp(params->imagename, "byteswap", 8) == 0) {
15179b9ebb7STom Rini 		do_swap32 = 1;
15279b9ebb7STom Rini 		int swapped = 0;
15379b9ebb7STom Rini 		uint32_t *data = (uint32_t *)ptr;
154c8e1ca3eSPhilipp Tomsich 		const off_t size_in_words =
155c8e1ca3eSPhilipp Tomsich 			DIV_ROUND_UP(sbuf->st_size, sizeof(uint32_t));
15679b9ebb7STom Rini 
157c8e1ca3eSPhilipp Tomsich 		while (swapped < size_in_words) {
158bf411ea9SKaricheri, Muralidharan 			*data = cpu_to_be32(*data);
15979b9ebb7STom Rini 			swapped++;
16079b9ebb7STom Rini 			data++;
16179b9ebb7STom Rini 		}
16279b9ebb7STom Rini 	}
1633decb14aSJohn Rigby }
1643decb14aSJohn Rigby 
1653decb14aSJohn Rigby /*
1663decb14aSJohn Rigby  * omapimage parameters
1673decb14aSJohn Rigby  */
168a93648d1SGuilherme Maciel Ferreira U_BOOT_IMAGE_TYPE(
169a93648d1SGuilherme Maciel Ferreira 	omapimage,
170a93648d1SGuilherme Maciel Ferreira 	"TI OMAP CH/GP Boot Image support",
171a93648d1SGuilherme Maciel Ferreira 	OMAP_FILE_HDR_SIZE,
172a93648d1SGuilherme Maciel Ferreira 	(void *)&omapimage_header,
173a93648d1SGuilherme Maciel Ferreira 	gpimage_check_params,
174a93648d1SGuilherme Maciel Ferreira 	omapimage_verify_header,
175a93648d1SGuilherme Maciel Ferreira 	omapimage_print_header,
176a93648d1SGuilherme Maciel Ferreira 	omapimage_set_header,
177a93648d1SGuilherme Maciel Ferreira 	NULL,
178a93648d1SGuilherme Maciel Ferreira 	omapimage_check_image_types,
179a93648d1SGuilherme Maciel Ferreira 	NULL,
180a93648d1SGuilherme Maciel Ferreira 	NULL
181a93648d1SGuilherme Maciel Ferreira );
182