Skip to content

Instantly share code, notes, and snippets.

@bradfa
Created August 11, 2015 19:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bradfa/ed5bc55d31d1a367d450 to your computer and use it in GitHub Desktop.
Save bradfa/ed5bc55d31d1a367d450 to your computer and use it in GitHub Desktop.
flashrom.patch for dediprog
--- dediprog.c.orig 2015-05-01 16:17:47.000000000 -0400
+++ dediprog.c 2015-05-07 07:52:43.000000000 -0400
@@ -110,8 +110,13 @@
target_leds = leds;
}
- ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, target_leds,
+ if (dediprog_firmwareversion >= FIRMWARE_VERSION(5,5,1))
+ ret = usb_control_msg(dediprog_handle, 0x42, 0x07, (target_leds << 8) | 0x09, 0x0,
NULL, 0x0, DEFAULT_TIMEOUT);
+ else
+ ret = usb_control_msg(dediprog_handle, 0x42, 0x07, 0x09, target_leds,
+ NULL, 0x0, DEFAULT_TIMEOUT);
+
if (ret != 0x0) {
msg_perr("Command Set LED 0x%x failed (%s)!\n",
leds, usb_strerror());
@@ -225,7 +230,27 @@
const char count_and_chunk[] = {count & 0xff,
(count >> 8) & 0xff,
chunksize & 0xff,
- (chunksize >> 8) & 0xff};
+ (chunksize >> 8) & 0xff,
+ 0xff,
+ 0x00,
+ (start % 0x10000) & 0xff,
+ ((start % 0x10000) >> 8) & 0xff,
+ (start / 0x10000) & 0xff,
+ ((start / 0x10000) >> 8) & 0xff};
+ unsigned int count_and_chunk_size;
+
+ /* Reverse engineering note:
+ * ========================
+ * Omitting the added 6 bytes to count_and_chunk[] on SF100 FW 5.5.1
+ * results in SF100 to incorrectly issue 0x0B (Fast Read) command with
+ * start at SPI address 0xF30000 instead of the expected address 0x0.
+ * (On a 8MiB W25Q64.V chip this wraps around to physical address 0x730000).
+ * Possibly a result of SF100 FW 5.5.1 receive data buffer initialization.
+ */
+ if (dediprog_firmwareversion >= FIRMWARE_VERSION(5,5,1))
+ count_and_chunk_size = 10;
+ else
+ count_and_chunk_size = 4;
if ((start % chunksize) || (len % chunksize)) {
msg_perr("%s: Unaligned start=%i, len=%i! Please report a bug "
@@ -239,10 +264,15 @@
/* Command Read SPI Bulk. No idea which read command is used on the
* SPI side.
*/
- ret = usb_control_msg(dediprog_handle, 0x42, 0x20, start % 0x10000,
+ if (dediprog_firmwareversion >= FIRMWARE_VERSION(5,5,1))
+ ret = usb_control_msg(dediprog_handle, 0x42, 0x20, 0x00,
+ 0x00, (char *)count_and_chunk,
+ count_and_chunk_size, DEFAULT_TIMEOUT);
+ else
+ ret = usb_control_msg(dediprog_handle, 0x42, 0x20, start % 0x10000,
start / 0x10000, (char *)count_and_chunk,
- sizeof(count_and_chunk), DEFAULT_TIMEOUT);
- if (ret != sizeof(count_and_chunk)) {
+ count_and_chunk_size, DEFAULT_TIMEOUT);
+ if (ret != count_and_chunk_size) {
msg_perr("Command Read SPI Bulk failed, %i %s!\n", ret,
usb_strerror());
return 1;
@@ -325,9 +355,37 @@
* space in a USB bulk transfer must be filled with 0xff padding.
*/
const unsigned int count = len / chunksize;
- const char count_and_cmd[] = {count & 0xff, (count >> 8) & 0xff, 0x00, dedi_spi_cmd};
+ const char count_and_cmd[] = {count & 0xff,
+ (count >> 8) & 0xff,
+ 0x00,
+ dedi_spi_cmd,
+ 0xff,
+ 0x00,
+ (start % 0x10000) & 0xff,
+ ((start % 0x10000) >> 8) & 0xff,
+ (start / 0x10000) & 0xff,
+ ((start / 0x10000) >> 8) & 0xff};
+ unsigned int count_and_cmd_size;
char usbbuf[512];
-
+
+ /* Reverse engineering note:
+ * ========================
+ * Omitting the added 6 bytes to count_and_cmd[] on SF100 FW 5.5.1
+ * results in SF100 to incorrectly issue 0x02 (Page Program) command with
+ * start at SPI address 0xF30000 instead of the expected address 0x0.
+ * (On a 8MiB W25Q64.V chip this wraps around to physical address 0x730000).
+ * Possibly a result of SF100 FW 5.5.1 receive data buffer initialization.
+ *
+ * Issuing a single spi_bulk_write() command with this appendage will
+ * correct the addressing so that all further spi_bulk_write() commands
+ * (with or without the appendage) will start at SPI address 0x0.
+ * Only a power cycle of the SF100 will reintroduce the error.
+ */
+ if (dediprog_firmwareversion >= FIRMWARE_VERSION(5,5,1))
+ count_and_cmd_size = 10;
+ else
+ count_and_cmd_size = 4;
+
/*
* We should change this check to
* chunksize > 512
@@ -351,9 +409,13 @@
/* Command Write SPI Bulk. No idea which write command is used on the
* SPI side.
*/
- ret = usb_control_msg(dediprog_handle, 0x42, 0x30, start % 0x10000, start / 0x10000,
- (char *)count_and_cmd, sizeof(count_and_cmd), DEFAULT_TIMEOUT);
- if (ret != sizeof(count_and_cmd)) {
+ if (dediprog_firmwareversion >= FIRMWARE_VERSION(5,5,1))
+ ret = usb_control_msg(dediprog_handle, 0x42, 0x30, 0x00, 0x00,
+ (char *)count_and_cmd, count_and_cmd_size, DEFAULT_TIMEOUT);
+ else
+ ret = usb_control_msg(dediprog_handle, 0x42, 0x30, start % 0x10000, start / 0x10000,
+ (char *)count_and_cmd, count_and_cmd_size, DEFAULT_TIMEOUT);
+ if (ret != count_and_cmd_size) {
msg_perr("Command Write SPI Bulk failed, %i %s!\n", ret,
usb_strerror());
return 1;
@@ -456,10 +518,28 @@
msg_perr("Untested readcnt=%i, aborting.\n", readcnt);
return 1;
}
-
- ret = usb_control_msg(dediprog_handle, 0x42, 0x1, 0xff,
- readcnt ? 0x1 : 0x0, (char *)writearr, writecnt,
- DEFAULT_TIMEOUT);
+
+ if (dediprog_firmwareversion >= FIRMWARE_VERSION(5,5,1))
+ if (*writearr == 0x6 || // Write Enable
+ *writearr == 0x60 || *writearr == 0xc7 || // Chip Erase
+ *writearr == 0x52 || *writearr == 0xd8 || // Block Erase
+ *writearr == 0x20) // Sector Erase
+ /* These commands are treated differently otherwise
+ * Read Status Register-1 (05h) will return incorrect
+ * results for WEL and WIP bits
+ * (at least on Winbond W25Q64BV Flash)
+ */
+ ret = usb_control_msg(dediprog_handle, 0x42, 0x1, 0x0,
+ 0x0, (char *)writearr, writecnt,
+ DEFAULT_TIMEOUT);
+ else
+ ret = usb_control_msg(dediprog_handle, 0x42, 0x1, 0x1,
+ 0x0, (char *)writearr, writecnt,
+ DEFAULT_TIMEOUT);
+ else
+ ret = usb_control_msg(dediprog_handle, 0x42, 0x1, 0xff,
+ readcnt ? 0x1 : 0x0, (char *)writearr, writecnt,
+ DEFAULT_TIMEOUT);
if (ret != writecnt) {
msg_perr("Send SPI failed, expected %i, got %i %s!\n",
writecnt, ret, usb_strerror());
@@ -468,8 +548,13 @@
if (!readcnt)
return 0;
memset(readarr, 0, readcnt);
- ret = usb_control_msg(dediprog_handle, 0xc2, 0x01, 0xbb8, 0x0000,
- (char *)readarr, readcnt, DEFAULT_TIMEOUT);
+
+ if (dediprog_firmwareversion >= FIRMWARE_VERSION(5,5,1))
+ ret = usb_control_msg(dediprog_handle, 0xc2, 0x1, 0x1, 0x0,
+ (char *)readarr, readcnt, DEFAULT_TIMEOUT);
+ else
+ ret = usb_control_msg(dediprog_handle, 0xc2, 0x1, 0xbb8, 0x0000,
+ (char *)readarr, readcnt, DEFAULT_TIMEOUT);
if (ret != readcnt) {
msg_perr("Receive SPI failed, expected %i, got %i %s!\n",
readcnt, ret, usb_strerror());
@@ -494,6 +579,12 @@
" String!\n");
return 1;
}
+ /* Reverse engineering note:
+ * ========================
+ * Dediprog Software SF6.0.4.33 application sends the devicestring
+ * command with wValue and wIndex values of 0x0 instead of 0xff.
+ * Both commands yield the same result, so nothing is changed for now.
+ */
/* Command Receive Device String. */
memset(buf, 0, sizeof(buf));
ret = usb_control_msg(dediprog_handle, 0xc2, 0x8, 0xff, 0xff, buf,
@@ -513,7 +604,7 @@
return 1;
}
/* Only these versions were tested. */
- if (fw[0] < 2 || fw[0] > 5) {
+ if (fw[0] < 2 || fw[0] > 6) {
msg_perr("Unexpected firmware version %d.%d.%d!\n", fw[0],
fw[1], fw[2]);
return 1;
@@ -650,6 +741,7 @@
}
return 0;
}
+#endif
/* Shutdown for firmware 5.x?
* Present in all logs with firmware 5.1.5
@@ -668,6 +760,7 @@
return 0;
}
+#if 0
/* Start/stop blinking?
* Present in all logs with firmware 5.1.5
* Always preceded by Command Receive Device String on 5.1.5
@@ -774,12 +867,12 @@
{
msg_pspew("%s\n", __func__);
-#if 0
+//#if 0
/* Shutdown on firmware 5.x */
- if (dediprog_firmwareversion == 5)
+ if (dediprog_firmwareversion >= 5)
if (dediprog_command_i())
return 1;
-#endif
+//#endif
/* URB 28. Command Set SPI Voltage to 0. */
if (dediprog_set_spi_voltage(0x0))
@@ -802,7 +895,7 @@
struct usb_device *dev;
char *voltage, *device, *spispeed, *target_str;
int spispeed_idx = 1;
- int millivolt = 3500;
+ int millivolt = 1800;
long usedevice = 0;
long target = 1;
int i, ret;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment