1 /* 2 * (C) Copyright 2010 3 * Linaro LTD, www.linaro.org 4 * Author: John Rigby <john.rigby@linaro.org> 5 * Based on TI's signGP.c 6 * 7 * (C) Copyright 2009 8 * Stefano Babic, DENX Software Engineering, sbabic@denx.de. 9 * 10 * (C) Copyright 2008 11 * Marvell Semiconductor <www.marvell.com> 12 * Written-by: Prafulla Wadaskar <prafulla@marvell.com> 13 * 14 * SPDX-License-Identifier: GPL-2.0+ 15 */ 16 17 #include "imagetool.h" 18 #include <compiler.h> 19 #include <image.h> 20 #include "gpheader.h" 21 #include "omapimage.h" 22 23 #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) 24 25 /* Header size is CH header rounded up to 512 bytes plus GP header */ 26 #define OMAP_CH_HDR_SIZE 512 27 #define OMAP_FILE_HDR_SIZE (OMAP_CH_HDR_SIZE + GPIMAGE_HDR_SIZE) 28 29 static int do_swap32 = 0; 30 31 static uint8_t omapimage_header[OMAP_FILE_HDR_SIZE]; 32 33 static int omapimage_check_image_types(uint8_t type) 34 { 35 if (type == IH_TYPE_OMAPIMAGE) 36 return EXIT_SUCCESS; 37 return EXIT_FAILURE; 38 } 39 40 static int omapimage_verify_header(unsigned char *ptr, int image_size, 41 struct image_tool_params *params) 42 { 43 struct ch_toc *toc = (struct ch_toc *)ptr; 44 struct gp_header *gph = (struct gp_header *)(ptr+OMAP_CH_HDR_SIZE); 45 uint32_t offset, size; 46 47 while (toc->section_offset != 0xffffffff 48 && toc->section_size != 0xffffffff) { 49 if (do_swap32) { 50 offset = cpu_to_be32(toc->section_offset); 51 size = cpu_to_be32(toc->section_size); 52 } else { 53 offset = toc->section_offset; 54 size = toc->section_size; 55 } 56 if (!offset || !size) 57 return -1; 58 if (offset >= OMAP_CH_HDR_SIZE || 59 offset+size >= OMAP_CH_HDR_SIZE) 60 return -1; 61 toc++; 62 } 63 64 return gph_verify_header(gph, do_swap32); 65 } 66 67 static void omapimage_print_section(struct ch_settings *chs) 68 { 69 const char *section_name; 70 71 if (chs->section_key) 72 section_name = "CHSETTINGS"; 73 else 74 section_name = "UNKNOWNKEY"; 75 76 printf("%s (%x) " 77 "valid:%x " 78 "version:%x " 79 "reserved:%x " 80 "flags:%x\n", 81 section_name, 82 chs->section_key, 83 chs->valid, 84 chs->version, 85 chs->reserved, 86 chs->flags); 87 } 88 89 static void omapimage_print_header(const void *ptr) 90 { 91 const struct ch_toc *toc = (struct ch_toc *)ptr; 92 const struct gp_header *gph = 93 (struct gp_header *)(ptr+OMAP_CH_HDR_SIZE); 94 uint32_t offset, size; 95 96 while (toc->section_offset != 0xffffffff 97 && toc->section_size != 0xffffffff) { 98 if (do_swap32) { 99 offset = cpu_to_be32(toc->section_offset); 100 size = cpu_to_be32(toc->section_size); 101 } else { 102 offset = toc->section_offset; 103 size = toc->section_size; 104 } 105 106 if (offset >= OMAP_CH_HDR_SIZE || 107 offset+size >= OMAP_CH_HDR_SIZE) 108 exit(EXIT_FAILURE); 109 110 printf("Section %s offset %x length %x\n", 111 toc->section_name, 112 toc->section_offset, 113 toc->section_size); 114 115 omapimage_print_section((struct ch_settings *)(ptr+offset)); 116 toc++; 117 } 118 119 gph_print_header(gph, do_swap32); 120 } 121 122 static int toc_offset(void *hdr, void *member) 123 { 124 return member - hdr; 125 } 126 127 static void omapimage_set_header(void *ptr, struct stat *sbuf, int ifd, 128 struct image_tool_params *params) 129 { 130 struct ch_toc *toc = (struct ch_toc *)ptr; 131 struct ch_settings *chs = (struct ch_settings *) 132 (ptr + 2 * sizeof(*toc)); 133 struct gp_header *gph = (struct gp_header *)(ptr + OMAP_CH_HDR_SIZE); 134 135 toc->section_offset = toc_offset(ptr, chs); 136 toc->section_size = sizeof(struct ch_settings); 137 strcpy((char *)toc->section_name, "CHSETTINGS"); 138 139 chs->section_key = KEY_CHSETTINGS; 140 chs->valid = 0; 141 chs->version = 1; 142 chs->reserved = 0; 143 chs->flags = 0; 144 145 toc++; 146 memset(toc, 0xff, sizeof(*toc)); 147 148 gph_set_header(gph, sbuf->st_size - OMAP_CH_HDR_SIZE, 149 params->addr, 0); 150 151 if (strncmp(params->imagename, "byteswap", 8) == 0) { 152 do_swap32 = 1; 153 int swapped = 0; 154 uint32_t *data = (uint32_t *)ptr; 155 const off_t size_in_words = 156 DIV_ROUND_UP(sbuf->st_size, sizeof(uint32_t)); 157 158 while (swapped < size_in_words) { 159 *data = cpu_to_be32(*data); 160 swapped++; 161 data++; 162 } 163 } 164 } 165 166 /* 167 * omapimage parameters 168 */ 169 U_BOOT_IMAGE_TYPE( 170 omapimage, 171 "TI OMAP CH/GP Boot Image support", 172 OMAP_FILE_HDR_SIZE, 173 (void *)&omapimage_header, 174 gpimage_check_params, 175 omapimage_verify_header, 176 omapimage_print_header, 177 omapimage_set_header, 178 NULL, 179 omapimage_check_image_types, 180 NULL, 181 NULL 182 ); 183