]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - tools/omapimage.c
karo: tx6: factor out PMIC initialization
[karo-tx-uboot.git] / tools / omapimage.c
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 /* Required to obtain the getline prototype from stdio.h */
18 #define _GNU_SOURCE
19
20 #include "mkimage.h"
21 #include <image.h>
22 #include "omapimage.h"
23
24 /* Header size is CH header rounded up to 512 bytes plus GP header */
25 #define OMAP_CH_HDR_SIZE 512
26 #define OMAP_GP_HDR_SIZE (sizeof(struct gp_header))
27 #define OMAP_FILE_HDR_SIZE (OMAP_CH_HDR_SIZE+OMAP_GP_HDR_SIZE)
28
29 static int do_swap32 = 0;
30
31 static uint32_t omapimage_swap32(uint32_t data)
32 {
33         uint32_t result = 0;
34         result  = (data & 0xFF000000) >> 24;
35         result |= (data & 0x00FF0000) >> 8;
36         result |= (data & 0x0000FF00) << 8;
37         result |= (data & 0x000000FF) << 24;
38         return result;
39 }
40
41 static uint8_t omapimage_header[OMAP_FILE_HDR_SIZE];
42
43 static int omapimage_check_image_types(uint8_t type)
44 {
45         if (type == IH_TYPE_OMAPIMAGE)
46                 return EXIT_SUCCESS;
47         else {
48                 return EXIT_FAILURE;
49         }
50 }
51
52 /*
53  * Only the simplest image type is currently supported:
54  * TOC pointing to CHSETTINGS
55  * TOC terminator
56  * CHSETTINGS
57  *
58  * padding to OMAP_CH_HDR_SIZE bytes
59  *
60  * gp header
61  *   size
62  *   load_addr
63  */
64 static int valid_gph_size(uint32_t size)
65 {
66         return size;
67 }
68
69 static int valid_gph_load_addr(uint32_t load_addr)
70 {
71         return load_addr;
72 }
73
74 static int omapimage_verify_header(unsigned char *ptr, int image_size,
75                         struct mkimage_params *params)
76 {
77         struct ch_toc *toc = (struct ch_toc *)ptr;
78         struct gp_header *gph = (struct gp_header *)(ptr+OMAP_CH_HDR_SIZE);
79         uint32_t offset, size, gph_size, gph_load_addr;
80
81         while (toc->section_offset != 0xffffffff
82                         && toc->section_size != 0xffffffff) {
83                 if (do_swap32) {
84                         offset = omapimage_swap32(toc->section_offset);
85                         size = omapimage_swap32(toc->section_size);
86                 } else {
87                         offset = toc->section_offset;
88                         size = toc->section_size;
89                 }
90                 if (!offset || !size)
91                         return -1;
92                 if (offset >= OMAP_CH_HDR_SIZE ||
93                     offset+size >= OMAP_CH_HDR_SIZE)
94                         return -1;
95                 toc++;
96         }
97
98         if (do_swap32) {
99                 gph_size = omapimage_swap32(gph->size);
100                 gph_load_addr = omapimage_swap32(gph->load_addr);
101         } else {
102                 gph_size = gph->size;
103                 gph_load_addr = gph->load_addr;
104         }
105
106         if (!valid_gph_size(gph_size))
107                 return -1;
108         if (!valid_gph_load_addr(gph_load_addr))
109                 return -1;
110
111         return 0;
112 }
113
114 static void omapimage_print_section(struct ch_settings *chs)
115 {
116         const char *section_name;
117
118         if (chs->section_key)
119                 section_name = "CHSETTINGS";
120         else
121                 section_name = "UNKNOWNKEY";
122
123         printf("%s (%x) "
124                 "valid:%x "
125                 "version:%x "
126                 "reserved:%x "
127                 "flags:%x\n",
128                 section_name,
129                 chs->section_key,
130                 chs->valid,
131                 chs->version,
132                 chs->reserved,
133                 chs->flags);
134 }
135
136 static void omapimage_print_header(const void *ptr)
137 {
138         const struct ch_toc *toc = (struct ch_toc *)ptr;
139         const struct gp_header *gph =
140                         (struct gp_header *)(ptr+OMAP_CH_HDR_SIZE);
141         uint32_t offset, size, gph_size, gph_load_addr;
142
143         while (toc->section_offset != 0xffffffff
144                         && toc->section_size != 0xffffffff) {
145                 if (do_swap32) {
146                         offset = omapimage_swap32(toc->section_offset);
147                         size = omapimage_swap32(toc->section_size);
148                 } else {
149                         offset = toc->section_offset;
150                         size = toc->section_size;
151                 }
152
153                 if (offset >= OMAP_CH_HDR_SIZE ||
154                     offset+size >= OMAP_CH_HDR_SIZE)
155                         exit(EXIT_FAILURE);
156
157                 printf("Section %s offset %x length %x\n",
158                         toc->section_name,
159                         toc->section_offset,
160                         toc->section_size);
161
162                 omapimage_print_section((struct ch_settings *)(ptr+offset));
163                 toc++;
164         }
165
166         if (do_swap32) {
167                 gph_size = omapimage_swap32(gph->size);
168                 gph_load_addr = omapimage_swap32(gph->load_addr);
169         } else {
170                 gph_size = gph->size;
171                 gph_load_addr = gph->load_addr;
172         }
173
174         if (!valid_gph_size(gph_size)) {
175                 fprintf(stderr, "Error: invalid image size %x\n", gph_size);
176                 exit(EXIT_FAILURE);
177         }
178
179         if (!valid_gph_load_addr(gph_load_addr)) {
180                 fprintf(stderr, "Error: invalid image load address %x\n",
181                                 gph_load_addr);
182                 exit(EXIT_FAILURE);
183         }
184
185         printf("GP Header: Size %x LoadAddr %x\n", gph_size, gph_load_addr);
186 }
187
188 static int toc_offset(void *hdr, void *member)
189 {
190         return member - hdr;
191 }
192
193 static void omapimage_set_header(void *ptr, struct stat *sbuf, int ifd,
194                                 struct mkimage_params *params)
195 {
196         struct ch_toc *toc = (struct ch_toc *)ptr;
197         struct ch_settings *chs = (struct ch_settings *)
198                                         (ptr + 2 * sizeof(*toc));
199         struct gp_header *gph = (struct gp_header *)(ptr + OMAP_CH_HDR_SIZE);
200
201         toc->section_offset = toc_offset(ptr, chs);
202         toc->section_size = sizeof(struct ch_settings);
203         strcpy((char *)toc->section_name, "CHSETTINGS");
204
205         chs->section_key = KEY_CHSETTINGS;
206         chs->valid = 0;
207         chs->version = 1;
208         chs->reserved = 0;
209         chs->flags = 0;
210
211         toc++;
212         memset(toc, 0xff, sizeof(*toc));
213
214         gph->size = sbuf->st_size - OMAP_FILE_HDR_SIZE;
215         gph->load_addr = params->addr;
216
217         if (strncmp(params->imagename, "byteswap", 8) == 0) {
218                 do_swap32 = 1;
219                 int swapped = 0;
220                 uint32_t *data = (uint32_t *)ptr;
221
222                 while (swapped <= (sbuf->st_size / sizeof(uint32_t))) {
223                         *data = omapimage_swap32(*data);
224                         swapped++;
225                         data++;
226                 }
227         }
228 }
229
230 int omapimage_check_params(struct mkimage_params *params)
231 {
232         return  (params->dflag && (params->fflag || params->lflag)) ||
233                 (params->fflag && (params->dflag || params->lflag)) ||
234                 (params->lflag && (params->dflag || params->fflag));
235 }
236
237 /*
238  * omapimage parameters
239  */
240 static struct image_type_params omapimage_params = {
241         .name           = "TI OMAP CH/GP Boot Image support",
242         .header_size    = OMAP_FILE_HDR_SIZE,
243         .hdr            = (void *)&omapimage_header,
244         .check_image_type = omapimage_check_image_types,
245         .verify_header  = omapimage_verify_header,
246         .print_header   = omapimage_print_header,
247         .set_header     = omapimage_set_header,
248         .check_params   = omapimage_check_params,
249 };
250
251 void init_omap_image_type(void)
252 {
253         mkimage_register(&omapimage_params);
254 }