FreeCalypso > hg > freecalypso-sw
comparison loadtools/flmain.c @ 405:a212b4968b29
fc-loadtool flash: another refactoring: geometry vs. command set
| author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
|---|---|
| date | Tue, 17 Jun 2014 00:33:05 +0000 |
| parents | loadtools/ltflash.c@7ceeec049be4 |
| children | 0b8e5072abde |
comparison
equal
deleted
inserted
replaced
| 404:7daea2476062 | 405:a212b4968b29 |
|---|---|
| 1 /* | |
| 2 * This module is the main entry point for fc-loadtool flash functions | |
| 3 */ | |
| 4 | |
| 5 #include <sys/types.h> | |
| 6 #include <stdio.h> | |
| 7 #include <stdint.h> | |
| 8 #include <string.h> | |
| 9 #include <strings.h> | |
| 10 #include <stdlib.h> | |
| 11 #include "flash.h" | |
| 12 | |
| 13 /* K5A32xx device description */ | |
| 14 | |
| 15 static struct flash_geom k5a32xx_topboot_geom = { | |
| 16 .total_size = 0x400000, | |
| 17 .nregions = 2, | |
| 18 .regions = {0x10000, 63, 0x2000, 8}, | |
| 19 .total_sectors = 71, | |
| 20 }; | |
| 21 | |
| 22 static struct flash_idcheck k5a32xx_topboot_idcheck[2] = { | |
| 23 {0x00, 0x00EC}, | |
| 24 {0x02, 0x22A0} | |
| 25 }; | |
| 26 | |
| 27 static struct flash_bank_desc k5a32xx_topboot_bankdesc = { | |
| 28 0x400000, &k5a32xx_topboot_geom, k5a32xx_topboot_idcheck, 2 | |
| 29 }; | |
| 30 | |
| 31 /* S{29,71}PL129N device description */ | |
| 32 | |
| 33 static struct flash_geom pl129n_ce1_geom = { | |
| 34 .total_size = 0x800000, | |
| 35 .nregions = 2, | |
| 36 .regions = {0x10000, 4, 0x40000, 31}, | |
| 37 .total_sectors = 35, | |
| 38 }; | |
| 39 | |
| 40 static struct flash_geom pl129n_ce2_geom = { | |
| 41 .total_size = 0x800000, | |
| 42 .nregions = 2, | |
| 43 .regions = {0x40000, 31, 0x10000, 4}, | |
| 44 .total_sectors = 35, | |
| 45 }; | |
| 46 | |
| 47 static struct flash_idcheck pl129n_idcheck[4] = { | |
| 48 {0x00, 0x0001}, | |
| 49 {0x02, 0x227E}, | |
| 50 {0x1C, 0x2221}, | |
| 51 {0x1E, 0x2200} | |
| 52 }; | |
| 53 | |
| 54 static struct flash_bank_desc pl129n_banks[2] = { | |
| 55 {0x800000, &pl129n_ce1_geom, pl129n_idcheck, 4}, | |
| 56 {0x800000, &pl129n_ce2_geom, pl129n_idcheck, 4} | |
| 57 }; | |
| 58 | |
| 59 /* bank configurations for CFI */ | |
| 60 | |
| 61 static struct flash_bank_desc cfi_4M_bankdesc = { | |
| 62 0x400000, 0, 0, 0 | |
| 63 }; | |
| 64 | |
| 65 static struct flash_bank_desc cfi_8M_bankdesc = { | |
| 66 0x800000, 0, 0, 0 | |
| 67 }; | |
| 68 | |
| 69 /* list of supported flash devices */ | |
| 70 | |
| 71 extern struct flash_cmdset flash_cmdset_amd; | |
| 72 | |
| 73 struct flash_device_desc flash_device_list[] = { | |
| 74 {"cfi-4M", &cfi_4M_bankdesc, 1, 0}, | |
| 75 {"cfi-8M", &cfi_8M_bankdesc, 1, 0}, | |
| 76 {"k5a32xx_t", &k5a32xx_topboot_bankdesc, 1, &flash_cmdset_amd}, | |
| 77 {"pl129n", pl129n_banks, 2, &flash_cmdset_amd}, | |
| 78 {0, 0, 0, 0} /* array terminator */ | |
| 79 }; | |
| 80 | |
| 81 /* the following variables describe our selected flash device */ | |
| 82 | |
| 83 struct flash_device_desc *selected_flash_device; | |
| 84 struct flash_bank_info flash_bank_info[2]; | |
| 85 | |
| 86 /* called from hwparam.c config file parser */ | |
| 87 void | |
| 88 set_flash_device(arg, filename_for_errs, lineno_for_errs) | |
| 89 char *arg; | |
| 90 char *filename_for_errs; | |
| 91 int lineno_for_errs; | |
| 92 { | |
| 93 char *cp, *np, *ep; | |
| 94 struct flash_device_desc *tp; | |
| 95 int bank; | |
| 96 struct flash_bank_info *bi; | |
| 97 | |
| 98 if (selected_flash_device) { | |
| 99 fprintf(stderr, "%s line %d: duplicate flash setting\n", | |
| 100 filename_for_errs, lineno_for_errs); | |
| 101 exit(1); | |
| 102 } | |
| 103 for (cp = arg; isspace(*cp); cp++) | |
| 104 ; | |
| 105 if (!*cp || *cp == '#') { | |
| 106 too_few_arg: fprintf(stderr, | |
| 107 "%s line %d: flash setting: too few arguments\n", | |
| 108 filename_for_errs, lineno_for_errs); | |
| 109 exit(1); | |
| 110 } | |
| 111 for (np = cp; *cp && !isspace(*cp); cp++) | |
| 112 ; | |
| 113 if (*cp) | |
| 114 *cp++ = '\0'; | |
| 115 for (tp = flash_device_list; tp->name; tp++) | |
| 116 if (!strcmp(tp->name, np)) | |
| 117 break; | |
| 118 if (!tp->name) { | |
| 119 fprintf(stderr, | |
| 120 "%s line %d: unknown flash device \"%s\"\n", | |
| 121 filename_for_errs, lineno_for_errs, np); | |
| 122 exit(1); | |
| 123 } | |
| 124 selected_flash_device = tp; | |
| 125 | |
| 126 /* now initialize flash_bank_info */ | |
| 127 for (bank = 0; bank < selected_flash_device->nbanks; bank++) { | |
| 128 while (isspace(*cp)) | |
| 129 cp++; | |
| 130 if (!*cp || *cp == '#') | |
| 131 goto too_few_arg; | |
| 132 for (np = cp; *cp && !isspace(*cp); cp++) | |
| 133 ; | |
| 134 if (*cp) | |
| 135 *cp++ = '\0'; | |
| 136 bi = flash_bank_info + bank; | |
| 137 bi->base_addr = strtoul(np, &ep, 16); | |
| 138 if (*ep) { | |
| 139 fprintf(stderr, | |
| 140 "%s line %d: syntax error (base addr expected after flash device type)\n", | |
| 141 filename_for_errs, lineno_for_errs); | |
| 142 exit(1); | |
| 143 } | |
| 144 /* the rest comes from the flash device type */ | |
| 145 bi->bank_desc = selected_flash_device->bank_desc + bank; | |
| 146 if (bi->base_addr & (bi->bank_desc->align_size - 1)) { | |
| 147 fprintf(stderr, | |
| 148 "%s line %d: flash bank %d base addr is not aligned to the bank size (0x%lx)\n", | |
| 149 filename_for_errs, lineno_for_errs, bank, | |
| 150 (u_long) bi->bank_desc->align_size); | |
| 151 exit(1); | |
| 152 } | |
| 153 bi->geom = bi->bank_desc->geom; | |
| 154 bi->ops = selected_flash_device->cmdset; | |
| 155 } | |
| 156 while (isspace(*cp)) | |
| 157 cp++; | |
| 158 if (*cp && *cp != '#') { | |
| 159 fprintf(stderr, | |
| 160 "%s line %d: flash setting: too many arguments\n", | |
| 161 filename_for_errs, lineno_for_errs); | |
| 162 exit(1); | |
| 163 } | |
| 164 } | |
| 165 | |
| 166 flashcmd_help() | |
| 167 { | |
| 168 return loadtool_help("flash"); | |
| 169 } | |
| 170 | |
| 171 flashcmd_info(argc, argv, bank) | |
| 172 char **argv; | |
| 173 { | |
| 174 struct flash_bank_info *bi; | |
| 175 | |
| 176 if (argc > 2) { | |
| 177 fprintf(stderr, "error: too many arguments\n"); | |
| 178 return(-1); | |
| 179 } | |
| 180 bi = flash_bank_info + bank; | |
| 181 printf("Flash device type: %s\n", selected_flash_device->name); | |
| 182 printf("Bank %d base address: %08lX\n", bank, (u_long) bi->base_addr); | |
| 183 if (flash_get_cfi(bank) < 0) | |
| 184 return(-1); | |
| 185 printf("Bank %d total size: %lx\n", bank, | |
| 186 (u_long) bi->geom->total_size); | |
| 187 printf("Sectors in bank %d: %u (%u regions)\n", bank, | |
| 188 bi->geom->total_sectors, bi->geom->nregions); | |
| 189 printf("Command set style: %s\n", bi->ops->cmdset_name); | |
| 190 flash_id_check(bank, 1); | |
| 191 if (selected_flash_device->nbanks == 2 && !bank) | |
| 192 printf("\nFlash device has 2 banks; flash2 command available\n"); | |
| 193 return(0); | |
| 194 } | |
| 195 | |
| 196 extern int flashcmd_blankchk(); | |
| 197 extern int flashcmd_dump2file(); | |
| 198 extern int flashcmd_erase(); | |
| 199 extern int flashcmd_progbin(); | |
| 200 extern int flashcmd_program_m0(); | |
| 201 extern int flashcmd_program_srec(); | |
| 202 extern int flashcmd_quickprog(); | |
| 203 extern int flashcmd_sectors(); | |
| 204 | |
| 205 static struct cmdtab { | |
| 206 char *cmd; | |
| 207 int (*func)(); | |
| 208 } cmdtab[] = { | |
| 209 {"blankchk", flashcmd_blankchk}, | |
| 210 {"dump2bin", flashcmd_dump2file}, | |
| 211 {"dump2srec", flashcmd_dump2file}, | |
| 212 {"erase", flashcmd_erase}, | |
| 213 {"help", flashcmd_help}, | |
| 214 {"info", flashcmd_info}, | |
| 215 {"program-bin", flashcmd_progbin}, | |
| 216 {"program-m0", flashcmd_program_m0}, | |
| 217 {"program-srec", flashcmd_program_srec}, | |
| 218 {"quickprog", flashcmd_quickprog}, | |
| 219 {"sectors", flashcmd_sectors}, | |
| 220 {0, 0} | |
| 221 }; | |
| 222 | |
| 223 cmd_flash(argc, argv) | |
| 224 char **argv; | |
| 225 { | |
| 226 int bank; | |
| 227 struct cmdtab *tp; | |
| 228 | |
| 229 if (!selected_flash_device) { | |
| 230 fprintf(stderr, "No flash configuration defined\n"); | |
| 231 return(-1); | |
| 232 } | |
| 233 if (argv[0][5] == '2') { | |
| 234 if (selected_flash_device->nbanks < 2) { | |
| 235 fprintf(stderr, "Flash device %s has only one bank\n", | |
| 236 selected_flash_device->name); | |
| 237 return(-1); | |
| 238 } | |
| 239 bank = 1; | |
| 240 } else | |
| 241 bank = 0; | |
| 242 for (tp = cmdtab; tp->cmd; tp++) | |
| 243 if (!strcmp(tp->cmd, argv[1])) | |
| 244 break; | |
| 245 if (!tp->func) { | |
| 246 fprintf(stderr, "%s %s: unknown/unimplemented subcommand\n", | |
| 247 argv[0], argv[1]); | |
| 248 return(-1); | |
| 249 } | |
| 250 return tp->func(argc, argv, bank); | |
| 251 } |
