3 * Marvell Semiconductor <www.marvell.com>
4 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
6 * SPDX-License-Identifier: GPL-2.0+
14 * Supported commands for configuration file
16 static table_entry_t kwbimage_cmds
[] = {
17 {CMD_BOOT_FROM
, "BOOT_FROM", "boot command", },
18 {CMD_NAND_ECC_MODE
, "NAND_ECC_MODE", "NAND mode", },
19 {CMD_NAND_PAGE_SIZE
, "NAND_PAGE_SIZE", "NAND size", },
20 {CMD_SATA_PIO_MODE
, "SATA_PIO_MODE", "SATA mode", },
21 {CMD_DDR_INIT_DELAY
, "DDR_INIT_DELAY", "DDR init dly", },
22 {CMD_DATA
, "DATA", "Reg Write Data", },
23 {CMD_INVALID
, "", "", },
27 * Supported Boot options for configuration file
29 static table_entry_t kwbimage_bootops
[] = {
30 {IBR_HDR_SPI_ID
, "spi", "SPI Flash", },
31 {IBR_HDR_NAND_ID
, "nand", "NAND Flash", },
32 {IBR_HDR_SATA_ID
, "sata", "Sata port", },
33 {IBR_HDR_PEX_ID
, "pex", "PCIe port", },
34 {IBR_HDR_UART_ID
, "uart", "Serial port", },
35 {-1, "", "Invalid", },
39 * Supported NAND ecc options configuration file
41 static table_entry_t kwbimage_eccmodes
[] = {
42 {IBR_HDR_ECC_DEFAULT
, "default", "Default mode", },
43 {IBR_HDR_ECC_FORCED_HAMMING
, "hamming", "Hamming mode", },
44 {IBR_HDR_ECC_FORCED_RS
, "rs", "RS mode", },
45 {IBR_HDR_ECC_DISABLED
, "disabled", "ECC Disabled", },
49 static struct kwb_header kwbimage_header
;
50 static int datacmd_cnt
= 0;
51 static char * fname
= "Unknown";
52 static int lineno
= -1;
55 * Report Error if xflag is set in addition to default
57 static int kwbimage_check_params(struct image_tool_params
*params
)
59 if (!strlen (params
->imagename
)) {
60 printf ("Error:%s - Configuration file not specified, "
61 "it is needed for kwbimage generation\n",
65 return ((params
->dflag
&& (params
->fflag
|| params
->lflag
)) ||
66 (params
->fflag
&& (params
->dflag
|| params
->lflag
)) ||
67 (params
->lflag
&& (params
->dflag
|| params
->fflag
)) ||
68 (params
->xflag
) || !(strlen (params
->imagename
)));
71 static uint32_t check_get_hexval (char *token
)
75 if (!sscanf (token
, "%x", &hexval
)) {
76 printf ("Error:%s[%d] - Invalid hex data(%s)\n", fname
,
84 * Generates 8 bit checksum
86 static uint8_t kwbimage_checksum8 (void *start
, uint32_t len
, uint8_t csum
)
88 register uint8_t sum
= csum
;
89 volatile uint8_t *p
= (volatile uint8_t *)start
;
91 /* check len and return zero checksum if invalid */
103 * Generates 32 bit checksum
105 static uint32_t kwbimage_checksum32 (uint32_t *start
, uint32_t len
, uint32_t csum
)
107 register uint32_t sum
= csum
;
108 volatile uint32_t *p
= start
;
110 /* check len and return zero checksum if invalid */
114 if (len
% sizeof(uint32_t)) {
115 printf ("Error:%s[%d] - length is not in multiple of %zu\n",
116 __FUNCTION__
, len
, sizeof(uint32_t));
123 len
-= sizeof(uint32_t);
128 static void kwbimage_check_cfgdata (char *token
, enum kwbimage_cmd cmdsw
,
129 struct kwb_header
*kwbhdr
)
131 bhr_t
*mhdr
= &kwbhdr
->kwb_hdr
;
132 extbhr_t
*exthdr
= &kwbhdr
->kwb_exthdr
;
137 i
= get_table_entry_id (kwbimage_bootops
,
138 "Kwbimage boot option", token
);
144 printf ("Preparing kirkwood boot image to boot "
147 case CMD_NAND_ECC_MODE
:
148 i
= get_table_entry_id (kwbimage_eccmodes
,
149 "NAND ecc mode", token
);
154 mhdr
->nandeccmode
= i
;
155 printf ("Nand ECC mode = %s\n", token
);
157 case CMD_NAND_PAGE_SIZE
:
159 (uint16_t) check_get_hexval (token
);
160 printf ("Nand page size = 0x%x\n", mhdr
->nandpagesize
);
162 case CMD_SATA_PIO_MODE
:
164 (uint8_t) check_get_hexval (token
);
165 printf ("Sata PIO mode = 0x%x\n",
168 case CMD_DDR_INIT_DELAY
:
170 (uint16_t) check_get_hexval (token
);
171 printf ("DDR init delay = %d msec\n", mhdr
->ddrinitdelay
);
174 exthdr
->rcfg
[datacmd_cnt
].raddr
=
175 check_get_hexval (token
);
186 printf ("Error:%s[%d] - Invalid data\n", fname
, lineno
);
191 * this function sets the kwbimage header by-
192 * 1. Abstracting input command line arguments data
193 * 2. parses the kwbimage configuration file and update extebded header data
194 * 3. calculates header, extended header and image checksums
196 static void kwdimage_set_ext_header (struct kwb_header
*kwbhdr
, char* name
) {
197 bhr_t
*mhdr
= &kwbhdr
->kwb_hdr
;
198 extbhr_t
*exthdr
= &kwbhdr
->kwb_exthdr
;
202 char * token
, *saveptr1
, *saveptr2
;
204 enum kwbimage_cmd cmd
;
207 /* set dram register offset */
208 exthdr
->dramregsoffs
= (intptr_t)&exthdr
->rcfg
- (intptr_t)mhdr
;
210 if ((fd
= fopen (name
, "r")) == 0) {
211 printf ("Error:%s - Can't open\n", fname
);
215 /* Simple kwimage.cfg file parser */
217 while ((getline (&line
, &len
, fd
)) > 0) {
219 token
= strtok_r (line
, "\r\n", &saveptr1
);
220 /* drop all lines with zero tokens (= empty lines) */
224 for (j
= 0, cmd
= CMD_INVALID
, line
= token
; ; line
= NULL
) {
225 token
= strtok_r (line
, " \t", &saveptr2
);
228 /* Drop all text starting with '#' as comments */
232 /* Process rest as valid config command line */
235 cmd
= get_table_entry_id (kwbimage_cmds
,
236 "Kwbimage command", token
);
238 if (cmd
== CMD_INVALID
)
243 kwbimage_check_cfgdata (token
, cmd
, kwbhdr
);
250 exthdr
->rcfg
[datacmd_cnt
].rdata
=
251 check_get_hexval (token
);
253 if (datacmd_cnt
> KWBIMAGE_MAX_CONFIG
) {
254 printf ("Error:%s[%d] - Found more "
255 "than max(%zd) allowed "
256 "data configurations\n",
258 KWBIMAGE_MAX_CONFIG
);
277 * Invalid Command error reporring
279 * command CMD_DATA needs three strings on a line
280 * whereas other commands need only two.
282 * if more than two/three (as per command type) are observed,
283 * then error will be reported
286 printf ("Error:%s[%d] - Invalid command\n", fname
, lineno
);
290 static void kwbimage_set_header (void *ptr
, struct stat
*sbuf
, int ifd
,
291 struct image_tool_params
*params
)
293 struct kwb_header
*hdr
= (struct kwb_header
*)ptr
;
294 bhr_t
*mhdr
= &hdr
->kwb_hdr
;
295 extbhr_t
*exthdr
= &hdr
->kwb_exthdr
;
299 /* Build and add image checksum header */
300 checksum
= kwbimage_checksum32 ((uint32_t *)ptr
, sbuf
->st_size
, 0);
302 size
= write (ifd
, &checksum
, sizeof(uint32_t));
303 if (size
!= sizeof(uint32_t)) {
304 printf ("Error:%s - Checksum write %d bytes %s\n",
305 params
->cmdname
, size
, params
->imagefile
);
309 sbuf
->st_size
+= sizeof(uint32_t);
311 mhdr
->blocksize
= sbuf
->st_size
- sizeof(struct kwb_header
);
312 mhdr
->srcaddr
= sizeof(struct kwb_header
);
313 mhdr
->destaddr
= params
->addr
;
314 mhdr
->execaddr
=params
->ep
;
315 mhdr
->ext
= 0x1; /* header extension appended */
317 kwdimage_set_ext_header (hdr
, params
->imagename
);
318 /* calculate checksums */
319 mhdr
->checkSum
= kwbimage_checksum8 ((void *)mhdr
, sizeof(bhr_t
), 0);
320 exthdr
->checkSum
= kwbimage_checksum8 ((void *)exthdr
,
321 sizeof(extbhr_t
), 0);
324 static int kwbimage_verify_header (unsigned char *ptr
, int image_size
,
325 struct image_tool_params
*params
)
327 struct kwb_header
*hdr
= (struct kwb_header
*)ptr
;
328 bhr_t
*mhdr
= &hdr
->kwb_hdr
;
329 extbhr_t
*exthdr
= &hdr
->kwb_exthdr
;
330 uint8_t calc_hdrcsum
;
331 uint8_t calc_exthdrcsum
;
333 calc_hdrcsum
= kwbimage_checksum8 ((void *)mhdr
,
334 sizeof(bhr_t
) - sizeof(uint8_t), 0);
335 if (calc_hdrcsum
!= mhdr
->checkSum
)
336 return -FDT_ERR_BADSTRUCTURE
; /* mhdr csum not matched */
338 calc_exthdrcsum
= kwbimage_checksum8 ((void *)exthdr
,
339 sizeof(extbhr_t
) - sizeof(uint8_t), 0);
340 if (calc_exthdrcsum
!= exthdr
->checkSum
)
341 return -FDT_ERR_BADSTRUCTURE
; /* exthdr csum not matched */
346 static void kwbimage_print_header (const void *ptr
)
348 struct kwb_header
*hdr
= (struct kwb_header
*) ptr
;
349 bhr_t
*mhdr
= &hdr
->kwb_hdr
;
350 char *name
= get_table_entry_name (kwbimage_bootops
,
351 "Kwbimage boot option",
352 (int) mhdr
->blockid
);
354 printf ("Image Type: Kirkwood Boot from %s Image\n", name
);
355 printf ("Data Size: ");
356 genimg_print_size (mhdr
->blocksize
- sizeof(uint32_t));
357 printf ("Load Address: %08x\n", mhdr
->destaddr
);
358 printf ("Entry Point: %08x\n", mhdr
->execaddr
);
361 static int kwbimage_check_image_types (uint8_t type
)
363 if (type
== IH_TYPE_KWBIMAGE
)
370 * kwbimage type parameters definition
372 static struct image_type_params kwbimage_params
= {
373 .name
= "Kirkwood Boot Image support",
374 .header_size
= sizeof(struct kwb_header
),
375 .hdr
= (void*)&kwbimage_header
,
376 .check_image_type
= kwbimage_check_image_types
,
377 .verify_header
= kwbimage_verify_header
,
378 .print_header
= kwbimage_print_header
,
379 .set_header
= kwbimage_set_header
,
380 .check_params
= kwbimage_check_params
,
383 void init_kwb_image_type (void)
385 register_image_type(&kwbimage_params
);