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