Created
August 11, 2015 19:13
-
-
Save bradfa/ed5bc55d31d1a367d450 to your computer and use it in GitHub Desktop.
flashrom.patch for dediprog
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- 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