Patchwork solved similar-but-different chips

login
register
about
Submitter Николай Николаев
Date 2013-03-27 12:20:45
Message ID <CABSK2pn4kXtOX_pf_9=6aMtrtCnebsiGs67gGdqvHL4TjLmVFA@mail.gmail.com>
Download mbox | patch
Permalink /patch/3896/
State New
Headers show

Comments

Николай Николаев - 2013-03-27 12:20:45
If we detected Multiple flash chips than
We can easy save all chips in dynamic list - pflashes.
and we will not have a restrictions with number chips
This is Dynamic List to sorted by Volage beginnig from minimal value.
Also I added to dynamic list the new parameter HEAD.
This is link on head of Dynamic List.
I added a new key "-F" or "--enum" for trying
choice chip automatically from array of Multiple chips
with identical value model_id.
Now we can easy introduce a new chips with identical value model_id and
different
chip names, reading, writing and other function.

for example:
if we have a three chips
M50FLW040A - already exists
.name = "M50FLW040A",
.model_id = ST_M50FLW040A,
...
.read = read_memmapped;
.volage = { 3000, 3600 },

M50FLW040B - is fairy chip
.name = "M50FLW040A",
.model_id = ST_M50FLW040A,
...
.read = read_memmapped_040B;
.volage = { 4500, 5500 },

M50FLW040C - is fairy chip
.name = "M50FLW040A",
.model_id = ST_M50FLW040A,
...
.read = read_memmapped_040C;
.volage = { 1690, 1900 },

and we want to add them to file flashrom.c
just will do it
now runnig the programm and see the array of Multiple chips

=OUT==================================================================================
./flashrom --programmer=internal --r bios.img -o rezult
flashrom v0.9.6.1-r1657 on Linux 2.6.32-220.el6.x86_64 (x86_64)
flashrom is free software, get the source code at http://www.flashrom.org

Calibrating delay loop... OK.
Found chipset "Intel ICH7/ICH7R". Enabling flash write... OK.
Found ST flash chip "M50FLW040A" (512 kB, LPC, FWH) at physical address
0xfff80000.
Found ST flash chip "M50FLW040B" (512 kB, LPC, FWH) at physical address
0xfff80000.
Found ST flash chip "M50FLW040C" (512 kB, LPC, FWH) at physical address
0xfff80000.

Multiple flash chips were detected:
"M50FLW040C" with minimal single supply voltage 1690mV
"M50FLW040A" with minimal single supply voltage 3000mV
"M50FLW040B" with minimal single supply voltage 4500mV

Please specify which chip to use with the -c <chipname> option
or use the -F enumeration option.for trying choice chip automatically
=END==================================================================================

now running with key "-F"

=OUT==================================================================================
./flashrom --programmer=internal --r bios.img -o rezult -F
flashrom v0.9.6.1-r1657 on Linux 2.6.32-220.el6.x86_64 (x86_64)
flashrom is free software, get the source code at http://www.flashrom.org

Calibrating delay loop... OK.
Found chipset "Intel ICH7/ICH7R". Enabling flash write... OK.
Found ST flash chip "M50FLW040A" (512 kB, LPC, FWH) at physical address
0xfff80000.
Found ST flash chip "M50FLW040B" (512 kB, LPC, FWH) at physical address
0xfff80000.
Found ST flash chip "M50FLW040C" (512 kB, LPC, FWH) at physical address
0xfff80000.

Multiple flash chips were detected:
"M50FLW040C" with minimal single supply voltage 1690mV
"M50FLW040A" with minimal single supply voltage 3000mV
"M50FLW040B" with minimal single supply voltage 4500mV

Please specify which chip to use with the -c <chipname> option
or use the -F enumeration option.for trying choice chip automatically
===
This flash part has status UNTESTED for operations: PROBE READ ERASE WRITE
The test status of this chip may have been updated in the latest development
version of flashrom. If you are running the latest development version,
please email a report to flashrom@flashrom.org if any of the above
operations
work correctly for you with this flash part. Please include the flashrom
output with the additional -V option for all operations you tested (-V, -Vr,
-VE, -Vw), and mention which mainboard or programmer you tested.
Please mention your board in the subject line. Thanks for your help!
Reading flash "M50FLW040C" with minimal single supply voltage 1690mV...
done.
=END==================================================================================

We found chips and we trying read data from every chip while will not be
successful operation read.

and i hope we will not need a reinvent the wheel with names of similar
chips like a N25Q064..1E
and puzzle over designation MX25U6435F and MX25L6439E

Patch

diff --git a/cli_classic.c b/cli_classic.c
index 14fb825..9a4b54c 100644
--- a/cli_classic.c
+++ b/cli_classic.c
@@ -42,7 +42,7 @@  static void cli_classic_usage(const char *name)
 #endif
 	       "-p <programmername>[:<parameters>] [-c <chipname>]\n"
 	       "[-E|(-r|-w|-v) <file>] [-l <layoutfile> [-i <imagename>]...] [-n] [-f]]\n"
-	       "[-V[V[V]]] [-o <logfile>]\n\n", name);
+	       "[-V[V[V]]] [-o <logfile>] [-F]\n\n", name);
 
 	printf(" -h | --help                        print this help text\n"
 	       " -R | --version                     print version (release)\n"
@@ -53,6 +53,7 @@  static void cli_classic_usage(const char *name)
 	       " -V | --verbose                     more verbose output\n"
 	       " -c | --chip <chipname>             probe only for specified flash chip\n"
 	       " -f | --force                       force specific operations (see man page)\n"
+	       " -F | --enum                        choice chip automatically\n"
 	       " -n | --noverify                    don't auto-verify\n"
 	       " -l | --layout <layoutfile>         read ROM layout from <layoutfile>\n"
 	       " -i | --image <name>                only flash image <name> from flash layout\n"
@@ -94,11 +95,14 @@  int main(int argc, char *argv[])
 	unsigned long size;
 	/* Probe for up to three flash chips. */
 	const struct flashchip *chip = NULL;
-	struct flashctx flashes[3] = {{0}};
-	struct flashctx *fill_flash;
+	struct flashctx flashes = {0};
+	struct flashctx *pflashes = NULL;
+	struct flashctx *psort = NULL;
+	struct flashctx *paddress = NULL;
 	const char *name;
 	int namelen, opt, i, j;
-	int startchip = -1, chipcount = 0, option_index = 0, force = 0;
+	int startchip = -1, chipcount = 0, option_index = 0, force = 0,
+	    chipenum = 0;
 #if CONFIG_PRINT_WIKI == 1
 	int list_supported_wiki = 0;
 #endif
@@ -106,8 +110,9 @@  int main(int argc, char *argv[])
 	int dont_verify_it = 0, list_supported = 0, operation_specified = 0;
 	enum programmer prog = PROGRAMMER_INVALID;
 	int ret = 0;
+	int ret_doit = 0;
 
-	static const char optstring[] = "r:Rw:v:nVEfc:l:i:p:Lzho:";
+	static const char optstring[] = "r:Rw:v:nVEfFc:l:i:p:Lzho:";
 	static const struct option long_options[] = {
 		{"read",		1, NULL, 'r'},
 		{"write",		1, NULL, 'w'},
@@ -117,6 +122,7 @@  int main(int argc, char *argv[])
 		{"chip",		1, NULL, 'c'},
 		{"verbose",		0, NULL, 'V'},
 		{"force",		0, NULL, 'f'},
+		{"enum",		0, NULL, 'F'},
 		{"layout",		1, NULL, 'l'},
 		{"image",		1, NULL, 'i'},
 		{"list-supported",	0, NULL, 'L'},
@@ -209,6 +215,9 @@  int main(int argc, char *argv[])
 		case 'f':
 			force = 1;
 			break;
+		case 'F':
+			chipenum = 1;
+			break;
 		case 'l':
 			if (layoutfile) {
 				fprintf(stderr, "Error: --layout specified "
@@ -425,22 +434,72 @@  int main(int argc, char *argv[])
 
 	for (j = 0; j < registered_programmer_count; j++) {
 		startchip = 0;
-		while (chipcount < ARRAY_SIZE(flashes)) {
-			startchip = probe_flash(&registered_programmers[j], startchip, &flashes[chipcount], 0);
+		while (1) {
+			paddress = pflashes;
+			if (chip_to_probe && chipcount)
+				break;
+			startchip = probe_flash(&registered_programmers[j], startchip, &flashes, 0);
 			if (startchip == -1)
 				break;
+			pflashes = calloc(1, sizeof(struct flashctx));
+			if (!pflashes) {
+				msg_gerr("Out of memory!\n");
+				exit(1);
+			}
+			memcpy(pflashes, &flashes, sizeof(struct flashctx));
+			/*
+			 * add item and sort by voltage
+			 */
+			if (paddress != NULL) {
+				for (psort = paddress; ; psort = psort->last) {
+					if (psort->chip->voltage.min >= pflashes->chip->voltage.min) {
+						pflashes->next = psort->next;
+						pflashes->last = psort;
+						psort->next = pflashes;
+						pflashes->head = &paddress;
+						if (psort == paddress)
+							paddress = pflashes;
+						else {
+							psort = pflashes->next;
+							psort->last = pflashes;
+						}
+						pflashes = paddress;
+						break;
+					}
+					if (psort->last == NULL) {
+						pflashes->next = psort;
+						pflashes->last = NULL;
+						psort->last = pflashes;
+						pflashes->head = &paddress;
+						pflashes = *(psort->head);
+						break;
+					}
+				}
+			} else {
+				pflashes->head = &paddress;
+				pflashes->last = paddress;
+				pflashes->next = NULL;
+			}
 			chipcount++;
 			startchip++;
 		}
 	}
-
 	if (chipcount > 1) {
-		msg_cinfo("Multiple flash chips were detected: \"%s\"", flashes[0].chip->name);
-		for (i = 1; i < chipcount; i++)
-			msg_cinfo(", \"%s\"", flashes[i].chip->name);
-		msg_cinfo("\nPlease specify which chip to use with the -c <chipname> option.\n");
-		ret = 1;
-		goto out_shutdown;
+		msg_cinfo("\nMultiple flash chips were detected:\n");
+		for (pflashes = *(pflashes->head); ; pflashes = pflashes->last) {
+			msg_cinfo("\"%s\" with minimal single supply voltage %dmV\n",
+				   pflashes->chip->name, pflashes->chip->voltage.min);
+			if (pflashes->last == NULL) {
+				pflashes = *(pflashes->head);
+				break;
+			}
+		}
+		msg_cinfo("\nPlease specify which chip to use with the -c <chipname> option\n");
+		msg_cinfo("or use the -F enumeration option for trying choice chip automatically\n");
+		if (!chipenum) {
+			ret = 1;
+			goto out_shutdown;
+		}
 	} else if (!chipcount) {
 		msg_cinfo("No EEPROM/flash device found.\n");
 		if (!force || !chip_to_probe) {
@@ -468,7 +527,7 @@  int main(int argc, char *argv[])
 					  "chip, using the first one.\n");
 			for (j = 0; j < registered_programmer_count; j++) {
 				pgm = &registered_programmers[j];
-				startchip = probe_flash(pgm, 0, &flashes[0], 1);
+				startchip = probe_flash(pgm, 0, pflashes, 1);
 				if (startchip != -1)
 					break;
 			}
@@ -479,26 +538,25 @@  int main(int argc, char *argv[])
 				goto out_shutdown;
 			}
 			msg_cinfo("Please note that forced reads most likely contain garbage.\n");
-			ret = read_flash_to_file(&flashes[0], filename);
-			free(flashes[0].chip);
+			ret = read_flash_to_file(pflashes, filename);
+			free(pflashes->chip);
 			goto out_shutdown;
 		}
 		ret = 1;
 		goto out_shutdown;
 	} else if (!chip_to_probe) {
 		/* repeat for convenience when looking at foreign logs */
-		tempstr = flashbuses_to_text(flashes[0].chip->bustype);
+		tempstr = flashbuses_to_text(pflashes->chip->bustype);
 		msg_gdbg("Found %s flash chip \"%s\" (%d kB, %s).\n",
-			 flashes[0].chip->vendor, flashes[0].chip->name, flashes[0].chip->total_size, tempstr);
+			pflashes->chip->vendor, pflashes->chip->name, pflashes->chip->total_size, tempstr);
 		free(tempstr);
 	}
 
-	fill_flash = &flashes[0];
-
-	check_chip_supported(fill_flash->chip);
+for (pflashes = *(pflashes->head); ; pflashes = pflashes->last) {
+	check_chip_supported(pflashes->chip);
 
-	size = fill_flash->chip->total_size * 1024;
-	if (check_max_decode(fill_flash->pgm->buses_supported & fill_flash->chip->bustype, size) && (!force)) {
+	size = pflashes->chip->total_size * 1024;
+	if (check_max_decode(pflashes->pgm->buses_supported & pflashes->chip->bustype, size) && (!force)) {
 		msg_cerr("Chip is too big for this programmer (-V gives details). Use --force to override.\n");
 		ret = 1;
 		goto out_shutdown;
@@ -518,19 +576,28 @@  int main(int argc, char *argv[])
 	 * Give the chip time to settle.
 	 */
 	programmer_delay(100000);
-	ret |= doit(fill_flash, force, filename, read_it, write_it, erase_it, verify_it);
+	ret_doit = doit(pflashes, force, filename, read_it, write_it, erase_it, verify_it);
+	if (!ret_doit) {
+		ret |= ret_doit;
+		break;
+	}
+	if (pflashes->last == NULL) {
+		pflashes = *(pflashes->head);
+		ret |= ret_doit;
+		break;
+	}
+}
 	/* Note: doit() already calls programmer_shutdown(). */
 	goto out;
 
 out_shutdown:
 	programmer_shutdown();
 out:
-	for (i = 0; i < chipcount; i++)
-		free(flashes[i].chip);
-
+	free(flashes.chip);
 	free(filename);
 	free(layoutfile);
 	free(pparam);
+	free(pflashes);
 	/* clean up global variables */
 	free((char *)chip_to_probe); /* Silence! Freeing is not modifying contents. */
 	chip_to_probe = NULL;
diff --git a/flash.h b/flash.h
index f73f12e..37cb2ec 100644
--- a/flash.h
+++ b/flash.h
@@ -172,6 +172,10 @@  struct flashctx {
 	/* Some flash devices have an additional register space. */
 	chipaddr virtual_registers;
 	struct registered_programmer *pgm;
+	/*pointer dynamic list*/
+	struct flashctx *last;
+	struct flashctx *next;
+	struct flashctx **head;
 };
 
 #define TEST_UNTESTED	0
diff --git a/flashrom.c b/flashrom.c
index 225b6f0..385aca7 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -1170,7 +1170,8 @@  int read_flash_to_file(struct flashctx *flash, const char *filename)
 	unsigned char *buf = calloc(size, sizeof(char));
 	int ret = 0;
 
-	msg_cinfo("Reading flash... ");
+	msg_cinfo("Reading flash \"%s\" with minimal single supply voltage %dmV... ",
+		   flash->chip->name, flash->chip->voltage.min);
 	if (!buf) {
 		msg_gerr("Memory allocation failed!\n");
 		msg_cinfo("FAILED.\n");