FreeCalypso > hg > freecalypso-tools
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 } |