FreeCalypso > hg > freecalypso-sw
view loadtools/ltflash.c @ 58:1f9302b6f342
fc-loadtool: started flash/flash2 command implementation
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Mon, 24 Jun 2013 06:30:57 +0000 |
parents | d98137625c0d |
children | 048329d0888e |
line wrap: on
line source
/* * In this module we are going to implement the flash operation commands * of fc-loadtool. */ #include <sys/types.h> #include <stdio.h> #include <stdint.h> #include <string.h> #include <strings.h> #include <stdlib.h> #include "flash.h" /* S{29,71}PL129N device description */ static struct flash_region_desc pl129n_ce1_regions[] = { /* 4 sectors of 64 KiB each at the beginning, then 256 KiB sectors */ {0x10000, 4}, {0x40000, 31}, {0, 0} /* array terminator */ }; static struct flash_region_desc pl129n_ce2_regions[] = { /* the other way around now */ {0x40000, 31}, {0x10000, 4}, {0, 0} /* array terminator */ }; static struct flash_bank_desc pl129n_banks[2] = { {pl129n_ce1_regions, 0xFFFC0000}, {pl129n_ce2_regions, 0xFFFC0000} }; /* list of supported flash devices */ struct flash_device_desc flash_device_list[] = { {"pl129n", pl129n_banks, 2}, {0, 0, 0} /* array terminator */ }; /* the following variables describe our selected flash device */ struct flash_device_desc *selected_flash_device; struct flash_bank_info flash_bank_info[2]; /* called from hwparam.c config file parser */ void set_flash_device(arg, filename_for_errs, lineno_for_errs) char *arg; char *filename_for_errs; int lineno_for_errs; { char *cp, *np, *ep; struct flash_device_desc *tp; int bank; struct flash_bank_info *bi; if (selected_flash_device) { fprintf(stderr, "%s line %d: duplicate flash setting\n", filename_for_errs, lineno_for_errs); exit(1); } for (cp = arg; isspace(*cp); cp++) ; if (!*cp || *cp == '#') { too_few_arg: fprintf(stderr, "%s line %d: flash setting: too few arguments\n", filename_for_errs, lineno_for_errs); exit(1); } for (np = cp; *cp && !isspace(*cp); cp++) ; if (*cp) *cp++ = '\0'; for (tp = flash_device_list; tp->name; tp++) if (!strcmp(tp->name, np)) break; if (!tp->name) { fprintf(stderr, "%s line %d: unknown flash device \"%s\"\n", filename_for_errs, lineno_for_errs, np); exit(1); } selected_flash_device = tp; /* now initialize flash_bank_info */ for (bank = 0; bank < selected_flash_device->nbanks; bank++) { while (isspace(*cp)) cp++; if (!*cp || *cp == '#') goto too_few_arg; for (np = cp; *cp && !isspace(*cp); cp++) ; if (*cp) *cp++ = '\0'; bi = flash_bank_info + bank; bi->base_addr = strtoul(np, &ep, 16); if (*ep) { fprintf(stderr, "%s line %d: syntax error (base addr expected after flash device type)\n", filename_for_errs, lineno_for_errs); exit(1); } /* the rest comes from the flash device type */ bi->bank_desc = selected_flash_device->bank_desc + bank; compute_flash_totsize_nsecs(bank); if (count_ones(bi->total_size) != 1) { fprintf(stderr, "fc-loadtool internal bug: flash bank %d size for %s is not a power of 2\n", bank, selected_flash_device->name); exit(1); } if (bi->base_addr & (bi->total_size - 1)) { fprintf(stderr, "%s line %d: flash bank %d base addr is not aligned to the bank size (0x%lx)\n", filename_for_errs, lineno_for_errs, bank, (u_long) bi->total_size); exit(1); } } while (isspace(*cp)) cp++; if (*cp && *cp != '#') { fprintf(stderr, "%s line %d: flash setting: too many arguments\n", filename_for_errs, lineno_for_errs); exit(1); } } flashcmd_blankchk(argc, argv, bank) char **argv; { printf("To be implemented\n"); return(1); } flashcmd_dump2file(argc, argv, bank) char **argv; { struct flash_bank_info *bi; u_long offset, dumplen, maxlen; char *strtoul_endp; int format; if (argc < 3 || argc > 5) { inv: fprintf(stderr, "usage: %s %s outfile [offset [length]]\n", argv[0], argv[1]); return(-1); } bi = flash_bank_info + bank; if (argc >= 4) { offset = strtoul(argv[3], &strtoul_endp, 16); if (*strtoul_endp) goto inv; if (offset >= bi->total_size) { fprintf(stderr, "error: specified offset exceeds flash bank size (0x%lx)\n", (u_long) bi->total_size); return(-1); } } else offset = 0; maxlen = bi->total_size - offset; if (argc >= 5) { dumplen = strtoul(argv[4], &strtoul_endp, 16); if (*strtoul_endp) goto inv; if (dumplen > maxlen) { fprintf(stderr, "error: specified offset+length exceed flash bank size (0x%lx)\n", (u_long) bi->total_size); return(-1); } } else dumplen = maxlen; switch (argv[1][5]) { case 'b': format = 0; break; case 's': format = 1; break; default: fprintf(stderr, "internal bug: bad format in flashcmd_dump2file()\n"); return(-1); } return loadtool_memdump(bi->base_addr + offset, dumplen, argv[2], format); } flashcmd_info(argc, argv, bank) char **argv; { struct flash_bank_info *bi; if (argc > 2) { fprintf(stderr, "error: too many arguments\n"); return(-1); } bi = flash_bank_info + bank; printf("Flash device type: %s\n", selected_flash_device->name); printf("Bank %d base address: %08lX\n", bank, (u_long) bi->base_addr); printf("Bank %d total size: %lx\n", bank, (u_long) bi->total_size); printf("Sectors in bank %d: %u\n", bank, bi->nsectors); if (selected_flash_device->nbanks == 2 && !bank) printf("\nFlash device has 2 banks; flash2 command available\n"); return(0); } static struct cmdtab { char *cmd; int (*func)(); } cmdtab[] = { {"blankchk", flashcmd_blankchk}, {"dump2bin", flashcmd_dump2file}, {"dump2srec", flashcmd_dump2file}, {"info", flashcmd_info}, {0, 0} }; cmd_flash(argc, argv) char **argv; { int bank; struct cmdtab *tp; if (!selected_flash_device) { fprintf(stderr, "No flash configuration defined\n"); return(-1); } if (argv[0][5] == '2') { if (selected_flash_device->nbanks < 2) { fprintf(stderr, "Flash device %s has only one bank\n", selected_flash_device->name); return(-1); } bank = 1; } else bank = 0; for (tp = cmdtab; tp->cmd; tp++) if (!strcmp(tp->cmd, argv[1])) break; if (!tp->func) { fprintf(stderr, "%s %s: unknown/unimplemented subcommand\n", argv[0], argv[1]); return(-1); } return tp->func(argc, argv, bank); }