xref: /rk3399_rockchip-uboot/tools/mxsboot.c (revision 1fbdb706106a6ad135f87d29bb8dfe09ff995950)
1 /*
2  * Freescale i.MX28 image generator
3  *
4  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
5  * on behalf of DENX Software Engineering GmbH
6  *
7  * SPDX-License-Identifier:	GPL-2.0+
8  */
9 
10 #include <fcntl.h>
11 #include <sys/stat.h>
12 #include <sys/types.h>
13 #include <unistd.h>
14 
15 #include "compiler.h"
16 
17 /*
18  * Default BCB layout.
19  *
20  * TWEAK this if you have blown any OCOTP fuses.
21  */
22 #define	STRIDE_PAGES		64
23 #define	STRIDE_COUNT		4
24 
25 /*
26  * Layout for 256Mb big NAND with 2048b page size, 64b OOB size and
27  * 128kb erase size.
28  *
29  * TWEAK this if you have different kind of NAND chip.
30  */
31 static uint32_t nand_writesize = 2048;
32 static uint32_t nand_oobsize = 64;
33 static uint32_t nand_erasesize = 128 * 1024;
34 
35 /*
36  * Sector on which the SigmaTel boot partition (0x53) starts.
37  */
38 static uint32_t sd_sector = 2048;
39 
40 /*
41  * Each of the U-Boot bootstreams is at maximum 1MB big.
42  *
43  * TWEAK this if, for some wild reason, you need to boot bigger image.
44  */
45 #define	MAX_BOOTSTREAM_SIZE	(1 * 1024 * 1024)
46 
47 /* i.MX28 NAND controller-specific constants. DO NOT TWEAK! */
48 #define	MXS_NAND_DMA_DESCRIPTOR_COUNT		4
49 #define	MXS_NAND_CHUNK_DATA_CHUNK_SIZE		512
50 #define	MXS_NAND_METADATA_SIZE			10
51 #define	MXS_NAND_BITS_PER_ECC_LEVEL		13
52 #define	MXS_NAND_COMMAND_BUFFER_SIZE		32
53 
54 struct mx28_nand_fcb {
55 	uint32_t		checksum;
56 	uint32_t		fingerprint;
57 	uint32_t		version;
58 	struct {
59 		uint8_t			data_setup;
60 		uint8_t			data_hold;
61 		uint8_t			address_setup;
62 		uint8_t			dsample_time;
63 		uint8_t			nand_timing_state;
64 		uint8_t			rea;
65 		uint8_t			rloh;
66 		uint8_t			rhoh;
67 	}			timing;
68 	uint32_t		page_data_size;
69 	uint32_t		total_page_size;
70 	uint32_t		sectors_per_block;
71 	uint32_t		number_of_nands;		/* Ignored */
72 	uint32_t		total_internal_die;		/* Ignored */
73 	uint32_t		cell_type;			/* Ignored */
74 	uint32_t		ecc_block_n_ecc_type;
75 	uint32_t		ecc_block_0_size;
76 	uint32_t		ecc_block_n_size;
77 	uint32_t		ecc_block_0_ecc_type;
78 	uint32_t		metadata_bytes;
79 	uint32_t		num_ecc_blocks_per_page;
80 	uint32_t		ecc_block_n_ecc_level_sdk;	/* Ignored */
81 	uint32_t		ecc_block_0_size_sdk;		/* Ignored */
82 	uint32_t		ecc_block_n_size_sdk;		/* Ignored */
83 	uint32_t		ecc_block_0_ecc_level_sdk;	/* Ignored */
84 	uint32_t		num_ecc_blocks_per_page_sdk;	/* Ignored */
85 	uint32_t		metadata_bytes_sdk;		/* Ignored */
86 	uint32_t		erase_threshold;
87 	uint32_t		boot_patch;
88 	uint32_t		patch_sectors;
89 	uint32_t		firmware1_starting_sector;
90 	uint32_t		firmware2_starting_sector;
91 	uint32_t		sectors_in_firmware1;
92 	uint32_t		sectors_in_firmware2;
93 	uint32_t		dbbt_search_area_start_address;
94 	uint32_t		badblock_marker_byte;
95 	uint32_t		badblock_marker_start_bit;
96 	uint32_t		bb_marker_physical_offset;
97 };
98 
99 struct mx28_nand_dbbt {
100 	uint32_t		checksum;
101 	uint32_t		fingerprint;
102 	uint32_t		version;
103 	uint32_t		number_bb;
104 	uint32_t		number_2k_pages_bb;
105 };
106 
107 struct mx28_nand_bbt {
108 	uint32_t		nand;
109 	uint32_t		number_bb;
110 	uint32_t		badblock[510];
111 };
112 
113 struct mx28_sd_drive_info {
114 	uint32_t		chip_num;
115 	uint32_t		drive_type;
116 	uint32_t		tag;
117 	uint32_t		first_sector_number;
118 	uint32_t		sector_count;
119 };
120 
121 struct mx28_sd_config_block {
122 	uint32_t			signature;
123 	uint32_t			primary_boot_tag;
124 	uint32_t			secondary_boot_tag;
125 	uint32_t			num_copies;
126 	struct mx28_sd_drive_info	drv_info[1];
127 };
128 
129 static inline uint32_t mx28_nand_ecc_size_in_bits(uint32_t ecc_strength)
130 {
131 	return ecc_strength * MXS_NAND_BITS_PER_ECC_LEVEL;
132 }
133 
134 static inline uint32_t mx28_nand_get_ecc_strength(uint32_t page_data_size,
135 						uint32_t page_oob_size)
136 {
137 	if (page_data_size == 2048)
138 		return 8;
139 
140 	if (page_data_size == 4096) {
141 		if (page_oob_size == 128)
142 			return 8;
143 
144 		if (page_oob_size == 218)
145 			return 16;
146 
147 		if (page_oob_size == 224)
148 			return 16;
149 	}
150 
151 	return 0;
152 }
153 
154 static inline uint32_t mx28_nand_get_mark_offset(uint32_t page_data_size,
155 						uint32_t ecc_strength)
156 {
157 	uint32_t chunk_data_size_in_bits;
158 	uint32_t chunk_ecc_size_in_bits;
159 	uint32_t chunk_total_size_in_bits;
160 	uint32_t block_mark_chunk_number;
161 	uint32_t block_mark_chunk_bit_offset;
162 	uint32_t block_mark_bit_offset;
163 
164 	chunk_data_size_in_bits = MXS_NAND_CHUNK_DATA_CHUNK_SIZE * 8;
165 	chunk_ecc_size_in_bits  = mx28_nand_ecc_size_in_bits(ecc_strength);
166 
167 	chunk_total_size_in_bits =
168 			chunk_data_size_in_bits + chunk_ecc_size_in_bits;
169 
170 	/* Compute the bit offset of the block mark within the physical page. */
171 	block_mark_bit_offset = page_data_size * 8;
172 
173 	/* Subtract the metadata bits. */
174 	block_mark_bit_offset -= MXS_NAND_METADATA_SIZE * 8;
175 
176 	/*
177 	 * Compute the chunk number (starting at zero) in which the block mark
178 	 * appears.
179 	 */
180 	block_mark_chunk_number =
181 			block_mark_bit_offset / chunk_total_size_in_bits;
182 
183 	/*
184 	 * Compute the bit offset of the block mark within its chunk, and
185 	 * validate it.
186 	 */
187 	block_mark_chunk_bit_offset = block_mark_bit_offset -
188 			(block_mark_chunk_number * chunk_total_size_in_bits);
189 
190 	if (block_mark_chunk_bit_offset > chunk_data_size_in_bits)
191 		return 1;
192 
193 	/*
194 	 * Now that we know the chunk number in which the block mark appears,
195 	 * we can subtract all the ECC bits that appear before it.
196 	 */
197 	block_mark_bit_offset -=
198 		block_mark_chunk_number * chunk_ecc_size_in_bits;
199 
200 	return block_mark_bit_offset;
201 }
202 
203 static inline uint32_t mx28_nand_mark_byte_offset(void)
204 {
205 	uint32_t ecc_strength;
206 	ecc_strength = mx28_nand_get_ecc_strength(nand_writesize, nand_oobsize);
207 	return mx28_nand_get_mark_offset(nand_writesize, ecc_strength) >> 3;
208 }
209 
210 static inline uint32_t mx28_nand_mark_bit_offset(void)
211 {
212 	uint32_t ecc_strength;
213 	ecc_strength = mx28_nand_get_ecc_strength(nand_writesize, nand_oobsize);
214 	return mx28_nand_get_mark_offset(nand_writesize, ecc_strength) & 0x7;
215 }
216 
217 static uint32_t mx28_nand_block_csum(uint8_t *block, uint32_t size)
218 {
219 	uint32_t csum = 0;
220 	int i;
221 
222 	for (i = 0; i < size; i++)
223 		csum += block[i];
224 
225 	return csum ^ 0xffffffff;
226 }
227 
228 static struct mx28_nand_fcb *mx28_nand_get_fcb(uint32_t size)
229 {
230 	struct mx28_nand_fcb *fcb;
231 	uint32_t bcb_size_bytes;
232 	uint32_t stride_size_bytes;
233 	uint32_t bootstream_size_pages;
234 	uint32_t fw1_start_page;
235 	uint32_t fw2_start_page;
236 
237 	fcb = malloc(nand_writesize);
238 	if (!fcb) {
239 		printf("MX28 NAND: Unable to allocate FCB\n");
240 		return NULL;
241 	}
242 
243 	memset(fcb, 0, nand_writesize);
244 
245 	fcb->fingerprint =			0x20424346;
246 	fcb->version =				0x01000000;
247 
248 	/*
249 	 * FIXME: These here are default values as found in kobs-ng. We should
250 	 * probably retrieve the data from NAND or something.
251 	 */
252 	fcb->timing.data_setup =		80;
253 	fcb->timing.data_hold =			60;
254 	fcb->timing.address_setup =		25;
255 	fcb->timing.dsample_time =		6;
256 
257 	fcb->page_data_size =		nand_writesize;
258 	fcb->total_page_size =		nand_writesize + nand_oobsize;
259 	fcb->sectors_per_block =	nand_erasesize / nand_writesize;
260 
261 	fcb->num_ecc_blocks_per_page =	(nand_writesize / 512) - 1;
262 	fcb->ecc_block_0_size =		512;
263 	fcb->ecc_block_n_size =		512;
264 	fcb->metadata_bytes =		10;
265 
266 	if (nand_writesize == 2048) {
267 		fcb->ecc_block_n_ecc_type =		4;
268 		fcb->ecc_block_0_ecc_type =		4;
269 	} else if (nand_writesize == 4096) {
270 		if (nand_oobsize == 128) {
271 			fcb->ecc_block_n_ecc_type =	4;
272 			fcb->ecc_block_0_ecc_type =	4;
273 		} else if (nand_oobsize == 218) {
274 			fcb->ecc_block_n_ecc_type =	8;
275 			fcb->ecc_block_0_ecc_type =	8;
276 		} else if (nand_oobsize == 224) {
277 			fcb->ecc_block_n_ecc_type =	8;
278 			fcb->ecc_block_0_ecc_type =	8;
279 		}
280 	}
281 
282 	if (fcb->ecc_block_n_ecc_type == 0) {
283 		printf("MX28 NAND: Unsupported NAND geometry\n");
284 		goto err;
285 	}
286 
287 	fcb->boot_patch =			0;
288 	fcb->patch_sectors =			0;
289 
290 	fcb->badblock_marker_byte =	mx28_nand_mark_byte_offset();
291 	fcb->badblock_marker_start_bit = mx28_nand_mark_bit_offset();
292 	fcb->bb_marker_physical_offset = nand_writesize;
293 
294 	stride_size_bytes = STRIDE_PAGES * nand_writesize;
295 	bcb_size_bytes = stride_size_bytes * STRIDE_COUNT;
296 
297 	bootstream_size_pages = (size + (nand_writesize - 1)) /
298 					nand_writesize;
299 
300 	fw1_start_page = 2 * bcb_size_bytes / nand_writesize;
301 	fw2_start_page = (2 * bcb_size_bytes + MAX_BOOTSTREAM_SIZE) /
302 				nand_writesize;
303 
304 	fcb->firmware1_starting_sector =	fw1_start_page;
305 	fcb->firmware2_starting_sector =	fw2_start_page;
306 	fcb->sectors_in_firmware1 =		bootstream_size_pages;
307 	fcb->sectors_in_firmware2 =		bootstream_size_pages;
308 
309 	fcb->dbbt_search_area_start_address =	STRIDE_PAGES * STRIDE_COUNT;
310 
311 	return fcb;
312 
313 err:
314 	free(fcb);
315 	return NULL;
316 }
317 
318 static struct mx28_nand_dbbt *mx28_nand_get_dbbt(void)
319 {
320 	struct mx28_nand_dbbt *dbbt;
321 
322 	dbbt = malloc(nand_writesize);
323 	if (!dbbt) {
324 		printf("MX28 NAND: Unable to allocate DBBT\n");
325 		return NULL;
326 	}
327 
328 	memset(dbbt, 0, nand_writesize);
329 
330 	dbbt->fingerprint	= 0x54424244;
331 	dbbt->version		= 0x1;
332 
333 	return dbbt;
334 }
335 
336 static inline uint8_t mx28_nand_parity_13_8(const uint8_t b)
337 {
338 	uint32_t parity = 0, tmp;
339 
340 	tmp = ((b >> 6) ^ (b >> 5) ^ (b >> 3) ^ (b >> 2)) & 1;
341 	parity |= tmp << 0;
342 
343 	tmp = ((b >> 7) ^ (b >> 5) ^ (b >> 4) ^ (b >> 2) ^ (b >> 1)) & 1;
344 	parity |= tmp << 1;
345 
346 	tmp = ((b >> 7) ^ (b >> 6) ^ (b >> 5) ^ (b >> 1) ^ (b >> 0)) & 1;
347 	parity |= tmp << 2;
348 
349 	tmp = ((b >> 7) ^ (b >> 4) ^ (b >> 3) ^ (b >> 0)) & 1;
350 	parity |= tmp << 3;
351 
352 	tmp = ((b >> 6) ^ (b >> 4) ^ (b >> 3) ^
353 		(b >> 2) ^ (b >> 1) ^ (b >> 0)) & 1;
354 	parity |= tmp << 4;
355 
356 	return parity;
357 }
358 
359 static uint8_t *mx28_nand_fcb_block(struct mx28_nand_fcb *fcb)
360 {
361 	uint8_t *block;
362 	uint8_t *ecc;
363 	int i;
364 
365 	block = malloc(nand_writesize + nand_oobsize);
366 	if (!block) {
367 		printf("MX28 NAND: Unable to allocate FCB block\n");
368 		return NULL;
369 	}
370 
371 	memset(block, 0, nand_writesize + nand_oobsize);
372 
373 	/* Update the FCB checksum */
374 	fcb->checksum = mx28_nand_block_csum(((uint8_t *)fcb) + 4, 508);
375 
376 	/* Figure 12-11. in iMX28RM, rev. 1, says FCB is at offset 12 */
377 	memcpy(block + 12, fcb, sizeof(struct mx28_nand_fcb));
378 
379 	/* ECC is at offset 12 + 512 */
380 	ecc = block + 12 + 512;
381 
382 	/* Compute the ECC parity */
383 	for (i = 0; i < sizeof(struct mx28_nand_fcb); i++)
384 		ecc[i] = mx28_nand_parity_13_8(block[i + 12]);
385 
386 	return block;
387 }
388 
389 static int mx28_nand_write_fcb(struct mx28_nand_fcb *fcb, uint8_t *buf)
390 {
391 	uint32_t offset;
392 	uint8_t *fcbblock;
393 	int ret = 0;
394 	int i;
395 
396 	fcbblock = mx28_nand_fcb_block(fcb);
397 	if (!fcbblock)
398 		return -1;
399 
400 	for (i = 0; i < STRIDE_PAGES * STRIDE_COUNT; i += STRIDE_PAGES) {
401 		offset = i * nand_writesize;
402 		memcpy(buf + offset, fcbblock, nand_writesize + nand_oobsize);
403 		/* Mark the NAND page is OK. */
404 		buf[offset + nand_writesize] = 0xff;
405 	}
406 
407 	free(fcbblock);
408 	return ret;
409 }
410 
411 static int mx28_nand_write_dbbt(struct mx28_nand_dbbt *dbbt, uint8_t *buf)
412 {
413 	uint32_t offset;
414 	int i = STRIDE_PAGES * STRIDE_COUNT;
415 
416 	for (; i < 2 * STRIDE_PAGES * STRIDE_COUNT; i += STRIDE_PAGES) {
417 		offset = i * nand_writesize;
418 		memcpy(buf + offset, dbbt, sizeof(struct mx28_nand_dbbt));
419 	}
420 
421 	return 0;
422 }
423 
424 static int mx28_nand_write_firmware(struct mx28_nand_fcb *fcb, int infd,
425 				    uint8_t *buf)
426 {
427 	int ret;
428 	off_t size;
429 	uint32_t offset1, offset2;
430 
431 	size = lseek(infd, 0, SEEK_END);
432 	lseek(infd, 0, SEEK_SET);
433 
434 	offset1 = fcb->firmware1_starting_sector * nand_writesize;
435 	offset2 = fcb->firmware2_starting_sector * nand_writesize;
436 
437 	ret = read(infd, buf + offset1, size);
438 	if (ret != size)
439 		return -1;
440 
441 	memcpy(buf + offset2, buf + offset1, size);
442 
443 	return 0;
444 }
445 
446 static void usage(void)
447 {
448 	printf(
449 		"Usage: mxsboot [ops] <type> <infile> <outfile>\n"
450 		"Augment BootStream file with a proper header for i.MX28 boot\n"
451 		"\n"
452 		"  <type>	type of image:\n"
453 		"                 \"nand\" for NAND image\n"
454 		"                 \"sd\" for SD image\n"
455 		"  <infile>     input file, the u-boot.sb bootstream\n"
456 		"  <outfile>    output file, the bootable image\n"
457 		"\n");
458 	printf(
459 		"For NAND boot, these options are accepted:\n"
460 		"  -w <size>    NAND page size\n"
461 		"  -o <size>    NAND OOB size\n"
462 		"  -e <size>    NAND erase size\n"
463 		"\n"
464 		"For SD boot, these options are accepted:\n"
465 		"  -p <sector>  Sector where the SGTL partition starts\n"
466 	);
467 }
468 
469 static int mx28_create_nand_image(int infd, int outfd)
470 {
471 	struct mx28_nand_fcb *fcb;
472 	struct mx28_nand_dbbt *dbbt;
473 	int ret = -1;
474 	uint8_t *buf;
475 	int size;
476 	ssize_t wr_size;
477 
478 	size = nand_writesize * 512 + 2 * MAX_BOOTSTREAM_SIZE;
479 
480 	buf = malloc(size);
481 	if (!buf) {
482 		printf("Can not allocate output buffer of %d bytes\n", size);
483 		goto err0;
484 	}
485 
486 	memset(buf, 0, size);
487 
488 	fcb = mx28_nand_get_fcb(MAX_BOOTSTREAM_SIZE);
489 	if (!fcb) {
490 		printf("Unable to compile FCB\n");
491 		goto err1;
492 	}
493 
494 	dbbt = mx28_nand_get_dbbt();
495 	if (!dbbt) {
496 		printf("Unable to compile DBBT\n");
497 		goto err2;
498 	}
499 
500 	ret = mx28_nand_write_fcb(fcb, buf);
501 	if (ret) {
502 		printf("Unable to write FCB to buffer\n");
503 		goto err3;
504 	}
505 
506 	ret = mx28_nand_write_dbbt(dbbt, buf);
507 	if (ret) {
508 		printf("Unable to write DBBT to buffer\n");
509 		goto err3;
510 	}
511 
512 	ret = mx28_nand_write_firmware(fcb, infd, buf);
513 	if (ret) {
514 		printf("Unable to write firmware to buffer\n");
515 		goto err3;
516 	}
517 
518 	wr_size = write(outfd, buf, size);
519 	if (wr_size != size) {
520 		ret = -1;
521 		goto err3;
522 	}
523 
524 	ret = 0;
525 
526 err3:
527 	free(dbbt);
528 err2:
529 	free(fcb);
530 err1:
531 	free(buf);
532 err0:
533 	return ret;
534 }
535 
536 static int mx28_create_sd_image(int infd, int outfd)
537 {
538 	int ret = -1;
539 	uint32_t *buf;
540 	int size;
541 	off_t fsize;
542 	ssize_t wr_size;
543 	struct mx28_sd_config_block *cb;
544 
545 	fsize = lseek(infd, 0, SEEK_END);
546 	lseek(infd, 0, SEEK_SET);
547 	size = fsize + 4 * 512;
548 
549 	buf = malloc(size);
550 	if (!buf) {
551 		printf("Can not allocate output buffer of %d bytes\n", size);
552 		goto err0;
553 	}
554 
555 	ret = read(infd, (uint8_t *)buf + 4 * 512, fsize);
556 	if (ret != fsize) {
557 		ret = -1;
558 		goto err1;
559 	}
560 
561 	cb = (struct mx28_sd_config_block *)buf;
562 
563 	cb->signature = 0x00112233;
564 	cb->primary_boot_tag = 0x1;
565 	cb->secondary_boot_tag = 0x1;
566 	cb->num_copies = 1;
567 	cb->drv_info[0].chip_num = 0x0;
568 	cb->drv_info[0].drive_type = 0x0;
569 	cb->drv_info[0].tag = 0x1;
570 	cb->drv_info[0].first_sector_number = sd_sector + 4;
571 	cb->drv_info[0].sector_count = (size - 4) / 512;
572 
573 	wr_size = write(outfd, buf, size);
574 	if (wr_size != size) {
575 		ret = -1;
576 		goto err1;
577 	}
578 
579 	ret = 0;
580 
581 err1:
582 	free(buf);
583 err0:
584 	return ret;
585 }
586 
587 static int parse_ops(int argc, char **argv)
588 {
589 	int i;
590 	int tmp;
591 	char *end;
592 	enum param {
593 		PARAM_WRITE,
594 		PARAM_OOB,
595 		PARAM_ERASE,
596 		PARAM_PART,
597 		PARAM_SD,
598 		PARAM_NAND
599 	};
600 	int type;
601 
602 	if (argc < 4)
603 		return -1;
604 
605 	for (i = 1; i < argc; i++) {
606 		if (!strncmp(argv[i], "-w", 2))
607 			type = PARAM_WRITE;
608 		else if (!strncmp(argv[i], "-o", 2))
609 			type = PARAM_OOB;
610 		else if (!strncmp(argv[i], "-e", 2))
611 			type = PARAM_ERASE;
612 		else if (!strncmp(argv[i], "-p", 2))
613 			type = PARAM_PART;
614 		else	/* SD/MMC */
615 			break;
616 
617 		tmp = strtol(argv[++i], &end, 10);
618 		if (tmp % 2)
619 			return -1;
620 		if (tmp <= 0)
621 			return -1;
622 
623 		if (type == PARAM_WRITE)
624 			nand_writesize = tmp;
625 		if (type == PARAM_OOB)
626 			nand_oobsize = tmp;
627 		if (type == PARAM_ERASE)
628 			nand_erasesize = tmp;
629 		if (type == PARAM_PART)
630 			sd_sector = tmp;
631 	}
632 
633 	if (strcmp(argv[i], "sd") && strcmp(argv[i], "nand"))
634 		return -1;
635 
636 	if (i + 3 != argc)
637 		return -1;
638 
639 	return i;
640 }
641 
642 int main(int argc, char **argv)
643 {
644 	int infd, outfd;
645 	int ret = 0;
646 	int offset;
647 
648 	offset = parse_ops(argc, argv);
649 	if (offset < 0) {
650 		usage();
651 		ret = 1;
652 		goto err1;
653 	}
654 
655 	infd = open(argv[offset + 1], O_RDONLY);
656 	if (infd < 0) {
657 		printf("Input BootStream file can not be opened\n");
658 		ret = 2;
659 		goto err1;
660 	}
661 
662 	outfd = open(argv[offset + 2], O_CREAT | O_TRUNC | O_WRONLY,
663 					S_IRUSR | S_IWUSR);
664 	if (outfd < 0) {
665 		printf("Output file can not be created\n");
666 		ret = 3;
667 		goto err2;
668 	}
669 
670 	if (!strcmp(argv[offset], "sd"))
671 		ret = mx28_create_sd_image(infd, outfd);
672 	else if (!strcmp(argv[offset], "nand"))
673 		ret = mx28_create_nand_image(infd, outfd);
674 
675 	close(outfd);
676 err2:
677 	close(infd);
678 err1:
679 	return ret;
680 }
681