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

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

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

#if INTERNAL_SUPPORT == 1
38
enum programmer programmer = PROGRAMMER_INTERNAL;
39 40 41 42 43 44 45
#elif DUMMY_SUPPORT == 1
enum programmer programmer = PROGRAMMER_DUMMY;
#else
/* Activating the #error explodes on make dep. */
//#error Neither internal nor dummy selected
#endif

46
char *programmer_param = NULL;
47

48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
/**
 * flashrom defaults to Parallel/LPC/FWH flash devices. If a known host
 * controller is found, the init routine sets the buses_supported bitfield to
 * contain the supported buses for that controller.
 */
enum chipbustype buses_supported = CHIP_BUSTYPE_NONSPI;

/**
 * Programmers supporting multiple buses can have differing size limits on
 * each bus. Store the limits for each bus in a common struct.
 */
struct decode_sizes max_rom_decode = {
	.parallel	= 0xffffffff,
	.lpc		= 0xffffffff,
	.fwh		= 0xffffffff,
	.spi		= 0xffffffff
};

66
const struct programmer_entry programmer_table[] = {
67
#if INTERNAL_SUPPORT == 1
68
	{
69
		.name			= "internal",
70 71
		.init			= internal_init,
		.shutdown		= internal_shutdown,
72 73
		.map_flash_region	= physmap,
		.unmap_flash_region	= physunmap,
74 75 76
		.chip_readb		= internal_chip_readb,
		.chip_readw		= internal_chip_readw,
		.chip_readl		= internal_chip_readl,
77
		.chip_readn		= internal_chip_readn,
78 79 80
		.chip_writeb		= internal_chip_writeb,
		.chip_writew		= internal_chip_writew,
		.chip_writel		= internal_chip_writel,
81
		.chip_writen		= fallback_chip_writen,
82
		.delay			= internal_delay,
83
	},
84
#endif
85

86
#if DUMMY_SUPPORT == 1
87
	{
88
		.name			= "dummy",
89 90
		.init			= dummy_init,
		.shutdown		= dummy_shutdown,
91 92
		.map_flash_region	= dummy_map,
		.unmap_flash_region	= dummy_unmap,
93 94 95
		.chip_readb		= dummy_chip_readb,
		.chip_readw		= dummy_chip_readw,
		.chip_readl		= dummy_chip_readl,
96
		.chip_readn		= dummy_chip_readn,
97 98 99
		.chip_writeb		= dummy_chip_writeb,
		.chip_writew		= dummy_chip_writew,
		.chip_writel		= dummy_chip_writel,
100
		.chip_writen		= dummy_chip_writen,
101
		.delay			= internal_delay,
102
	},
103
#endif
104

105
#if NIC3COM_SUPPORT == 1
106
	{
107
		.name			= "nic3com",
108 109
		.init			= nic3com_init,
		.shutdown		= nic3com_shutdown,
110 111
		.map_flash_region	= fallback_map,
		.unmap_flash_region	= fallback_unmap,
112
		.chip_readb		= nic3com_chip_readb,
113 114
		.chip_readw		= fallback_chip_readw,
		.chip_readl		= fallback_chip_readl,
115
		.chip_readn		= fallback_chip_readn,
116
		.chip_writeb		= nic3com_chip_writeb,
117 118
		.chip_writew		= fallback_chip_writew,
		.chip_writel		= fallback_chip_writel,
119
		.chip_writen		= fallback_chip_writen,
120
		.delay			= internal_delay,
121
	},
122
#endif
123

124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
#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

143
#if DRKAISER_SUPPORT == 1
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
	{
		.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,
	},
160
#endif
161

162
#if SATASII_SUPPORT == 1
163
	{
164
		.name			= "satasii",
165 166
		.init			= satasii_init,
		.shutdown		= satasii_shutdown,
167 168
		.map_flash_region	= fallback_map,
		.unmap_flash_region	= fallback_unmap,
169 170 171
		.chip_readb		= satasii_chip_readb,
		.chip_readw		= fallback_chip_readw,
		.chip_readl		= fallback_chip_readl,
172
		.chip_readn		= fallback_chip_readn,
173 174 175
		.chip_writeb		= satasii_chip_writeb,
		.chip_writew		= fallback_chip_writew,
		.chip_writel		= fallback_chip_writel,
176
		.chip_writen		= fallback_chip_writen,
177
		.delay			= internal_delay,
178
	},
179
#endif
180

181
#if INTERNAL_SUPPORT == 1
182
	{
183
		.name			= "it87spi",
184
		.init			= it87spi_init,
185
		.shutdown		= noop_shutdown,
186 187
		.map_flash_region	= fallback_map,
		.unmap_flash_region	= fallback_unmap,
188
		.chip_readb		= noop_chip_readb,
189 190 191
		.chip_readw		= fallback_chip_readw,
		.chip_readl		= fallback_chip_readl,
		.chip_readn		= fallback_chip_readn,
192
		.chip_writeb		= noop_chip_writeb,
193 194 195
		.chip_writew		= fallback_chip_writew,
		.chip_writel		= fallback_chip_writel,
		.chip_writen		= fallback_chip_writen,
196
		.delay			= internal_delay,
197
	},
198
#endif
199

200
#if FT2232_SPI_SUPPORT == 1
201
	{
202
		.name			= "ft2232spi",
203
		.init			= ft2232_spi_init,
204
		.shutdown		= noop_shutdown, /* Missing shutdown */
205 206
		.map_flash_region	= fallback_map,
		.unmap_flash_region	= fallback_unmap,
207
		.chip_readb		= noop_chip_readb,
208 209 210
		.chip_readw		= fallback_chip_readw,
		.chip_readl		= fallback_chip_readl,
		.chip_readn		= fallback_chip_readn,
211
		.chip_writeb		= noop_chip_writeb,
212 213 214 215 216
		.chip_writew		= fallback_chip_writew,
		.chip_writel		= fallback_chip_writel,
		.chip_writen		= fallback_chip_writen,
		.delay			= internal_delay,
	},
217
#endif
218

219
#if SERPROG_SUPPORT == 1
220
	{
221
		.name			= "serprog",
222 223 224 225 226 227 228 229 230 231 232 233 234 235
		.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,
	},
236
#endif
237

238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
#if BUSPIRATE_SPI_SUPPORT == 1
	{
		.name			= "buspiratespi",
		.init			= buspirate_spi_init,
		.shutdown		= buspirate_spi_shutdown,
		.map_flash_region	= fallback_map,
		.unmap_flash_region	= fallback_unmap,
		.chip_readb		= noop_chip_readb,
		.chip_readw		= fallback_chip_readw,
		.chip_readl		= fallback_chip_readl,
		.chip_readn		= fallback_chip_readn,
		.chip_writeb		= noop_chip_writeb,
		.chip_writew		= fallback_chip_writew,
		.chip_writel		= fallback_chip_writel,
		.chip_writen		= fallback_chip_writen,
		.delay			= internal_delay,
	},
#endif

257
	{}, /* This entry corresponds to PROGRAMMER_INVALID. */
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 285 286 287 288 289 290 291 292 293 294 295 296
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);
}

297 298 299 300 301
void chip_writen(uint8_t *buf, chipaddr addr, size_t len)
{
	programmer_table[programmer].chip_writen(buf, addr, len);
}

302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
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);
}

317 318 319 320 321
void chip_readn(uint8_t *buf, chipaddr addr, size_t len)
{
	programmer_table[programmer].chip_readn(buf, addr, len);
}

322 323 324 325 326
void programmer_delay(int usecs)
{
	programmer_table[programmer].delay(usecs);
}

327
void map_flash_registers(struct flashchip *flash)
328 329
{
	size_t size = flash->total_size * 1024;
330
	/* Flash registers live 4 MByte below the flash. */
331
	/* FIXME: This is incorrect for nonstandard flashbase. */
332
	flash->virtual_registers = (chipaddr)programmer_map_flash_region("flash chip registers", (0xFFFFFFFF - 0x400000 - size + 1), size);
333 334
}

335
int read_memmapped(struct flashchip *flash, uint8_t *buf, int start, int len)
336
{
337
	chip_readn(buf, flash->virtual_memory + start, len);
338 339 340 341
		
	return 0;
}

342 343
unsigned long flashbase = 0;

344 345 346 347 348
int min(int a, int b)
{
	return (a < b) ? a : b;
}

349 350 351 352 353
int max(int a, int b)
{
	return (a > b) ? a : b;
}

354 355 356 357 358 359 360 361 362
int bitcount(unsigned long a)
{
	int i = 0;
	for (; a != 0; a >>= 1)
		if (a & 1)
			i++;
	return i;
}

363 364 365 366 367 368 369 370 371
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;
}

372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425
/* This is a somewhat hacked function similar in some ways to strtok().
 * It will look for needle in haystack, return a copy of needle and remove
 * everything from the first occurrence of needle to the next delimiter
 * from haystack.
 */
char *extract_param(char **haystack, char *needle, char *delim)
{
	char *param_pos, *rest, *tmp;
	char *dev = NULL;
	int devlen;

	param_pos = strstr(*haystack, needle);
	do {
		if (!param_pos)
			return NULL;
		/* Beginning of the string? */
		if (param_pos == *haystack)
			break;
		/* After a delimiter? */
		if (strchr(delim, *(param_pos - 1)))
			break;
		/* Continue searching. */
		param_pos++;
		param_pos = strstr(param_pos, needle);
	} while (1);
		
	if (param_pos) {
		param_pos += strlen(needle);
		devlen = strcspn(param_pos, delim);
		if (devlen) {
			dev = malloc(devlen + 1);
			if (!dev) {
				fprintf(stderr, "Out of memory!\n");
				exit(1);
			}
			strncpy(dev, param_pos, devlen);
			dev[devlen] = '\0';
		}
		rest = param_pos + devlen;
		rest += strspn(rest, delim);
		param_pos -= strlen(needle);
		memmove(param_pos, rest, strlen(rest) + 1);
		tmp = realloc(*haystack, strlen(*haystack) + 1);
		if (!tmp) {
			fprintf(stderr, "Out of memory!\n");
			exit(1);
		}
		*haystack = tmp;
	}
	

	return dev;
}

426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442
/* 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;
}

/**
443 444
 * @cmpbuf	buffer to compare against, cmpbuf[0] is expected to match the
		flash content at location start
445 446 447 448 449 450 451 452 453 454
 * @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);
455
	int failcount = 0;
456 457 458 459

	if (!len)
		goto out_free;

460 461 462 463
	if (!flash->read) {
		fprintf(stderr, "ERROR: flashrom has no read function for this flash chip.\n");
		return 1;
	}
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492
	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;
493
		flash->read(flash, readbuf, starthere, lenhere);
494 495
		for (j = 0; j < lenhere; j++) {
			if (cmpbuf[starthere - start + j] != readbuf[j]) {
496 497 498 499 500 501 502
				/* 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]);
503 504 505
			}
		}
	}
506 507 508 509 510
	if (failcount) {
		fprintf(stderr, " failed byte count from 0x%08x-0x%08x: 0x%x\n",
			start, start + len - 1, failcount);
		ret = -1;
	}
511 512 513 514 515 516

out_free:
	free(readbuf);
	return ret;
}

517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 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 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652
/* This function generates various test patterns useful for testing controller
 * and chip communication as well as chip behaviour.
 *
 * If a byte can be written multiple times, each time keeping 0-bits at 0
 * and changing 1-bits to 0 if the new value for that bit is 0, the effect
 * is essentially an AND operation. That's also the reason why this function
 * provides the result of AND between various patterns.
 *
 * Below is a list of patterns (and their block length).
 * Pattern 0 is 05 15 25 35 45 55 65 75 85 95 a5 b5 c5 d5 e5 f5 (16 Bytes)
 * Pattern 1 is 0a 1a 2a 3a 4a 5a 6a 7a 8a 9a aa ba ca da ea fa (16 Bytes)
 * Pattern 2 is 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f (16 Bytes)
 * Pattern 3 is a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af (16 Bytes)
 * Pattern 4 is 00 10 20 30 40 50 60 70 80 90 a0 b0 c0 d0 e0 f0 (16 Bytes)
 * Pattern 5 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f (16 Bytes)
 * Pattern 6 is 00 (1 Byte)
 * Pattern 7 is ff (1 Byte)
 * Patterns 0-7 have a big-endian block number in the last 2 bytes of each 256
 * byte block.
 *
 * Pattern 8 is 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11... (256 B)
 * Pattern 9 is ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee... (256 B)
 * Pattern 10 is 00 00 00 01 00 02 00 03 00 04... (128 kB big-endian counter)
 * Pattern 11 is ff ff ff fe ff fd ff fc ff fb... (128 kB big-endian downwards)
 * Pattern 12 is 00 (1 Byte)
 * Pattern 13 is ff (1 Byte)
 * Patterns 8-13 have no block number.
 *
 * Patterns 0-3 are created to detect and efficiently diagnose communication
 * slips like missed bits or bytes and their repetitive nature gives good visual
 * cues to the person inspecting the results. In addition, the following holds:
 * AND Pattern 0/1 == Pattern 4
 * AND Pattern 2/3 == Pattern 5
 * AND Pattern 0/1/2/3 == AND Pattern 4/5 == Pattern 6
 * A weakness of pattern 0-5 is the inability to detect swaps/copies between
 * any two 16-byte blocks except for the last 16-byte block in a 256-byte bloc.
 * They work perfectly for detecting any swaps/aliasing of blocks >= 256 bytes.
 * 0x5 and 0xa were picked because they are 0101 and 1010 binary.
 * Patterns 8-9 are best for detecting swaps/aliasing of blocks < 256 bytes.
 * Besides that, they provide for bit testing of the last two bytes of every
 * 256 byte block which contains the block number for patterns 0-6.
 * Patterns 10-11 are special purpose for detecting subblock aliasing with
 * block sizes >256 bytes (some Dataflash chips etc.)
 * AND Pattern 8/9 == Pattern 12
 * AND Pattern 10/11 == Pattern 12
 * Pattern 13 is the completely erased state.
 * None of the patterns can detect aliasing at boundaries which are a multiple
 * of 16 MBytes (but such chips do not exist anyway for Parallel/LPC/FWH/SPI).
 */
int generate_testpattern(uint8_t *buf, uint32_t size, int variant)
{
	int i;

	if (!buf) {
		fprintf(stderr, "Invalid buffer!\n");
		return 1;
	}

	switch (variant) {
	case 0:
		for (i = 0; i < size; i++)
			buf[i] = (i & 0xf) << 4 | 0x5;
		break;
	case 1:
		for (i = 0; i < size; i++)
			buf[i] = (i & 0xf) << 4 | 0xa;
		break;
	case 2:
		for (i = 0; i < size; i++)
			buf[i] = 0x50 | (i & 0xf);
		break;
	case 3:
		for (i = 0; i < size; i++)
			buf[i] = 0xa0 | (i & 0xf);
		break;
	case 4:
		for (i = 0; i < size; i++)
			buf[i] = (i & 0xf) << 4;
		break;
	case 5:
		for (i = 0; i < size; i++)
			buf[i] = i & 0xf;
		break;
	case 6:
		memset(buf, 0x00, size);
		break;
	case 7:
		memset(buf, 0xff, size);
		break;
	case 8:
		for (i = 0; i < size; i++)
			buf[i] = i & 0xff;
		break;
	case 9:
		for (i = 0; i < size; i++)
			buf[i] = ~(i & 0xff);
		break;
	case 10:
		for (i = 0; i < size % 2; i++) {
			buf[i * 2] = (i >> 8) & 0xff;
			buf[i * 2 + 1] = i & 0xff;
		}
		if (size & 0x1)
			buf[i * 2] = (i >> 8) & 0xff;
		break;
	case 11:
		for (i = 0; i < size % 2; i++) {
			buf[i * 2] = ~((i >> 8) & 0xff);
			buf[i * 2 + 1] = ~(i & 0xff);
		}
		if (size & 0x1)
			buf[i * 2] = ~((i >> 8) & 0xff);
		break;
	case 12:
		memset(buf, 0x00, size);
		break;
	case 13:
		memset(buf, 0xff, size);
		break;
	}

	if ((variant >= 0) && (variant <= 7)) {
		/* Write block number in the last two bytes of each 256-byte
		 * block, big endian for easier reading of the hexdump.
		 * Note that this wraps around for chips larger than 2^24 bytes
		 * (16 MB).
		 */
		for (i = 0; i < size / 256; i++) {
			buf[i * 256 + 254] = (i >> 8) & 0xff;
			buf[i * 256 + 255] = i & 0xff;
		}
	}

	return 0;
}

653 654 655 656 657 658 659 660 661 662 663 664 665 666 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 694 695 696 697 698 699 700
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;
}

701
struct flashchip *probe_flash(struct flashchip *first_flash, int force)
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
702
{
703
	struct flashchip *flash;
704 705 706
	unsigned long base = 0;
	uint32_t size;
	enum chipbustype buses_common;
707
	char *tmp;
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
708

709
	for (flash = first_flash; flash && flash->name; flash++) {
710
		if (chip_to_probe && strcmp(flash->name, chip_to_probe) != 0)
711
			continue;
712 713
		printf_debug("Probing for %s %s, %d KB: ",
			     flash->vendor, flash->name, flash->total_size);
Peter Stuge's avatar
Peter Stuge committed
714
		if (!flash->probe && !force) {
715 716 717
			printf_debug("failed! flashrom has no probe function for this flash chip.\n");
			continue;
		}
718 719
		buses_common = buses_supported & flash->bustype;
		if (!buses_common) {
720 721 722 723 724 725 726 727
			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
728

729
		size = flash->total_size * 1024;
730
		check_max_decode(buses_common, size);
Stefan Reinauer's avatar
Stefan Reinauer committed
731

732
		base = flashbase ? flashbase : (0xffffffff - size + 1);
733
		flash->virtual_memory = (chipaddr)programmer_map_flash_region("flash chip", base, size);
734

735 736 737
		if (force)
			break;

738 739 740
		if (flash->probe(flash) != 1)
			goto notfound;

741 742
		if (first_flash == flashchips
		    || flash->model_id != GENERIC_DEVICE_ID)
743
			break;
Stefan Reinauer's avatar
Stefan Reinauer committed
744

745
notfound:
746
		programmer_unmap_flash_region((void *)flash->virtual_memory, size);
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
747
	}
Uwe Hermann's avatar
Uwe Hermann committed
748

749 750 751
	if (!flash || !flash->name)
		return NULL;

752 753 754 755
	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);

756
	return flash;
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
757 758
}

Stefan Reinauer's avatar
Stefan Reinauer committed
759
int verify_flash(struct flashchip *flash, uint8_t *buf)
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
760
{
761
	int ret;
762
	int total_size = flash->total_size * 1024;
763

764
	printf("Verifying flash... ");
765

766
	ret = verify_range(flash, buf, 0, total_size, NULL);
767

768 769
	if (!ret)
		printf("VERIFIED.          \n");
770

771
	return ret;
Ronald G. Minnich's avatar
Fixes  
Ronald G. Minnich committed
772 773
}

774
int read_flash(struct flashchip *flash, char *filename)
775 776 777 778 779
{
	unsigned long numbytes;
	FILE *image;
	unsigned long size = flash->total_size * 1024;
	unsigned char *buf = calloc(size, sizeof(char));
780 781 782 783 784

	if (!filename) {
		printf("Error: No filename specified.\n");
		return 1;
	}
785 786 787 788 789
	if ((image = fopen(filename, "w")) == NULL) {
		perror(filename);
		exit(1);
	}
	printf("Reading flash... ");
790 791 792 793 794
	if (!flash->read) {
		printf("FAILED!\n");
		fprintf(stderr, "ERROR: flashrom has no read function for this flash chip.\n");
		return 1;
	} else
795
		flash->read(flash, buf, 0, size);
796 797 798

	numbytes = fwrite(buf, 1, size, image);
	fclose(image);
799
	free(buf);
800 801 802 803 804 805 806 807
	printf("%s.\n", numbytes == size ? "done" : "FAILED");
	if (numbytes != size)
		return 1;
	return 0;
}

int erase_flash(struct flashchip *flash)
{
808
	int i, j, k, ret = 0, found = 0;
809
	unsigned int start, len;
810

811
	printf("Erasing flash chip... ");
812
	for (k = 0; k < NUM_ERASEFUNCTIONS; k++) {
813
		unsigned int done = 0;
814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836
		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++) {
837 838 839 840 841 842 843 844 845 846 847
			/* Blocks with zero size are bugs in flashchips.c.
			 * FIXME: This check should be performed on startup.
			 */
			if (eraser.eraseblocks[i].count &&
			    !eraser.eraseblocks[i].size) {
				fprintf(stderr, "ERROR: Erase region with size "
					"0 for this chip. Please report a bug "
					"at flashrom@flashrom.org\n");
				ret = 1;
				break;
			}
848 849 850 851
			/* 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++) {
852 853 854 855 856
				start = done + eraser.eraseblocks[i].size * j;
				len = eraser.eraseblocks[i].size;
				printf_debug("0x%06x-0x%06x, ", start,
					     start + len - 1);
				ret = eraser.block_erase(flash, start, len);
857 858 859 860 861
				if (ret)
					break;
			}
			if (ret)
				break;
862 863
			done += eraser.eraseblocks[i].count *
				eraser.eraseblocks[i].size;
864
		}
865 866 867 868 869
		printf_debug("\n");
		if (done != flash->total_size * 1024)
			fprintf(stderr, "ERROR: Erase region walking erased "
				"0x%06x bytes total, expected 0x%06x bytes.",
				done, flash->total_size * 1024);
870 871 872 873 874 875 876 877 878 879 880
		/* 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) {
881 882 883
		fprintf(stderr, "ERROR: flashrom has no erase function for this flash chip.\n");
		return 1;
	}
884

885 886 887 888 889 890
	if (ret) {
		fprintf(stderr, "FAILED!\n");
	} else {
		printf("SUCCESS.\n");
	}
	return ret;
891 892
}

893
void emergency_help_message(void)
894 895
{
	fprintf(stderr, "Your flash chip is in an unknown state.\n"
896 897 898
		"Get help on IRC at irc.freenode.net (channel #flashrom) or\n"
		"mail flashrom@flashrom.org!\n--------------------"
		"-----------------------------------------------------------\n"
899 900 901
		"DO NOT REBOOT OR POWEROFF!\n");
}

902 903 904 905 906 907 908 909 910 911 912 913 914
/* The way to go if you want a delimited list of programmers*/
void list_programmers(char *delim)
{
	enum programmer p;
	for (p = 0; p < PROGRAMMER_INVALID; p++) {
		printf("%s", programmer_table[p].name);
		if (p < PROGRAMMER_INVALID - 1)
			printf("%s", delim);
	}
	printf("\n");	
}

void cli_usage(const char *name)
Ronald G. Minnich's avatar
Ronald G. Minnich committed
915
{
916 917 918 919 920
	const char *pname;
	int pnamelen;
	int remaining = 0;
	enum programmer p;

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

924 925 926 927
	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");
928

929
	printf
930 931 932
	    ("   -r | --read:                      read flash and save into file\n"
	     "   -w | --write:                     write file into flash\n"
	     "   -v | --verify:                    verify flash against file\n"
933
	     "   -n | --noverify:                  don't verify flash against file\n"
934 935 936
	     "   -E | --erase:                     erase flash device\n"
	     "   -V | --verbose:                   more verbose output\n"
	     "   -c | --chip <chipname>:           probe only for specified flash chip\n"
937
#if INTERNAL_SUPPORT == 1
938
	     "   -m | --mainboard <[vendor:]part>: override mainboard settings\n"
939
#endif
940
	     "   -f | --force:                     force write without checking image\n"
941
	     "   -l | --layout <file.layout>:      read ROM layout from file\n"
942
	     "   -i | --image <name>:              only flash image name from flash layout\n"
943
	     "   -L | --list-supported:            print supported devices\n"
944
#if PRINT_WIKI_SUPPORT == 1
945
	     "   -z | --list-supported-wiki:       print supported devices in wiki syntax\n"
946
#endif
947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973
	     "   -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(
974
	     "   -h | --help:                      print this help text\n"
975
	     "   -R | --version:                   print the version (release)\n"
976 977
	     "\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");
978
	exit(1);
Ronald G. Minnich's avatar
Ronald G. Minnich committed
979 980
}

981 982
void print_version(void)
{
983
	printf("flashrom v%s\n", flashrom_version);
984 985
}

986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046
int selfcheck(void)
{
	/* Safety check. */
	if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
		fprintf(stderr, "Programmer table miscompilation!\n");
		return 1;
	}
	if (spi_programmer_count - 1 != SPI_CONTROLLER_INVALID) {
		fprintf(stderr, "SPI programmer table miscompilation!\n");
		return 1;
	}
#if BITBANG_SPI_SUPPORT == 1
	if (bitbang_spi_master_count - 1 != BITBANG_SPI_INVALID) {
		fprintf(stderr, "Bitbanging SPI master table miscompilation!\n");
		return 1;
	}
#endif
	return 0;
}

void check_chip_supported(struct flashchip *flash)
{
	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");
		}
		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))) {
			printf("This flash part has status UNTESTED for operations:");
			if (!(flash->tested & TEST_BAD_PROBE) && !(flash->tested & TEST_OK_PROBE))
				printf(" PROBE");
			if (!(flash->tested & TEST_BAD_READ) && !(flash->tested & TEST_OK_READ))
				printf(" READ");
			if (!(flash->tested & TEST_BAD_ERASE) && !(flash->tested & TEST_OK_ERASE))
				printf(" ERASE");
			if (!(flash->tested & TEST_BAD_WRITE) && !(flash->tested & TEST_OK_WRITE))
				printf(" WRITE");
			printf("\n");
		}
		printf("Please email a report to flashrom@flashrom.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 or programmer you tested. Thanks for your "
		       "help!\n===\n");
	}
}

1047
int main(int argc, char *argv[])
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
1048
{
1049
	unsigned long size;
Claus Gindhart's avatar
Claus Gindhart committed
1050 1051
	/* Probe for up to three flash chips. */
	struct flashchip *flash, *flashes[3];
1052 1053
	const char *name;
	int namelen;
1054
	int opt;
1055
	int option_index = 0;
Peter Stuge's avatar
Peter Stuge committed
1056
	int force = 0;
1057
	int read_it = 0, write_it = 0, erase_it = 0, verify_it = 0;
1058
	int dont_verify_it = 0, list_supported = 0;
1059
#if PRINT_WIKI_SUPPORT == 1
1060 1061
	int list_supported_wiki = 0;
#endif
1062
	int operation_specified = 0;
1063
	int i;
1064

1065
#if PRINT_WIKI_SUPPORT == 1
1066 1067 1068 1069
	const char *optstring = "rRwvnVEfc:m:l:i:p:Lzh";
#else
	const char *optstring = "rRwvnVEfc:m:l:i:p:Lh";
#endif
1070 1071 1072 1073 1074
	static struct option long_options[] = {
		{"read", 0, 0, 'r'},
		{"write", 0, 0, 'w'},
		{"erase", 0, 0, 'E'},
		{"verify", 0, 0, 'v'},
1075
		{"noverify", 0, 0, 'n'},
1076 1077 1078 1079 1080 1081
		{"chip", 1, 0, 'c'},
		{"mainboard", 1, 0, 'm'},
		{"verbose", 0, 0, 'V'},
		{"force", 0, 0, 'f'},
		{"layout", 1, 0, 'l'},
		{"image", 1, 0, 'i'},
1082
		{"list-supported", 0, 0, 'L'},
1083
#if PRINT_WIKI_SUPPORT == 1
1084
		{"list-supported-wiki", 0, 0, 'z'},
1085
#endif
1086
		{"programmer", 1, 0, 'p'},
1087
		{"help", 0, 0, 'h'},
1088
		{"version", 0, 0, 'R'},
1089
		{0, 0, 0, 0}
1090
	};
1091

1092
	char *filename = NULL;
1093

1094
	char *tempstr = NULL;
1095

1096 1097
	print_version();

1098 1099 1100
	if (argc > 1) {
		/* Yes, print them. */
		int i;
1101
		printf_debug("The arguments are:\n");
1102
		for (i = 1; i < argc; ++i)
1103
			printf_debug("%s\n", argv[i]);
1104 1105
	}

1106
	if (selfcheck())
1107
		exit(1);
1108

1109
	setbuf(stdout, NULL);
1110
	while ((opt = getopt_long(argc, argv, optstring,
1111
				  long_options, &option_index)) != EOF) {
1112 1113
		switch (opt) {
		case 'r':
1114 1115 1116 1117 1118
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				exit(1);
			}
1119 1120 1121
			read_it = 1;
			break;
		case 'w':
1122 1123 1124 1125 1126
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				exit(1);
			}
1127 1128 1129
			write_it = 1;
			break;
		case 'v':
1130
			//FIXME: gracefully handle superfluous -v
1131 1132 1133 1134 1135
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				exit(1);
			}
1136 1137 1138 1139 1140
			if (dont_verify_it) {
				fprintf(stderr, "--verify and --noverify are"
					"mutually exclusive. Aborting.\n");
				exit(1);
			}
1141 1142
			verify_it = 1;
			break;
1143
		case 'n':
1144 1145 1146 1147 1148
			if (verify_it) {
				fprintf(stderr, "--verify and --noverify are"
					"mutually exclusive. Aborting.\n");
				exit(1);
			}
1149 1150
			dont_verify_it = 1;
			break;
1151 1152 1153
		case 'c':
			chip_to_probe = strdup(optarg);
			break;
Ollie Lho's avatar
Ollie Lho committed
1154 1155 1156
		case 'V':
			verbose = 1;
			break;
1157
		case 'E':
1158 1159 1160 1161 1162
			if (++operation_specified > 1) {
				fprintf(stderr, "More than one operation "
					"specified. Aborting.\n");
				exit(1);
			}
1163 1164
			erase_it = 1;
			break;
1165
#if INTERNAL_SUPPORT == 1
1166 1167
		case 'm':
			tempstr = strdup(optarg);
1168
			lb_vendor_dev_from_string(tempstr);
1169
			break;
1170
#endif
1171
		case 'f':
1172
			force = 1;
1173 1174
			break;
		case 'l':
1175
			tempstr = strdup(optarg);
1176 1177
			if (read_romlayout(tempstr))
				exit(1);
1178 1179
			break;
		case 'i':
1180
			tempstr = strdup(optarg);
1181 1182
			find_romentry(tempstr);
			break;
1183
		case 'L':
Uwe Hermann's avatar
Uwe Hermann committed
1184
			list_supported = 1;
1185
			break;
1186
#if PRINT_WIKI_SUPPORT == 1
1187 1188 1189
		case 'z':
			list_supported_wiki = 1;
			break;
1190
#endif
1191
		case 'p':
1192 1193 1194 1195 1196
			for (programmer = 0; programmer < PROGRAMMER_INVALID; programmer++) {
				name = programmer_table[programmer].name;
				namelen = strlen(name);
				if (strncmp(optarg, name, namelen) == 0) {
					switch (optarg[namelen]) {
1197
					case ':':
1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213
						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) {
1214
				printf("Error: Unknown programmer %s.\n", optarg);
1215 1216 1217
				exit(1);
			}
			break;
1218
		case 'R':
1219
			/* print_version() is always called during startup. */
1220 1221
			exit(0);
			break;
1222
		case 'h':
1223
		default:
1224
			cli_usage(argv[0]);
1225 1226 1227
			break;
		}
	}
1228

Uwe Hermann's avatar
Uwe Hermann committed
1229
	if (list_supported) {
1230
		print_supported();
Uwe Hermann's avatar
Uwe Hermann committed
1231 1232 1233
		exit(0);
	}

1234
#if PRINT_WIKI_SUPPORT == 1
1235
	if (list_supported_wiki) {
1236
		print_supported_wiki();
1237 1238
		exit(0);
	}
1239
#endif
1240

1241
	if (read_it && write_it) {
Uwe Hermann's avatar
Uwe Hermann committed
1242
		printf("Error: -r and -w are mutually exclusive.\n");
1243
		cli_usage(argv[0]);
1244
	}
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
1245

1246 1247
	if (optind < argc)
		filename = argv[optind++];
1248 1249 1250
	
	if (optind < argc) {
		printf("Error: Extra parameter found.\n");
1251
		cli_usage(argv[0]);
1252
	}
Ronald G. Minnich's avatar
Ronald G. Minnich committed
1253

1254 1255 1256 1257
	if (programmer_init()) {
		fprintf(stderr, "Error: Programmer initialization failed.\n");
		exit(1);
	}
1258

1259
	// FIXME: Delay calibration should happen in programmer code.
1260
	myusec_calibrate_delay();
1261

Claus Gindhart's avatar
Claus Gindhart committed
1262
	for (i = 0; i < ARRAY_SIZE(flashes); i++) {
1263 1264
		flashes[i] =
		    probe_flash(i ? flashes[i - 1] + 1 : flashchips, 0);
Claus Gindhart's avatar
Claus Gindhart committed
1265 1266 1267 1268 1269 1270 1271 1272 1273 1274
		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");
1275
		programmer_shutdown();
Claus Gindhart's avatar
Claus Gindhart committed
1276 1277
		exit(1);
	} else if (!flashes[0]) {
1278
		printf("No EEPROM/flash device found.\n");
Peter Stuge's avatar
Peter Stuge committed
1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293
		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);
			}
1294
			printf("Please note that forced reads most likely contain garbage.\n");
1295
			return read_flash(flashes[0], filename);
Peter Stuge's avatar
Peter Stuge committed
1296
		}
1297
		// FIXME: flash writes stay enabled!
1298
		programmer_shutdown();
1299 1300
		exit(1);
	}
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
1301

Claus Gindhart's avatar
Claus Gindhart committed
1302 1303
	flash = flashes[0];

1304
	check_chip_supported(flash);
1305

1306 1307 1308 1309 1310 1311 1312 1313 1314
	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;
	}

1315 1316 1317
	if (!(read_it | write_it | verify_it | erase_it)) {
		printf("No operations were specified.\n");
		// FIXME: flash writes stay enabled!
1318
		programmer_shutdown();
1319 1320 1321
		exit(1);
	}

1322
	if (!filename && !erase_it) {
1323 1324
		printf("Error: No filename specified.\n");
		// FIXME: flash writes stay enabled!
1325
		programmer_shutdown();
1326
		exit(1);
1327 1328
	}

1329 1330 1331 1332
	/* Always verify write operations unless -n is used. */
	if (write_it && !dont_verify_it)
		verify_it = 1;

1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347
	return doit(flash, force, filename, read_it, write_it, erase_it, verify_it);
}

/* This function signature is horrible. We need to design a better interface,
 * but right now it allows us to split off the CLI code.
 */
int doit(struct flashchip *flash, int force, char *filename, int read_it, int write_it, int erase_it, int verify_it)
{
	uint8_t *buf;
	unsigned long numbytes;
	FILE *image;
	int ret = 0;
	unsigned long size;

	size = flash->total_size * 1024;
1348
	buf = (uint8_t *) calloc(size, sizeof(char));
1349

1350
	if (erase_it) {
1351 1352 1353 1354
		if (flash->tested & TEST_BAD_ERASE) {
			fprintf(stderr, "Erase is not working on this chip. ");
			if (!force) {
				fprintf(stderr, "Aborting.\n");
1355
				programmer_shutdown();
1356 1357 1358 1359 1360 1361 1362
				return 1;
			} else {
				fprintf(stderr, "Continuing anyway.\n");
			}
		}
		if (erase_flash(flash)) {
			emergency_help_message();
1363
			programmer_shutdown();
1364
			return 1;
1365
		}
1366
	} else if (read_it) {
1367 1368
		if (read_flash(flash, filename)) {
			programmer_shutdown();
1369
			return 1;
1370
		}
1371
	} else {
1372 1373
		struct stat image_stat;

1374 1375 1376 1377 1378
		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");
1379
				programmer_shutdown();
1380 1381 1382 1383 1384 1385 1386 1387 1388
				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");
1389
				programmer_shutdown();
1390 1391 1392 1393 1394
				return 1;
			} else {
				fprintf(stderr, "Continuing anyway.\n");
			}
		}
1395
		if ((image = fopen(filename, "r")) == NULL) {
1396
			perror(filename);
1397
			programmer_shutdown();
1398 1399
			exit(1);
		}
1400 1401
		if (fstat(fileno(image), &image_stat) != 0) {
			perror(filename);
1402
			programmer_shutdown();
1403 1404
			exit(1);
		}
1405
		if (image_stat.st_size != flash->total_size * 1024) {
Uwe Hermann's avatar
Uwe Hermann committed
1406
			fprintf(stderr, "Error: Image size doesn't match\n");
1407
			programmer_shutdown();
1408 1409 1410
			exit(1);
		}

1411
		numbytes = fread(buf, 1, size, image);
1412
#if INTERNAL_SUPPORT == 1
Peter Stuge's avatar
Peter Stuge committed
1413
		show_id(buf, size, force);
1414
#endif
1415
		fclose(image);
1416 1417
		if (numbytes != size) {
			fprintf(stderr, "Error: Failed to read file. Got %ld bytes, wanted %ld!\n", numbytes, size);
1418
			programmer_shutdown();
1419 1420
			return 1;
		}
1421
	}
Ronald G. Minnich's avatar
Ronald G. Minnich committed
1422

1423 1424
	// This should be moved into each flash part's code to do it 
	// cleanly. This does the job.
1425
	handle_romentries(buf, flash);
1426

1427
	// ////////////////////////////////////////////////////////////
1428

1429
	if (write_it) {
1430
		printf("Writing flash chip... ");
1431 1432
		if (!flash->write) {
			fprintf(stderr, "Error: flashrom has no write function for this flash chip.\n");
1433
			programmer_shutdown();
1434 1435
			return 1;
		}
1436 1437 1438
		ret = flash->write(flash, buf);
		if (ret) {
			fprintf(stderr, "FAILED!\n");
1439
			emergency_help_message();
1440
			programmer_shutdown();
1441 1442 1443 1444
			return 1;
		} else {
			printf("COMPLETE.\n");
		}
1445
	}
1446

1447 1448 1449 1450
	if (verify_it) {
		/* Work around chips which need some time to calm down. */
		if (write_it)
			programmer_delay(1000*1000);
1451
		ret = verify_flash(flash, buf);
1452
		/* If we tried to write, and verification now fails, we
1453 1454 1455 1456 1457
		 * might have an emergency situation.
		 */
		if (ret && write_it)
			emergency_help_message();
	}
1458

1459 1460
	programmer_shutdown();

Stefan Reinauer's avatar
Stefan Reinauer committed
1461
	return ret;
Ronald G. Minnich's avatar
Dammit  
Ronald G. Minnich committed
1462
}