flashrom.c 23.1 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

Ronald G. Minnich's avatar
Ronald G. Minnich committed
33
char *chip_to_probe = NULL;
Peter Stuge's avatar
Peter Stuge committed
34
int verbose = 0;
35 36 37 38
int programmer = PROGRAMMER_INTERNAL;

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

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

70 71 72
	{
		.init			= nic3com_init,
		.shutdown		= nic3com_shutdown,
73 74
		.map_flash_region	= fallback_map,
		.unmap_flash_region	= fallback_unmap,
75
		.chip_readb		= nic3com_chip_readb,
76 77
		.chip_readw		= fallback_chip_readw,
		.chip_readl		= fallback_chip_readl,
78
		.chip_readn		= fallback_chip_readn,
79
		.chip_writeb		= nic3com_chip_writeb,
80 81
		.chip_writew		= fallback_chip_writew,
		.chip_writel		= fallback_chip_writel,
82
		.chip_writen		= fallback_chip_writen,
83
		.delay			= internal_delay,
84 85
	},

86 87 88
	{
		.init			= satasii_init,
		.shutdown		= satasii_shutdown,
89 90
		.map_flash_region	= fallback_map,
		.unmap_flash_region	= fallback_unmap,
91 92 93
		.chip_readb		= satasii_chip_readb,
		.chip_readw		= fallback_chip_readw,
		.chip_readl		= fallback_chip_readl,
94
		.chip_readn		= fallback_chip_readn,
95 96 97
		.chip_writeb		= satasii_chip_writeb,
		.chip_writew		= fallback_chip_writew,
		.chip_writel		= fallback_chip_writel,
98
		.chip_writen		= fallback_chip_writen,
99
		.delay			= internal_delay,
100 101
	},

102 103 104 105 106 107
	{
		.init			= it87spi_init,
		.shutdown		= dummy_shutdown,
		.map_flash_region	= dummy_map,
		.unmap_flash_region	= dummy_unmap,
		.chip_readb		= dummy_chip_readb,
108 109 110
		.chip_readw		= fallback_chip_readw,
		.chip_readl		= fallback_chip_readl,
		.chip_readn		= fallback_chip_readn,
111
		.chip_writeb		= dummy_chip_writeb,
112 113 114
		.chip_writew		= fallback_chip_writew,
		.chip_writel		= fallback_chip_writel,
		.chip_writen		= fallback_chip_writen,
115
		.delay			= internal_delay,
116 117
	},

118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
	{
		.init			= ft2232_spi_init,
		.shutdown		= dummy_shutdown,
		.map_flash_region	= dummy_map,
		.unmap_flash_region	= dummy_unmap,
		.chip_readb		= dummy_chip_readb,
		.chip_readw		= fallback_chip_readw,
		.chip_readl		= fallback_chip_readl,
		.chip_readn		= fallback_chip_readn,
		.chip_writeb		= dummy_chip_writeb,
		.chip_writew		= fallback_chip_writew,
		.chip_writel		= fallback_chip_writel,
		.chip_writen		= fallback_chip_writen,
		.delay			= internal_delay,
	},
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
	{
		.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,
	},
148

149 150
	{},
};
151

152 153 154 155 156 157 158 159 160 161 162 163 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
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);
}

189 190 191 192 193
void chip_writen(uint8_t *buf, chipaddr addr, size_t len)
{
	programmer_table[programmer].chip_writen(buf, addr, len);
}

194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
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);
}

209 210 211 212 213 214
void chip_readn(uint8_t *buf, chipaddr addr, size_t len)
{
	programmer_table[programmer].chip_readn(buf, addr, len);
	return;
}

215 216 217 218 219
void programmer_delay(int usecs)
{
	programmer_table[programmer].delay(usecs);
}

220
void map_flash_registers(struct flashchip *flash)
221 222
{
	size_t size = flash->total_size * 1024;
223
	/* Flash registers live 4 MByte below the flash. */
224
	flash->virtual_registers = (chipaddr)programmer_map_flash_region("flash chip registers", (0xFFFFFFFF - 0x400000 - size + 1), size);
225 226
}

227
int read_memmapped(struct flashchip *flash, uint8_t *buf, int start, int len)
228
{
229
	chip_readn(buf, flash->virtual_memory + start, len);
230 231 232 233
		
	return 0;
}

234 235 236 237 238
int min(int a, int b)
{
	return (a < b) ? a : b;
}

239 240 241 242 243
int max(int a, int b)
{
	return (a > b) ? a : b;
}

244 245 246 247 248 249 250 251 252
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;
}

253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
/* 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);

	if (!len)
		goto out_free;

285 286 287 288
	if (!flash->read) {
		fprintf(stderr, "ERROR: flashrom has no read function for this flash chip.\n");
		return 1;
	}
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
	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;
318
		flash->read(flash, readbuf, starthere, lenhere);
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
		for (j = 0; j < lenhere; j++) {
			if (cmpbuf[starthere - start + j] != readbuf[j]) {
				fprintf(stderr, "%s FAILED at 0x%08x! "
					"Expected=0x%02x, Read=0x%02x\n",
					message, starthere + j,
					cmpbuf[starthere - start + j], readbuf[j]);
				ret = -1;
				goto out_free;
			}
		}
	}

out_free:
	free(readbuf);
	return ret;
}

336
struct flashchip *probe_flash(struct flashchip *first_flash, int force)
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
337
{
338
	struct flashchip *flash;
339
	unsigned long base = 0, size;
340
	char *tmp;
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
341

342
	for (flash = first_flash; flash && flash->name; flash++) {
343
		if (chip_to_probe && strcmp(flash->name, chip_to_probe) != 0)
344
			continue;
345 346
		printf_debug("Probing for %s %s, %d KB: ",
			     flash->vendor, flash->name, flash->total_size);
Peter Stuge's avatar
Peter Stuge committed
347
		if (!flash->probe && !force) {
348 349 350
			printf_debug("failed! flashrom has no probe function for this flash chip.\n");
			continue;
		}
351 352 353 354 355 356 357 358 359
		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
360

361
		size = flash->total_size * 1024;
Stefan Reinauer's avatar
Stefan Reinauer committed
362

363
		base = flashbase ? flashbase : (0xffffffff - size + 1);
364
		flash->virtual_memory = (chipaddr)programmer_map_flash_region("flash chip", base, size);
365

366 367 368
		if (force)
			break;

369 370 371
		if (flash->probe(flash) != 1)
			goto notfound;

372 373
		if (first_flash == flashchips
		    || flash->model_id != GENERIC_DEVICE_ID)
374
			break;
Stefan Reinauer's avatar
Stefan Reinauer committed
375

376
notfound:
377
		programmer_unmap_flash_region((void *)flash->virtual_memory, size);
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
378
	}
Uwe Hermann's avatar
Uwe Hermann committed
379

380 381 382 383
	if (!flash || !flash->name)
		return NULL;

	printf("Found chip \"%s %s\" (%d KB) at physical address 0x%lx.\n",
Peter Stuge's avatar
Peter Stuge committed
384
	       flash->vendor, flash->name, flash->total_size, base);
385
	return flash;
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
386 387
}

Stefan Reinauer's avatar
Stefan Reinauer committed
388
int verify_flash(struct flashchip *flash, uint8_t *buf)
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
389
{
390
	int ret;
391
	int total_size = flash->total_size * 1024;
392

393
	printf("Verifying flash... ");
394

395
	ret = verify_range(flash, buf, 0, total_size, NULL);
396

397 398
	if (!ret)
		printf("VERIFIED.          \n");
399

400
	return ret;
Ronald G. Minnich's avatar
Fixes  
Ronald G. Minnich committed
401 402
}

403
int read_flash(struct flashchip *flash, char *filename)
404 405 406 407 408
{
	unsigned long numbytes;
	FILE *image;
	unsigned long size = flash->total_size * 1024;
	unsigned char *buf = calloc(size, sizeof(char));
409 410 411 412 413

	if (!filename) {
		printf("Error: No filename specified.\n");
		return 1;
	}
414 415 416 417 418
	if ((image = fopen(filename, "w")) == NULL) {
		perror(filename);
		exit(1);
	}
	printf("Reading flash... ");
419 420 421 422 423
	if (!flash->read) {
		printf("FAILED!\n");
		fprintf(stderr, "ERROR: flashrom has no read function for this flash chip.\n");
		return 1;
	} else
424
		flash->read(flash, buf, 0, size);
425 426 427

	numbytes = fwrite(buf, 1, size, image);
	fclose(image);
428
	free(buf);
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
	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;
	}
446 447
	flash->erase(flash);

448 449 450
	/* FIXME: The lines below are superfluous. We should check the result
	 * of flash->erase(flash) instead.
	 */
451 452 453 454 455
	if (!flash->read) {
		printf("FAILED!\n");
		fprintf(stderr, "ERROR: flashrom has no read function for this flash chip.\n");
		return 1;
	} else
456
		flash->read(flash, buf, 0, size);
457

458 459 460 461 462 463 464 465 466 467 468
	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;
}

Ronald G. Minnich's avatar
Ronald G. Minnich committed
469 470
void usage(const char *name)
{
471
	printf("usage: %s [-VfLzhR] [-E|-r file|-w file|-v file] [-c chipname]\n"
472
              "       [-m [vendor:]part] [-l file] [-i image] [-p programmer]\n\n", name);
473

474 475 476 477
	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");
478

479
	printf
480 481 482 483 484 485 486 487
	    ("   -r | --read:                      read flash and save into file\n"
	     "   -w | --write:                     write file into flash\n"
	     "   -v | --verify:                    verify flash against file\n"
	     "   -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"
488
	     "   -l | --layout <file.layout>:      read ROM layout from file\n"
489
	     "   -i | --image <name>:              only flash image name from flash layout\n"
490
	     "   -L | --list-supported:            print supported devices\n"
491
	     "   -z | --list-supported-wiki:       print supported devices in wiki syntax\n"
492
	     "   -p | --programmer <name>:         specify the programmer device\n"
493
	     "                                     (internal, dummy, nic3com, satasii,\n"
494
	     "                                     it87spi, ft2232spi, serprog)\n"
495
	     "   -h | --help:                      print this help text\n"
496
	     "   -R | --version:                   print the version (release)\n"
497 498
	     "\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");
499
	exit(1);
Ronald G. Minnich's avatar
Ronald G. Minnich committed
500 501
}

502 503
void print_version(void)
{
Carl-Daniel Hailfinger's avatar
Carl-Daniel Hailfinger committed
504
	printf("flashrom v%s\n", FLASHROM_VERSION);
505 506
}

507
int main(int argc, char *argv[])
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
508
{
509
	uint8_t *buf;
510
	unsigned long size, numbytes;
511
	FILE *image;
Claus Gindhart's avatar
Claus Gindhart committed
512 513
	/* Probe for up to three flash chips. */
	struct flashchip *flash, *flashes[3];
514
	int opt;
515
	int option_index = 0;
Peter Stuge's avatar
Peter Stuge committed
516
	int force = 0;
517
	int read_it = 0, write_it = 0, erase_it = 0, verify_it = 0;
518
	int list_supported = 0, list_supported_wiki = 0;
519
	int operation_specified = 0;
Claus Gindhart's avatar
Claus Gindhart committed
520
	int ret = 0, i;
521

522 523 524 525 526 527 528 529 530 531 532
	static struct option long_options[] = {
		{"read", 0, 0, 'r'},
		{"write", 0, 0, 'w'},
		{"erase", 0, 0, 'E'},
		{"verify", 0, 0, 'v'},
		{"chip", 1, 0, 'c'},
		{"mainboard", 1, 0, 'm'},
		{"verbose", 0, 0, 'V'},
		{"force", 0, 0, 'f'},
		{"layout", 1, 0, 'l'},
		{"image", 1, 0, 'i'},
533
		{"list-supported", 0, 0, 'L'},
534
		{"list-supported-wiki", 0, 0, 'z'},
535
		{"programmer", 1, 0, 'p'},
536
		{"help", 0, 0, 'h'},
537
		{"version", 0, 0, 'R'},
538
		{0, 0, 0, 0}
539
	};
540

541
	char *filename = NULL;
542

543
	char *tempstr = NULL, *tempstr2 = NULL;
544

545 546
	print_version();

547 548 549
	if (argc > 1) {
		/* Yes, print them. */
		int i;
550
		printf_debug("The arguments are:\n");
551
		for (i = 1; i < argc; ++i)
552
			printf_debug("%s\n", argv[i]);
553 554
	}

555
	setbuf(stdout, NULL);
556
	while ((opt = getopt_long(argc, argv, "rRwvVEfc:m:l:i:p:Lzh",
557
				  long_options, &option_index)) != EOF) {
558 559
		switch (opt) {
		case 'r':
560 561 562 563 564
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				exit(1);
			}
565 566 567
			read_it = 1;
			break;
		case 'w':
568 569 570 571 572
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				exit(1);
			}
573 574 575
			write_it = 1;
			break;
		case 'v':
576 577 578 579 580
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				exit(1);
			}
581 582 583 584 585
			verify_it = 1;
			break;
		case 'c':
			chip_to_probe = strdup(optarg);
			break;
Ollie Lho's avatar
Ollie Lho committed
586 587 588
		case 'V':
			verbose = 1;
			break;
589
		case 'E':
590 591 592 593 594
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				exit(1);
			}
595 596
			erase_it = 1;
			break;
597 598 599
		case 'm':
			tempstr = strdup(optarg);
			strtok(tempstr, ":");
600
			tempstr2 = strtok(NULL, ":");
601
			if (tempstr2) {
602 603
				lb_vendor = tempstr;
				lb_part = tempstr2;
604
			} else {
605 606
				lb_vendor = NULL;
				lb_part = tempstr;
607 608 609
			}
			break;
		case 'f':
610
			force = 1;
611 612
			break;
		case 'l':
613
			tempstr = strdup(optarg);
614 615
			if (read_romlayout(tempstr))
				exit(1);
616 617
			break;
		case 'i':
618
			tempstr = strdup(optarg);
619 620
			find_romentry(tempstr);
			break;
621
		case 'L':
Uwe Hermann's avatar
Uwe Hermann committed
622
			list_supported = 1;
623
			break;
624 625 626
		case 'z':
			list_supported_wiki = 1;
			break;
627 628 629
		case 'p':
			if (strncmp(optarg, "internal", 8) == 0) {
				programmer = PROGRAMMER_INTERNAL;
630 631
			} else if (strncmp(optarg, "dummy", 5) == 0) {
				programmer = PROGRAMMER_DUMMY;
632 633
				if (optarg[5] == '=')
					dummytype = strdup(optarg + 6);
634 635
			} else if (strncmp(optarg, "nic3com", 7) == 0) {
				programmer = PROGRAMMER_NIC3COM;
636
				if (optarg[7] == '=')
637
					pcidev_bdf = strdup(optarg + 8);
638 639 640 641
			} else if (strncmp(optarg, "satasii", 7) == 0) {
				programmer = PROGRAMMER_SATASII;
				if (optarg[7] == '=')
					pcidev_bdf = strdup(optarg + 8);
642 643
			} else if (strncmp(optarg, "it87spi", 7) == 0) {
				programmer = PROGRAMMER_IT87SPI;
644 645
			} else if (strncmp(optarg, "ft2232spi", 9) == 0) {
				programmer = PROGRAMMER_FT2232SPI;
646 647 648 649
 			} else if (strncmp(optarg, "serprog", 7) == 0) {
 				programmer = PROGRAMMER_SERPROG;
 				if (optarg[7] == '=')
 					serprog_param = strdup(optarg + 8);
650 651 652 653 654
			} else {
				printf("Error: Unknown programmer.\n");
				exit(1);
			}
			break;
655
		case 'R':
656
			/* print_version() is always called during startup. */
657 658
			exit(0);
			break;
659
		case 'h':
660 661 662 663 664
		default:
			usage(argv[0]);
			break;
		}
	}
665

Uwe Hermann's avatar
Uwe Hermann committed
666 667 668 669 670 671 672
	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);
673
		print_supported_pcidevs(satas_sii);
Uwe Hermann's avatar
Uwe Hermann committed
674 675 676
		exit(0);
	}

677
	if (list_supported_wiki) {
Uwe Hermann's avatar
Uwe Hermann committed
678
		print_wiki_tables();
679 680 681
		exit(0);
	}

682
	if (read_it && write_it) {
Uwe Hermann's avatar
Uwe Hermann committed
683
		printf("Error: -r and -w are mutually exclusive.\n");
684 685
		usage(argv[0]);
	}
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
686

687 688
	if (optind < argc)
		filename = argv[optind++];
Ronald G. Minnich's avatar
Ronald G. Minnich committed
689

690
	ret = programmer_init();
691

692
	myusec_calibrate_delay();
693

Claus Gindhart's avatar
Claus Gindhart committed
694
	for (i = 0; i < ARRAY_SIZE(flashes); i++) {
695 696
		flashes[i] =
		    probe_flash(i ? flashes[i - 1] + 1 : flashchips, 0);
Claus Gindhart's avatar
Claus Gindhart committed
697 698 699 700 701 702 703 704 705 706 707 708
		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]) {
709
		printf("No EEPROM/flash device found.\n");
Peter Stuge's avatar
Peter Stuge committed
710 711 712 713 714 715 716 717 718 719 720 721 722 723 724
		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);
			}
725
			return read_flash(flashes[0], filename);
Peter Stuge's avatar
Peter Stuge committed
726
		}
727
		// FIXME: flash writes stay enabled!
728 729
		exit(1);
	}
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
730

Claus Gindhart's avatar
Claus Gindhart committed
731 732
	flash = flashes[0];

733 734 735 736 737 738 739 740 741 742 743 744 745
	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");
746 747 748 749 750
		}
		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))) {
751
			printf("This flash part has status UNTESTED for operations:");
752
			if (!(flash->tested & TEST_BAD_PROBE) && !(flash->tested & TEST_OK_PROBE))
753
				printf(" PROBE");
754
			if (!(flash->tested & TEST_BAD_READ) && !(flash->tested & TEST_OK_READ))
755
				printf(" READ");
756
			if (!(flash->tested & TEST_BAD_ERASE) && !(flash->tested & TEST_OK_ERASE))
757
				printf(" ERASE");
758
			if (!(flash->tested & TEST_BAD_WRITE) && !(flash->tested & TEST_OK_WRITE))
759 760 761
				printf(" WRITE");
			printf("\n");
		}
762 763 764 765 766 767
		printf("Please email a report to flashrom@coreboot.org if any "
		       "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");
768
	}
769

770 771 772 773 774 775
	if (!(read_it | write_it | verify_it | erase_it)) {
		printf("No operations were specified.\n");
		// FIXME: flash writes stay enabled!
		exit(1);
	}

776
	if (!filename && !erase_it) {
777 778 779
		printf("Error: No filename specified.\n");
		// FIXME: flash writes stay enabled!
		exit(1);
780 781
	}

782 783
	size = flash->total_size * 1024;
	buf = (uint8_t *) calloc(size, sizeof(char));
784

785
	if (erase_it) {
786
		if (erase_flash(flash))
787
			return 1;
788
	} else if (read_it) {
789
		if (read_flash(flash, filename))
790
			return 1;
791
	} else {
792 793
		struct stat image_stat;

794
		if ((image = fopen(filename, "r")) == NULL) {
795 796 797
			perror(filename);
			exit(1);
		}
798 799 800 801
		if (fstat(fileno(image), &image_stat) != 0) {
			perror(filename);
			exit(1);
		}
802
		if (image_stat.st_size != flash->total_size * 1024) {
Uwe Hermann's avatar
Uwe Hermann committed
803
			fprintf(stderr, "Error: Image size doesn't match\n");
804 805 806
			exit(1);
		}

807
		numbytes = fread(buf, 1, size, image);
Peter Stuge's avatar
Peter Stuge committed
808
		show_id(buf, size, force);
809
		fclose(image);
810 811 812 813
		if (numbytes != size) {
			fprintf(stderr, "Error: Failed to read file. Got %ld bytes, wanted %ld!\n", numbytes, size);
			return 1;
		}
814
	}
Ronald G. Minnich's avatar
Ronald G. Minnich committed
815

816 817
	// This should be moved into each flash part's code to do it 
	// cleanly. This does the job.
818
	/* FIXME: Adapt to the external flasher infrastructure. */
819
	handle_romentries(buf, (uint8_t *) flash->virtual_memory);
820

821
	// ////////////////////////////////////////////////////////////
822

823
	if (write_it) {
824
		printf("Writing flash chip... ");
825 826 827 828
		if (!flash->write) {
			fprintf(stderr, "Error: flashrom has no write function for this flash chip.\n");
			return 1;
		}
Stefan Reinauer's avatar
Stefan Reinauer committed
829
		ret |= flash->write(flash, buf);
830
		if (!ret) printf("COMPLETE.\n");
831
	}
832

833
	if (verify_it)
Stefan Reinauer's avatar
Stefan Reinauer committed
834
		ret |= verify_flash(flash, buf);
835

836 837
	programmer_shutdown();

Stefan Reinauer's avatar
Stefan Reinauer committed
838
	return ret;
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
839
}