Root/usbboot/src/command_line.c

1/*
2 * Copyright(C) 2009 Qi Hardware Inc.,
3 * Authors: Xiangfu Liu <xiangfu@qi-hardware.com>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22#include <ctype.h>
23#include <fcntl.h>
24#include <unistd.h>
25
26#include "usb_boot_defines.h"
27#include "ingenic_usb.h"
28#include "cmd.h"
29#include "xburst-tools_version.h"
30#include "nand.h"
31#include "mem.h"
32
33extern struct nand_in nand_in;
34extern struct sdram_in sdram_in;
35static char code_buf[4 * 512 * 1024];
36extern struct ingenic_dev ingenic_dev;
37typedef int (*command_callback_t)(size_t argc, char *argv[]);
38
39struct command {
40    const char *name;
41    command_callback_t callback;
42};
43
44#define COMMAND(_name, _callback) {\
45    .name = _name, \
46    .callback = (command_callback_t)_callback, \
47}
48
49static const char COMMANDS[][COMMAND_NUM]=
50{
51    "go",
52    "fconfig",
53    "boot", /* index 20 */
54    "list",
55    "select",
56    "unselect",
57    "chip",
58    "unchip",
59    "nmark",
60    "nmake",
61    "load",
62    "memtest",
63    "run",
64};
65
66static unsigned long parse_number(const char *s, int *err)
67{
68    unsigned long val = 0;
69    unsigned int base = 10;
70    char *endptr;
71
72    if (s == 0 || *s == 0) {
73        if (err)
74            *err = 1;
75        return 0;
76    }
77
78    if (*s == '0') {
79        ++s;
80        if (*s == 'x') {
81            base = 16;
82            ++s;
83        } else if (*s != 0) {
84            base = 8;
85        }
86    } else if (*s == 'b') {
87        ++s;
88        base = 2;
89    }
90
91    val = strtoul(s, &endptr, base);
92
93    if (*endptr) {
94        if (err)
95            *err = 1;
96        return 0;
97    }
98
99    if (err)
100        *err = 0;
101
102    return val;
103}
104
105static unsigned long parse_number_print_error(const char *s, int *err)
106{
107    unsigned long value;
108    int err2 = 0;
109    value = parse_number(s, &err2);
110    if (err2) {
111        fprintf(stderr, "Error: %s is not a number\n", s);
112        if (err)
113            ++err;
114    }
115
116    return value;
117}
118
119static int handle_exit()
120{
121    exit(0);
122    return 0;
123}
124
125static int handle_help()
126{
127    printf(" command support in current version:\n"
128    /* " query" */
129    /* " querya" */
130    /* " erase" */
131    /* " read" */
132    /* " prog" */
133    " nquery query NAND flash info\n"
134    " nerase erase NAND flash\n"
135    " nread read NAND flash data with checking bad block and ECC\n"
136    " nreadraw read NAND flash data without checking bad block and ECC\n"
137    " nreadoo read NAND flash oob without checking bad block and ECC\n" /* index 10 */
138    " nprog program NAND flash with data and ECC\n"
139    " ndump dump NAND flash data to file\n"
140    " help print this help\n"
141    " version show current USB Boot software version\n"
142    " go execute program in SDRAM\n"
143    " fconfig set USB Boot config file(not implement)\n"
144    " exit quit from current session\n"
145    " readnand read data from nand flash and store to SDRAM\n"
146    " boot boot device and make it in stage2\n" /* index 20 */
147    " list show current device number can connect(not implement)\n"
148    /* " select" */
149    /* " unselect" */
150    /* " chip" */
151    /* " unchip" */
152    " nmark mark a bad block in NAND flash\n"
153    " nmake read all data from nand flash and store to file(not implement)\n"
154    " load load file data to SDRAM\n"
155    " memtest do SDRAM test\n"
156    " run run command script in file(implement by -c args)\n"
157    " sdprog program SD card(not implement)\n"
158    " sdread read data from SD card(not implement)\n");
159
160    return 0;
161}
162
163static int handle_version()
164{
165    printf("USB Boot Software current version: %s\n", XBURST_TOOLS_VERSION);
166
167    return 0;
168}
169
170static int handle_boot()
171{
172    boot(&ingenic_dev, STAGE1_FILE_PATH, STAGE2_FILE_PATH);
173
174    return 0;
175}
176
177static int handle_nand_erase(size_t argc, char *argv[])
178{
179    uint32_t start_block, num_blocks;
180    unsigned int device_idx;
181    uint8_t nand_idx;
182    int err;
183
184    if (argc < 5) {
185        printf(" Usage: nerase (1) (2) (3) (4)\n"
186               " 1:start block number\n"
187               " 2:block length\n"
188               " 3:device index number\n"
189               " 4:flash chip index number\n");
190        return -1;
191    }
192
193    start_block = parse_number_print_error(argv[1], &err);
194    num_blocks = parse_number_print_error(argv[2], &err);
195    device_idx = parse_number_print_error(argv[3], &err);
196    nand_idx = parse_number_print_error(argv[4], &err);
197    if (err)
198        return err;
199
200    if (nand_idx >= MAX_DEV_NUM) {
201        printf(" Flash index number overflow!\n");
202        return -1;
203    }
204
205    if (nand_erase(&ingenic_dev, nand_idx, start_block, num_blocks))
206        return -1;
207
208    return 0;
209}
210
211static int handle_nand_mark(size_t argc, char *argv[])
212{
213    uint32_t block;
214    unsigned int device_idx;
215    uint8_t nand_idx;
216    int err = 0;
217
218    if (argc < 4) {
219        printf("Usage: nerase (1) (2) (3)\n"
220               "1: bad block number\n"
221               "2: device index number\n"
222               "3: flash chip index number\n");
223        return -1;
224    }
225
226    block = parse_number_print_error(argv[1], &err);
227    device_idx = parse_number_print_error(argv[2], &err);
228    nand_idx = parse_number_print_error(argv[3], &err);
229    if (err)
230        return err;
231
232    if (nand_idx >= MAX_DEV_NUM) {
233        printf("Flash index number overflow!\n");
234        return -1;
235    }
236
237    nand_markbad(&ingenic_dev, nand_idx, block);
238
239    return 0;
240}
241
242static int handle_memtest(size_t argc, char *argv[])
243{
244    unsigned int device_idx;
245    unsigned int start, size;
246    int err = 0;
247
248    if (argc != 2 && argc != 4)
249    {
250        printf(" Usage: memtest (1) [2] [3]\n"
251               " 1: device index number\n"
252               " 2: SDRAM start address\n"
253               " 3: test size\n");
254        return -1;
255    }
256
257    if (argc == 4) {
258        start = parse_number_print_error(argv[2], &err);
259        size = parse_number_print_error(argv[3], &err);
260    } else {
261        start = 0;
262        size = 0;
263    }
264    device_idx = parse_number_print_error(argv[1], &err);
265    if (err)
266        return err;
267
268    debug_memory(&ingenic_dev, device_idx, start, size);
269    return 0;
270}
271
272static int handle_load(size_t argc, char *argv[])
273{
274    if (argc != 4) {
275        printf(" Usage:"
276               " load (1) (2) (3) \n"
277               " 1:SDRAM start address\n"
278               " 2:image file name\n"
279               " 3:device index number\n");
280
281        return -1;
282    }
283
284    sdram_in.start=strtoul(argv[1], NULL, 0);
285    printf(" start:::::: 0x%x\n", sdram_in.start);
286
287    sdram_in.dev = atoi(argv[3]);
288    sdram_in.buf = code_buf;
289    sdram_load_file(&ingenic_dev, &sdram_in, argv[2]);
290    return 0;
291}
292
293static size_t command_parse(char *cmd, char *argv[])
294{
295    size_t argc = 0;
296
297    if (cmd == 0 || *cmd == 0)
298        return 0;
299
300
301    while (isspace(*cmd)) {
302        ++cmd;
303    }
304
305    argv[0] = cmd;
306    argc = 1;
307
308    while (*cmd) {
309        if (isspace(*cmd)) {
310            *cmd = 0;
311
312            do {
313                ++cmd;
314            } while (isspace(*cmd));
315
316            if (*cmd == 0 || argc >= MAX_ARGC)
317                break;
318
319            argv[argc] = cmd;
320            ++argc;
321        }
322
323        ++cmd;
324    }
325
326    return argc;
327}
328
329static int nand_read_callback(void *data, const char *buf, size_t size)
330{
331    return 0;
332}
333
334static int handle_nand_read(size_t argc, char *argv[])
335{
336    int mode;
337    uint32_t start_page, num_pages;
338    unsigned int device_idx;
339    uint8_t nand_idx;
340    int err = 0;
341
342    if (argc != 5) {
343        printf("Usage: %s <start page> <length> <device index> "
344                    "<nand chip index>\n", argv[0]);
345        return -1;
346    }
347
348    if (strcmp(argv[0], "nread") == 0) {
349        mode = NAND_READ;
350    } else if (strcmp(argv[0], "nreadraw") == 0) {
351        mode = NAND_READ_RAW;
352    } else if (strcmp(argv[0], "nreadoob") == 0) {
353        mode = NAND_READ_OOB;
354    } else {
355        return -1;
356    }
357
358    start_page = parse_number_print_error(argv[1], &err);
359    num_pages = parse_number_print_error(argv[2], &err);
360    device_idx = parse_number_print_error(argv[3], &err);
361    nand_idx = parse_number_print_error(argv[4], &err);
362    if (err)
363        return err;
364
365    return nand_read(&ingenic_dev, nand_idx, mode, start_page, num_pages, 0,
366                    nand_read_callback, NULL);
367}
368
369static int nand_dump_callback(void *data, const char *buf, size_t size)
370{
371    int fd = *(int*)(data);
372
373    write(fd, buf, size);
374
375    return 0;
376}
377
378static int handle_nand_dump(size_t argc, char *argv[])
379{
380    int mode;
381    uint32_t start_page, num_pages;
382    uint8_t nand_idx;
383    int err = 0;
384    int fd;
385
386    if (argc != 5) {
387        printf("Usage: %s <start page> <length> <filename> <mode>\n", argv[0]);
388        return -1;
389    }
390
391    if (strcmp(argv[4], "-n") == 0) {
392        mode = NAND_READ;
393    } else if (strcmp(argv[4], "-e") == 0) {
394        mode = NAND_READ_RAW;
395    } else if (strcmp(argv[4], "-o") == 0) {
396        mode = NAND_READ_OOB;
397    } else {
398        return -1;
399    }
400
401    start_page = parse_number_print_error(argv[1], &err);
402    num_pages = parse_number_print_error(argv[2], &err);
403/* device_idx = parse_number_print_error(argv[3], &err);*/
404    nand_idx = 0;
405    if (err)
406        return err;
407
408    fd = creat(argv[3], 0644);
409
410    err = nand_read(&ingenic_dev, nand_idx, mode, start_page, num_pages, 0,
411                    nand_dump_callback, &fd);
412
413    close(fd);
414
415    return err;
416}
417
418static int handle_nand_query(size_t argc, char *argv[])
419{
420    unsigned int device_idx;
421    uint8_t nand_idx;
422    int err = 0;
423
424    if (argc != 3) {
425        printf("Usage: %s <device index> <nand chip index>\n", argv[0]);
426        return -1;
427    }
428
429    device_idx = parse_number_print_error(argv[1], &err);
430    nand_idx = parse_number_print_error(argv[2], &err);
431    if (err)
432        return err;
433
434    return nand_query(&ingenic_dev, nand_idx);
435}
436
437static int handle_nand_prog(size_t argc, char *argv[])
438{
439    uint32_t start_page;
440    unsigned int device_idx;
441    uint8_t nand_idx, mode = -1;
442    int err = 0;
443
444    if (argc != 6) {
445        printf("Usage: %s <start page> <filename> <device index> <nand chip index> <mode>\n", argv[0]);
446        return -1;
447    }
448
449    start_page = parse_number_print_error(argv[1], &err);
450    device_idx = parse_number_print_error(argv[3], &err);
451    nand_idx = parse_number_print_error(argv[4], &err);
452
453    if (argv[5][0] == '-') {
454        switch (argv[5][1]) {
455        case 'e':
456            mode = NO_OOB;
457            break;
458        case 'o':
459            mode = OOB_NO_ECC;
460            break;
461        case 'r':
462            mode = OOB_ECC;
463            break;
464        default:
465            break;
466        }
467    }
468    if (mode == -1) {
469        printf("%s: Invalid mode '%s'\n", argv[0], argv[5]);
470        err = -1;
471    }
472
473    if (err)
474        return err;
475
476
477    nand_prog(&ingenic_dev, nand_idx, start_page, argv[2], mode);
478
479    return 0;
480}
481
482static int handle_mem_read(size_t argc, char *argv[])
483{
484    uint32_t addr;
485    uint32_t val;
486    int err = 0;
487    if (argc != 2)
488        printf("Usage: %s <addr>\n", argv[0]);
489
490    addr = parse_number_print_error(argv[1], &err);
491    if (err)
492        return err;
493
494    switch (argv[0][7]) {
495    case '8':
496        val = mem_read8(&ingenic_dev, addr);
497        break;
498    case '1':
499        val = mem_read16(&ingenic_dev, addr);
500        break;
501    default:
502        val = mem_read32(&ingenic_dev, addr);
503        break;
504    }
505
506    printf("0x%x = 0x%x\n", addr, val);
507
508    return 0;
509}
510
511static int handle_mem_write(size_t argc, char *argv[])
512{
513    uint32_t addr;
514    uint32_t val;
515    int err = 0;
516
517    if (argc != 3)
518        printf("Usage: %s <addr> <value>\n", argv[0]);
519
520    addr = parse_number_print_error(argv[1], &err);
521    val = parse_number_print_error(argv[2], &err);
522    if (err)
523        return err;
524
525    switch (argv[0][8]) {
526    case '8':
527        mem_write8(&ingenic_dev, addr, val);
528        break;
529    case '1':
530        mem_write16(&ingenic_dev, addr, val);
531        break;
532    default:
533        mem_write32(&ingenic_dev, addr, val);
534        break;
535    }
536
537    printf("0x%x = 0x%x\n", addr, val);
538
539    return 0;
540}
541
542
543static const struct command commands[] = {
544    COMMAND("version", handle_version),
545    COMMAND("help", handle_help),
546    COMMAND("nquery", handle_nand_query),
547    COMMAND("nerase", handle_nand_erase),
548    COMMAND("nread", handle_nand_read),
549    COMMAND("nreadraw", handle_nand_read),
550    COMMAND("nreadoo", handle_nand_read),
551    COMMAND("nprog", handle_nand_prog),
552    COMMAND("nwrite", handle_nand_prog),
553    COMMAND("nmark", handle_nand_mark),
554    COMMAND("ndump", handle_nand_dump),
555    COMMAND("exit", handle_exit),
556    COMMAND("boot", handle_boot),
557    COMMAND("memread", handle_mem_read),
558    COMMAND("memwrite", handle_mem_write),
559    COMMAND("memread16", handle_mem_read),
560    COMMAND("memwrite16", handle_mem_write),
561    COMMAND("memread8", handle_mem_read),
562    COMMAND("memwrite8", handle_mem_write),
563    COMMAND("memtest", handle_memtest),
564    COMMAND("load", handle_load),
565};
566
567int command_handle(char *buf)
568{
569    size_t argc;
570    char *argv[MAX_ARGC];
571    size_t i;
572
573    argc = command_parse(buf, argv);
574
575    if (argc == 0)
576        return 0;
577
578    for (i = 0; i < ARRAY_SIZE(commands); ++i) {
579        if (strcmp(commands[i].name, argv[0]) == 0)
580            return commands[i].callback(argc, argv);
581    }
582
583    printf("Unknow command \"%s\"\n", argv[0]);
584
585    return -1;
586}
587

Archive Download this file



interactive