FreeCalypso > hg > freecalypso-tools
view loadtools/flmain.c @ 437:2cd705c8116e
loadtools: Mot C155 turns out to have the same flash partition quirks
as the flash chip on TI's D-Sample
c155.config changed to use the fixed 28f640w30b config instead of CFI,
and a bit of C code in fc-loadtool had to be changed too so that
flash erase-program-boot still works.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 06 Nov 2018 16:02:23 +0000 |
parents | 545e1718f5fb |
children | 0dd2c87c1b63 |
line wrap: on
line source
/* * This module is the main entry point for fc-loadtool flash functions */ #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <stdint.h> #include <string.h> #include <strings.h> #include <stdlib.h> #include "flash.h" /* K5A32xx device description */ static struct flash_geom k5a32xx_topboot_geom = { .total_size = 0x400000, .nregions = 2, .regions = {0x10000, 63, 0x2000, 8}, .total_sectors = 71, }; static struct flash_idcheck k5a32xx_topboot_idcheck[2] = { {0x00, 0x00EC}, {0x02, 0x22A0} }; static struct flash_bank_desc k5a32xx_topboot_bankdesc = { 0x400000, &k5a32xx_topboot_geom, k5a32xx_topboot_idcheck, 2 }; /* S{29,71}PL129N device description */ static struct flash_geom pl129n_ce1_geom = { .total_size = 0x800000, .nregions = 2, .regions = {0x10000, 4, 0x40000, 31}, .total_sectors = 35, }; static struct flash_geom pl129n_ce2_geom = { .total_size = 0x800000, .nregions = 2, .regions = {0x40000, 31, 0x10000, 4}, .total_sectors = 35, }; static struct flash_idcheck pl129n_idcheck[4] = { {0x00, 0x0001}, {0x02, 0x227E}, {0x1C, 0x2221}, {0x1E, 0x2200} }; static struct flash_bank_desc pl129n_banks[2] = { {0x800000, &pl129n_ce1_geom, pl129n_idcheck, 4}, {0x800000, &pl129n_ce2_geom, pl129n_idcheck, 4} }; /* 28F640W30B device description */ static struct flash_geom f640w30b_geom = { .total_size = 0x800000, .nregions = 2, .regions = {0x2000, 8, 0x10000, 127}, .total_sectors = 135, }; static struct flash_idcheck f640w30b_idcheck[2] = { {0x00, 0x0089}, {0x02, 0x8855} }; static struct flash_bank_desc f640w30b_bankdesc = { 0x800000, &f640w30b_geom, f640w30b_idcheck, 2 }; /* bank configurations for CFI */ static struct flash_bank_desc cfi_4M_bankdesc = { 0x400000, 0, 0, 0 }; static struct flash_bank_desc cfi_8M_bankdesc = { 0x800000, 0, 0, 0 }; /* list of supported flash devices */ extern struct flash_cmdset flash_cmdset_amd; extern struct flash_cmdset flash_cmdset_intel_w30; struct flash_device_desc flash_device_list[] = { {"cfi-4M", &cfi_4M_bankdesc, 1, 0}, {"cfi-8M", &cfi_8M_bankdesc, 1, 0}, {"k5a32xx_t", &k5a32xx_topboot_bankdesc, 1, &flash_cmdset_amd}, {"pl129n", pl129n_banks, 2, &flash_cmdset_amd}, {"28f640w30b", &f640w30b_bankdesc, 1, &flash_cmdset_intel_w30}, {0, 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; if (bi->base_addr & (bi->bank_desc->align_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->bank_desc->align_size); exit(1); } bi->geom = bi->bank_desc->geom; bi->ops = selected_flash_device->cmdset; } 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_help() { return loadtool_help("flash"); } 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); if (flash_get_cfi(bank) < 0) return(-1); printf("Bank %d total size: %lx\n", bank, (u_long) bi->geom->total_size); printf("Sectors in bank %d: %u (%u regions)\n", bank, bi->geom->total_sectors, bi->geom->nregions); printf("Command set style: %s\n", bi->ops->cmdset_name); flash_id_check(bank, 1); if (selected_flash_device->nbanks == 2 && !bank) printf("\nFlash device has 2 banks; flash2 command available\n"); return(0); } extern int flashcmd_blankchk(); extern int flashcmd_dump2file(); extern int flashcmd_erase(); extern int flashcmd_erase_program_boot(); extern int flashcmd_progbin(); extern int flashcmd_program_m0(); extern int flashcmd_program_srec(); extern int flashcmd_quickprog(); extern int flashcmd_reset(); extern int flashcmd_sectors(); extern int flashcmd_status(); extern int flashcmd_unlock(); static struct cmdtab { char *cmd; int (*func)(); } cmdtab[] = { {"blankchk", flashcmd_blankchk}, {"dump2bin", flashcmd_dump2file}, {"dump2srec", flashcmd_dump2file}, {"erase", flashcmd_erase}, {"erase-program-boot", flashcmd_erase_program_boot}, {"help", flashcmd_help}, {"info", flashcmd_info}, {"program-bin", flashcmd_progbin}, {"program-m0", flashcmd_program_m0}, {"program-srec", flashcmd_program_srec}, {"quickprog", flashcmd_quickprog}, {"reset", flashcmd_reset}, {"sectors", flashcmd_sectors}, {"status", flashcmd_status}, {"unlock", flashcmd_unlock}, {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); }