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