Patchwork Invalid OPCODE 0x9f

login
register
about
Submitter Vasiliy Vylegzhanin
Date 2013-08-07 15:22:45
Message ID <CAHp+LVUmib8H3uGv-y-HhbZ1A+nQdo_M3dTF8V44Ay3X4Xh+ZQ@mail.gmail.com>
Download mbox | patch
Permalink /patch/4004/
State New
Headers show

Comments

Vasiliy Vylegzhanin - 2013-08-07 15:22:45
I begin to hate Intel for latest issues with AMT and flashing.

Yep, I also wonder, why block_erase_20 didn't work.
Just 2 patches from patchwork (for better region support, applied manually)
and chip declaration (copy-paste of original 25x64):

Original bios dump: http://paste.flashrom.org/view.php?id=1743 (bzip2)
After flashing: http://paste.flashrom.org/view.php?id=1744 (bzip2)
Vendor's utility and image: http://paste.flashrom.org/view.php?id=1745 (zip)



On Wed, Aug 7, 2013 at 6:48 PM, Stefan Tauner <
stefan.tauner@student.tuwien.ac.at> wrote:

> On Wed, 7 Aug 2013 14:42:40 +0400
> Vasiliy Vylegzhanin <6vasia@gmail.com> wrote:
>
> > And I failed. There are some (modified?) phoenix flash tools, but they
> > refuse to flash the same BIOS version.
> > I've added W25x64 REMS ID and tried to flash it. Somehow flashrom managed
> > to erase whole chip and yes, it failed to write @0x00580000.
> > Is there any way to write write-protected regions on W25X64? I really
> don't
> > want to desolder it, and I can't reboot cause BB is erased.
> > Write log attached.
>
> Hello Vasiliy,
>
> there are no write-protected regions that are specific to the flash
> chip, it all depends on the Intel chipset configuration only (i.e. the
> same would have happened with another flash chip).
>
> TBH I dont totally grasp your log. Your overall analysis seems to be
> correct though: the erase opcode might have got through. I wonder what
> your changes are exactly. Can you please post your patch? I also wonder
> how your images look like. If you can please upload them to
> http://paste.flashrom.org (they will be password protected there
> because we are not allowed to redistribute vendor images of course...)
>
> --
> Kind regards/Mit freundlichen Grüßen, Stefan Tauner
>

Patch

diff -Nur flashrom-orig/flashchips.c flashrom-m/flashchips.c
--- flashrom-orig/flashchips.c	2013-03-19 21:06:22.307763803 +0400
+++ flashrom-m/flashchips.c	2013-08-07 13:54:42.569084841 +0400
@@ -6561,6 +6561,40 @@ 
 	},
 
 	{
+		.vendor		= "Numonyx",
+		.name		= "N25Q128", 
+		.bustype	= BUS_SPI,
+		.manufacture_id = ST_ID,
+		.model_id	= ST_N25Q128,
+		.total_size	= 16384,
+		.page_size	= 256,
+		/* supports SFDP */
+		/* OTP: 64B total; read 0x4B, write 0x42 */
+		.feature_bits	= FEATURE_WRSR_WREN | FEATURE_OTP,
+		.tested		= TEST_UNTESTED,
+		.probe		= probe_spi_rdid,
+		.probe_timing	= TIMING_ZERO,
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = { {4 * 1024, 4096 } },
+				.block_erase = spi_block_erase_20,
+			}, {
+				.eraseblocks = { {64 * 1024, 256} },
+				.block_erase = spi_block_erase_d8,
+			}, {
+				.eraseblocks = { {16 * 1024 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			}
+		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
+		.unlock		= spi_disable_blockprotect,
+		.write		= spi_chip_write_256,
+		.read		= spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+		.voltage	= {2700, 3600},
+	},
+
+	{
 		.vendor		= "PMC",
 		.name		= "Pm25LV010",
 		.bustype	= BUS_SPI,
@@ -10195,6 +10229,44 @@ 
 		.probe_timing	= TIMING_ZERO,
 		.block_erasers	=
 		{
+			{
+				.eraseblocks = { {4 * 1024, 2048} },
+				.block_erase = spi_block_erase_20,
+			}, {
+				.eraseblocks = { {32 * 1024, 256} },
+				.block_erase = spi_block_erase_52,
+			}, {
+				.eraseblocks = { {64 * 1024, 128} },
+				.block_erase = spi_block_erase_d8,
+			}, {
+				.eraseblocks = { {8 * 1024 * 1024, 1} },
+				.block_erase = spi_block_erase_60,
+			}, {
+				.eraseblocks = { {8 * 1024 * 1024, 1} },
+				.block_erase = spi_block_erase_c7,
+			}
+		},
+		.printlock	= spi_prettyprint_status_register_plain, /* TODO: improve */
+		.unlock		= spi_disable_blockprotect,
+		.write		= spi_chip_write_256,
+		.read		= spi_chip_read,
+		.voltage	= {2700, 3600},
+	},
+
+	{
+		.vendor		= "Winbond",
+		.name		= "W25X64 (REMS)",
+		.bustype	= BUS_SPI,
+		.manufacture_id	= WINBOND_NEX_ID,
+		.model_id	= WINBOND_NEX_W25X64_REMS,
+		.total_size	= 8192,
+		.page_size	= 256,
+		.feature_bits	= FEATURE_WRSR_WREN,
+		.tested		= TEST_OK_PROBE,
+		.probe		= probe_spi_rems,
+		.probe_timing	= TIMING_ZERO,
+		.block_erasers	=
+		{
 			{
 				.eraseblocks = { {4 * 1024, 2048} },
 				.block_erase = spi_block_erase_20,

diff -Nur flashrom-orig/flashchips.h flashrom-m/flashchips.h
--- flashrom-orig/flashchips.h	2013-03-19 21:06:24.747763812 +0400
+++ flashrom-m/flashchips.h	2013-08-07 13:56:57.879083083 +0400
@@ -615,6 +615,7 @@ 
 #define ST_N25Q032__1E		0xBB16		/* N25Q032, 1.8V, (uniform sectors expected) */
 #define ST_N25Q064__3E		0xBA17		/* N25Q064, 3.0V, (uniform sectors expected) */
 #define ST_N25Q064__1E		0xBB17		/* N25Q064, 1.8V, (uniform sectors expected) */
+#define ST_N25Q128		0xBA18		/* N25Q128, 3.0V, (uniform sectors expected) */
 
 #define SYNCMOS_MVC_ID		0x40	/* SyncMOS (SM) and Mosel Vitelic Corporation (MVC) */
 #define MVC_V29C51000T		0x00
@@ -656,6 +657,7 @@ 
 #define WINBOND_NEX_W25Q32	0x4016
 #define WINBOND_NEX_W25Q64	0x4017
 #define WINBOND_NEX_W25Q128	0x4018
+#define WINBOND_NEX_W25X64_REMS	0x16
 
 #define WINBOND_ID		0xDA	/* Winbond */
 #define WINBOND_W19B160BB	0x49

diff -Nur flashrom-orig/flash.h flashrom-m/flash.h
--- flashrom-orig/flash.h	2013-03-19 18:03:18.097719486 +0400
+++ flashrom-m/flash.h	2013-03-20 17:05:03.498053956 +0400
@@ -39,6 +39,13 @@ 
 #define TIMEOUT_ERROR	-101
 
 typedef unsigned long chipaddr;
+typedef struct {
+	unsigned int start;
+	unsigned int end;
+	unsigned int included;
+	char name[256];
+	char file[256]; /* file == "" means not specified. */
+} romlayout_t;
 
 int register_shutdown(int (*function) (void *data), void *data);
 void *programmer_map_flash_region(const char *descr, unsigned long phys_addr,
@@ -305,6 +312,7 @@ 
 int process_include_args(void);
 int read_romlayout(char *name);
 int handle_romentries(const struct flashctx *flash, uint8_t *oldcontents, uint8_t *newcontents);
+romlayout_t *get_next_included_romentry(unsigned int start);
 
 /* spi.c */
 struct spi_command {

diff -Nur flashrom-orig/flashrom.c flashrom-m/flashrom.c
--- flashrom-orig/flashrom.c	2013-03-19 18:03:18.407719488 +0400
+++ flashrom-m/flashrom.c	2013-03-20 18:39:52.188076904 +0400
@@ -1139,7 +1139,7 @@ 
 	return 0;
 }
 
-int write_buf_to_file(unsigned char *buf, unsigned long size,
+int write_dump_to_file(unsigned char *buf, unsigned long size,
 		      const char *filename)
 {
 	unsigned long numbytes;
@@ -1164,26 +1164,81 @@ 
 	return 0;
 }
 
+int write_buf_to_file(unsigned char *buf, unsigned long size,
+		      const char *filename)
+{
+	romlayout_t *l;
+	int ret = 0;
+
+	ret = write_dump_to_file(buf, size, filename);
+	if (ret)
+		return ret;
+
+	l = get_next_included_romentry(0);
+
+	while (l != NULL) {
+		const char* name = (l->file[0] == '\0') ? l->name : l->file;
+		unsigned int len = l->end - l->start + 1;
+		msg_gdbg2("Writing \"%s\" to \"%s\" 0x%08x - 0x%08x (%uB)... ",
+			  l->name, l->file, l->start, l->end, len);
+		if(write_dump_to_file(buf + l->start, len, name)) {
+			msg_gdbg2("failed. ");
+			return 1;
+		}
+		msg_gdbg2("done. ");
+		l = get_next_included_romentry(l->end + 1);
+	};
+
+	return 0;
+}
+
+int read_flash_to_buf(struct flashctx *flash, uint8_t *buf)
+{
+	romlayout_t *l;
+
+	if (!flash->chip->read) {
+		msg_cerr("No read function available for this flash chip.\n");
+		return 1;
+	}
+
+	l = get_next_included_romentry(0);
+	/* No included rom entries. Assume complete readout wanted. */
+	if (l == NULL)
+		return flash->chip->read(flash, buf, 0, flash->chip->total_size * 1024);
+
+	do {
+		unsigned int len = l->end - l->start + 1;
+		msg_gdbg2("Reading \"%s\" 0x%08x - 0x%08x (%uB)... ", l->name,
+			  l->start, l->end, len);
+		if(flash->chip->read(flash, buf + l->start, l->start, len)) {
+			msg_gdbg2("failed. ");
+			return 1;
+		}
+		msg_gdbg2("done. ");
+		l = get_next_included_romentry(l->end + 1);
+	} while (l != NULL);
+
+	return 0;
+}
+
+
 int read_flash_to_file(struct flashctx *flash, const char *filename)
 {
 	unsigned long size = flash->chip->total_size * 1024;
-	unsigned char *buf = calloc(size, sizeof(char));
 	int ret = 0;
+	uint8_t *buf;
 
 	msg_cinfo("Reading flash... ");
-	if (!buf) {
+	buf = calloc(size, sizeof(uint8_t));
+	if (buf == NULL) {
 		msg_gerr("Memory allocation failed!\n");
-		msg_cinfo("FAILED.\n");
-		return 1;
-	}
-	if (!flash->chip->read) {
-		msg_cerr("No read function available for this flash chip.\n");
 		ret = 1;
 		goto out_free;
 	}
-	if (flash->chip->read(flash, buf, 0, size)) {
+
+	ret = read_flash_to_buf(flash, buf);
+	if (ret != 0) {
 		msg_cerr("Read operation failed!\n");
-		ret = 1;
 		goto out_free;
 	}
 
@@ -1902,7 +1957,7 @@ 
 	 * takes time as well.
 	 */
 	msg_cinfo("Reading old flash chip contents... ");
-	if (flash->chip->read(flash, oldcontents, 0, size)) {
+	if (read_flash_to_buf(flash, oldcontents)) {
 		ret = 1;
 		msg_cinfo("FAILED.\n");
 		goto out;
        
diff -Nur flashrom-orig/layout.c flashrom-m/layout.c
--- flashrom-orig/layout.c	2013-02-08 15:53:55.643213321 +0400
+++ flashrom-m/layout.c	2013-03-20 14:25:34.348015347 +0400
@@ -29,13 +29,6 @@ 
 
 #define MAX_ROMLAYOUT	32
 
-typedef struct {
-	unsigned int start;
-	unsigned int end;
-	unsigned int included;
-	char name[256];
-} romlayout_t;
-
 /* include_args lists arguments specified at the command line with -i. They
  * must be processed at some point so that desired regions are marked as
  * "included" in the rom_entries list.