flashrom.c 25.9 KB
Newer Older
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
1
/*
2
 * This file is part of the flashrom project.
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
3
 *
4 5
 * Copyright (C) 2000 Silicon Integrated System Corporation
 * Copyright (C) 2004 Tyan Corp <yhlu@tyan.com>
6
 * Copyright (C) 2005-2008 coresystems GmbH
7
 * Copyright (C) 2008,2009 Carl-Daniel Hailfinger
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
8
 *
9 10 11 12
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
13
 *
14 15 16 17
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
18
 *
19 20 21
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
22 23 24
 */

#include <fcntl.h>
25 26
#include <sys/types.h>
#include <sys/stat.h>
Ronald G. Minnich's avatar
Ronald G. Minnich committed
27
#include <string.h>
Ronald G. Minnich's avatar
Ronald G. Minnich committed
28
#include <stdlib.h>
29
#include <getopt.h>
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
30
#include "flash.h"
31
#include "flashchips.h"
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
32

33
const char *flashrom_version = FLASHROM_VERSION;
Ronald G. Minnich's avatar
Ronald G. Minnich committed
34
char *chip_to_probe = NULL;
Peter Stuge's avatar
Peter Stuge committed
35
int verbose = 0;
36
enum programmer programmer = PROGRAMMER_INTERNAL;
37
char *programmer_param = NULL;
38 39 40

const struct programmer_entry programmer_table[] = {
	{
41
		.name			= "internal",
42 43
		.init			= internal_init,
		.shutdown		= internal_shutdown,
44 45
		.map_flash_region	= physmap,
		.unmap_flash_region	= physunmap,
46 47 48
		.chip_readb		= internal_chip_readb,
		.chip_readw		= internal_chip_readw,
		.chip_readl		= internal_chip_readl,
49
		.chip_readn		= internal_chip_readn,
50 51 52
		.chip_writeb		= internal_chip_writeb,
		.chip_writew		= internal_chip_writew,
		.chip_writel		= internal_chip_writel,
53
		.chip_writen		= fallback_chip_writen,
54
		.delay			= internal_delay,
55 56
	},

57
	{
58
		.name			= "dummy",
59 60
		.init			= dummy_init,
		.shutdown		= dummy_shutdown,
61 62
		.map_flash_region	= dummy_map,
		.unmap_flash_region	= dummy_unmap,
63 64 65
		.chip_readb		= dummy_chip_readb,
		.chip_readw		= dummy_chip_readw,
		.chip_readl		= dummy_chip_readl,
66
		.chip_readn		= dummy_chip_readn,
67 68 69
		.chip_writeb		= dummy_chip_writeb,
		.chip_writew		= dummy_chip_writew,
		.chip_writel		= dummy_chip_writel,
70
		.chip_writen		= dummy_chip_writen,
71
		.delay			= internal_delay,
72 73
	},

74
	{
75
		.name			= "nic3com",
76 77
		.init			= nic3com_init,
		.shutdown		= nic3com_shutdown,
78 79
		.map_flash_region	= fallback_map,
		.unmap_flash_region	= fallback_unmap,
80
		.chip_readb		= nic3com_chip_readb,
81 82
		.chip_readw		= fallback_chip_readw,
		.chip_readl		= fallback_chip_readl,
83
		.chip_readn		= fallback_chip_readn,
84
		.chip_writeb		= nic3com_chip_writeb,
85 86
		.chip_writew		= fallback_chip_writew,
		.chip_writel		= fallback_chip_writel,
87
		.chip_writen		= fallback_chip_writen,
88
		.delay			= internal_delay,
89 90
	},

91
	{
92
		.name			= "satasii",
93 94
		.init			= satasii_init,
		.shutdown		= satasii_shutdown,
95 96
		.map_flash_region	= fallback_map,
		.unmap_flash_region	= fallback_unmap,
97 98 99
		.chip_readb		= satasii_chip_readb,
		.chip_readw		= fallback_chip_readw,
		.chip_readl		= fallback_chip_readl,
100
		.chip_readn		= fallback_chip_readn,
101 102 103
		.chip_writeb		= satasii_chip_writeb,
		.chip_writew		= fallback_chip_writew,
		.chip_writel		= fallback_chip_writel,
104
		.chip_writen		= fallback_chip_writen,
105
		.delay			= internal_delay,
106 107
	},

108
	{
109
		.name			= "it87spi",
110
		.init			= it87spi_init,
111 112 113
		.shutdown		= fallback_shutdown,
		.map_flash_region	= fallback_map,
		.unmap_flash_region	= fallback_unmap,
114
		.chip_readb		= dummy_chip_readb,
115 116 117
		.chip_readw		= fallback_chip_readw,
		.chip_readl		= fallback_chip_readl,
		.chip_readn		= fallback_chip_readn,
118
		.chip_writeb		= fallback_chip_writeb,
119 120 121
		.chip_writew		= fallback_chip_writew,
		.chip_writel		= fallback_chip_writel,
		.chip_writen		= fallback_chip_writen,
122
		.delay			= internal_delay,
123 124
	},

125
#if FT2232_SPI_SUPPORT == 1
126
	{
127
		.name			= "ft2232spi",
128
		.init			= ft2232_spi_init,
129 130 131
		.shutdown		= fallback_shutdown,
		.map_flash_region	= fallback_map,
		.unmap_flash_region	= fallback_unmap,
132 133 134 135
		.chip_readb		= dummy_chip_readb,
		.chip_readw		= fallback_chip_readw,
		.chip_readl		= fallback_chip_readl,
		.chip_readn		= fallback_chip_readn,
136
		.chip_writeb		= fallback_chip_writeb,
137 138 139 140 141
		.chip_writew		= fallback_chip_writew,
		.chip_writel		= fallback_chip_writel,
		.chip_writen		= fallback_chip_writen,
		.delay			= internal_delay,
	},
142
#endif
143

144
#if SERPROG_SUPPORT == 1
145
	{
146
		.name			= "serprog",
147 148 149 150 151 152 153 154 155 156 157 158 159 160
		.init			= serprog_init,
		.shutdown		= serprog_shutdown,
		.map_flash_region	= fallback_map,
		.unmap_flash_region	= fallback_unmap,
		.chip_readb		= serprog_chip_readb,
		.chip_readw		= fallback_chip_readw,
		.chip_readl		= fallback_chip_readl,
		.chip_readn		= serprog_chip_readn,
		.chip_writeb		= serprog_chip_writeb,
		.chip_writew		= fallback_chip_writew,
		.chip_writel		= fallback_chip_writel,
		.chip_writen		= fallback_chip_writen,
		.delay			= serprog_delay,
	},
161
#endif
162

163
	{}, /* This entry corresponds to PROGRAMMER_INVALID. */
164
};
165

166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
int programmer_init(void)
{
	return programmer_table[programmer].init();
}

int programmer_shutdown(void)
{
	return programmer_table[programmer].shutdown();
}

void *programmer_map_flash_region(const char *descr, unsigned long phys_addr,
				  size_t len)
{
	return programmer_table[programmer].map_flash_region(descr,
							     phys_addr, len);
}

void programmer_unmap_flash_region(void *virt_addr, size_t len)
{
	programmer_table[programmer].unmap_flash_region(virt_addr, len);
}

void chip_writeb(uint8_t val, chipaddr addr)
{
	programmer_table[programmer].chip_writeb(val, addr);
}

void chip_writew(uint16_t val, chipaddr addr)
{
	programmer_table[programmer].chip_writew(val, addr);
}

void chip_writel(uint32_t val, chipaddr addr)
{
	programmer_table[programmer].chip_writel(val, addr);
}

203 204 205 206 207
void chip_writen(uint8_t *buf, chipaddr addr, size_t len)
{
	programmer_table[programmer].chip_writen(buf, addr, len);
}

208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
uint8_t chip_readb(const chipaddr addr)
{
	return programmer_table[programmer].chip_readb(addr);
}

uint16_t chip_readw(const chipaddr addr)
{
	return programmer_table[programmer].chip_readw(addr);
}

uint32_t chip_readl(const chipaddr addr)
{
	return programmer_table[programmer].chip_readl(addr);
}

223 224 225 226 227
void chip_readn(uint8_t *buf, chipaddr addr, size_t len)
{
	programmer_table[programmer].chip_readn(buf, addr, len);
}

228 229 230 231 232
void programmer_delay(int usecs)
{
	programmer_table[programmer].delay(usecs);
}

233
void map_flash_registers(struct flashchip *flash)
234 235
{
	size_t size = flash->total_size * 1024;
236
	/* Flash registers live 4 MByte below the flash. */
237
	/* FIXME: This is incorrect for nonstandard flashbase. */
238
	flash->virtual_registers = (chipaddr)programmer_map_flash_region("flash chip registers", (0xFFFFFFFF - 0x400000 - size + 1), size);
239 240
}

241
int read_memmapped(struct flashchip *flash, uint8_t *buf, int start, int len)
242
{
243
	chip_readn(buf, flash->virtual_memory + start, len);
244 245 246 247
		
	return 0;
}

248 249 250 251 252
int min(int a, int b)
{
	return (a < b) ? a : b;
}

253 254 255 256 257
int max(int a, int b)
{
	return (a > b) ? a : b;
}

258 259 260 261 262 263 264 265 266
char *strcat_realloc(char *dest, const char *src)
{
	dest = realloc(dest, strlen(dest) + strlen(src) + 1);
	if (!dest)
		return NULL;
	strcat(dest, src);
	return dest;
}

267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
/* start is an offset to the base address of the flash chip */
int check_erased_range(struct flashchip *flash, int start, int len)
{
	int ret;
	uint8_t *cmpbuf = malloc(len);

	if (!cmpbuf) {
		fprintf(stderr, "Could not allocate memory!\n");
		exit(1);
	}
	memset(cmpbuf, 0xff, len);
	ret = verify_range(flash, cmpbuf, start, len, "ERASE");
	free(cmpbuf);
	return ret;
}

/**
 * @cmpbuf	buffer to compare against
 * @start	offset to the base address of the flash chip
 * @len		length of the verified area
 * @message	string to print in the "FAILED" message
 * @return	0 for success, -1 for failure
 */
int verify_range(struct flashchip *flash, uint8_t *cmpbuf, int start, int len, char *message)
{
	int i, j, starthere, lenhere, ret = 0;
	int page_size = flash->page_size;
	uint8_t *readbuf = malloc(page_size);
295
	int failcount = 0;
296 297 298 299

	if (!len)
		goto out_free;

300 301 302 303
	if (!flash->read) {
		fprintf(stderr, "ERROR: flashrom has no read function for this flash chip.\n");
		return 1;
	}
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
	if (!readbuf) {
		fprintf(stderr, "Could not allocate memory!\n");
		exit(1);
	}

	if (start + len > flash->total_size * 1024) {
		fprintf(stderr, "Error: %s called with start 0x%x + len 0x%x >"
			" total_size 0x%x\n", __func__, start, len,
			flash->total_size * 1024);
		ret = -1;
		goto out_free;
	}
	if (!message)
		message = "VERIFY";
	
	/* Warning: This loop has a very unusual condition and body.
	 * The loop needs to go through each page with at least one affected
	 * byte. The lowest page number is (start / page_size) since that
	 * division rounds down. The highest page number we want is the page
	 * where the last byte of the range lives. That last byte has the
	 * address (start + len - 1), thus the highest page number is
	 * (start + len - 1) / page_size. Since we want to include that last
	 * page as well, the loop condition uses <=.
	 */
	for (i = start / page_size; i <= (start + len - 1) / page_size; i++) {
		/* Byte position of the first byte in the range in this page. */
		starthere = max(start, i * page_size);
		/* Length of bytes in the range in this page. */
		lenhere = min(start + len, (i + 1) * page_size) - starthere;
333
		flash->read(flash, readbuf, starthere, lenhere);
334 335
		for (j = 0; j < lenhere; j++) {
			if (cmpbuf[starthere - start + j] != readbuf[j]) {
336 337 338 339 340 341 342
				/* Only print the first failure. */
				if (!failcount++)
					fprintf(stderr, "%s FAILED at 0x%08x! "
						"Expected=0x%02x, Read=0x%02x,",
						message, starthere + j,
						cmpbuf[starthere - start + j],
						readbuf[j]);
343 344 345
			}
		}
	}
346 347 348 349 350
	if (failcount) {
		fprintf(stderr, " failed byte count from 0x%08x-0x%08x: 0x%x\n",
			start, start + len - 1, failcount);
		ret = -1;
	}
351 352 353 354 355 356

out_free:
	free(readbuf);
	return ret;
}

357
struct flashchip *probe_flash(struct flashchip *first_flash, int force)
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
358
{
359
	struct flashchip *flash;
360
	unsigned long base = 0, size;
361
	char *tmp;
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
362

363
	for (flash = first_flash; flash && flash->name; flash++) {
364
		if (chip_to_probe && strcmp(flash->name, chip_to_probe) != 0)
365
			continue;
366 367
		printf_debug("Probing for %s %s, %d KB: ",
			     flash->vendor, flash->name, flash->total_size);
Peter Stuge's avatar
Peter Stuge committed
368
		if (!flash->probe && !force) {
369 370 371
			printf_debug("failed! flashrom has no probe function for this flash chip.\n");
			continue;
		}
372 373 374 375 376 377 378 379 380
		if (!(buses_supported & flash->bustype)) {
			tmp = flashbuses_to_text(buses_supported);
			printf_debug("skipped. Host bus type %s ", tmp);
			free(tmp);
			tmp = flashbuses_to_text(flash->bustype);
			printf_debug("and chip bus type %s are incompatible.\n", tmp);
			free(tmp);
			continue;
		}
Stefan Reinauer's avatar
Stefan Reinauer committed
381

382
		size = flash->total_size * 1024;
Stefan Reinauer's avatar
Stefan Reinauer committed
383

384
		base = flashbase ? flashbase : (0xffffffff - size + 1);
385
		flash->virtual_memory = (chipaddr)programmer_map_flash_region("flash chip", base, size);
386

387 388 389
		if (force)
			break;

390 391 392
		if (flash->probe(flash) != 1)
			goto notfound;

393 394
		if (first_flash == flashchips
		    || flash->model_id != GENERIC_DEVICE_ID)
395
			break;
Stefan Reinauer's avatar
Stefan Reinauer committed
396

397
notfound:
398
		programmer_unmap_flash_region((void *)flash->virtual_memory, size);
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
399
	}
Uwe Hermann's avatar
Uwe Hermann committed
400

401 402 403
	if (!flash || !flash->name)
		return NULL;

404 405 406 407
	printf("Found chip \"%s %s\" (%d KB, %s) at physical address 0x%lx.\n",
	       flash->vendor, flash->name, flash->total_size,
	       flashbuses_to_text(flash->bustype), base);

408
	return flash;
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
409 410
}

Stefan Reinauer's avatar
Stefan Reinauer committed
411
int verify_flash(struct flashchip *flash, uint8_t *buf)
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
412
{
413
	int ret;
414
	int total_size = flash->total_size * 1024;
415

416
	printf("Verifying flash... ");
417

418
	ret = verify_range(flash, buf, 0, total_size, NULL);
419

420 421
	if (!ret)
		printf("VERIFIED.          \n");
422

423
	return ret;
Ronald G. Minnich's avatar
Fixes  
Ronald G. Minnich committed
424 425
}

426
int read_flash(struct flashchip *flash, char *filename)
427 428 429 430 431
{
	unsigned long numbytes;
	FILE *image;
	unsigned long size = flash->total_size * 1024;
	unsigned char *buf = calloc(size, sizeof(char));
432 433 434 435 436

	if (!filename) {
		printf("Error: No filename specified.\n");
		return 1;
	}
437 438 439 440 441
	if ((image = fopen(filename, "w")) == NULL) {
		perror(filename);
		exit(1);
	}
	printf("Reading flash... ");
442 443 444 445 446
	if (!flash->read) {
		printf("FAILED!\n");
		fprintf(stderr, "ERROR: flashrom has no read function for this flash chip.\n");
		return 1;
	} else
447
		flash->read(flash, buf, 0, size);
448 449 450

	numbytes = fwrite(buf, 1, size, image);
	fclose(image);
451
	free(buf);
452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468
	printf("%s.\n", numbytes == size ? "done" : "FAILED");
	if (numbytes != size)
		return 1;
	return 0;
}

int erase_flash(struct flashchip *flash)
{
	uint32_t erasedbytes;
	unsigned long size = flash->total_size * 1024;
	unsigned char *buf = calloc(size, sizeof(char));
	printf("Erasing flash chip... ");
	if (NULL == flash->erase) {
		printf("FAILED!\n");
		fprintf(stderr, "ERROR: flashrom has no erase function for this flash chip.\n");
		return 1;
	}
469 470
	flash->erase(flash);

471 472 473
	/* FIXME: The lines below are superfluous. We should check the result
	 * of flash->erase(flash) instead.
	 */
474 475 476 477 478
	if (!flash->read) {
		printf("FAILED!\n");
		fprintf(stderr, "ERROR: flashrom has no read function for this flash chip.\n");
		return 1;
	} else
479
		flash->read(flash, buf, 0, size);
480

481 482 483 484 485 486 487 488 489 490 491
	for (erasedbytes = 0; erasedbytes < size; erasedbytes++)
		if (0xff != buf[erasedbytes]) {
			printf("FAILED!\n");
			fprintf(stderr, "ERROR at 0x%08x: Expected=0xff, Read=0x%02x\n",
				erasedbytes, buf[erasedbytes]);
			return 1;
		}
	printf("SUCCESS.\n");
	return 0;
}

492 493 494 495 496 497 498 499 500
void emergency_help_message()
{
	fprintf(stderr, "Your flash chip is in an unknown state.\n"
		"Get help on IRC at irc.freenode.net channel #flashrom or\n"
		"mail flashrom@flashrom.org\n"
		"------------------------------------------------------------\n"
		"DO NOT REBOOT OR POWEROFF!\n");
}

Ronald G. Minnich's avatar
Ronald G. Minnich committed
501 502
void usage(const char *name)
{
503 504 505 506 507
	const char *pname;
	int pnamelen;
	int remaining = 0;
	enum programmer p;

508
	printf("usage: %s [-VfLzhR] [-E|-r file|-w file|-v file] [-c chipname]\n"
509
              "       [-m [vendor:]part] [-l file] [-i image] [-p programmer]\n\n", name);
510

511 512 513 514
	printf("Please note that the command line interface for flashrom will "
		"change before\nflashrom 1.0. Do not use flashrom in scripts "
		"or other automated tools without\nchecking that your flashrom"
		" version won't interpret options in a different way.\n\n");
515

516
	printf
517 518 519
	    ("   -r | --read:                      read flash and save into file\n"
	     "   -w | --write:                     write file into flash\n"
	     "   -v | --verify:                    verify flash against file\n"
520
	     "   -n | --noverify:                  don't verify flash against file\n"
521 522 523 524 525
	     "   -E | --erase:                     erase flash device\n"
	     "   -V | --verbose:                   more verbose output\n"
	     "   -c | --chip <chipname>:           probe only for specified flash chip\n"
	     "   -m | --mainboard <[vendor:]part>: override mainboard settings\n"
	     "   -f | --force:                     force write without checking image\n"
526
	     "   -l | --layout <file.layout>:      read ROM layout from file\n"
527
	     "   -i | --image <name>:              only flash image name from flash layout\n"
528
	     "   -L | --list-supported:            print supported devices\n"
529
	     "   -z | --list-supported-wiki:       print supported devices in wiki syntax\n"
530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556
	     "   -p | --programmer <name>:         specify the programmer device");

	for (p = 0; p < PROGRAMMER_INVALID; p++) {
		pname = programmer_table[p].name;
		pnamelen = strlen(pname);
		if (remaining - pnamelen - 2 < 0) {
			printf("\n                                     ");
			remaining = 43;
		} else {
			printf(" ");
			remaining--;
		}
		if (p == 0) {
			printf("(");
			remaining--;
		}
		printf("%s", pname);
		remaining -= pnamelen;
		if (p < PROGRAMMER_INVALID - 1) {
			printf(",");
			remaining--;
		} else {
			printf(")\n");
		}
	}
		
	printf(
557
	     "   -h | --help:                      print this help text\n"
558
	     "   -R | --version:                   print the version (release)\n"
559 560
	     "\nYou can specify one of -E, -r, -w, -v or no operation. If no operation is\n"
	     "specified, then all that happens is that flash info is dumped.\n\n");
561
	exit(1);
Ronald G. Minnich's avatar
Ronald G. Minnich committed
562 563
}

564 565
void print_version(void)
{
566
	printf("flashrom v%s\n", flashrom_version);
567 568
}

569
int main(int argc, char *argv[])
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
570
{
571
	uint8_t *buf;
572
	unsigned long size, numbytes;
573
	FILE *image;
Claus Gindhart's avatar
Claus Gindhart committed
574 575
	/* Probe for up to three flash chips. */
	struct flashchip *flash, *flashes[3];
576 577
	const char *name;
	int namelen;
578
	int opt;
579
	int option_index = 0;
Peter Stuge's avatar
Peter Stuge committed
580
	int force = 0;
581
	int read_it = 0, write_it = 0, erase_it = 0, verify_it = 0;
582
	int dont_verify_it = 0, list_supported = 0, list_supported_wiki = 0;
583
	int operation_specified = 0;
Claus Gindhart's avatar
Claus Gindhart committed
584
	int ret = 0, i;
585

586 587 588 589 590
	static struct option long_options[] = {
		{"read", 0, 0, 'r'},
		{"write", 0, 0, 'w'},
		{"erase", 0, 0, 'E'},
		{"verify", 0, 0, 'v'},
591
		{"noverify", 0, 0, 'n'},
592 593 594 595 596 597
		{"chip", 1, 0, 'c'},
		{"mainboard", 1, 0, 'm'},
		{"verbose", 0, 0, 'V'},
		{"force", 0, 0, 'f'},
		{"layout", 1, 0, 'l'},
		{"image", 1, 0, 'i'},
598
		{"list-supported", 0, 0, 'L'},
599
		{"list-supported-wiki", 0, 0, 'z'},
600
		{"programmer", 1, 0, 'p'},
601
		{"help", 0, 0, 'h'},
602
		{"version", 0, 0, 'R'},
603
		{0, 0, 0, 0}
604
	};
605

606
	char *filename = NULL;
607

608
	char *tempstr = NULL, *tempstr2 = NULL;
609

610 611
	print_version();

612 613 614
	if (argc > 1) {
		/* Yes, print them. */
		int i;
615
		printf_debug("The arguments are:\n");
616
		for (i = 1; i < argc; ++i)
617
			printf_debug("%s\n", argv[i]);
618 619
	}

620 621 622 623 624
	/* Safety check. */
	if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
		fprintf(stderr, "Programmer table miscompilation!\n");
		exit(1);
	}
625 626 627 628
	if (spi_programmer_count - 1 != SPI_CONTROLLER_INVALID) {
		fprintf(stderr, "SPI programmer table miscompilation!\n");
		exit(1);
	}
629

630
	setbuf(stdout, NULL);
631
	while ((opt = getopt_long(argc, argv, "rRwvnVEfc:m:l:i:p:Lzh",
632
				  long_options, &option_index)) != EOF) {
633 634
		switch (opt) {
		case 'r':
635 636 637 638 639
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				exit(1);
			}
640 641 642
			read_it = 1;
			break;
		case 'w':
643 644 645 646 647
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				exit(1);
			}
648 649 650
			write_it = 1;
			break;
		case 'v':
651 652 653 654 655
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				exit(1);
			}
656 657
			verify_it = 1;
			break;
658 659 660
		case 'n':
			dont_verify_it = 1;
			break;
661 662 663
		case 'c':
			chip_to_probe = strdup(optarg);
			break;
Ollie Lho's avatar
Ollie Lho committed
664 665 666
		case 'V':
			verbose = 1;
			break;
667
		case 'E':
668 669 670 671 672
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				exit(1);
			}
673 674
			erase_it = 1;
			break;
675 676 677
		case 'm':
			tempstr = strdup(optarg);
			strtok(tempstr, ":");
678
			tempstr2 = strtok(NULL, ":");
679
			if (tempstr2) {
680 681
				lb_vendor = tempstr;
				lb_part = tempstr2;
682
			} else {
683 684
				lb_vendor = NULL;
				lb_part = tempstr;
685 686 687
			}
			break;
		case 'f':
688
			force = 1;
689 690
			break;
		case 'l':
691
			tempstr = strdup(optarg);
692 693
			if (read_romlayout(tempstr))
				exit(1);
694 695
			break;
		case 'i':
696
			tempstr = strdup(optarg);
697 698
			find_romentry(tempstr);
			break;
699
		case 'L':
Uwe Hermann's avatar
Uwe Hermann committed
700
			list_supported = 1;
701
			break;
702 703 704
		case 'z':
			list_supported_wiki = 1;
			break;
705
		case 'p':
706 707 708 709 710
			for (programmer = 0; programmer < PROGRAMMER_INVALID; programmer++) {
				name = programmer_table[programmer].name;
				namelen = strlen(name);
				if (strncmp(optarg, name, namelen) == 0) {
					switch (optarg[namelen]) {
711
					case ':':
712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727
						programmer_param = strdup(optarg + namelen + 1);
						break;
					case '\0':
						break;
					default:
						/* The continue refers to the
						 * for loop. It is here to be
						 * able to differentiate between
						 * foo and foobar.
						 */
						continue;
					}
					break;
				}
			}
			if (programmer == PROGRAMMER_INVALID) {
728
				printf("Error: Unknown programmer %s.\n", optarg);
729 730 731
				exit(1);
			}
			break;
732
		case 'R':
733
			/* print_version() is always called during startup. */
734 735
			exit(0);
			break;
736
		case 'h':
737 738 739 740 741
		default:
			usage(argv[0]);
			break;
		}
	}
742

Uwe Hermann's avatar
Uwe Hermann committed
743 744 745 746 747 748 749
	if (list_supported) {
		print_supported_chips();
		print_supported_chipsets();
		print_supported_boards();
		printf("\nSupported PCI devices flashrom can use "
		       "as programmer:\n\n");
		print_supported_pcidevs(nics_3com);
750
		print_supported_pcidevs(satas_sii);
Uwe Hermann's avatar
Uwe Hermann committed
751 752 753
		exit(0);
	}

754
	if (list_supported_wiki) {
Uwe Hermann's avatar
Uwe Hermann committed
755
		print_wiki_tables();
756 757 758
		exit(0);
	}

759
	if (read_it && write_it) {
Uwe Hermann's avatar
Uwe Hermann committed
760
		printf("Error: -r and -w are mutually exclusive.\n");
761 762
		usage(argv[0]);
	}
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
763

764 765
	if (optind < argc)
		filename = argv[optind++];
Ronald G. Minnich's avatar
Ronald G. Minnich committed
766

767 768 769 770
	if (programmer_init()) {
		fprintf(stderr, "Error: Programmer initialization failed.\n");
		exit(1);
	}
771

772
	myusec_calibrate_delay();
773

Claus Gindhart's avatar
Claus Gindhart committed
774
	for (i = 0; i < ARRAY_SIZE(flashes); i++) {
775 776
		flashes[i] =
		    probe_flash(i ? flashes[i - 1] + 1 : flashchips, 0);
Claus Gindhart's avatar
Claus Gindhart committed
777 778 779 780 781 782 783 784 785 786 787 788
		if (!flashes[i])
			for (i++; i < ARRAY_SIZE(flashes); i++)
				flashes[i] = NULL;
	}

	if (flashes[1]) {
		printf("Multiple flash chips were detected:");
		for (i = 0; i < ARRAY_SIZE(flashes) && flashes[i]; i++)
			printf(" %s", flashes[i]->name);
		printf("\nPlease specify which chip to use with the -c <chipname> option.\n");
		exit(1);
	} else if (!flashes[0]) {
789
		printf("No EEPROM/flash device found.\n");
Peter Stuge's avatar
Peter Stuge committed
790 791 792 793 794 795 796 797 798 799 800 801 802 803 804
		if (!force || !chip_to_probe) {
			printf("If you know which flash chip you have, and if this version of flashrom\n");
			printf("supports a similar flash chip, you can try to force read your chip. Run:\n");
			printf("flashrom -f -r -c similar_supported_flash_chip filename\n");
			printf("\n");
			printf("Note: flashrom can never write when the flash chip isn't found automatically.\n");
		}
		if (force && read_it && chip_to_probe) {
			printf("Force read (-f -r -c) requested, forcing chip probe success:\n");
			flashes[0] = probe_flash(flashchips, 1);
			if (!flashes[0]) {
				printf("flashrom does not support a flash chip named '%s'.\n", chip_to_probe);
				printf("Run flashrom -L to view the hardware supported in this flashrom version.\n");
				exit(1);
			}
805
			printf("Please note that forced reads most likely contain garbage.\n");
806
			return read_flash(flashes[0], filename);
Peter Stuge's avatar
Peter Stuge committed
807
		}
808
		// FIXME: flash writes stay enabled!
809 810
		exit(1);
	}
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
811

Claus Gindhart's avatar
Claus Gindhart committed
812 813
	flash = flashes[0];

814 815 816 817 818 819 820 821 822 823 824 825 826
	if (TEST_OK_MASK != (flash->tested & TEST_OK_MASK)) {
		printf("===\n");
		if (flash->tested & TEST_BAD_MASK) {
			printf("This flash part has status NOT WORKING for operations:");
			if (flash->tested & TEST_BAD_PROBE)
				printf(" PROBE");
			if (flash->tested & TEST_BAD_READ)
				printf(" READ");
			if (flash->tested & TEST_BAD_ERASE)
				printf(" ERASE");
			if (flash->tested & TEST_BAD_WRITE)
				printf(" WRITE");
			printf("\n");
827 828 829 830 831
		}
		if ((!(flash->tested & TEST_BAD_PROBE) && !(flash->tested & TEST_OK_PROBE)) ||
		    (!(flash->tested & TEST_BAD_READ) && !(flash->tested & TEST_OK_READ)) ||
		    (!(flash->tested & TEST_BAD_ERASE) && !(flash->tested & TEST_OK_ERASE)) ||
		    (!(flash->tested & TEST_BAD_WRITE) && !(flash->tested & TEST_OK_WRITE))) {
832
			printf("This flash part has status UNTESTED for operations:");
833
			if (!(flash->tested & TEST_BAD_PROBE) && !(flash->tested & TEST_OK_PROBE))
834
				printf(" PROBE");
835
			if (!(flash->tested & TEST_BAD_READ) && !(flash->tested & TEST_OK_READ))
836
				printf(" READ");
837
			if (!(flash->tested & TEST_BAD_ERASE) && !(flash->tested & TEST_OK_ERASE))
838
				printf(" ERASE");
839
			if (!(flash->tested & TEST_BAD_WRITE) && !(flash->tested & TEST_OK_WRITE))
840 841 842
				printf(" WRITE");
			printf("\n");
		}
843
		printf("Please email a report to flashrom@flashrom.org if any "
844 845 846 847 848
		       "of the above operations\nwork correctly for you with "
		       "this flash part. Please include the flashrom\noutput "
		       "with the additional -V option for all operations you "
		       "tested (-V, -rV,\n-wV, -EV), and mention which "
		       "mainboard you tested. Thanks for your help!\n===\n");
849
	}
850

851 852 853 854 855 856
	if (!(read_it | write_it | verify_it | erase_it)) {
		printf("No operations were specified.\n");
		// FIXME: flash writes stay enabled!
		exit(1);
	}

857
	if (!filename && !erase_it) {
858 859 860
		printf("Error: No filename specified.\n");
		// FIXME: flash writes stay enabled!
		exit(1);
861 862
	}

863 864 865 866
	/* Always verify write operations unless -n is used. */
	if (write_it && !dont_verify_it)
		verify_it = 1;

867 868
	size = flash->total_size * 1024;
	buf = (uint8_t *) calloc(size, sizeof(char));
869

870
	if (erase_it) {
871 872 873 874 875 876 877 878 879 880 881
		if (flash->tested & TEST_BAD_ERASE) {
			fprintf(stderr, "Erase is not working on this chip. ");
			if (!force) {
				fprintf(stderr, "Aborting.\n");
				return 1;
			} else {
				fprintf(stderr, "Continuing anyway.\n");
			}
		}
		if (erase_flash(flash)) {
			emergency_help_message();
882
			return 1;
883
		}
884
	} else if (read_it) {
885
		if (read_flash(flash, filename))
886
			return 1;
887
	} else {
888 889
		struct stat image_stat;

890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908
		if (flash->tested & TEST_BAD_ERASE) {
			fprintf(stderr, "Erase is not working on this chip "
				"and erase is needed for write. ");
			if (!force) {
				fprintf(stderr, "Aborting.\n");
				return 1;
			} else {
				fprintf(stderr, "Continuing anyway.\n");
			}
		}
		if (flash->tested & TEST_BAD_WRITE) {
			fprintf(stderr, "Write is not working on this chip. ");
			if (!force) {
				fprintf(stderr, "Aborting.\n");
				return 1;
			} else {
				fprintf(stderr, "Continuing anyway.\n");
			}
		}
909
		if ((image = fopen(filename, "r")) == NULL) {
910 911 912
			perror(filename);
			exit(1);
		}
913 914 915 916
		if (fstat(fileno(image), &image_stat) != 0) {
			perror(filename);
			exit(1);
		}
917
		if (image_stat.st_size != flash->total_size * 1024) {
Uwe Hermann's avatar
Uwe Hermann committed
918
			fprintf(stderr, "Error: Image size doesn't match\n");
919 920 921
			exit(1);
		}

922
		numbytes = fread(buf, 1, size, image);
Peter Stuge's avatar
Peter Stuge committed
923
		show_id(buf, size, force);
924
		fclose(image);
925 926 927 928
		if (numbytes != size) {
			fprintf(stderr, "Error: Failed to read file. Got %ld bytes, wanted %ld!\n", numbytes, size);
			return 1;
		}
929
	}
Ronald G. Minnich's avatar
Ronald G. Minnich committed
930

931 932
	// This should be moved into each flash part's code to do it 
	// cleanly. This does the job.
933
	handle_romentries(buf, flash);
934

935
	// ////////////////////////////////////////////////////////////
936

937
	if (write_it) {
938
		printf("Writing flash chip... ");
939 940 941 942
		if (!flash->write) {
			fprintf(stderr, "Error: flashrom has no write function for this flash chip.\n");
			return 1;
		}
943 944 945
		ret = flash->write(flash, buf);
		if (ret) {
			fprintf(stderr, "FAILED!\n");
946
			emergency_help_message();
947 948 949 950
			return 1;
		} else {
			printf("COMPLETE.\n");
		}
951
	}
952

953 954 955 956
	if (verify_it) {
		/* Work around chips which need some time to calm down. */
		if (write_it)
			programmer_delay(1000*1000);
957
		ret = verify_flash(flash, buf);
958 959 960 961 962 963
		/* If we tried to write, and now we don't properly verify, we
		 * might have an emergency situation.
		 */
		if (ret && write_it)
			emergency_help_message();
	}
964

965 966
	programmer_shutdown();

Stefan Reinauer's avatar
Stefan Reinauer committed
967
	return ret;
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
968
}