blob: cf3874c8095a5155c5e098dba10161287cbfaf56 [file] [log] [blame]
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +00001/*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2000 Silicon Integrated System Corporation
5 * Copyright (C) 2004 Tyan Corp <yhlu@tyan.com>
6 * Copyright (C) 2005-2008 coresystems GmbH
7 * Copyright (C) 2008,2009,2010 Carl-Daniel Hailfinger
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
Carl-Daniel Hailfinger831e8f42010-05-30 22:24:40 +000024#include <stdio.h>
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +000025#include <fcntl.h>
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +000026#include <sys/stat.h>
27#include <string.h>
28#include <stdlib.h>
29#include <getopt.h>
30#include "flash.h"
31#include "flashchips.h"
Carl-Daniel Hailfinger5b997c32010-07-27 22:41:39 +000032#include "programmer.h"
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +000033
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +000034static void cli_classic_usage(const char *name)
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +000035{
Carl-Daniel Hailfinger4e3391f2012-07-22 12:01:43 +000036 printf("Usage: flashrom [-h|-R|-L|"
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +000037#if CONFIG_PRINT_WIKI == 1
Carl-Daniel Hailfinger4e3391f2012-07-22 12:01:43 +000038 "-z|"
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +000039#endif
Carl-Daniel Hailfinger4e3391f2012-07-22 12:01:43 +000040 "-p <programmername>[:<parameters>]\n"
41 " [-E|-r <file>|-w <file>|-v <file>] [-c <chipname>]\n"
42 " [-l <file> [-i <image>]] [-n] [-f]]\n"
43 " [-V[V[V]]] [-o <logfile>]\n\n");
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +000044
45 printf("Please note that the command line interface for flashrom has "
46 "changed between\n"
Carl-Daniel Hailfinger4e3391f2012-07-22 12:01:43 +000047 "0.9.5 and 0.9.6 and will change again before flashrom 1.0.\n"
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +000048 "Do not use flashrom in scripts or other automated tools "
49 "without checking\n"
50 "that your flashrom version won't interpret options in a "
51 "different way.\n\n");
52
53 printf(" -h | --help print this help text\n"
54 " -R | --version print version (release)\n"
55 " -r | --read <file> read flash and save to "
56 "<file>\n"
57 " -w | --write <file> write <file> to flash\n"
58 " -v | --verify <file> verify flash against "
59 "<file>\n"
60 " -E | --erase erase flash device\n"
61 " -V | --verbose more verbose output\n"
62 " -c | --chip <chipname> probe only for specified "
63 "flash chip\n"
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +000064 " -f | --force force specific operations "
65 "(see man page)\n"
66 " -n | --noverify don't auto-verify\n"
67 " -l | --layout <file> read ROM layout from "
68 "<file>\n"
69 " -i | --image <name> only flash image <name> "
70 "from flash layout\n"
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +000071 " -o | --output <name> log to file <name>\n"
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +000072 " -L | --list-supported print supported devices\n"
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +000073#if CONFIG_PRINT_WIKI == 1
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +000074 " -z | --list-supported-wiki print supported devices "
75 "in wiki syntax\n"
76#endif
77 " -p | --programmer <name>[:<param>] specify the programmer "
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +000078 "device\n");
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +000079
Carl-Daniel Hailfingera73fb492010-10-06 23:48:34 +000080 list_programmers_linebreak(37, 80, 1);
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +000081 printf("\nYou can specify one of -h, -R, -L, "
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +000082#if CONFIG_PRINT_WIKI == 1
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +000083 "-z, "
84#endif
85 "-E, -r, -w, -v or no operation.\n"
86 "If no operation is specified, flashrom will only probe for "
87 "flash chips.\n\n");
88}
89
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +000090static void cli_classic_abort_usage(void)
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +000091{
Uwe Hermann2db77a02010-06-04 17:07:39 +000092 printf("Please run \"flashrom --help\" for usage info.\n");
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +000093 exit(1);
94}
95
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +000096static int check_filename(char *filename, char *type)
97{
98 if (!filename || (filename[0] == '\0')) {
99 fprintf(stderr, "Error: No %s file specified.\n", type);
100 return 1;
101 }
102 /* Not an error, but maybe the user intended to specify a CLI option instead of a file name. */
103 if (filename[0] == '-')
104 fprintf(stderr, "Warning: Supplied %s file name starts with -\n", type);
105 return 0;
106}
107
Uwe Hermann394ee782011-08-20 14:14:22 +0000108int main(int argc, char *argv[])
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000109{
110 unsigned long size;
111 /* Probe for up to three flash chips. */
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +0000112 const struct flashchip *flash;
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +0000113 struct flashctx flashes[3];
114 struct flashctx *fill_flash;
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000115 const char *name;
Carl-Daniel Hailfingerc40cff72011-12-20 00:19:29 +0000116 int namelen, opt, i, j;
Carl-Daniel Hailfingerb428e972012-02-16 20:31:25 +0000117 int startchip = -1, chipcount = 0, option_index = 0, force = 0;
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +0000118#if CONFIG_PRINT_WIKI == 1
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000119 int list_supported_wiki = 0;
120#endif
Carl-Daniel Hailfinger082c8b52011-08-15 19:54:20 +0000121 int read_it = 0, write_it = 0, erase_it = 0, verify_it = 0;
122 int dont_verify_it = 0, list_supported = 0, operation_specified = 0;
Carl-Daniel Hailfinger2e681602011-09-08 00:00:29 +0000123 enum programmer prog = PROGRAMMER_INVALID;
Carl-Daniel Hailfinger082c8b52011-08-15 19:54:20 +0000124 int ret = 0;
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000125
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +0000126 static const char optstring[] = "r:Rw:v:nVEfc:l:i:p:Lzho:";
Mathias Krausea60faab2011-01-17 07:50:42 +0000127 static const struct option long_options[] = {
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000128 {"read", 1, NULL, 'r'},
129 {"write", 1, NULL, 'w'},
130 {"erase", 0, NULL, 'E'},
131 {"verify", 1, NULL, 'v'},
132 {"noverify", 0, NULL, 'n'},
133 {"chip", 1, NULL, 'c'},
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000134 {"verbose", 0, NULL, 'V'},
135 {"force", 0, NULL, 'f'},
136 {"layout", 1, NULL, 'l'},
137 {"image", 1, NULL, 'i'},
138 {"list-supported", 0, NULL, 'L'},
139 {"list-supported-wiki", 0, NULL, 'z'},
140 {"programmer", 1, NULL, 'p'},
141 {"help", 0, NULL, 'h'},
142 {"version", 0, NULL, 'R'},
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +0000143 {"output", 1, NULL, 'o'},
Uwe Hermann91f4afa2011-07-28 08:13:25 +0000144 {NULL, 0, NULL, 0},
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000145 };
146
147 char *filename = NULL;
Carl-Daniel Hailfinger46284452012-01-11 02:10:11 +0000148 char *layoutfile = NULL;
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +0000149 char *logfile = NULL;
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000150 char *tempstr = NULL;
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000151 char *pparam = NULL;
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000152
153 print_version();
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +0000154 print_banner();
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000155
156 if (selfcheck())
157 exit(1);
158
159 setbuf(stdout, NULL);
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +0000160 /* FIXME: Delay all operation_specified checks until after command
161 * line parsing to allow --help overriding everything else.
162 */
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000163 while ((opt = getopt_long(argc, argv, optstring,
164 long_options, &option_index)) != EOF) {
165 switch (opt) {
166 case 'r':
167 if (++operation_specified > 1) {
168 fprintf(stderr, "More than one operation "
169 "specified. Aborting.\n");
Uwe Hermann2db77a02010-06-04 17:07:39 +0000170 cli_classic_abort_usage();
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000171 }
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +0000172 filename = strdup(optarg);
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000173 read_it = 1;
174 break;
175 case 'w':
176 if (++operation_specified > 1) {
177 fprintf(stderr, "More than one operation "
178 "specified. Aborting.\n");
Uwe Hermann2db77a02010-06-04 17:07:39 +0000179 cli_classic_abort_usage();
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000180 }
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +0000181 filename = strdup(optarg);
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000182 write_it = 1;
183 break;
184 case 'v':
185 //FIXME: gracefully handle superfluous -v
186 if (++operation_specified > 1) {
187 fprintf(stderr, "More than one operation "
188 "specified. Aborting.\n");
Uwe Hermann2db77a02010-06-04 17:07:39 +0000189 cli_classic_abort_usage();
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000190 }
191 if (dont_verify_it) {
192 fprintf(stderr, "--verify and --noverify are"
193 "mutually exclusive. Aborting.\n");
Uwe Hermann2db77a02010-06-04 17:07:39 +0000194 cli_classic_abort_usage();
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000195 }
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +0000196 filename = strdup(optarg);
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000197 verify_it = 1;
198 break;
199 case 'n':
200 if (verify_it) {
201 fprintf(stderr, "--verify and --noverify are"
202 "mutually exclusive. Aborting.\n");
Uwe Hermann2db77a02010-06-04 17:07:39 +0000203 cli_classic_abort_usage();
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000204 }
205 dont_verify_it = 1;
206 break;
207 case 'c':
208 chip_to_probe = strdup(optarg);
209 break;
210 case 'V':
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +0000211 verbose_screen++;
212 if (verbose_screen > MSG_DEBUG2)
213 verbose_logfile = verbose_screen;
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000214 break;
215 case 'E':
216 if (++operation_specified > 1) {
217 fprintf(stderr, "More than one operation "
218 "specified. Aborting.\n");
Uwe Hermann2db77a02010-06-04 17:07:39 +0000219 cli_classic_abort_usage();
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000220 }
221 erase_it = 1;
222 break;
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000223 case 'f':
224 force = 1;
225 break;
226 case 'l':
Carl-Daniel Hailfinger46284452012-01-11 02:10:11 +0000227 if (layoutfile) {
228 fprintf(stderr, "Error: --layout specified "
229 "more than once. Aborting.\n");
Uwe Hermann2db77a02010-06-04 17:07:39 +0000230 cli_classic_abort_usage();
Carl-Daniel Hailfinger46284452012-01-11 02:10:11 +0000231 }
232 layoutfile = strdup(optarg);
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000233 break;
234 case 'i':
235 tempstr = strdup(optarg);
Louis Yung-Chieh Lo9bcf2682011-12-25 09:12:16 +0000236 if (register_include_arg(tempstr))
Carl-Daniel Hailfingerd5660142011-07-15 23:47:45 +0000237 cli_classic_abort_usage();
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000238 break;
239 case 'L':
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +0000240 if (++operation_specified > 1) {
241 fprintf(stderr, "More than one operation "
242 "specified. Aborting.\n");
Uwe Hermann2db77a02010-06-04 17:07:39 +0000243 cli_classic_abort_usage();
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +0000244 }
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000245 list_supported = 1;
246 break;
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000247 case 'z':
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +0000248#if CONFIG_PRINT_WIKI == 1
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +0000249 if (++operation_specified > 1) {
250 fprintf(stderr, "More than one operation "
251 "specified. Aborting.\n");
Uwe Hermann2db77a02010-06-04 17:07:39 +0000252 cli_classic_abort_usage();
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +0000253 }
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000254 list_supported_wiki = 1;
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +0000255#else
256 fprintf(stderr, "Error: Wiki output was not compiled "
257 "in. Aborting.\n");
Uwe Hermann2db77a02010-06-04 17:07:39 +0000258 cli_classic_abort_usage();
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000259#endif
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +0000260 break;
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000261 case 'p':
Carl-Daniel Hailfinger2e681602011-09-08 00:00:29 +0000262 if (prog != PROGRAMMER_INVALID) {
263 fprintf(stderr, "Error: --programmer specified "
264 "more than once. You can separate "
265 "multiple\nparameters for a programmer "
266 "with \",\". Please see the man page "
267 "for details.\n");
268 cli_classic_abort_usage();
269 }
270 for (prog = 0; prog < PROGRAMMER_INVALID; prog++) {
271 name = programmer_table[prog].name;
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000272 namelen = strlen(name);
273 if (strncmp(optarg, name, namelen) == 0) {
274 switch (optarg[namelen]) {
275 case ':':
Carl-Daniel Hailfingerad3cc552010-07-03 11:02:10 +0000276 pparam = strdup(optarg + namelen + 1);
277 if (!strlen(pparam)) {
278 free(pparam);
279 pparam = NULL;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000280 }
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000281 break;
282 case '\0':
283 break;
284 default:
285 /* The continue refers to the
286 * for loop. It is here to be
287 * able to differentiate between
288 * foo and foobar.
289 */
290 continue;
291 }
292 break;
293 }
294 }
Carl-Daniel Hailfinger2e681602011-09-08 00:00:29 +0000295 if (prog == PROGRAMMER_INVALID) {
Carl-Daniel Hailfinger4e3391f2012-07-22 12:01:43 +0000296 fprintf(stderr, "Error: Unknown programmer \"%s\". Valid choices are:\n",
297 optarg);
298 list_programmers_linebreak(0, 80, 0);
Uwe Hermann2db77a02010-06-04 17:07:39 +0000299 cli_classic_abort_usage();
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000300 }
301 break;
302 case 'R':
303 /* print_version() is always called during startup. */
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +0000304 if (++operation_specified > 1) {
305 fprintf(stderr, "More than one operation "
306 "specified. Aborting.\n");
Uwe Hermann2db77a02010-06-04 17:07:39 +0000307 cli_classic_abort_usage();
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +0000308 }
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000309 exit(0);
310 break;
311 case 'h':
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +0000312 if (++operation_specified > 1) {
313 fprintf(stderr, "More than one operation "
314 "specified. Aborting.\n");
Uwe Hermann2db77a02010-06-04 17:07:39 +0000315 cli_classic_abort_usage();
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +0000316 }
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000317 cli_classic_usage(argv[0]);
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +0000318 exit(0);
319 break;
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +0000320 case 'o':
321#ifdef STANDALONE
322 fprintf(stderr, "Log file not supported in standalone mode. Aborting.\n");
323 cli_classic_abort_usage();
324#else /* STANDALONE */
325 logfile = strdup(optarg);
326 if (logfile[0] == '\0') {
327 fprintf(stderr, "No log filename specified.\n");
328 cli_classic_abort_usage();
329 }
330#endif /* STANDALONE */
331 break;
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +0000332 default:
Uwe Hermann2db77a02010-06-04 17:07:39 +0000333 cli_classic_abort_usage();
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000334 break;
335 }
336 }
337
Carl-Daniel Hailfingerd5660142011-07-15 23:47:45 +0000338 if (optind < argc) {
339 fprintf(stderr, "Error: Extra parameter found.\n");
340 cli_classic_abort_usage();
341 }
342
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +0000343 if ((read_it | write_it | verify_it) && check_filename(filename, "image")) {
344 cli_classic_abort_usage();
345 }
346 if (layoutfile && check_filename(layoutfile, "layout")) {
347 cli_classic_abort_usage();
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000348 }
349
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +0000350#ifndef STANDALONE
351 if (logfile && check_filename(logfile, "log"))
352 cli_classic_abort_usage();
353 if (logfile && open_logfile(logfile))
354 return 1;
355#endif /* !STANDALONE */
356
Carl-Daniel Hailfinger71127722010-05-31 15:27:27 +0000357#if CONFIG_PRINT_WIKI == 1
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000358 if (list_supported_wiki) {
359 print_supported_wiki();
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +0000360 ret = 0;
361 goto out;
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000362 }
363#endif
364
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +0000365 if (list_supported) {
366 print_supported();
367 ret = 0;
368 goto out;
369 }
Carl-Daniel Hailfinger46284452012-01-11 02:10:11 +0000370
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +0000371#ifndef STANDALONE
372 start_logging();
373#endif /* !STANDALONE */
374
375 print_buildinfo();
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +0000376 msg_gdbg("Command line (%i args):", argc - 1);
377 for (i = 0; i < argc; i++) {
378 msg_gdbg(" %s", argv[i]);
379 }
380 msg_gdbg("\n");
381
382 if (layoutfile && read_romlayout(layoutfile)) {
383 ret = 1;
384 goto out;
385 }
386 if (process_include_args()) {
387 ret = 1;
388 goto out;
389 }
Carl-Daniel Hailfinger63fd9022011-12-14 22:25:15 +0000390 /* Does a chip with the requested name exist in the flashchips array? */
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000391 if (chip_to_probe) {
392 for (flash = flashchips; flash && flash->name; flash++)
393 if (!strcmp(flash->name, chip_to_probe))
394 break;
395 if (!flash || !flash->name) {
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +0000396 msg_cerr("Error: Unknown chip '%s' specified.\n", chip_to_probe);
397 msg_gerr("Run flashrom -L to view the hardware supported in this flashrom version.\n");
398 ret = 1;
399 goto out;
Carl-Daniel Hailfinger27023762010-04-28 15:22:14 +0000400 }
401 /* Clean up after the check. */
402 flash = NULL;
403 }
Carl-Daniel Hailfinger8841d3e2010-05-15 15:04:37 +0000404
Carl-Daniel Hailfinger4e3391f2012-07-22 12:01:43 +0000405 if (prog == PROGRAMMER_INVALID) {
406 msg_perr("Please select a programmer with the --programmer parameter.\n"
407 "Valid choices are:\n");
408 list_programmers_linebreak(0, 80, 0);
409 ret = 1;
410 goto out;
411 }
Carl-Daniel Hailfinger2e681602011-09-08 00:00:29 +0000412
Carl-Daniel Hailfinger49884202010-05-22 07:10:46 +0000413 /* FIXME: Delay calibration should happen in programmer code. */
414 myusec_calibrate_delay();
415
Carl-Daniel Hailfinger2e681602011-09-08 00:00:29 +0000416 if (programmer_init(prog, pparam)) {
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +0000417 msg_perr("Error: Programmer initialization failed.\n");
Carl-Daniel Hailfingerd5660142011-07-15 23:47:45 +0000418 ret = 1;
419 goto out_shutdown;
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000420 }
Carl-Daniel Hailfingerc40cff72011-12-20 00:19:29 +0000421 tempstr = flashbuses_to_text(get_buses_supported());
422 msg_pdbg("The following protocols are supported: %s.\n",
Carl-Daniel Hailfingereaacd2d2011-11-09 23:40:00 +0000423 tempstr);
424 free(tempstr);
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000425
Carl-Daniel Hailfingerc40cff72011-12-20 00:19:29 +0000426 for (j = 0; j < registered_programmer_count; j++) {
427 startchip = 0;
Michael Karcher222bf102011-12-22 23:27:03 +0000428 while (chipcount < ARRAY_SIZE(flashes)) {
Carl-Daniel Hailfingerc40cff72011-12-20 00:19:29 +0000429 startchip = probe_flash(&registered_programmers[j],
Michael Karcher222bf102011-12-22 23:27:03 +0000430 startchip,
431 &flashes[chipcount], 0);
Carl-Daniel Hailfingerc40cff72011-12-20 00:19:29 +0000432 if (startchip == -1)
433 break;
434 chipcount++;
435 startchip++;
436 }
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000437 }
438
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +0000439 if (chipcount > 1) {
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +0000440 msg_cinfo("Multiple flash chips were detected: \"%s\"", flashes[0].name);
Stefan Tauner716e0982011-07-25 20:38:52 +0000441 for (i = 1; i < chipcount; i++)
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +0000442 msg_cinfo(", \"%s\"", flashes[i].name);
443 msg_cinfo("\nPlease specify which chip to use with the -c <chipname> option.\n");
Carl-Daniel Hailfingerd5660142011-07-15 23:47:45 +0000444 ret = 1;
445 goto out_shutdown;
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +0000446 } else if (!chipcount) {
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +0000447 msg_cinfo("No EEPROM/flash device found.\n");
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000448 if (!force || !chip_to_probe) {
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +0000449 msg_cinfo("Note: flashrom can never write if the flash chip isn't found "
450 "automatically.\n");
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000451 }
452 if (force && read_it && chip_to_probe) {
Carl-Daniel Hailfingerb428e972012-02-16 20:31:25 +0000453 struct registered_programmer *pgm;
454 int compatible_programmers = 0;
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +0000455 msg_cinfo("Force read (-f -r -c) requested, pretending the chip is there:\n");
Carl-Daniel Hailfingerb428e972012-02-16 20:31:25 +0000456 /* This loop just counts compatible controllers. */
457 for (j = 0; j < registered_programmer_count; j++) {
458 pgm = &registered_programmers[j];
459 if (pgm->buses_supported & flashes[0].bustype)
460 compatible_programmers++;
461 }
462 if (compatible_programmers > 1)
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +0000463 msg_cinfo("More than one compatible controller found for the requested flash "
464 "chip, using the first one.\n");
Carl-Daniel Hailfingerb428e972012-02-16 20:31:25 +0000465 for (j = 0; j < registered_programmer_count; j++) {
466 pgm = &registered_programmers[j];
467 startchip = probe_flash(pgm, 0, &flashes[0], 1);
468 if (startchip != -1)
469 break;
470 }
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +0000471 if (startchip == -1) {
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +0000472 msg_cinfo("Probing for flash chip '%s' failed.\n", chip_to_probe);
Carl-Daniel Hailfingerd5660142011-07-15 23:47:45 +0000473 ret = 1;
474 goto out_shutdown;
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000475 }
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +0000476 msg_cinfo("Please note that forced reads most likely contain garbage.\n");
477 ret = read_flash_to_file(&flashes[0], filename);
478 goto out_shutdown;
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000479 }
Carl-Daniel Hailfingerd5660142011-07-15 23:47:45 +0000480 ret = 1;
481 goto out_shutdown;
Stefan Tauner1d947632011-09-11 22:08:58 +0000482 } else if (!chip_to_probe) {
483 /* repeat for convenience when looking at foreign logs */
484 tempstr = flashbuses_to_text(flashes[0].bustype);
485 msg_gdbg("Found %s flash chip \"%s\" (%d kB, %s).\n",
486 flashes[0].vendor, flashes[0].name,
487 flashes[0].total_size, tempstr);
488 free(tempstr);
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000489 }
490
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +0000491 fill_flash = &flashes[0];
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000492
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +0000493 check_chip_supported(fill_flash);
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000494
Carl-Daniel Hailfinger4c823182011-05-04 00:39:50 +0000495 size = fill_flash->total_size * 1024;
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +0000496 if (check_max_decode(fill_flash->pgm->buses_supported & fill_flash->bustype, size) && (!force)) {
497 msg_cerr("Chip is too big for this programmer (-V gives details). Use --force to override.\n");
Carl-Daniel Hailfingerd5660142011-07-15 23:47:45 +0000498 ret = 1;
499 goto out_shutdown;
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000500 }
501
502 if (!(read_it | write_it | verify_it | erase_it)) {
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +0000503 msg_ginfo("No operations were specified.\n");
Carl-Daniel Hailfingerd5660142011-07-15 23:47:45 +0000504 goto out_shutdown;
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000505 }
506
507 /* Always verify write operations unless -n is used. */
508 if (write_it && !dont_verify_it)
509 verify_it = 1;
510
Carl-Daniel Hailfinger9ad42552010-09-15 10:20:16 +0000511 /* FIXME: We should issue an unconditional chip reset here. This can be
512 * done once we have a .reset function in struct flashchip.
513 * Give the chip time to settle.
514 */
515 programmer_delay(100000);
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +0000516 ret |= doit(fill_flash, force, filename, read_it, write_it, erase_it, verify_it);
517 /* Note: doit() already calls programmer_shutdown(). */
518 goto out;
Carl-Daniel Hailfingerd5660142011-07-15 23:47:45 +0000519
520out_shutdown:
521 programmer_shutdown();
Carl-Daniel Hailfinger901a3ba2012-05-14 22:54:58 +0000522out:
Carl-Daniel Hailfinger1c155482012-06-06 09:17:06 +0000523#ifndef STANDALONE
524 ret |= close_logfile();
525#endif /* !STANDALONE */
Carl-Daniel Hailfingerd5660142011-07-15 23:47:45 +0000526 return ret;
Carl-Daniel Hailfingera84835a2010-01-07 03:24:05 +0000527}