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 }