flashrom.c 31.2 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
#if DUMMY_SUPPORT == 1
58
	{
59
		.name			= "dummy",
60 61
		.init			= dummy_init,
		.shutdown		= dummy_shutdown,
62 63
		.map_flash_region	= dummy_map,
		.unmap_flash_region	= dummy_unmap,
64 65 66
		.chip_readb		= dummy_chip_readb,
		.chip_readw		= dummy_chip_readw,
		.chip_readl		= dummy_chip_readl,
67
		.chip_readn		= dummy_chip_readn,
68 69 70
		.chip_writeb		= dummy_chip_writeb,
		.chip_writew		= dummy_chip_writew,
		.chip_writel		= dummy_chip_writel,
71
		.chip_writen		= dummy_chip_writen,
72
		.delay			= internal_delay,
73
	},
74
#endif
75

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

95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
#if GFXNVIDIA_SUPPORT == 1
	{
		.name			= "gfxnvidia",
		.init			= gfxnvidia_init,
		.shutdown		= gfxnvidia_shutdown,
		.map_flash_region	= fallback_map,
		.unmap_flash_region	= fallback_unmap,
		.chip_readb		= gfxnvidia_chip_readb,
		.chip_readw		= fallback_chip_readw,
		.chip_readl		= fallback_chip_readl,
		.chip_readn		= fallback_chip_readn,
		.chip_writeb		= gfxnvidia_chip_writeb,
		.chip_writew		= fallback_chip_writew,
		.chip_writel		= fallback_chip_writel,
		.chip_writen		= fallback_chip_writen,
		.delay			= internal_delay,
	},
#endif

114
#if DRKAISER_SUPPORT == 1
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
	{
		.name			= "drkaiser",
		.init			= drkaiser_init,
		.shutdown		= drkaiser_shutdown,
		.map_flash_region	= fallback_map,
		.unmap_flash_region	= fallback_unmap,
		.chip_readb		= drkaiser_chip_readb,
		.chip_readw		= fallback_chip_readw,
		.chip_readl		= fallback_chip_readl,
		.chip_readn		= fallback_chip_readn,
		.chip_writeb		= drkaiser_chip_writeb,
		.chip_writew		= fallback_chip_writew,
		.chip_writel		= fallback_chip_writel,
		.chip_writen		= fallback_chip_writen,
		.delay			= internal_delay,
	},
131
#endif
132

133
#if SATASII_SUPPORT == 1
134
	{
135
		.name			= "satasii",
136 137
		.init			= satasii_init,
		.shutdown		= satasii_shutdown,
138 139
		.map_flash_region	= fallback_map,
		.unmap_flash_region	= fallback_unmap,
140 141 142
		.chip_readb		= satasii_chip_readb,
		.chip_readw		= fallback_chip_readw,
		.chip_readl		= fallback_chip_readl,
143
		.chip_readn		= fallback_chip_readn,
144 145 146
		.chip_writeb		= satasii_chip_writeb,
		.chip_writew		= fallback_chip_writew,
		.chip_writel		= fallback_chip_writel,
147
		.chip_writen		= fallback_chip_writen,
148
		.delay			= internal_delay,
149
	},
150
#endif
151

152
	{
153
		.name			= "it87spi",
154
		.init			= it87spi_init,
155
		.shutdown		= noop_shutdown,
156 157
		.map_flash_region	= fallback_map,
		.unmap_flash_region	= fallback_unmap,
158
		.chip_readb		= noop_chip_readb,
159 160 161
		.chip_readw		= fallback_chip_readw,
		.chip_readl		= fallback_chip_readl,
		.chip_readn		= fallback_chip_readn,
162
		.chip_writeb		= noop_chip_writeb,
163 164 165
		.chip_writew		= fallback_chip_writew,
		.chip_writel		= fallback_chip_writel,
		.chip_writen		= fallback_chip_writen,
166
		.delay			= internal_delay,
167 168
	},

169
#if FT2232_SPI_SUPPORT == 1
170
	{
171
		.name			= "ft2232spi",
172
		.init			= ft2232_spi_init,
173
		.shutdown		= noop_shutdown, /* Missing shutdown */
174 175
		.map_flash_region	= fallback_map,
		.unmap_flash_region	= fallback_unmap,
176
		.chip_readb		= noop_chip_readb,
177 178 179
		.chip_readw		= fallback_chip_readw,
		.chip_readl		= fallback_chip_readl,
		.chip_readn		= fallback_chip_readn,
180
		.chip_writeb		= noop_chip_writeb,
181 182 183 184 185
		.chip_writew		= fallback_chip_writew,
		.chip_writel		= fallback_chip_writel,
		.chip_writen		= fallback_chip_writen,
		.delay			= internal_delay,
	},
186
#endif
187

188
#if SERPROG_SUPPORT == 1
189
	{
190
		.name			= "serprog",
191 192 193 194 195 196 197 198 199 200 201 202 203 204
		.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,
	},
205
#endif
206

207
	{}, /* This entry corresponds to PROGRAMMER_INVALID. */
208
};
209

210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
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);
}

247 248 249 250 251
void chip_writen(uint8_t *buf, chipaddr addr, size_t len)
{
	programmer_table[programmer].chip_writen(buf, addr, len);
}

252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
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);
}

267 268 269 270 271
void chip_readn(uint8_t *buf, chipaddr addr, size_t len)
{
	programmer_table[programmer].chip_readn(buf, addr, len);
}

272 273 274 275 276
void programmer_delay(int usecs)
{
	programmer_table[programmer].delay(usecs);
}

277
void map_flash_registers(struct flashchip *flash)
278 279
{
	size_t size = flash->total_size * 1024;
280
	/* Flash registers live 4 MByte below the flash. */
281
	/* FIXME: This is incorrect for nonstandard flashbase. */
282
	flash->virtual_registers = (chipaddr)programmer_map_flash_region("flash chip registers", (0xFFFFFFFF - 0x400000 - size + 1), size);
283 284
}

285
int read_memmapped(struct flashchip *flash, uint8_t *buf, int start, int len)
286
{
287
	chip_readn(buf, flash->virtual_memory + start, len);
288 289 290 291
		
	return 0;
}

292 293 294 295 296
int min(int a, int b)
{
	return (a < b) ? a : b;
}

297 298 299 300 301
int max(int a, int b)
{
	return (a > b) ? a : b;
}

302 303 304 305 306 307 308 309 310
int bitcount(unsigned long a)
{
	int i = 0;
	for (; a != 0; a >>= 1)
		if (a & 1)
			i++;
	return i;
}

311 312 313 314 315 316 317 318 319
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;
}

320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
/* 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);
348
	int failcount = 0;
349 350 351 352

	if (!len)
		goto out_free;

353 354 355 356
	if (!flash->read) {
		fprintf(stderr, "ERROR: flashrom has no read function for this flash chip.\n");
		return 1;
	}
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
	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;
386
		flash->read(flash, readbuf, starthere, lenhere);
387 388
		for (j = 0; j < lenhere; j++) {
			if (cmpbuf[starthere - start + j] != readbuf[j]) {
389 390 391 392 393 394 395
				/* 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]);
396 397 398
			}
		}
	}
399 400 401 402 403
	if (failcount) {
		fprintf(stderr, " failed byte count from 0x%08x-0x%08x: 0x%x\n",
			start, start + len - 1, failcount);
		ret = -1;
	}
404 405 406 407 408 409

out_free:
	free(readbuf);
	return ret;
}

410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
int check_max_decode(enum chipbustype buses, uint32_t size)
{
	int limitexceeded = 0;
	if ((buses & CHIP_BUSTYPE_PARALLEL) &&
	    (max_rom_decode.parallel < size)) {
		limitexceeded++;
		printf_debug("Chip size %u kB is bigger than supported "
			     "size %u kB of chipset/board/programmer "
			     "for %s interface, "
			     "probe/read/erase/write may fail. ", size / 1024,
			     max_rom_decode.parallel / 1024, "Parallel");
	}
	if ((buses & CHIP_BUSTYPE_LPC) && (max_rom_decode.lpc < size)) {
		limitexceeded++;
		printf_debug("Chip size %u kB is bigger than supported "
			     "size %u kB of chipset/board/programmer "
			     "for %s interface, "
			     "probe/read/erase/write may fail. ", size / 1024,
			     max_rom_decode.lpc / 1024, "LPC");
	}
	if ((buses & CHIP_BUSTYPE_FWH) && (max_rom_decode.fwh < size)) {
		limitexceeded++;
		printf_debug("Chip size %u kB is bigger than supported "
			     "size %u kB of chipset/board/programmer "
			     "for %s interface, "
			     "probe/read/erase/write may fail. ", size / 1024,
			     max_rom_decode.fwh / 1024, "FWH");
	}
	if ((buses & CHIP_BUSTYPE_SPI) && (max_rom_decode.spi < size)) {
		limitexceeded++;
		printf_debug("Chip size %u kB is bigger than supported "
			     "size %u kB of chipset/board/programmer "
			     "for %s interface, "
			     "probe/read/erase/write may fail. ", size / 1024,
			     max_rom_decode.spi / 1024, "SPI");
	}
	if (!limitexceeded)
		return 0;
	/* Sometimes chip and programmer have more than one bus in common,
	 * and the limit is not exceeded on all buses. Tell the user.
	 */
	if (bitcount(buses) > limitexceeded)
		printf_debug("There is at least one common chip/programmer "
			     "interface which can support a chip of this size. "
			     "You can try --force at your own risk.\n");
	return 1;
}

458
struct flashchip *probe_flash(struct flashchip *first_flash, int force)
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
459
{
460
	struct flashchip *flash;
461 462 463
	unsigned long base = 0;
	uint32_t size;
	enum chipbustype buses_common;
464
	char *tmp;
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
465

466
	for (flash = first_flash; flash && flash->name; flash++) {
467
		if (chip_to_probe && strcmp(flash->name, chip_to_probe) != 0)
468
			continue;
469 470
		printf_debug("Probing for %s %s, %d KB: ",
			     flash->vendor, flash->name, flash->total_size);
Peter Stuge's avatar
Peter Stuge committed
471
		if (!flash->probe && !force) {
472 473 474
			printf_debug("failed! flashrom has no probe function for this flash chip.\n");
			continue;
		}
475 476
		buses_common = buses_supported & flash->bustype;
		if (!buses_common) {
477 478 479 480 481 482 483 484
			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
485

486
		size = flash->total_size * 1024;
487
		check_max_decode(buses_common, size);
Stefan Reinauer's avatar
Stefan Reinauer committed
488

489
		base = flashbase ? flashbase : (0xffffffff - size + 1);
490
		flash->virtual_memory = (chipaddr)programmer_map_flash_region("flash chip", base, size);
491

492 493 494
		if (force)
			break;

495 496 497
		if (flash->probe(flash) != 1)
			goto notfound;

498 499
		if (first_flash == flashchips
		    || flash->model_id != GENERIC_DEVICE_ID)
500
			break;
Stefan Reinauer's avatar
Stefan Reinauer committed
501

502
notfound:
503
		programmer_unmap_flash_region((void *)flash->virtual_memory, size);
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
504
	}
Uwe Hermann's avatar
Uwe Hermann committed
505

506 507 508
	if (!flash || !flash->name)
		return NULL;

509 510 511 512
	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);

513
	return flash;
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
514 515
}

Stefan Reinauer's avatar
Stefan Reinauer committed
516
int verify_flash(struct flashchip *flash, uint8_t *buf)
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
517
{
518
	int ret;
519
	int total_size = flash->total_size * 1024;
520

521
	printf("Verifying flash... ");
522

523
	ret = verify_range(flash, buf, 0, total_size, NULL);
524

525 526
	if (!ret)
		printf("VERIFIED.          \n");
527

528
	return ret;
Ronald G. Minnich's avatar
Fixes  
Ronald G. Minnich committed
529 530
}

531
int read_flash(struct flashchip *flash, char *filename)
532 533 534 535 536
{
	unsigned long numbytes;
	FILE *image;
	unsigned long size = flash->total_size * 1024;
	unsigned char *buf = calloc(size, sizeof(char));
537 538 539 540 541

	if (!filename) {
		printf("Error: No filename specified.\n");
		return 1;
	}
542 543 544 545 546
	if ((image = fopen(filename, "w")) == NULL) {
		perror(filename);
		exit(1);
	}
	printf("Reading flash... ");
547 548 549 550 551
	if (!flash->read) {
		printf("FAILED!\n");
		fprintf(stderr, "ERROR: flashrom has no read function for this flash chip.\n");
		return 1;
	} else
552
		flash->read(flash, buf, 0, size);
553 554 555

	numbytes = fwrite(buf, 1, size, image);
	fclose(image);
556
	free(buf);
557 558 559 560 561 562 563 564
	printf("%s.\n", numbytes == size ? "done" : "FAILED");
	if (numbytes != size)
		return 1;
	return 0;
}

int erase_flash(struct flashchip *flash)
{
565 566
	int i, j, k, ret = 0, found = 0;

567
	printf("Erasing flash chip... ");
568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614
	for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
		unsigned long done = 0;
		struct block_eraser eraser = flash->block_erasers[k];

		printf_debug("Looking at blockwise erase function %i... ", k);
		if (!eraser.block_erase && !eraser.eraseblocks[0].count) {
			printf_debug("not defined. "
				"Looking for another erase function.\n");
			continue;
		}
		if (!eraser.block_erase && eraser.eraseblocks[0].count) {
			printf_debug("eraseblock layout is known, but no "
				"matching block erase function found. "
				"Looking for another erase function.\n");
			continue;
		}
		if (eraser.block_erase && !eraser.eraseblocks[0].count) {
			printf_debug("block erase function found, but "
				"eraseblock layout is unknown. "
				"Looking for another erase function.\n");
			continue;
		}
		found = 1;
		printf_debug("trying... ");
		for (i = 0; i < NUM_ERASEREGIONS; i++) {
			/* count==0 for all automatically initialized array
			 * members so the loop below won't be executed for them.
			 */
			for (j = 0; j < eraser.eraseblocks[i].count; j++) {
				ret = eraser.block_erase(flash, done + eraser.eraseblocks[i].size * j, eraser.eraseblocks[i].size);
				if (ret)
					break;
			}
			if (ret)
				break;
		}
		/* If everything is OK, don't try another erase function. */
		if (!ret)
			break;
	}
	/* If no block erase function was found or block erase failed, retry. */
	if ((!found || ret) && (flash->erase)) {
		found = 1;
		printf_debug("Trying whole-chip erase function... ");
		ret = flash->erase(flash);
	}
	if (!found) {
615 616 617
		fprintf(stderr, "ERROR: flashrom has no erase function for this flash chip.\n");
		return 1;
	}
618

619 620 621 622 623 624
	if (ret) {
		fprintf(stderr, "FAILED!\n");
	} else {
		printf("SUCCESS.\n");
	}
	return ret;
625 626
}

627
void emergency_help_message(void)
628 629
{
	fprintf(stderr, "Your flash chip is in an unknown state.\n"
630 631 632
		"Get help on IRC at irc.freenode.net (channel #flashrom) or\n"
		"mail flashrom@flashrom.org!\n--------------------"
		"-----------------------------------------------------------\n"
633 634 635
		"DO NOT REBOOT OR POWEROFF!\n");
}

Ronald G. Minnich's avatar
Ronald G. Minnich committed
636 637
void usage(const char *name)
{
638 639 640 641 642
	const char *pname;
	int pnamelen;
	int remaining = 0;
	enum programmer p;

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

646 647 648 649
	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");
650

651
	printf
652 653 654
	    ("   -r | --read:                      read flash and save into file\n"
	     "   -w | --write:                     write file into flash\n"
	     "   -v | --verify:                    verify flash against file\n"
655
	     "   -n | --noverify:                  don't verify flash against file\n"
656 657 658 659 660
	     "   -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"
661
	     "   -l | --layout <file.layout>:      read ROM layout from file\n"
662
	     "   -i | --image <name>:              only flash image name from flash layout\n"
663
	     "   -L | --list-supported:            print supported devices\n"
664
#if PRINT_WIKI_SUPPORT == 1
665
	     "   -z | --list-supported-wiki:       print supported devices in wiki syntax\n"
666
#endif
667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693
	     "   -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(
694
	     "   -h | --help:                      print this help text\n"
695
	     "   -R | --version:                   print the version (release)\n"
696 697
	     "\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");
698
	exit(1);
Ronald G. Minnich's avatar
Ronald G. Minnich committed
699 700
}

701 702
void print_version(void)
{
703
	printf("flashrom v%s\n", flashrom_version);
704 705
}

706
int main(int argc, char *argv[])
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
707
{
708
	uint8_t *buf;
709
	unsigned long size, numbytes;
710
	FILE *image;
Claus Gindhart's avatar
Claus Gindhart committed
711 712
	/* Probe for up to three flash chips. */
	struct flashchip *flash, *flashes[3];
713 714
	const char *name;
	int namelen;
715
	int opt;
716
	int option_index = 0;
Peter Stuge's avatar
Peter Stuge committed
717
	int force = 0;
718
	int read_it = 0, write_it = 0, erase_it = 0, verify_it = 0;
719
	int dont_verify_it = 0, list_supported = 0;
720
#if PRINT_WIKI_SUPPORT == 1
721 722
	int list_supported_wiki = 0;
#endif
723
	int operation_specified = 0;
Claus Gindhart's avatar
Claus Gindhart committed
724
	int ret = 0, i;
725

726
#if PRINT_WIKI_SUPPORT == 1
727 728 729 730
	const char *optstring = "rRwvnVEfc:m:l:i:p:Lzh";
#else
	const char *optstring = "rRwvnVEfc:m:l:i:p:Lh";
#endif
731 732 733 734 735
	static struct option long_options[] = {
		{"read", 0, 0, 'r'},
		{"write", 0, 0, 'w'},
		{"erase", 0, 0, 'E'},
		{"verify", 0, 0, 'v'},
736
		{"noverify", 0, 0, 'n'},
737 738 739 740 741 742
		{"chip", 1, 0, 'c'},
		{"mainboard", 1, 0, 'm'},
		{"verbose", 0, 0, 'V'},
		{"force", 0, 0, 'f'},
		{"layout", 1, 0, 'l'},
		{"image", 1, 0, 'i'},
743
		{"list-supported", 0, 0, 'L'},
744
#if PRINT_WIKI_SUPPORT == 1
745
		{"list-supported-wiki", 0, 0, 'z'},
746
#endif
747
		{"programmer", 1, 0, 'p'},
748
		{"help", 0, 0, 'h'},
749
		{"version", 0, 0, 'R'},
750
		{0, 0, 0, 0}
751
	};
752

753
	char *filename = NULL;
754

755
	char *tempstr = NULL, *tempstr2 = NULL;
756

757 758
	print_version();

759 760 761
	if (argc > 1) {
		/* Yes, print them. */
		int i;
762
		printf_debug("The arguments are:\n");
763
		for (i = 1; i < argc; ++i)
764
			printf_debug("%s\n", argv[i]);
765 766
	}

767 768 769 770 771
	/* Safety check. */
	if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
		fprintf(stderr, "Programmer table miscompilation!\n");
		exit(1);
	}
772 773 774 775
	if (spi_programmer_count - 1 != SPI_CONTROLLER_INVALID) {
		fprintf(stderr, "SPI programmer table miscompilation!\n");
		exit(1);
	}
776
#if BITBANG_SPI_SUPPORT == 1
777
	if (bitbang_spi_master_count - 1 != BITBANG_SPI_INVALID) {
778 779 780 781
		fprintf(stderr, "Bitbanging SPI master table miscompilation!\n");
		exit(1);
	}
#endif
782

783
	setbuf(stdout, NULL);
784
	while ((opt = getopt_long(argc, argv, optstring,
785
				  long_options, &option_index)) != EOF) {
786 787
		switch (opt) {
		case 'r':
788 789 790 791 792
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				exit(1);
			}
793 794 795
			read_it = 1;
			break;
		case 'w':
796 797 798 799 800
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				exit(1);
			}
801 802 803
			write_it = 1;
			break;
		case 'v':
804
			//FIXME: gracefully handle superfluous -v
805 806 807 808 809
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				exit(1);
			}
810 811 812 813 814
			if (dont_verify_it) {
				fprintf(stderr, "--verify and --noverify are"
					"mutually exclusive. Aborting.\n");
				exit(1);
			}
815 816
			verify_it = 1;
			break;
817
		case 'n':
818 819 820 821 822
			if (verify_it) {
				fprintf(stderr, "--verify and --noverify are"
					"mutually exclusive. Aborting.\n");
				exit(1);
			}
823 824
			dont_verify_it = 1;
			break;
825 826 827
		case 'c':
			chip_to_probe = strdup(optarg);
			break;
Ollie Lho's avatar
Ollie Lho committed
828 829 830
		case 'V':
			verbose = 1;
			break;
831
		case 'E':
832 833 834 835 836
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				exit(1);
			}
837 838
			erase_it = 1;
			break;
839 840 841
		case 'm':
			tempstr = strdup(optarg);
			strtok(tempstr, ":");
842
			tempstr2 = strtok(NULL, ":");
843
			if (tempstr2) {
844 845
				lb_vendor = tempstr;
				lb_part = tempstr2;
846
			} else {
847 848
				lb_vendor = NULL;
				lb_part = tempstr;
849 850 851
			}
			break;
		case 'f':
852
			force = 1;
853 854
			break;
		case 'l':
855
			tempstr = strdup(optarg);
856 857
			if (read_romlayout(tempstr))
				exit(1);
858 859
			break;
		case 'i':
860
			tempstr = strdup(optarg);
861 862
			find_romentry(tempstr);
			break;
863
		case 'L':
Uwe Hermann's avatar
Uwe Hermann committed
864
			list_supported = 1;
865
			break;
866
#if PRINT_WIKI_SUPPORT == 1
867 868 869
		case 'z':
			list_supported_wiki = 1;
			break;
870
#endif
871
		case 'p':
872 873 874 875 876
			for (programmer = 0; programmer < PROGRAMMER_INVALID; programmer++) {
				name = programmer_table[programmer].name;
				namelen = strlen(name);
				if (strncmp(optarg, name, namelen) == 0) {
					switch (optarg[namelen]) {
877
					case ':':
878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893
						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) {
894
				printf("Error: Unknown programmer %s.\n", optarg);
895 896 897
				exit(1);
			}
			break;
898
		case 'R':
899
			/* print_version() is always called during startup. */
900 901
			exit(0);
			break;
902
		case 'h':
903 904 905 906 907
		default:
			usage(argv[0]);
			break;
		}
	}
908

Uwe Hermann's avatar
Uwe Hermann committed
909
	if (list_supported) {
910
		print_supported();
Uwe Hermann's avatar
Uwe Hermann committed
911 912 913
		exit(0);
	}

914
#if PRINT_WIKI_SUPPORT == 1
915
	if (list_supported_wiki) {
916
		print_supported_wiki();
917 918
		exit(0);
	}
919
#endif
920

921
	if (read_it && write_it) {
Uwe Hermann's avatar
Uwe Hermann committed
922
		printf("Error: -r and -w are mutually exclusive.\n");
923 924
		usage(argv[0]);
	}
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
925

926 927
	if (optind < argc)
		filename = argv[optind++];
928 929 930 931 932
	
	if (optind < argc) {
		printf("Error: Extra parameter found.\n");
		usage(argv[0]);
	}
Ronald G. Minnich's avatar
Ronald G. Minnich committed
933

934 935 936 937
	if (programmer_init()) {
		fprintf(stderr, "Error: Programmer initialization failed.\n");
		exit(1);
	}
938

939
	myusec_calibrate_delay();
940

Claus Gindhart's avatar
Claus Gindhart committed
941
	for (i = 0; i < ARRAY_SIZE(flashes); i++) {
942 943
		flashes[i] =
		    probe_flash(i ? flashes[i - 1] + 1 : flashchips, 0);
Claus Gindhart's avatar
Claus Gindhart committed
944 945 946 947 948 949 950 951 952 953
		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");
954
		programmer_shutdown();
Claus Gindhart's avatar
Claus Gindhart committed
955 956
		exit(1);
	} else if (!flashes[0]) {
957
		printf("No EEPROM/flash device found.\n");
Peter Stuge's avatar
Peter Stuge committed
958 959 960 961 962 963 964 965 966 967 968 969 970 971 972
		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);
			}
973
			printf("Please note that forced reads most likely contain garbage.\n");
974
			return read_flash(flashes[0], filename);
Peter Stuge's avatar
Peter Stuge committed
975
		}
976
		// FIXME: flash writes stay enabled!
977
		programmer_shutdown();
978 979
		exit(1);
	}
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
980

Claus Gindhart's avatar
Claus Gindhart committed
981 982
	flash = flashes[0];

983 984 985 986 987 988 989 990 991 992 993 994 995
	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");
996 997 998 999 1000
		}
		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))) {
1001
			printf("This flash part has status UNTESTED for operations:");
1002
			if (!(flash->tested & TEST_BAD_PROBE) && !(flash->tested & TEST_OK_PROBE))
1003
				printf(" PROBE");
1004
			if (!(flash->tested & TEST_BAD_READ) && !(flash->tested & TEST_OK_READ))
1005
				printf(" READ");
1006
			if (!(flash->tested & TEST_BAD_ERASE) && !(flash->tested & TEST_OK_ERASE))
1007
				printf(" ERASE");
1008
			if (!(flash->tested & TEST_BAD_WRITE) && !(flash->tested & TEST_OK_WRITE))
1009 1010 1011
				printf(" WRITE");
			printf("\n");
		}
1012
		printf("Please email a report to flashrom@flashrom.org if any "
1013 1014 1015 1016 1017
		       "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");
1018
	}
1019

1020 1021 1022 1023 1024 1025 1026 1027 1028
	size = flash->total_size * 1024;
	if (check_max_decode((buses_supported & flash->bustype), size) &&
	    (!force)) {
		fprintf(stderr, "Chip is too big for this programmer "
			"(-V gives details). Use --force to override.\n");
		programmer_shutdown();
		return 1;
	}

1029 1030 1031
	if (!(read_it | write_it | verify_it | erase_it)) {
		printf("No operations were specified.\n");
		// FIXME: flash writes stay enabled!
1032
		programmer_shutdown();
1033 1034 1035
		exit(1);
	}

1036
	if (!filename && !erase_it) {
1037 1038
		printf("Error: No filename specified.\n");
		// FIXME: flash writes stay enabled!
1039
		programmer_shutdown();
1040
		exit(1);
1041 1042
	}

1043 1044 1045 1046
	/* Always verify write operations unless -n is used. */
	if (write_it && !dont_verify_it)
		verify_it = 1;

1047
	buf = (uint8_t *) calloc(size, sizeof(char));
1048

1049
	if (erase_it) {
1050 1051 1052 1053
		if (flash->tested & TEST_BAD_ERASE) {
			fprintf(stderr, "Erase is not working on this chip. ");
			if (!force) {
				fprintf(stderr, "Aborting.\n");
1054
				programmer_shutdown();
1055 1056 1057 1058 1059 1060 1061
				return 1;
			} else {
				fprintf(stderr, "Continuing anyway.\n");
			}
		}
		if (erase_flash(flash)) {
			emergency_help_message();
1062
			programmer_shutdown();
1063
			return 1;
1064
		}
1065
	} else if (read_it) {
1066 1067
		if (read_flash(flash, filename)) {
			programmer_shutdown();
1068
			return 1;
1069
		}
1070
	} else {
1071 1072
		struct stat image_stat;

1073 1074 1075 1076 1077
		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");
1078
				programmer_shutdown();
1079 1080 1081 1082 1083 1084 1085 1086 1087
				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");
1088
				programmer_shutdown();
1089 1090 1091 1092 1093
				return 1;
			} else {
				fprintf(stderr, "Continuing anyway.\n");
			}
		}
1094
		if ((image = fopen(filename, "r")) == NULL) {
1095
			perror(filename);
1096
			programmer_shutdown();
1097 1098
			exit(1);
		}
1099 1100
		if (fstat(fileno(image), &image_stat) != 0) {
			perror(filename);
1101
			programmer_shutdown();
1102 1103
			exit(1);
		}
1104
		if (image_stat.st_size != flash->total_size * 1024) {
Uwe Hermann's avatar
Uwe Hermann committed
1105
			fprintf(stderr, "Error: Image size doesn't match\n");
1106
			programmer_shutdown();
1107 1108 1109
			exit(1);
		}

1110
		numbytes = fread(buf, 1, size, image);
Peter Stuge's avatar
Peter Stuge committed
1111
		show_id(buf, size, force);
1112
		fclose(image);
1113 1114
		if (numbytes != size) {
			fprintf(stderr, "Error: Failed to read file. Got %ld bytes, wanted %ld!\n", numbytes, size);
1115
			programmer_shutdown();
1116 1117
			return 1;
		}
1118
	}
Ronald G. Minnich's avatar
Ronald G. Minnich committed
1119

1120 1121
	// This should be moved into each flash part's code to do it 
	// cleanly. This does the job.
1122
	handle_romentries(buf, flash);
1123

1124
	// ////////////////////////////////////////////////////////////
1125

1126
	if (write_it) {
1127
		printf("Writing flash chip... ");
1128 1129
		if (!flash->write) {
			fprintf(stderr, "Error: flashrom has no write function for this flash chip.\n");
1130
			programmer_shutdown();
1131 1132
			return 1;
		}
1133 1134 1135
		ret = flash->write(flash, buf);
		if (ret) {
			fprintf(stderr, "FAILED!\n");
1136
			emergency_help_message();
1137
			programmer_shutdown();
1138 1139 1140 1141
			return 1;
		} else {
			printf("COMPLETE.\n");
		}
1142
	}
1143

1144 1145 1146 1147
	if (verify_it) {
		/* Work around chips which need some time to calm down. */
		if (write_it)
			programmer_delay(1000*1000);
1148
		ret = verify_flash(flash, buf);
1149
		/* If we tried to write, and verification now fails, we
1150 1151 1152 1153 1154
		 * might have an emergency situation.
		 */
		if (ret && write_it)
			emergency_help_message();
	}
1155

1156 1157
	programmer_shutdown();

Stefan Reinauer's avatar
Stefan Reinauer committed
1158
	return ret;
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
1159
}