Root/usbboot/src/cmd.c

1/*
2 * Copyright(C) 2009 Qi Hardware Inc.,
3 * Authors: Marek Lindner <lindner_marek@yahoo.de>
4 * Xiangfu Liu <xiangfu@sharism.cc>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <stdio.h>
21#include <string.h>
22#include <unistd.h>
23#include <stdlib.h>
24#include <errno.h>
25#include <fcntl.h>
26#include <sys/types.h>
27#include <sys/stat.h>
28#include <ctype.h>
29#include <byteswap.h>
30#include "cmd.h"
31#include "command_line.h"
32#include "ingenic_cfg.h"
33#include "ingenic_usb.h"
34#include "ingenic_request.h"
35#include "usb_boot_defines.h"
36
37static int load_file(struct ingenic_dev *id, const char *file_path)
38{
39    struct stat fst;
40    struct fw_args *fw_args_copy;
41    int fd, status, res = -1;
42
43    status = stat(file_path, &fst);
44
45    if (status < 0) {
46        fprintf(stderr, "Error - can't get file size from '%s': %s\n",
47            file_path, strerror(errno));
48        goto out;
49    }
50
51    id->file_len = fst.st_size;
52    id->file_buff = code_buf;
53
54    fd = open(file_path, O_RDONLY);
55
56    if (fd < 0) {
57        fprintf(stderr, "Error - can't open file '%s': %s\n",
58            file_path, strerror(errno));
59        goto out;
60    }
61
62    status = read(fd, id->file_buff, id->file_len);
63
64    if (status < id->file_len) {
65        fprintf(stderr, "Error - can't read file '%s': %s\n",
66            file_path, strerror(errno));
67        goto close;
68    }
69
70    fw_args_copy = malloc(sizeof(struct fw_args));
71    if (!fw_args_copy)
72        goto close;
73
74    memcpy(fw_args_copy, &hand.fw_args, sizeof(struct fw_args));
75
76#if defined (__BIG_ENDIAN__) || defined(MIPSEB)
77    fw_args_copy->cpu_id = bswap_32(fw_args_copy->cpu_id);
78    fw_args_copy->boudrate = bswap_32(fw_args_copy->boudrate);
79    fw_args_copy->start = bswap_32(fw_args_copy->start);
80    fw_args_copy->size = bswap_32(fw_args_copy->size);
81#endif
82
83    /* write args to code */
84    memcpy(id->file_buff + 8, fw_args_copy,
85           sizeof(struct fw_args));
86
87    free(fw_args_copy);
88
89    res = 1;
90
91close:
92    close(fd);
93out:
94    return res;
95}
96
97int get_ingenic_cpu()
98{
99    int status;
100
101    status = usb_get_ingenic_cpu(&ingenic_dev);
102
103    switch (status) {
104    case JZ4740V1:
105        hand.fw_args.cpu_id = 0x4740;
106        break;
107    case JZ4750V1:
108        hand.fw_args.cpu_id = 0x4750;
109        break;
110    case JZ4760V1:
111        hand.fw_args.cpu_id = 0x4760;
112        break;
113    case BOOT4740:
114        hand.fw_args.cpu_id = 0x4740;
115        break;
116    case BOOT4750:
117        hand.fw_args.cpu_id = 0x4750;
118        break;
119    case BOOT4760:
120        hand.fw_args.cpu_id = 0x4760;
121        break;
122    default:
123        hand.fw_args.cpu_id = 0;
124    }
125
126    return status;
127}
128
129/* After upload stage2. we have to init the device */
130void init_cfg()
131{
132    struct hand *hand_copy;
133    int cpu = get_ingenic_cpu();
134    if (cpu != BOOT4740 && cpu != BOOT4750 && cpu != BOOT4760) {
135        printf(" Device unboot! boot it first!\n");
136        return;
137    }
138
139    hand_copy = malloc(sizeof(struct hand));
140    if (!hand_copy)
141        goto xout;
142
143    memcpy(hand_copy, &hand, sizeof(struct hand));
144
145#if defined (__BIG_ENDIAN__) || defined(MIPSEB)
146    hand_copy->fw_args.cpu_id = bswap_32(hand.fw_args.cpu_id);
147    hand_copy->fw_args.boudrate = bswap_32(hand.fw_args.boudrate);
148    hand_copy->fw_args.start = bswap_32(hand.fw_args.start);
149    hand_copy->fw_args.size = bswap_32(hand.fw_args.size);
150
151    hand_copy->pt = bswap_32(hand.pt);
152    hand_copy->nand_bw = bswap_32(hand_copy->nand_bw);
153    hand_copy->nand_rc = bswap_32(hand_copy->nand_rc);
154    hand_copy->nand_ps = bswap_32(hand_copy->nand_ps);
155    hand_copy->nand_ppb = bswap_32(hand_copy->nand_ppb);
156    hand_copy->nand_force_erase = bswap_32(hand_copy->nand_force_erase);
157    hand_copy->nand_pn = bswap_32(hand_copy->nand_pn);
158    hand_copy->nand_os = bswap_32(hand_copy->nand_os);
159    hand_copy->nand_eccpos = bswap_32(hand_copy->nand_eccpos);
160    hand_copy->nand_bbpage = bswap_32(hand_copy->nand_bbpage);
161    hand_copy->nand_bbpos = bswap_32(hand_copy->nand_bbpos);
162    hand_copy->nand_plane = bswap_32(hand_copy->nand_plane);
163    hand_copy->nand_bchbit = bswap_32(hand_copy->nand_bchbit);
164    hand_copy->nand_wppin = bswap_32(hand_copy->nand_wppin);
165    hand_copy->nand_bpc = bswap_32(hand_copy->nand_bpc);
166#endif
167
168
169    ingenic_dev.file_buff = (unsigned char *)hand_copy;
170    ingenic_dev.file_len = sizeof(struct hand);
171    if (usb_send_data_to_ingenic(&ingenic_dev) != 1)
172        goto xout;
173
174    free(hand_copy);
175
176    sleep(1);
177    if (usb_ingenic_configration(&ingenic_dev, DS_hand) != 1)
178        goto xout;
179
180    if (usb_read_data_from_ingenic(&ingenic_dev, ret, 8) != 1)
181        goto xout;
182
183    printf(" Configuring XBurst CPU succeeded.\n");
184    return;
185xout:
186    printf(" Configuring XBurst CPU failed.\n");
187}
188
189int boot(char *stage1_path, char *stage2_path){
190    int status = get_ingenic_cpu();
191
192    if (status == BOOT4740 || status == BOOT4750 || status == BOOT4760) {
193        printf(" Already booted.\n");
194        return 1;
195    } else {
196        printf(" CPU not yet booted, now booting...\n");
197
198        /* now we upload the boot stage1 */
199        printf(" Loading stage1 from '%s'\n", stage1_path);
200        if (load_file(&ingenic_dev, stage1_path) < 1)
201            return -1;
202
203        if (usb_ingenic_upload(&ingenic_dev, 1) < 1)
204            return -1;
205
206        /* now we upload the boot stage2 */
207        usleep(100);
208        printf(" Loading stage2 from '%s'\n", stage2_path);
209        if (load_file(&ingenic_dev, stage2_path) < 1)
210            return -1;
211
212        if (usb_ingenic_upload(&ingenic_dev, 2) < 1)
213            return -1;
214
215        printf(" Booted successfully!\n");
216    }
217
218    usleep(100);
219    init_cfg();
220
221    return 1;
222}
223
224/* nand function */
225int error_check(unsigned char *org,unsigned char * obj,unsigned int size)
226{
227    unsigned int i;
228    printf(" Comparing %d bytes - ", size);
229    for (i = 0; i < size; i++) {
230        if (org[i] != obj[i]) {
231            unsigned int s = (i < 8) ? i : i - 8;
232            printf("FAIL at off %d, wrote 0x%x, read 0x%x\n", i, org[i], obj[i]);
233            printf(" off %d write: %02x %02x %02x %02x %02x %02x %02x %02x"
234                   " %02x %02x %02x %02x %02x %02x %02x %02x\n", s,
235                org[s], org[s+1], org[s+2], org[s+3], org[s+4], org[s+5], org[s+6], org[s+7],
236                org[s+8], org[s+9], org[s+10], org[s+11], org[s+12], org[s+13], org[s+14], org[s+15]);
237            printf(" off %d read: %02x %02x %02x %02x %02x %02x %02x %02x"
238                   " %02x %02x %02x %02x %02x %02x %02x %02x\n", s,
239                obj[s], obj[s+1], obj[s+2], obj[s+3], obj[s+4], obj[s+5], obj[s+6], obj[s+7],
240                obj[s+8], obj[s+9], obj[s+10], obj[s+11], obj[s+12], obj[s+13], obj[s+14], obj[s+15]);
241            fflush(NULL);
242            return 0;
243        }
244    }
245    printf("SUCCESS\n");
246    fflush(NULL);
247    return 1;
248}
249
250int nand_markbad(struct nand_in *ni)
251{
252    int cpu = get_ingenic_cpu();
253    if (cpu != BOOT4740 && cpu != BOOT4750 && cpu != BOOT4760) {
254        printf(" Device unboot! boot it first!\n");
255        return -1;
256    }
257    printf(" Mark bad block : %d\n",ni->start);
258    usb_send_data_address_to_ingenic(&ingenic_dev, ni->start);
259    usb_ingenic_nand_ops(&ingenic_dev, NAND_MARK_BAD);
260    usb_read_data_from_ingenic(&ingenic_dev, ret, 8);
261    printf(" Mark bad block at %d\n",((ret[3] << 24) |
262                       (ret[2] << 16) |
263                       (ret[1] << 8) |
264                       (ret[0] << 0)) / hand.nand_ppb);
265    return 0;
266}
267
268int nand_program_check(struct nand_in *ni, unsigned int *start_page)
269{
270    unsigned int i, page_num, cur_page = -1;
271    unsigned int start_addr;
272    unsigned short temp;
273    int cpu;
274    int status = -1;
275
276    printf(" Writing NAND page %d len %d...\n", ni->start, ni->length);
277    if (ni->length > (unsigned int)MAX_TRANSFER_SIZE) {
278        printf(" Buffer size too long!\n");
279        goto err;
280    }
281
282    cpu = get_ingenic_cpu();
283    if (cpu != BOOT4740 && cpu != BOOT4750 && cpu != BOOT4760) {
284        printf(" Device unboot! boot it first!\n");
285        goto err;
286    }
287
288    ingenic_dev.file_buff = ni->buf;
289    ingenic_dev.file_len = ni->length;
290    usb_send_data_to_ingenic(&ingenic_dev);
291    for (i = 0; i < ni->max_chip; i++) {
292        if ((ni->cs_map)[i] == 0)
293            continue;
294        if (ni->option == NO_OOB) {
295            page_num = ni->length / hand.nand_ps;
296            if ((ni->length % hand.nand_ps) !=0)
297                page_num++;
298        } else {
299            page_num = ni->length /
300                (hand.nand_ps + hand.nand_os);
301            if ((ni->length% (hand.nand_ps + hand.nand_os)) !=0)
302                page_num++;
303        }
304        temp = ((ni->option << 12) & 0xf000) +
305            ((i<<4) & 0xff0) + NAND_PROGRAM;
306        if (usb_send_data_address_to_ingenic(&ingenic_dev, ni->start) != 1)
307            goto err;
308        if (usb_send_data_length_to_ingenic(&ingenic_dev, page_num) != 1)
309            goto err;
310        if (usb_ingenic_nand_ops(&ingenic_dev, temp) != 1)
311            goto err;
312        if (usb_read_data_from_ingenic(&ingenic_dev, ret, 8) != 1)
313            goto err;
314
315        printf(" Finish! (len %d start_page %d page_num %d)\n",
316               ni->length, ni->start, page_num);
317
318        /* Read back to check! */
319        usb_send_data_address_to_ingenic(&ingenic_dev, ni->start);
320        usb_send_data_length_to_ingenic(&ingenic_dev, page_num);
321
322        switch (ni->option) {
323        case OOB_ECC:
324            temp = ((OOB_ECC << 12) & 0xf000) +
325                ((i << 4) & 0xff0) + NAND_READ;
326            start_addr = page_num * (hand.nand_ps + hand.nand_os);
327            break;
328        case OOB_NO_ECC: /* do not support data verify */
329            temp = ((OOB_NO_ECC << 12) & 0xf000) +
330                ((i << 4) & 0xff0) + NAND_READ;
331            start_addr = page_num * (hand.nand_ps + hand.nand_os);
332            break;
333        case NO_OOB:
334        default:
335            temp = ((NO_OOB << 12) & 0xf000) +
336                ((i << 4) & 0xff0) + NAND_READ;
337            start_addr = page_num * hand.nand_ps;
338            break;
339        }
340
341        printf(" Checking %d bytes...", ni->length);
342        usb_ingenic_nand_ops(&ingenic_dev, temp);
343        usb_read_data_from_ingenic(&ingenic_dev, check_buf, start_addr);
344        usb_read_data_from_ingenic(&ingenic_dev, ret, 8);
345
346        cur_page = (ret[3] << 24) | (ret[2] << 16) | (ret[1] << 8) |
347            (ret[0] << 0);
348
349        if (ni->start == 0 && hand.nand_ps == 4096 &&
350            hand.fw_args.cpu_id == 0x4740) {
351            printf(" No check! end at page: %d\n", cur_page);
352            fflush(NULL);
353            continue;
354        }
355
356        if (!ni->check(ni->buf, check_buf, ni->length)) {
357            struct nand_in bad;
358            /*
359             * tbd: doesn't the other side skip bad blocks too? Can we just deduct 1 from cur_page?
360             * tbd: why do we only mark a block as bad if the last page in the block was written?
361             */
362            bad.start = (cur_page - 1) / hand.nand_ppb;
363            if (cur_page % hand.nand_ppb == 0)
364                nand_markbad(&bad);
365        }
366
367        printf(" End at page: %d\n", cur_page);
368        fflush(NULL);
369    }
370
371    *start_page = cur_page;
372
373    status = 1;
374err:
375    return status;
376}
377
378int nand_erase(struct nand_in *ni)
379{
380    unsigned int start_blk, blk_num, end_block;
381    unsigned short temp;
382    int cpu;
383    int i;
384
385    start_blk = ni->start;
386    blk_num = ni->length;
387    if (start_blk > (unsigned int)NAND_MAX_BLK_NUM) {
388        printf(" Start block number overflow!\n");
389        return -1;
390    }
391    if (blk_num > (unsigned int)NAND_MAX_BLK_NUM) {
392        printf(" Length block number overflow!\n");
393        return -1;
394    }
395
396    cpu = get_ingenic_cpu();
397    if (cpu != BOOT4740 && cpu != BOOT4750 && cpu != BOOT4760) {
398        printf(" Device unboot! boot it first!\n");
399        return -1;
400    }
401
402    for (i = 0; i < ni->max_chip; i++) {
403        if ((ni->cs_map)[i]==0)
404            continue;
405        printf(" Erasing No.%d device No.%d flash (start_blk %u blk_num %u)......\n",
406               ni->dev, i, start_blk, blk_num);
407
408        usb_send_data_address_to_ingenic(&ingenic_dev, start_blk);
409        usb_send_data_length_to_ingenic(&ingenic_dev, blk_num);
410
411        temp = ((i << 4) & 0xff0) + NAND_ERASE;
412        usb_ingenic_nand_ops(&ingenic_dev, temp);
413
414        usb_read_data_from_ingenic(&ingenic_dev, ret, 8);
415        printf(" Finish!");
416    }
417    end_block = ((ret[3] << 24) |
418             (ret[2] << 16) |
419             (ret[1] << 8) |
420             (ret[0] << 0)) / hand.nand_ppb;
421    printf(" Return: %02x %02x %02x %02x %02x %02x %02x %02x (position %d)\n",
422           ret[0], ret[1], ret[2], ret[3], ret[4], ret[5], ret[6], ret[7], end_block);
423    if (!hand.nand_force_erase) {
424    /* not force erase, show bad block infomation */
425        printf(" There are marked bad blocks: %d\n",
426               end_block - start_blk - blk_num );
427    } else {
428    /* force erase, no bad block infomation can show */
429        printf(" Force erase, no bad block infomation!\n" );
430    }
431
432    return 1;
433}
434
435int nand_program_file(struct nand_in *ni, char *fname)
436{
437
438    int flen, m, j, k;
439    unsigned int start_page = 0, code_len, offset, transfer_size;
440    int fd, status;
441    struct stat fst;
442    struct nand_in n_in;
443
444    status = stat(fname, &fst);
445
446    if (status < 0) {
447        fprintf(stderr, "Error - can't get file size from '%s': %s\n",
448            fname, strerror(errno));
449        return -1;
450    }
451    flen = fst.st_size;
452
453    fd = open(fname, O_RDONLY);
454    if (fd < 0) {
455        fprintf(stderr, "Error - can't open file '%s': %s\n",
456            fname, strerror(errno));
457        return -1;
458    }
459
460    printf(" Programing No.%d device, flen %d, start page %d...\n",ni->dev, flen, ni->start);
461    n_in.start = ni->start / hand.nand_ppb;
462    if (ni->option == NO_OOB) {
463        if (flen % (hand.nand_ppb * hand.nand_ps) == 0)
464            n_in.length = flen / (hand.nand_ps * hand.nand_ppb);
465        else
466            n_in.length = flen / (hand.nand_ps * hand.nand_ppb) + 1;
467    } else {
468        if (flen % (hand.nand_ppb * (hand.nand_ps + hand.nand_os)) == 0)
469            n_in.length = flen /
470                ((hand.nand_ps + hand.nand_os) * hand.nand_ppb);
471        else
472            n_in.length = flen /
473                ((hand.nand_ps + hand.nand_os) * hand.nand_ppb)
474                + 1;
475    }
476    n_in.cs_map = ni->cs_map;
477    n_in.dev = ni->dev;
478    n_in.max_chip = ni->max_chip;
479    if (nand_erase(&n_in) != 1)
480        return -1;
481    if (ni->option == NO_OOB)
482        transfer_size = (hand.nand_ppb * hand.nand_ps);
483    else
484        transfer_size = (hand.nand_ppb * (hand.nand_ps + hand.nand_os));
485
486    m = flen / transfer_size;
487    j = flen % transfer_size;
488    printf(" Size to send %d, transfer_size %d\n", flen, transfer_size);
489    printf(" Image type : %s\n", IMAGE_TYPE[ni->option]);
490    printf(" It will cause %d times buffer transfer.\n", j == 0 ? m : m + 1);
491    fflush(NULL);
492
493    offset = 0;
494    for (k = 0; k < m; k++) {
495        code_len = transfer_size;
496        status = read(fd, code_buf, code_len);
497        if (status < code_len) {
498            fprintf(stderr, "Error - can't read file '%s': %s\n",
499                fname, strerror(errno));
500            return -1;
501        }
502
503        ni->length = code_len; /* code length,not page number! */
504        ni->buf = code_buf;
505        if (nand_program_check(ni, &start_page) == -1)
506            return -1;
507
508        if (start_page - ni->start > hand.nand_ppb)
509            printf(" Info - skip bad block!\n");
510        ni->start = start_page;
511
512        offset += code_len ;
513    }
514
515    if (j) {
516        code_len = j;
517        if (j % hand.nand_ps)
518            j += hand.nand_ps - (j % hand.nand_ps);
519        memset(code_buf, 0, j); /* set all to null */
520
521        status = read(fd, code_buf, code_len);
522
523        if (status < code_len) {
524            fprintf(stderr, "Error - can't read file '%s': %s\n",
525                fname, strerror(errno));
526            return -1;
527        }
528
529        ni->length = j;
530        ni->buf = code_buf;
531        if (nand_program_check(ni, &start_page) == -1)
532            return -1;
533
534        if (start_page - ni->start > hand.nand_ppb)
535            printf(" Info - skip bad block!");
536
537    }
538
539    close(fd);
540    return 1;
541}
542
543int init_nand_in(void)
544{
545    nand_in.buf = code_buf;
546    nand_in.check = error_check;
547    nand_in.dev = 0;
548    nand_in.cs_map = cs;
549    memset(nand_in.cs_map, 0, MAX_DEV_NUM);
550
551    nand_in.max_chip = 16;
552    return 0;
553}
554
555int nand_prog(void)
556{
557    int status = -1;
558    char *image_file;
559    char *help = " Usage: nprog (1) (2) (3) (4) (5)\n"
560        " (1)\tstart page number\n"
561        " (2)\timage file name\n"
562        " (3)\tdevice index number\n"
563        " (4)\tflash index number\n"
564        " (5) image type must be:\n"
565        " \t-n:\tno oob\n"
566        " \t-o:\twith oob no ecc\n"
567        " \t-e:\twith oob and ecc\n";
568
569    if (com_argc != 6) {
570        printf("%s", help);
571        return 0;
572    }
573
574    init_nand_in();
575
576    nand_in.start = atoi(com_argv[1]);
577    image_file = com_argv[2];
578    nand_in.dev = atoi(com_argv[3]);
579
580    (nand_in.cs_map)[atoi(com_argv[4])] = 1;
581    if (!strcmp(com_argv[5], "-e"))
582        nand_in.option = OOB_ECC;
583    else if (!strcmp(com_argv[5], "-o"))
584        nand_in.option = OOB_NO_ECC;
585    else if (!strcmp(com_argv[5], "-n"))
586        nand_in.option = NO_OOB;
587    else
588        printf("%s", help);
589
590    if (hand.nand_plane == 1)
591        nand_program_file(&nand_in, image_file);
592
593    status = 1;
594
595    return status;
596}
597
598int nand_query(void)
599{
600    int cpu, i;
601    unsigned char csn;
602    unsigned short ops;
603
604    if (com_argc < 3) {
605        printf(" Usage: nquery (1) (2)\n"
606               " (1):device index number\n"
607               " (2):flash index number\n");
608        return -1;
609    }
610    init_nand_in();
611
612    nand_in.dev = atoi(com_argv[1]);
613    (nand_in.cs_map)[atoi(com_argv[2])] = 1;
614
615    for (i = 0; i < nand_in.max_chip; i++) {
616        if ((nand_in.cs_map)[i] != 0)
617            break;
618    }
619    if (i >= nand_in.max_chip)
620        return -1;
621
622    cpu = get_ingenic_cpu();
623    if (cpu != BOOT4740 && cpu != BOOT4750 && cpu != BOOT4760) {
624        printf(" Device unboot! boot it first!\n");
625        return -1;
626    }
627
628    csn = i;
629    printf(" ID of No.%d device No.%d flash: \n", nand_in.dev, csn);
630
631    ops = ((csn << 4) & 0xff0) + NAND_QUERY;
632    usb_ingenic_nand_ops(&ingenic_dev, ops);
633    usb_read_data_from_ingenic(&ingenic_dev, ret, 8);
634    printf(" Vendor ID :0x%x \n",(unsigned char)ret[0]);
635    printf(" Product ID :0x%x \n",(unsigned char)ret[1]);
636    printf(" Chip ID :0x%x \n",(unsigned char)ret[2]);
637    printf(" Page ID :0x%x \n",(unsigned char)ret[3]);
638    printf(" Plane ID :0x%x \n",(unsigned char)ret[4]);
639
640    usb_read_data_from_ingenic(&ingenic_dev, ret, 8);
641
642    return 1;
643}
644
645int nand_read(int mode)
646{
647    unsigned int cpu, j;
648    unsigned int start_addr, length, page_num;
649    unsigned char csn;
650    unsigned short temp = 0;
651
652    if (com_argc < 5) {
653        printf(" Usage: nread (1) (2) (3) (4)\n"
654               " 1:start page number\n"
655               " 2:length in byte\n"
656               " 3:device index number\n"
657               " 4:flash index number\n");
658        return -1;
659    }
660
661    init_nand_in();
662
663    nand_in.start = atoi(com_argv[1]);
664    nand_in.length = atoi(com_argv[2]);
665    nand_in.dev = atoi(com_argv[3]);
666
667    csn = atoi(com_argv[4]);
668    start_addr = nand_in.start;
669    length = nand_in.length;
670
671    if (csn >= MAX_DEV_NUM) {
672        printf(" Flash index number overflow!\n");
673        return -1;
674    }
675    nand_in.cs_map[csn] = 1;
676
677    if (start_addr > NAND_MAX_PAGE_NUM || length > NAND_MAX_PAGE_NUM ) {
678        printf(" Page number overflow!\n");
679        return -1;
680    }
681
682    cpu = get_ingenic_cpu();
683    if (cpu != BOOT4740 && cpu != BOOT4750 && cpu != BOOT4760) {
684        printf(" Device unboot! boot it first!\n");
685        return -1;
686    }
687
688    printf(" Reading from No.%d device No.%d flash....\n", nand_in.dev, csn);
689
690    page_num = length / hand.nand_ps +1;
691
692    switch(mode) {
693    case NAND_READ:
694        temp = ((NO_OOB<<12) & 0xf000) + ((csn<<4) & 0xff0) + NAND_READ;
695        break;
696    case NAND_READ_OOB:
697        temp = ((csn<<4) & 0xff0) + NAND_READ_OOB;
698        break;
699    case NAND_READ_RAW:
700        temp = ((NO_OOB<<12) & 0xf000) + ((csn<<4) & 0xff0) +
701            NAND_READ_RAW;
702        break;
703    default:
704        printf(" Unknow mode!\n");
705        return -1;
706    }
707
708    usb_send_data_address_to_ingenic(&ingenic_dev, start_addr);
709    usb_send_data_length_to_ingenic(&ingenic_dev, page_num);
710
711    usb_ingenic_nand_ops(&ingenic_dev, temp);
712
713    usb_read_data_from_ingenic(&ingenic_dev, nand_in.buf, page_num * hand.nand_ps);
714
715    for (j = 0; j < length; j++) {
716        if (j % 16 == 0)
717            printf("\n 0x%08x : ",j);
718        printf("%02x ",(nand_in.buf)[j]);
719    }
720    printf("\n");
721
722    usb_read_data_from_ingenic(&ingenic_dev, ret, 8);
723    printf(" Operation end position : %d \n",
724           (ret[3]<<24)|(ret[2]<<16)|(ret[1]<<8)|(ret[0]<<0));
725
726    return 1;
727}
728
729int debug_memory(unsigned int start, unsigned int size)
730{
731    unsigned int buffer[8],tmp;
732
733    tmp = get_ingenic_cpu();
734    if (tmp == BOOT4740 || tmp == BOOT4750 || tmp == BOOT4760) {
735        printf(" This command only run under UNBOOT state!\n");
736        return -1;
737    }
738
739    switch (tmp) {
740    case 1:
741        tmp = 0;
742        hand.fw_args.cpu_id = 0x4740;
743        break;
744    case 2:
745        tmp = 0;
746        hand.fw_args.cpu_id = 0x4750;
747        break;
748    }
749
750    hand.fw_args.debug_ops = 1;/* tell device it's memory debug */
751    hand.fw_args.start = start;
752
753    if (size == 0)
754        hand.fw_args.size = total_size;
755    else
756        hand.fw_args.size = size;
757
758    printf(" Now test memory from 0x%x to 0x%x: \n",
759           start, start + hand.fw_args.size);
760
761    if (load_file(&ingenic_dev, stage1) < 1)
762        return -1;
763    if (usb_ingenic_upload(&ingenic_dev, 1) < 1)
764        return -1;
765
766    usleep(100);
767    usb_read_data_from_ingenic(&ingenic_dev, (unsigned char *)buffer, 8);
768    if (buffer[0] != 0)
769        printf(" Test memory fail! Last error address is 0x%x !\n",
770               buffer[0]);
771    else
772        printf(" Test memory pass!\n");
773
774    return 1;
775}
776
777int debug_gpio(unsigned char ops, unsigned char pin)
778{
779    unsigned int tmp;
780
781    tmp = get_ingenic_cpu();
782    if (tmp == BOOT4740 || tmp == BOOT4750 || tmp == BOOT4760) {
783        printf(" This command only run under UNBOOT state!\n");
784        return -1;
785    }
786
787    switch (tmp) {
788    case 1:
789        tmp = 0;
790        hand.fw_args.cpu_id = 0x4740;
791        if (pin > 124) {
792            printf(" Jz4740 has 124 GPIO pin in all!\n");
793            return -1;
794        }
795        break;
796    case 2:
797        tmp = 0;
798        hand.fw_args.cpu_id = 0x4750;
799        if (pin > 178) {
800            printf(" Jz4750 has 178 GPIO pin in all!\n");
801            return -1;
802        }
803        break;
804    }
805
806    hand.fw_args.debug_ops = ops;/* tell device it's memory debug */
807    hand.fw_args.pin_num = pin;
808
809    if (ops == 2)
810        printf(" GPIO %d set!\n",pin);
811    else
812        printf(" GPIO %d clear!\n",pin);
813
814    if (load_file(&ingenic_dev, stage1) < 1)
815        return -1;
816    if (usb_ingenic_upload(&ingenic_dev, 1) < 1)
817        return -1;
818
819    return 0;
820}
821
822int debug_go(void)
823{
824    unsigned int addr, obj;
825    if (com_argc<3) {
826        printf(" Usage: go (1) (2) \n"
827               " 1:start SDRAM address\n"
828               " 2:device index number\n");
829        return 0;
830    }
831
832    addr = strtoul(com_argv[1], NULL, 0);
833    obj = atoi(com_argv[2]);
834
835    printf(" Executing No.%d device at address 0x%x\n", obj, addr);
836
837    if (usb_ingenic_start(&ingenic_dev, VR_PROGRAM_START2, addr) < 1)
838        return -1;
839
840    return 1;
841}
842
843int sdram_load(struct sdram_in *si)
844{
845    int cpu = get_ingenic_cpu();
846    if (cpu != BOOT4740 && cpu != BOOT4750 && cpu != BOOT4760) {
847        printf(" Device unboot! boot it first!\n");
848        return -1;
849    }
850
851    if (si->length > (unsigned int) MAX_LOAD_SIZE) {
852        printf(" Image length too long!\n");
853        return -1;
854    }
855
856    ingenic_dev.file_buff = si->buf;
857    ingenic_dev.file_len = si->length;
858    usb_send_data_to_ingenic(&ingenic_dev);
859    usb_send_data_address_to_ingenic(&ingenic_dev, si->start);
860    usb_send_data_length_to_ingenic(&ingenic_dev, si->length);
861    usb_ingenic_sdram_ops(&ingenic_dev, SDRAM_LOAD);
862
863    usb_read_data_from_ingenic(&ingenic_dev, ret, 8);
864    printf(" Load last address at 0x%x\n",
865           ((ret[3]<<24)|(ret[2]<<16)|(ret[1]<<8)|(ret[0]<<0)));
866
867    return 1;
868}
869
870int sdram_load_file(struct sdram_in *si, char *file_path)
871{
872    struct stat fst;
873    unsigned int flen, m, j, k;
874    int fd, status, res = -1;
875
876    status = stat(file_path, &fst);
877    if (status < 0) {
878        fprintf(stderr, "Error - can't get file size from '%s': %s\n",
879            file_path, strerror(errno));
880        goto out;
881    }
882    flen = fst.st_size;
883
884    fd = open(file_path, O_RDONLY);
885    if (fd < 0) {
886        fprintf(stderr, "Error - can't open file '%s': %s\n",
887            file_path, strerror(errno));
888        goto out;
889    }
890
891    m = flen / MAX_LOAD_SIZE;
892    j = flen % MAX_LOAD_SIZE;
893
894    printf(" Total size to send in byte is :%d\n", flen);
895    printf(" Loading data to SDRAM :\n");
896
897    for (k = 0; k < m; k++) {
898        status = read(fd, si->buf, MAX_LOAD_SIZE);
899        if (status < MAX_LOAD_SIZE) {
900            fprintf(stderr, "Error - can't read file '%s': %s\n",
901                file_path, strerror(errno));
902            goto close;
903        }
904
905        si->length = MAX_LOAD_SIZE;
906        if (sdram_load(si) < 1)
907            goto close;
908
909        si->start += MAX_LOAD_SIZE;
910        if ( k % 60 == 0)
911            printf(" 0x%x \n", si->start);
912    }
913
914    if (j) {
915        if (j % 4 !=0)
916            j += 4 - (j % 4);
917        status = read(fd, si->buf, j);
918        if (status < j) {
919            fprintf(stderr, "Error - can't read file '%s': %s\n",
920                file_path, strerror(errno));
921            goto close;
922        }
923
924        si->length = j;
925        if (sdram_load(si) < 1)
926            goto close;
927    }
928
929    res = 1;
930
931close:
932    close(fd);
933out:
934    return res;
935}
936
937int device_reset(int ops)
938{
939    int cpu = get_ingenic_cpu();
940    if (cpu != BOOT4740 && cpu != BOOT4750 && cpu != BOOT4760) {
941        printf(" Device unboot! boot it first!\n");
942        return -1;
943    }
944
945    if (usb_ingenic_reset(&ingenic_dev, ops) < 1)
946        return -1;
947
948    return 1;
949}
950

Archive Download this file



interactive