flashrom.c 24 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 38 39

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

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

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

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

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

119 120
	{
		.init			= ft2232_spi_init,
121 122 123
		.shutdown		= fallback_shutdown,
		.map_flash_region	= fallback_map,
		.unmap_flash_region	= fallback_unmap,
124 125 126 127
		.chip_readb		= dummy_chip_readb,
		.chip_readw		= fallback_chip_readw,
		.chip_readl		= fallback_chip_readl,
		.chip_readn		= fallback_chip_readn,
128
		.chip_writeb		= fallback_chip_writeb,
129 130 131 132 133
		.chip_writew		= fallback_chip_writew,
		.chip_writel		= fallback_chip_writel,
		.chip_writen		= fallback_chip_writen,
		.delay			= internal_delay,
	},
134

135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
	{
		.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,
	},
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 189 190
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);
}

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

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

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

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

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

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

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

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

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

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
/* 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);
282
	int failcount = 0;
283 284 285 286

	if (!len)
		goto out_free;

287 288 289 290
	if (!flash->read) {
		fprintf(stderr, "ERROR: flashrom has no read function for this flash chip.\n");
		return 1;
	}
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 318 319
	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;
320
		flash->read(flash, readbuf, starthere, lenhere);
321 322
		for (j = 0; j < lenhere; j++) {
			if (cmpbuf[starthere - start + j] != readbuf[j]) {
323 324 325 326 327 328 329
				/* 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]);
330 331 332
			}
		}
	}
333 334 335 336 337
	if (failcount) {
		fprintf(stderr, " failed byte count from 0x%08x-0x%08x: 0x%x\n",
			start, start + len - 1, failcount);
		ret = -1;
	}
338 339 340 341 342 343

out_free:
	free(readbuf);
	return ret;
}

344
struct flashchip *probe_flash(struct flashchip *first_flash, int force)
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
345
{
346
	struct flashchip *flash;
347
	unsigned long base = 0, size;
348
	char *tmp;
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
349

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

369
		size = flash->total_size * 1024;
Stefan Reinauer's avatar
Stefan Reinauer committed
370

371
		base = flashbase ? flashbase : (0xffffffff - size + 1);
372
		flash->virtual_memory = (chipaddr)programmer_map_flash_region("flash chip", base, size);
373

374 375 376
		if (force)
			break;

377 378 379
		if (flash->probe(flash) != 1)
			goto notfound;

380 381
		if (first_flash == flashchips
		    || flash->model_id != GENERIC_DEVICE_ID)
382
			break;
Stefan Reinauer's avatar
Stefan Reinauer committed
383

384
notfound:
385
		programmer_unmap_flash_region((void *)flash->virtual_memory, size);
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
386
	}
Uwe Hermann's avatar
Uwe Hermann committed
387

388 389 390
	if (!flash || !flash->name)
		return NULL;

391 392 393 394
	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);

395
	return flash;
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
396 397
}

Stefan Reinauer's avatar
Stefan Reinauer committed
398
int verify_flash(struct flashchip *flash, uint8_t *buf)
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
399
{
400
	int ret;
401
	int total_size = flash->total_size * 1024;
402

403
	printf("Verifying flash... ");
404

405
	ret = verify_range(flash, buf, 0, total_size, NULL);
406

407 408
	if (!ret)
		printf("VERIFIED.          \n");
409

410
	return ret;
Ronald G. Minnich's avatar
Fixes  
Ronald G. Minnich committed
411 412
}

413
int read_flash(struct flashchip *flash, char *filename)
414 415 416 417 418
{
	unsigned long numbytes;
	FILE *image;
	unsigned long size = flash->total_size * 1024;
	unsigned char *buf = calloc(size, sizeof(char));
419 420 421 422 423

	if (!filename) {
		printf("Error: No filename specified.\n");
		return 1;
	}
424 425 426 427 428
	if ((image = fopen(filename, "w")) == NULL) {
		perror(filename);
		exit(1);
	}
	printf("Reading flash... ");
429 430 431 432 433
	if (!flash->read) {
		printf("FAILED!\n");
		fprintf(stderr, "ERROR: flashrom has no read function for this flash chip.\n");
		return 1;
	} else
434
		flash->read(flash, buf, 0, size);
435 436 437

	numbytes = fwrite(buf, 1, size, image);
	fclose(image);
438
	free(buf);
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
	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;
	}
456 457
	flash->erase(flash);

458 459 460
	/* FIXME: The lines below are superfluous. We should check the result
	 * of flash->erase(flash) instead.
	 */
461 462 463 464 465
	if (!flash->read) {
		printf("FAILED!\n");
		fprintf(stderr, "ERROR: flashrom has no read function for this flash chip.\n");
		return 1;
	} else
466
		flash->read(flash, buf, 0, size);
467

468 469 470 471 472 473 474 475 476 477 478
	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
479 480
void usage(const char *name)
{
481
	printf("usage: %s [-VfLzhR] [-E|-r file|-w file|-v file] [-c chipname]\n"
482
              "       [-m [vendor:]part] [-l file] [-i image] [-p programmer]\n\n", name);
483

484 485 486 487
	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");
488

489
	printf
490 491 492
	    ("   -r | --read:                      read flash and save into file\n"
	     "   -w | --write:                     write file into flash\n"
	     "   -v | --verify:                    verify flash against file\n"
493
	     "   -n | --noverify:                  don't verify flash against file\n"
494 495 496 497 498
	     "   -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"
499
	     "   -l | --layout <file.layout>:      read ROM layout from file\n"
500
	     "   -i | --image <name>:              only flash image name from flash layout\n"
501
	     "   -L | --list-supported:            print supported devices\n"
502
	     "   -z | --list-supported-wiki:       print supported devices in wiki syntax\n"
503
	     "   -p | --programmer <name>:         specify the programmer device\n"
504
	     "                                     (internal, dummy, nic3com, satasii,\n"
505
	     "                                     it87spi, ft2232spi, serprog)\n"
506
	     "   -h | --help:                      print this help text\n"
507
	     "   -R | --version:                   print the version (release)\n"
508 509
	     "\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");
510
	exit(1);
Ronald G. Minnich's avatar
Ronald G. Minnich committed
511 512
}

513 514
void print_version(void)
{
515
	printf("flashrom v%s\n", flashrom_version);
516 517
}

518
int main(int argc, char *argv[])
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
519
{
520
	uint8_t *buf;
521
	unsigned long size, numbytes;
522
	FILE *image;
Claus Gindhart's avatar
Claus Gindhart committed
523 524
	/* Probe for up to three flash chips. */
	struct flashchip *flash, *flashes[3];
525
	int opt;
526
	int option_index = 0;
Peter Stuge's avatar
Peter Stuge committed
527
	int force = 0;
528
	int read_it = 0, write_it = 0, erase_it = 0, verify_it = 0;
529
	int dont_verify_it = 0, list_supported = 0, list_supported_wiki = 0;
530
	int operation_specified = 0;
Claus Gindhart's avatar
Claus Gindhart committed
531
	int ret = 0, i;
532

533 534 535 536 537
	static struct option long_options[] = {
		{"read", 0, 0, 'r'},
		{"write", 0, 0, 'w'},
		{"erase", 0, 0, 'E'},
		{"verify", 0, 0, 'v'},
538
		{"noverify", 0, 0, 'n'},
539 540 541 542 543 544
		{"chip", 1, 0, 'c'},
		{"mainboard", 1, 0, 'm'},
		{"verbose", 0, 0, 'V'},
		{"force", 0, 0, 'f'},
		{"layout", 1, 0, 'l'},
		{"image", 1, 0, 'i'},
545
		{"list-supported", 0, 0, 'L'},
546
		{"list-supported-wiki", 0, 0, 'z'},
547
		{"programmer", 1, 0, 'p'},
548
		{"help", 0, 0, 'h'},
549
		{"version", 0, 0, 'R'},
550
		{0, 0, 0, 0}
551
	};
552

553
	char *filename = NULL;
554

555
	char *tempstr = NULL, *tempstr2 = NULL;
556

557 558
	print_version();

559 560 561
	if (argc > 1) {
		/* Yes, print them. */
		int i;
562
		printf_debug("The arguments are:\n");
563
		for (i = 1; i < argc; ++i)
564
			printf_debug("%s\n", argv[i]);
565 566
	}

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

Uwe Hermann's avatar
Uwe Hermann committed
685 686 687 688 689 690 691
	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);
692
		print_supported_pcidevs(satas_sii);
Uwe Hermann's avatar
Uwe Hermann committed
693 694 695
		exit(0);
	}

696
	if (list_supported_wiki) {
Uwe Hermann's avatar
Uwe Hermann committed
697
		print_wiki_tables();
698 699 700
		exit(0);
	}

701
	if (read_it && write_it) {
Uwe Hermann's avatar
Uwe Hermann committed
702
		printf("Error: -r and -w are mutually exclusive.\n");
703 704
		usage(argv[0]);
	}
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
705

706 707
	if (optind < argc)
		filename = argv[optind++];
Ronald G. Minnich's avatar
Ronald G. Minnich committed
708

709 710 711 712
	if (programmer_init()) {
		fprintf(stderr, "Error: Programmer initialization failed.\n");
		exit(1);
	}
713

714
	myusec_calibrate_delay();
715

Claus Gindhart's avatar
Claus Gindhart committed
716
	for (i = 0; i < ARRAY_SIZE(flashes); i++) {
717 718
		flashes[i] =
		    probe_flash(i ? flashes[i - 1] + 1 : flashchips, 0);
Claus Gindhart's avatar
Claus Gindhart committed
719 720 721 722 723 724 725 726 727 728 729 730
		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]) {
731
		printf("No EEPROM/flash device found.\n");
Peter Stuge's avatar
Peter Stuge committed
732 733 734 735 736 737 738 739 740 741 742 743 744 745 746
		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);
			}
747
			return read_flash(flashes[0], filename);
Peter Stuge's avatar
Peter Stuge committed
748
		}
749
		// FIXME: flash writes stay enabled!
750 751
		exit(1);
	}
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
752

Claus Gindhart's avatar
Claus Gindhart committed
753 754
	flash = flashes[0];

755 756 757 758 759 760 761 762 763 764 765 766 767
	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");
768 769 770 771 772
		}
		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))) {
773
			printf("This flash part has status UNTESTED for operations:");
774
			if (!(flash->tested & TEST_BAD_PROBE) && !(flash->tested & TEST_OK_PROBE))
775
				printf(" PROBE");
776
			if (!(flash->tested & TEST_BAD_READ) && !(flash->tested & TEST_OK_READ))
777
				printf(" READ");
778
			if (!(flash->tested & TEST_BAD_ERASE) && !(flash->tested & TEST_OK_ERASE))
779
				printf(" ERASE");
780
			if (!(flash->tested & TEST_BAD_WRITE) && !(flash->tested & TEST_OK_WRITE))
781 782 783
				printf(" WRITE");
			printf("\n");
		}
784
		printf("Please email a report to flashrom@flashrom.org if any "
785 786 787 788 789
		       "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");
790
	}
791

792 793 794 795 796 797
	if (!(read_it | write_it | verify_it | erase_it)) {
		printf("No operations were specified.\n");
		// FIXME: flash writes stay enabled!
		exit(1);
	}

798
	if (!filename && !erase_it) {
799 800 801
		printf("Error: No filename specified.\n");
		// FIXME: flash writes stay enabled!
		exit(1);
802 803
	}

804 805 806 807
	/* Always verify write operations unless -n is used. */
	if (write_it && !dont_verify_it)
		verify_it = 1;

808 809
	size = flash->total_size * 1024;
	buf = (uint8_t *) calloc(size, sizeof(char));
810

811
	if (erase_it) {
812
		if (erase_flash(flash))
813
			return 1;
814
	} else if (read_it) {
815
		if (read_flash(flash, filename))
816
			return 1;
817
	} else {
818 819
		struct stat image_stat;

820
		if ((image = fopen(filename, "r")) == NULL) {
821 822 823
			perror(filename);
			exit(1);
		}
824 825 826 827
		if (fstat(fileno(image), &image_stat) != 0) {
			perror(filename);
			exit(1);
		}
828
		if (image_stat.st_size != flash->total_size * 1024) {
Uwe Hermann's avatar
Uwe Hermann committed
829
			fprintf(stderr, "Error: Image size doesn't match\n");
830 831 832
			exit(1);
		}

833
		numbytes = fread(buf, 1, size, image);
Peter Stuge's avatar
Peter Stuge committed
834
		show_id(buf, size, force);
835
		fclose(image);
836 837 838 839
		if (numbytes != size) {
			fprintf(stderr, "Error: Failed to read file. Got %ld bytes, wanted %ld!\n", numbytes, size);
			return 1;
		}
840
	}
Ronald G. Minnich's avatar
Ronald G. Minnich committed
841

842 843
	// This should be moved into each flash part's code to do it 
	// cleanly. This does the job.
844
	/* FIXME: Adapt to the external flasher infrastructure. */
845
	handle_romentries(buf, (uint8_t *) flash->virtual_memory);
846

847
	// ////////////////////////////////////////////////////////////
848

849
	if (write_it) {
850
		printf("Writing flash chip... ");
851 852 853 854
		if (!flash->write) {
			fprintf(stderr, "Error: flashrom has no write function for this flash chip.\n");
			return 1;
		}
855 856 857 858 859 860 861
		ret = flash->write(flash, buf);
		if (ret) {
			fprintf(stderr, "FAILED!\n");
			return 1;
		} else {
			printf("COMPLETE.\n");
		}
862
	}
863

864
	if (verify_it)
865
		ret = verify_flash(flash, buf);
866

867 868
	programmer_shutdown();

Stefan Reinauer's avatar
Stefan Reinauer committed
869
	return ret;
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
870
}