FreeCalypso > hg > freecalypso-sw
comparison loadtools/flmisc.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 * Miscellaneous flash commands (fc-loadtool) are implemented here | |
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 extern struct flash_bank_info flash_bank_info[2]; | |
14 | |
15 flashcmd_blankchk(argc, argv, bank) | |
16 char **argv; | |
17 { | |
18 struct flash_bank_info *bi; | |
19 u_long offset, len; | |
20 char *strtoul_endp; | |
21 char *targv[4], targ_start[10], targ_len[10]; | |
22 | |
23 if (argc != 4) { | |
24 inv: fprintf(stderr, "usage: %s %s hex-start-offset hex-length\n", | |
25 argv[0], argv[1]); | |
26 return(-1); | |
27 } | |
28 offset = strtoul(argv[2], &strtoul_endp, 16); | |
29 if (*strtoul_endp) | |
30 goto inv; | |
31 if (flash_get_cfi(bank) < 0) | |
32 return(-1); | |
33 bi = flash_bank_info + bank; | |
34 if (offset >= bi->geom->total_size) { | |
35 fprintf(stderr, | |
36 "error: specified offset exceeds flash bank size (0x%lx)\n", | |
37 (u_long) bi->geom->total_size); | |
38 return(-1); | |
39 } | |
40 len = strtoul(argv[3], &strtoul_endp, 16); | |
41 if (*strtoul_endp) | |
42 goto inv; | |
43 if (len > bi->geom->total_size - offset) { | |
44 fprintf(stderr, | |
45 "error: specified offset+length exceed flash bank size (0x%lx)\n", | |
46 (u_long) bi->geom->total_size); | |
47 return(-1); | |
48 } | |
49 sprintf(targ_start, "%lx", (u_long) bi->base_addr + offset); | |
50 sprintf(targ_len, "%lx", len); | |
51 targv[0] = "blankchk"; | |
52 targv[1] = targ_start; | |
53 targv[2] = targ_len; | |
54 targv[3] = 0; | |
55 tpinterf_make_cmd(targv); | |
56 if (tpinterf_send_cmd() < 0) | |
57 return(-1); | |
58 return tpinterf_pass_output(10); /* 10 s timeout */ | |
59 } | |
60 | |
61 flashcmd_dump2file(argc, argv, bank) | |
62 char **argv; | |
63 { | |
64 struct flash_bank_info *bi; | |
65 u_long offset, dumplen, maxlen; | |
66 char *strtoul_endp; | |
67 int format; | |
68 | |
69 if (argc < 3 || argc > 5) { | |
70 inv: fprintf(stderr, "usage: %s %s outfile [offset [length]]\n", | |
71 argv[0], argv[1]); | |
72 return(-1); | |
73 } | |
74 if (flash_get_cfi(bank) < 0) | |
75 return(-1); | |
76 bi = flash_bank_info + bank; | |
77 if (argc >= 4) { | |
78 offset = strtoul(argv[3], &strtoul_endp, 16); | |
79 if (*strtoul_endp) | |
80 goto inv; | |
81 if (offset >= bi->geom->total_size) { | |
82 fprintf(stderr, | |
83 "error: specified offset exceeds flash bank size (0x%lx)\n", | |
84 (u_long) bi->geom->total_size); | |
85 return(-1); | |
86 } | |
87 } else | |
88 offset = 0; | |
89 maxlen = bi->geom->total_size - offset; | |
90 if (argc >= 5) { | |
91 dumplen = strtoul(argv[4], &strtoul_endp, 16); | |
92 if (*strtoul_endp) | |
93 goto inv; | |
94 if (dumplen > maxlen) { | |
95 fprintf(stderr, | |
96 "error: specified offset+length exceed flash bank size (0x%lx)\n", | |
97 (u_long) bi->geom->total_size); | |
98 return(-1); | |
99 } | |
100 } else | |
101 dumplen = maxlen; | |
102 switch (argv[1][5]) { | |
103 case 'b': | |
104 format = 0; | |
105 break; | |
106 case 's': | |
107 format = 1; | |
108 break; | |
109 default: | |
110 fprintf(stderr, | |
111 "internal bug: bad format in flashcmd_dump2file()\n"); | |
112 return(-1); | |
113 } | |
114 return loadtool_memdump(bi->base_addr + offset, dumplen, argv[2], | |
115 format); | |
116 } | |
117 | |
118 flashcmd_erase(argc, argv, bank) | |
119 char **argv; | |
120 { | |
121 struct flash_bank_info *bi; | |
122 u_long offset, len; | |
123 char *strtoul_endp; | |
124 struct sector_info *startsec, *endsec, *sp; | |
125 int stat; | |
126 | |
127 if (argc != 4) { | |
128 inv: fprintf(stderr, "usage: %s %s hex-start-offset hex-length\n", | |
129 argv[0], argv[1]); | |
130 return(-1); | |
131 } | |
132 offset = strtoul(argv[2], &strtoul_endp, 16); | |
133 if (*strtoul_endp) | |
134 goto inv; | |
135 if (flash_get_cfi(bank) < 0) | |
136 return(-1); | |
137 bi = flash_bank_info + bank; | |
138 if (offset >= bi->geom->total_size) { | |
139 fprintf(stderr, | |
140 "error: specified offset exceeds flash bank size (0x%lx)\n", | |
141 (u_long) bi->geom->total_size); | |
142 return(-1); | |
143 } | |
144 len = strtoul(argv[3], &strtoul_endp, 16); | |
145 if (*strtoul_endp) | |
146 goto inv; | |
147 if (len > bi->geom->total_size - offset) { | |
148 fprintf(stderr, | |
149 "error: specified offset+length exceed flash bank size (0x%lx)\n", | |
150 (u_long) bi->geom->total_size); | |
151 return(-1); | |
152 } | |
153 if (!len) { | |
154 printf("Zero length specified - nothing to do!\n"); | |
155 return(0); | |
156 } | |
157 /* now enforce sector alignment for both offset and length */ | |
158 if (get_flash_sector_table(bank) < 0) | |
159 return(-1); | |
160 if (get_flash_sector_range(bi, offset, len, &startsec, &endsec) < 0) | |
161 return(-1); | |
162 stat = flash_id_check(bank, 0); | |
163 if (stat) | |
164 return(stat); | |
165 printf("Erasing %d sector(s)\n", endsec - startsec); | |
166 for (sp = startsec; sp < endsec; sp++) { | |
167 stat = bi->ops->erase_sector(bi, sp); | |
168 if (stat) | |
169 return(stat); | |
170 putchar('.'); | |
171 fflush(stdout); | |
172 } | |
173 putchar('\n'); | |
174 return(0); | |
175 } | |
176 | |
177 flashcmd_quickprog(argc, argv, bank) | |
178 char **argv; | |
179 { | |
180 struct flash_bank_info *bi; | |
181 char *targv[4], targ_base[10]; | |
182 int stat; | |
183 | |
184 if (flash_get_cfi(bank) < 0) | |
185 return(-1); | |
186 if (argc != 4) { | |
187 fprintf(stderr, "usage: %s %s hex-offset hex-data-string\n", | |
188 argv[0], argv[1]); | |
189 return(-1); | |
190 } | |
191 bi = flash_bank_info + bank; | |
192 sprintf(targ_base, "%lx", (u_long) bi->base_addr); | |
193 targv[0] = bi->ops->loadagent_setbase_cmd; | |
194 targv[1] = targ_base; | |
195 targv[2] = 0; | |
196 tpinterf_make_cmd(targv); | |
197 if (tpinterf_send_cmd() < 0) | |
198 return(-1); | |
199 stat = tpinterf_pass_output(1); | |
200 if (stat) | |
201 return(stat); | |
202 targv[0] = bi->ops->loadagent_program_cmd; | |
203 targv[1] = argv[2]; | |
204 targv[2] = argv[3]; | |
205 targv[3] = 0; | |
206 if (tpinterf_make_cmd(targv) < 0) { | |
207 fprintf(stderr, | |
208 "error: unable to form AMFW/INFW target command\n"); | |
209 return(-1); | |
210 } | |
211 if (tpinterf_send_cmd() < 0) | |
212 return(-1); | |
213 return tpinterf_pass_output(1); | |
214 } |