FreeCalypso > hg > freecalypso-tools
view loadtools/flmain.c @ 416:30f6d1c32c6f
doc/Flash-boot-defect article removed (no longer relevant)
This article is no longer relevant because the issue in question
only affected one (1) defective FCDEV3B board which was not
and never will be sold.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 26 Oct 2018 07:11:08 +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); }