comparison loadtools/flmain.c @ 0:e7502631a0f9

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