Hi Stefan,
On 14.01.2010 14:08, Stefan Reinauer wrote:
On 1/14/10 5:24 AM, Carl-Daniel Hailfinger wrote:
Dediprog SF100 support. Very fragile, lots of stuff guessed from logs. May explode spontaneously.
I think I know enough to actually use it to ID the chip, but that's it. A USB log with which includes writing an image from the original software (pretty much any image) would help clear up a few ambiguities.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Awesome..!
Thanks!
It seems to be talking to the device and get through the initialization, but it ends up with no "SPI" chips being "incompatible":
Actually, that's intentional. That way I could avoid hooking up the driver in the SPI core (which would mean I'd have to create dummy command functions) and still get initialization testing.
MacPro:flashrom stepan$ ./flashrom -p dediprog -V flashrom v0.9.1-r862 Found USB device (0483:dada). Sending RDID Receiving response: 20 20 16 10 00 00 00 00 00 00 00 00 00 00 00 00
Which flash chip is this? The response suggests a ST M25P32 flash chip, but the extra "10" at the end looks rather strange.
Not sure if this code is intended:
/* URB 9. Command Receive Device String. */ memset(buf, 0, sizeof(buf)); ret = usb_control_msg(dediprog_handle, 0xc2, 0x8, 0xff, 0xff, buf, 0x10, DEFAULT_TIMEOUT); if ((ret != 0x10) || !memcmp(buf, "SF100 V:2.1.1 ", 0x10)) {
This would bail out if the version string is "SF100 V:2.1.1 "
Right, that's a bug. Considering that this was coded at 5am, I'm surprised there was only one bug.
msg_perr("Unexpected response 3!\n"); return 1; }
Here I added this:
buf[0xf]=0; msg_pdbg("Found a Dediprog %s\n", buf);
That potentially truncates the string. I'll use strnlen/strncpy to write the string to a separate buffer which is big enough.
Which got me:
flashrom v0.9.1-r862 Found USB device (0483:dada). Found a Dediprog SF100 V:3.1.8
Hm. The best idea might be to match against the model name and the major version.
Let me know if you need more information
A log with SniffUsb 2.0.0006 from http://www.pcausa.com/Utilities/UsbSnoop/ would be very appreciated. I wrote a tool to decode the log generated with that SniffUsb version. Feel free to point me to a private upload via IRC (the log may contain programmer serial numbers).
What the log should contain: - Plugging in the SF100 - Starting the programming software - SPI device detection/probe - Full read - Erase (optional) - Full write (optional) - No custom settings (but you can do a probe-only run with changed settings in another file if you want to help decode a few more commands)
It would be cool if you could use a small SPI chip (4 Mbit or so) because the logs roughly have 4x-20x the size of the flash chip.
Please do not use a SST chip (log would be at least 100x the size of the flash chip). Pretty much all other vendors are OK.
I will post an updated patch soon.
Regards, Carl-Daniel
On 1/15/10 4:28 PM, Carl-Daniel Hailfinger wrote:
MacPro:flashrom stepan$ ./flashrom -p dediprog -V flashrom v0.9.1-r862 Found USB device (0483:dada). Sending RDID Receiving response: 20 20 16 10 00 00 00 00 00 00 00 00 00 00 00 00
Which flash chip is this? The response suggests a ST M25P32 flash chip, but the extra "10" at the end looks rather strange.
It's a Numonyx M25P32 (until a couple of years ago parts of the company were known as SP) Here I added this:
buf[0xf]=0; msg_pdbg("Found a Dediprog %s\n", buf);
That potentially truncates the string. I'll use strnlen/strncpy to write the string to a separate buffer which is big enough.
Yes, I just didn't want to fiddle with the buffer size and all dediprog devices I've seen have a space in the last character. Using a 0x11 bytes big buffer would be the correct approach.
Let me know if you need more information
A log with SniffUsb 2.0.0006 from http://www.pcausa.com/Utilities/UsbSnoop/ would be very appreciated. I wrote a tool to decode the log generated with that SniffUsb version. Feel free to point me to a private upload via IRC (the log may contain programmer serial numbers).
Will produce these asap.
It would be cool if you could use a small SPI chip (4 Mbit or so) because the logs roughly have 4x-20x the size of the flash chip.
That might be a problem, I think 32MBit are the only ones I have here at the moment.. :-} I'll have a look.
Please do not use a SST chip (log would be at least 100x the size of the flash chip). Pretty much all other vendors are OK.
Why is that?
Stefan
On 15.01.2010 17:08, Stefan Reinauer wrote:
On 1/15/10 4:28 PM, Carl-Daniel Hailfinger wrote:
MacPro:flashrom stepan$ ./flashrom -p dediprog -V flashrom v0.9.1-r862 Found USB device (0483:dada). Sending RDID Receiving response: 20 20 16 10 00 00 00 00 00 00 00 00 00 00 00 00
Which flash chip is this? The response suggests a ST M25P32 flash chip, but the extra "10" at the end looks rather strange.
It's a Numonyx M25P32 (until a couple of years ago parts of the company were known as SP)
OK, thanks for confirming.
Here I added this:
buf[0xf]=0; msg_pdbg("Found a Dediprog %s\n", buf);
That potentially truncates the string. I'll use strnlen/strncpy to write the string to a separate buffer which is big enough.
Yes, I just didn't want to fiddle with the buffer size and all dediprog devices I've seen have a space in the last character. Using a 0x11 bytes big buffer would be the correct approach.
That's an option as well, right.
Let me know if you need more information
A log with SniffUsb 2.0.0006 from http://www.pcausa.com/Utilities/UsbSnoop/ would be very appreciated. I wrote a tool to decode the log generated with that SniffUsb version. Feel free to point me to a private upload via IRC (the log may contain programmer serial numbers).
Will produce these asap.
Thanks.
It would be cool if you could use a small SPI chip (4 Mbit or so) because the logs roughly have 4x-20x the size of the flash chip.
That might be a problem, I think 32MBit are the only ones I have here at the moment.. :-} I'll have a look.
OK, I can parse that stuff, it's just that the log may be rather large (80-160 MByte).
Please do not use a SST chip (log would be at least 100x the size of the flash chip). Pretty much all other vendors are OK.
Why is that?
SST doesn't support page write, so you get one USB transaction per written byte. And one transaction takes ~1100 bytes (so yes, I was off by an order of magnitude) in the log. I doubt you want to upload a log with a size of 4 Gigabytes. Plus, my scripts will take a long time to run on such a big log, and besides that the information gathered from a SST log would be essentially zero because it has no long write transactions (which is pretty much the only transaction type I don't have in my log yet).
Regards, Carl-Daniel
Good news: I decoded a few more commands. The v2 and v3 firmware seem to have identical commands.
Bad news: Some things are done internally by the programmer (namely, big reads and writes) and it seems you can't influence the actual SPI commands for that. It is unclear whether commands bigger than 4 bytes can be sent (i.e. writes). It is unclear whether more than 4 bytes of chip response can be read. Some commands are still totally undecoded (one is probably IDLE and another one RESET, but that's pretty much speculation).
I know how to test my assumptions, though.
AFAIK the Dediprog can do "fast" (partial) writes. A log from such a partial write (i.e. zero out some area that was 0xff before) would clear up a lot of stuff.
Separate logs from ID/read with changed frequencies (one log per frequency) would help as well.
What else can be set? Voltage? Timing? Other stuff?
Regards, Carl-Daniel
Dediprog SF100 support. Reverse engineered from USB logs. I never touched that programmer nor did I ever see the associated software. Disabled by default until it is complete. The driver needs to be hooked up to the SPI core before it will do anything besides init and diagnostics.
I successfully reverse engineered all commands, but some are still somewhat magic. Logs from "flashrom -p dediprog -V" are appreciated.
Stefan, I did not use your Ack because the code has changed so much. A new review/test/ack would be very appreciated.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-dediprog/flash.h =================================================================== --- flashrom-dediprog/flash.h (Revision 862) +++ flashrom-dediprog/flash.h (Arbeitskopie) @@ -67,6 +67,9 @@ #if BUSPIRATE_SPI_SUPPORT == 1 PROGRAMMER_BUSPIRATESPI, #endif +#if DEDIPROG_SUPPORT == 1 + PROGRAMMER_DEDIPROG, +#endif PROGRAMMER_INVALID /* This must always be the last entry. */ };
@@ -470,6 +473,10 @@ int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); int buspirate_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
+/* dediprog.c */ +int dediprog_init(void); +int dediprog_shutdown(void); + /* flashrom.c */ extern enum chipbustype buses_supported; struct decode_sizes { Index: flashrom-dediprog/Makefile =================================================================== --- flashrom-dediprog/Makefile (Revision 862) +++ flashrom-dediprog/Makefile (Arbeitskopie) @@ -96,6 +96,9 @@ # Always enable Bus Pirate SPI for now. CONFIG_BUSPIRATESPI ?= yes
+# Disable Dediprog SF100 until support is complete and tested. +CONFIG_DEDIPROG ?= no + # Disable wiki printing by default. It is only useful if you have wiki access. CONFIG_PRINT_WIKI ?= no
@@ -160,6 +163,12 @@ PROGRAMMER_OBJS += buspirate_spi.o endif
+ifeq ($(CONFIG_DEDIPROG), yes) +FEATURE_CFLAGS += -D'DEDIPROG_SUPPORT=1' +FEATURE_LIBS += -lusb +PROGRAMMER_OBJS += dediprog.o +endif + # Ugly, but there's no elif/elseif. ifeq ($(CONFIG_SERPROG), yes) LIB_OBJS += serial.o Index: flashrom-dediprog/flashrom.c =================================================================== --- flashrom-dediprog/flashrom.c (Revision 862) +++ flashrom-dediprog/flashrom.c (Arbeitskopie) @@ -44,7 +44,7 @@ * if more than one of them is selected. If only one is selected, it is clear * that the user wants that one to become the default. */ -#if NIC3COM_SUPPORT+GFXNVIDIA_SUPPORT+DRKAISER_SUPPORT+SATASII_SUPPORT+FT2232_SPI_SUPPORT+SERPROG_SUPPORT+BUSPIRATE_SPI_SUPPORT > 1 +#if NIC3COM_SUPPORT+GFXNVIDIA_SUPPORT+DRKAISER_SUPPORT+SATASII_SUPPORT+FT2232_SPI_SUPPORT+SERPROG_SUPPORT+BUSPIRATE_SPI_SUPPORT+DEDIPROG_SUPPORT > 1 #error Please enable either CONFIG_DUMMY or CONFIG_INTERNAL or disable support for all external programmers except one. #endif enum programmer programmer = @@ -69,6 +69,9 @@ #if BUSPIRATE_SPI_SUPPORT == 1 PROGRAMMER_BUSPIRATESPI #endif +#if DEDIPROG_SUPPORT == 1 + PROGRAMMER_DEDIPROG +#endif ; #endif
@@ -283,6 +286,25 @@ }, #endif
+#if DEDIPROG_SUPPORT == 1 + { + .name = "dediprog", + .init = dediprog_init, + .shutdown = dediprog_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 + {}, /* This entry corresponds to PROGRAMMER_INVALID. */ };
Index: flashrom-dediprog/dediprog.c =================================================================== --- flashrom-dediprog/dediprog.c (Revision 0) +++ flashrom-dediprog/dediprog.c (Revision 0) @@ -0,0 +1,382 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2010 Carl-Daniel Hailfinger + * + * 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; version 2 of the License. + * + * 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. + * + * 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 + */ + +#include <string.h> +#include <stdlib.h> +#include <ctype.h> +#include <sys/types.h> +#include <usb.h> +#include "flash.h" +#include "spi.h" + +#define DEFAULT_TIMEOUT 3000 +usb_dev_handle *dediprog_handle; + +int dediprog_do_stuff(void); + +void print_hex(void *buf, size_t len) +{ + size_t i; + + for (i = 0; i < len; i++) + msg_pdbg(" %02x", ((uint8_t *)buf)[i]); +} + +struct usb_device *get_device_by_vid_pid(uint16_t vid, uint16_t pid) +{ + struct usb_bus *bus; + struct usb_device *dev; + + for (bus = usb_get_busses(); bus; bus = bus->next) + for (dev = bus->devices; dev; dev = dev->next) + if ((dev->descriptor.idVendor == vid) && + (dev->descriptor.idProduct == pid)) + return dev; + + return NULL; +} + +//int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout); + +int dediprog_set_spi_voltage(uint16_t voltage) +{ + int ret; + unsigned int mv; + + switch (voltage) { + case 0x0: + /* Admittedly this one is an assumption. */ + mv = 0; + break; + case 0x12: + mv = 1800; + break; + case 0x11: + mv = 2500; + break; + case 0x10: + mv = 3500; + break; + default: + msg_perr("Unknown voltage selector 0x%x! Aborting.\n", voltage); + return 1; + } + msg_pdbg("Setting SPI voltage to %u.%03u V\n", mv / 1000, mv % 1000); + + ret = usb_control_msg(dediprog_handle, 0x42, 0x9, voltage, 0xff, NULL, 0x0, DEFAULT_TIMEOUT); + if (ret != 0x0) { + msg_perr("Command Set SPI Voltage 0x%x failed!\n", voltage); + return 1; + } + return 0; +} + +/* After dediprog_set_spi_speed, the original app always calls + * dediprog_set_spi_voltage(0) and then + * dediprog_check_devicestring() four times in a row. + * After that, dediprog_command_a() is called. + * This looks suspiciously like the microprocessor in the SF100 has to be + * restarted/reinitialized in case the speed changes. + */ +int dediprog_set_spi_speed(uint16_t speed) +{ + int ret; + unsigned int khz; + + /* Case 1 and 2 are in weird order. Probably an organically "grown" + * interface. + * Base frequency is 24000 kHz, divisors are (in order) + * 1, 3, 2, 8, 11, 16, 32, 64. + */ + switch (speed) { + case 0x0: + khz = 24000; + break; + case 0x1: + khz = 8000; + break; + case 0x2: + khz = 12000; + break; + case 0x3: + khz = 3000; + break; + case 0x4: + khz = 2180; + break; + case 0x5: + khz = 1500; + break; + case 0x6: + khz = 750; + break; + case 0x7: + khz = 375; + break; + default: + msg_perr("Unknown frequency selector 0x%x! Aborting.\n", speed); + return 1; + } + msg_pdbg("Setting SPI speed to %u kHz\n", khz); + + ret = usb_control_msg(dediprog_handle, 0x42, 0x61, speed, 0xff, NULL, 0x0, DEFAULT_TIMEOUT); + if (ret != 0x0) { + msg_perr("Command Set SPI Speed 0x%x failed!\n", speed); + return 1; + } + return 0; +} + +int dediprog_spi_send_command(unsigned int writecnt, unsigned int readcnt, + const unsigned char *writearr, unsigned char *readarr) +{ + int ret; + + /* Paranoid, but I don't want to be blamed if anything explodes. */ + if ((writecnt != 1) && (writecnt != 4)) + msg_perr("Untested writecnt=%i, aborting.\n", writecnt); + if (readcnt > 4) + msg_perr("Untested readcnt=%i, aborting.\n", readcnt); + if ((readcnt == 0) && (writecnt != 1)) + msg_perr("Untested writecnt=%i, readcnt=%i combination, " + "aborting.\n", writecnt, readcnt); + + ret = usb_control_msg(dediprog_handle, 0x42, 0x1, 0xff, readcnt ? 0x1 : 0x0, (char *)writearr, writecnt, DEFAULT_TIMEOUT); + if (ret != writecnt) { + msg_perr("Command Send SPI failed, ret=%i!\n", ret); + return 1; + } + if (!readcnt) + return 0; + memset(readarr, 0, readcnt); + ret = usb_control_msg(dediprog_handle, 0xc2, 0x01, 0xbb8, 0x0000, (char *)readarr, readcnt, DEFAULT_TIMEOUT); + if (ret != 0x4) { + msg_perr("Command Receive SPI failed, ret=%i!\n", ret); + return 1; + } + return 0; +} + +int dediprog_check_devicestring(void) +{ + int ret; + char buf[0x11]; + + /* Command Prepare Receive Device String. */ + memset(buf, 0, sizeof(buf)); + ret = usb_control_msg(dediprog_handle, 0xc3, 0x7, 0x0, 0xef03, buf, 0x1, DEFAULT_TIMEOUT); + /* The char casting is needed to stop gcc complaining about an always true comparison. */ + if ((ret != 0x1) || (buf[0] != (char)0xff)) { + msg_perr("Unexpected response to Command Prepare Receive Device" + " String!\n"); + return 1; + } + /* Command Receive Device String. */ + memset(buf, 0, sizeof(buf)); + ret = usb_control_msg(dediprog_handle, 0xc2, 0x8, 0xff, 0xff, buf, 0x10, DEFAULT_TIMEOUT); + if (ret != 0x10) { + msg_perr("Incomplete/failed Command Receive Device String!\n"); + return 1; + } + buf[0x10] = '\0'; + msg_pdbg("Found a %s\n", buf); + if (memcmp(buf, "SF100", 0x5)) { + msg_perr("Device not a SF100!\n"); + return 1; + } + /* Only these versions were tested. */ + if (memcmp(buf, "SF100 V:2.1.1 ", 0x10) && + memcmp(buf, "SF100 V:3.1.8 ", 0x10)) { + msg_perr("Unexpected firmware version!\n"); + return 1; + } + return 0; +} + +/* Command A seems to be some sort of device init. It is either followed by + * dediprog_check_devicestring (often) or Command A (often) or + * Command F (once). + */ +int dediprog_command_a(void) +{ + int ret; + char buf[0x1]; + + memset(buf, 0, sizeof(buf)); + ret = usb_control_msg(dediprog_handle, 0xc3, 0xb, 0x0, 0x0, buf, 0x1, DEFAULT_TIMEOUT); + if ((ret != 0x1) || (buf[0] != 0x6f)) { + msg_perr("Unexpected response to Command A!\n"); + return 1; + } + return 0; +} + +/* Command C is only sent after dediprog_check_devicestring, but not after every + * invocation of dediprog_check_devicestring. It is only sent after the first + * dediprog_command_a(); dediprog_check_devicestring() sequence in each session. + * I'm tempted to call this one start_SPI_engine or finish_init. + */ +int dediprog_command_c(void) +{ + int ret; + + ret = usb_control_msg(dediprog_handle, 0x42, 0x4, 0x0, 0x0, NULL, 0x0, DEFAULT_TIMEOUT); + if (ret != 0x0) { + msg_perr("Unexpected response to Command C!\n"); + return 1; + } + return 0; +} + +/* Very strange. Seems to be a programmer keepalive or somesuch. + * Wait unsuccessfully for timeout ms to read one byte. + * Is usually called after setting voltage to 0. + */ +int dediprog_command_f(int timeout) +{ + int ret; + char buf[0x1]; + + memset(buf, 0, sizeof(buf)); + ret = usb_control_msg(dediprog_handle, 0xc2, 0x11, 0xff, 0xff, buf, 0x1, timeout); + if (ret != 0x0) { + msg_perr("Unexpected response to Command F!\n"); + return 1; + } + return 0; +} + +/* URB numbers refer to the first log ever captured. */ +int dediprog_init(void) +{ + struct usb_device *dev; + + msg_pspew("%s\n", __func__); + + /* Here comes the USB stuff. */ + usb_init(); + usb_find_busses(); + usb_find_devices(); + dev = get_device_by_vid_pid(0x0483, 0xdada); + if (!dev) { + msg_perr("Could not find a Dediprog SF100 on USB!\n"); + return 1; + } + msg_pdbg("Found USB device (%04x:%04x).\n", + dev->descriptor.idVendor, + dev->descriptor.idProduct); + dediprog_handle = usb_open(dev); + /* URB 6. Command A. */ + if (dediprog_command_a()) + return 1; + /* URB 7. Command A. */ + if (dediprog_command_a()) + return 1; + /* URB 8. Command Prepare Receive Device String. */ + /* URB 9. Command Receive Device String. */ + if (dediprog_check_devicestring()) + return 1; + /* URB 10. Command C. */ + if (dediprog_command_c()) + return 1; + /* URB 11. Command Set SPI Voltage. */ + if (dediprog_set_spi_voltage(0x10)) + return 1; + + /* FIXME: Enable this once the driver is hooked up to the SPI layer. */ +#if 0 + buses_supported = CHIP_BUSTYPE_SPI; + spi_controller = SPI_CONTROLLER_DEDIPROG; +#else + /* For now, just to make sure nothing is sent. */ + buses_supported = CHIP_BUSTYPE_NONE; +#endif + msg_pinfo("All probes will fail because this driver is not hooked up " + "to the SPI infrastructure yet."); + + /* Execute RDID by hand for now. */ + dediprog_do_stuff(); + + return 0; +} + +/* Leftovers from reverse engineering. Keep for documentation purposes until + * completely understood. + */ +int dediprog_do_stuff(void) +{ + char buf[0x4]; + /* SPI command processing starts here. */ + + /* URB 12. Command Send SPI. */ + /* URB 13. Command Receive SPI. */ + memset(buf, 0, sizeof(buf)); + /* JEDEC RDID */ + msg_pdbg("Sending RDID\n"); + buf[0] = JEDEC_RDID; + if (dediprog_spi_send_command(JEDEC_RDID_OUTSIZE, JEDEC_RDID_INSIZE, (unsigned char *)buf, (unsigned char *)buf)) + return 1; + msg_pdbg("Receiving response: "); + print_hex(buf, JEDEC_RDID_OUTSIZE); +#if 0 + /* URB 14-27 are more SPI commands. */ + /* URB 28. Command Set SPI Voltage. */ + if (dediprog_set_spi_voltage(0x0)) + return 1; + /* URB 29-38. Command F, unsuccessful wait. */ + if (dediprog_command_f(544)) + return 1; + /* URB 39. Command Set SPI Voltage. */ + if (dediprog_set_spi_voltage(0x10)) + return 1; + /* URB 40. Command Set SPI Speed. */ + if (dediprog_set_spi_speed(0x2)) + return 1; + /* URB 41 is just URB 28. */ + /* URB 42,44,46,48,51,53 is just URB 8. */ + /* URB 43,45,47,49,52,54 is just URB 9. */ + /* URB 50 is just URB 6/7. */ + /* URB 55-131 is just URB 29-38. (wait unsuccessfully for 4695 (maybe 4751) ms)*/ + /* URB 132,134 is just URB 6/7. */ + /* URB 133 is just URB 29-38. */ + /* URB 135 is just URB 8. */ + /* URB 136 is just URB 9. */ + /* URB 137 is just URB 11. */ + + /* Command I is probably Start Bulk Read. Data is u16 blockcount, u16 blocksize. */ + /* Command J is probably Start Bulk Write. Data is u16 blockcount, u16 blocksize. */ + /* Bulk transfer sizes for Command I/J are always 512 bytes, rest is filled with 0xff. */ +#endif + + msg_pinfo("All probes will fail because this driver is not hooked up " + "to the SPI infrastructure yet."); + return 0; +} + +int dediprog_shutdown(void) +{ + msg_pspew("%s\n", __func__); + + msg_pinfo("Should probably set SPI voltage to 0 on shutdown.\n"); + if (usb_close(dediprog_handle)) { + msg_perr("Couldn't close USB device!\n"); + return 1; + } + return 0; +}
Resend with SPI read length check fixed. Thanks to Stefan for testing.
Dediprog SF100 support. Reverse engineered from USB logs. I never touched that programmer nor did I ever see the associated software. Disabled by default until it is complete. The driver needs to be hooked up to the SPI core before it will do anything besides init and diagnostics.
I successfully reverse engineered all commands, but some are still somewhat magic. Logs from "flashrom -p dediprog -V" are appreciated.
Stefan, I did not use your Ack because the code has changed so much. A new review/test/ack would be very appreciated.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-dediprog/flash.h =================================================================== --- flashrom-dediprog/flash.h (Revision 862) +++ flashrom-dediprog/flash.h (Arbeitskopie) @@ -67,6 +67,9 @@ #if BUSPIRATE_SPI_SUPPORT == 1 PROGRAMMER_BUSPIRATESPI, #endif +#if DEDIPROG_SUPPORT == 1 + PROGRAMMER_DEDIPROG, +#endif PROGRAMMER_INVALID /* This must always be the last entry. */ };
@@ -470,6 +473,10 @@ int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); int buspirate_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
+/* dediprog.c */ +int dediprog_init(void); +int dediprog_shutdown(void); + /* flashrom.c */ extern enum chipbustype buses_supported; struct decode_sizes { Index: flashrom-dediprog/Makefile =================================================================== --- flashrom-dediprog/Makefile (Revision 862) +++ flashrom-dediprog/Makefile (Arbeitskopie) @@ -96,6 +96,9 @@ # Always enable Bus Pirate SPI for now. CONFIG_BUSPIRATESPI ?= yes
+# Disable Dediprog SF100 until support is complete and tested. +CONFIG_DEDIPROG ?= no + # Disable wiki printing by default. It is only useful if you have wiki access. CONFIG_PRINT_WIKI ?= no
@@ -160,6 +163,12 @@ PROGRAMMER_OBJS += buspirate_spi.o endif
+ifeq ($(CONFIG_DEDIPROG), yes) +FEATURE_CFLAGS += -D'DEDIPROG_SUPPORT=1' +FEATURE_LIBS += -lusb +PROGRAMMER_OBJS += dediprog.o +endif + # Ugly, but there's no elif/elseif. ifeq ($(CONFIG_SERPROG), yes) LIB_OBJS += serial.o Index: flashrom-dediprog/flashrom.c =================================================================== --- flashrom-dediprog/flashrom.c (Revision 862) +++ flashrom-dediprog/flashrom.c (Arbeitskopie) @@ -44,7 +44,7 @@ * if more than one of them is selected. If only one is selected, it is clear * that the user wants that one to become the default. */ -#if NIC3COM_SUPPORT+GFXNVIDIA_SUPPORT+DRKAISER_SUPPORT+SATASII_SUPPORT+FT2232_SPI_SUPPORT+SERPROG_SUPPORT+BUSPIRATE_SPI_SUPPORT > 1 +#if NIC3COM_SUPPORT+GFXNVIDIA_SUPPORT+DRKAISER_SUPPORT+SATASII_SUPPORT+FT2232_SPI_SUPPORT+SERPROG_SUPPORT+BUSPIRATE_SPI_SUPPORT+DEDIPROG_SUPPORT > 1 #error Please enable either CONFIG_DUMMY or CONFIG_INTERNAL or disable support for all external programmers except one. #endif enum programmer programmer = @@ -69,6 +69,9 @@ #if BUSPIRATE_SPI_SUPPORT == 1 PROGRAMMER_BUSPIRATESPI #endif +#if DEDIPROG_SUPPORT == 1 + PROGRAMMER_DEDIPROG +#endif ; #endif
@@ -283,6 +286,25 @@ }, #endif
+#if DEDIPROG_SUPPORT == 1 + { + .name = "dediprog", + .init = dediprog_init, + .shutdown = dediprog_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 + {}, /* This entry corresponds to PROGRAMMER_INVALID. */ };
Index: flashrom-dediprog/dediprog.c =================================================================== --- flashrom-dediprog/dediprog.c (Revision 0) +++ flashrom-dediprog/dediprog.c (Revision 0) @@ -0,0 +1,384 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2010 Carl-Daniel Hailfinger + * + * 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; version 2 of the License. + * + * 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. + * + * 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 + */ + +#include <string.h> +#include <stdlib.h> +#include <ctype.h> +#include <sys/types.h> +#include <usb.h> +#include "flash.h" +#include "spi.h" + +#define DEFAULT_TIMEOUT 3000 +usb_dev_handle *dediprog_handle; + +int dediprog_do_stuff(void); + +void print_hex(void *buf, size_t len) +{ + size_t i; + + for (i = 0; i < len; i++) + msg_pdbg(" %02x", ((uint8_t *)buf)[i]); +} + +struct usb_device *get_device_by_vid_pid(uint16_t vid, uint16_t pid) +{ + struct usb_bus *bus; + struct usb_device *dev; + + for (bus = usb_get_busses(); bus; bus = bus->next) + for (dev = bus->devices; dev; dev = dev->next) + if ((dev->descriptor.idVendor == vid) && + (dev->descriptor.idProduct == pid)) + return dev; + + return NULL; +} + +//int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout); + +int dediprog_set_spi_voltage(uint16_t voltage) +{ + int ret; + unsigned int mv; + + switch (voltage) { + case 0x0: + /* Admittedly this one is an assumption. */ + mv = 0; + break; + case 0x12: + mv = 1800; + break; + case 0x11: + mv = 2500; + break; + case 0x10: + mv = 3500; + break; + default: + msg_perr("Unknown voltage selector 0x%x! Aborting.\n", voltage); + return 1; + } + msg_pdbg("Setting SPI voltage to %u.%03u V\n", mv / 1000, mv % 1000); + + ret = usb_control_msg(dediprog_handle, 0x42, 0x9, voltage, 0xff, NULL, 0x0, DEFAULT_TIMEOUT); + if (ret != 0x0) { + msg_perr("Command Set SPI Voltage 0x%x failed!\n", voltage); + return 1; + } + return 0; +} + +/* After dediprog_set_spi_speed, the original app always calls + * dediprog_set_spi_voltage(0) and then + * dediprog_check_devicestring() four times in a row. + * After that, dediprog_command_a() is called. + * This looks suspiciously like the microprocessor in the SF100 has to be + * restarted/reinitialized in case the speed changes. + */ +int dediprog_set_spi_speed(uint16_t speed) +{ + int ret; + unsigned int khz; + + /* Case 1 and 2 are in weird order. Probably an organically "grown" + * interface. + * Base frequency is 24000 kHz, divisors are (in order) + * 1, 3, 2, 8, 11, 16, 32, 64. + */ + switch (speed) { + case 0x0: + khz = 24000; + break; + case 0x1: + khz = 8000; + break; + case 0x2: + khz = 12000; + break; + case 0x3: + khz = 3000; + break; + case 0x4: + khz = 2180; + break; + case 0x5: + khz = 1500; + break; + case 0x6: + khz = 750; + break; + case 0x7: + khz = 375; + break; + default: + msg_perr("Unknown frequency selector 0x%x! Aborting.\n", speed); + return 1; + } + msg_pdbg("Setting SPI speed to %u kHz\n", khz); + + ret = usb_control_msg(dediprog_handle, 0x42, 0x61, speed, 0xff, NULL, 0x0, DEFAULT_TIMEOUT); + if (ret != 0x0) { + msg_perr("Command Set SPI Speed 0x%x failed!\n", speed); + return 1; + } + return 0; +} + +int dediprog_spi_send_command(unsigned int writecnt, unsigned int readcnt, + const unsigned char *writearr, unsigned char *readarr) +{ + int ret; + + /* Paranoid, but I don't want to be blamed if anything explodes. */ + if ((writecnt != 1) && (writecnt != 4)) + msg_perr("Untested writecnt=%i, aborting.\n", writecnt); + if (readcnt > 4) + msg_perr("Untested readcnt=%i, aborting.\n", readcnt); + if ((readcnt == 0) && (writecnt != 1)) + msg_perr("Untested writecnt=%i, readcnt=%i combination, " + "aborting.\n", writecnt, readcnt); + + ret = usb_control_msg(dediprog_handle, 0x42, 0x1, 0xff, readcnt ? 0x1 : 0x0, (char *)writearr, writecnt, DEFAULT_TIMEOUT); + if (ret != writecnt) { + msg_perr("Command Send SPI failed, ret=%i, expected %i!\n", + ret, writecnt); + return 1; + } + if (!readcnt) + return 0; + memset(readarr, 0, readcnt); + ret = usb_control_msg(dediprog_handle, 0xc2, 0x01, 0xbb8, 0x0000, (char *)readarr, readcnt, DEFAULT_TIMEOUT); + if (ret != readcnt) { + msg_perr("Command Receive SPI failed, ret=%i, expected %i!\n", + ret, readcnt); + return 1; + } + return 0; +} + +int dediprog_check_devicestring(void) +{ + int ret; + char buf[0x11]; + + /* Command Prepare Receive Device String. */ + memset(buf, 0, sizeof(buf)); + ret = usb_control_msg(dediprog_handle, 0xc3, 0x7, 0x0, 0xef03, buf, 0x1, DEFAULT_TIMEOUT); + /* The char casting is needed to stop gcc complaining about an always true comparison. */ + if ((ret != 0x1) || (buf[0] != (char)0xff)) { + msg_perr("Unexpected response to Command Prepare Receive Device" + " String!\n"); + return 1; + } + /* Command Receive Device String. */ + memset(buf, 0, sizeof(buf)); + ret = usb_control_msg(dediprog_handle, 0xc2, 0x8, 0xff, 0xff, buf, 0x10, DEFAULT_TIMEOUT); + if (ret != 0x10) { + msg_perr("Incomplete/failed Command Receive Device String!\n"); + return 1; + } + buf[0x10] = '\0'; + msg_pdbg("Found a %s\n", buf); + if (memcmp(buf, "SF100", 0x5)) { + msg_perr("Device not a SF100!\n"); + return 1; + } + /* Only these versions were tested. */ + if (memcmp(buf, "SF100 V:2.1.1 ", 0x10) && + memcmp(buf, "SF100 V:3.1.8 ", 0x10)) { + msg_perr("Unexpected firmware version!\n"); + return 1; + } + return 0; +} + +/* Command A seems to be some sort of device init. It is either followed by + * dediprog_check_devicestring (often) or Command A (often) or + * Command F (once). + */ +int dediprog_command_a(void) +{ + int ret; + char buf[0x1]; + + memset(buf, 0, sizeof(buf)); + ret = usb_control_msg(dediprog_handle, 0xc3, 0xb, 0x0, 0x0, buf, 0x1, DEFAULT_TIMEOUT); + if ((ret != 0x1) || (buf[0] != 0x6f)) { + msg_perr("Unexpected response to Command A!\n"); + return 1; + } + return 0; +} + +/* Command C is only sent after dediprog_check_devicestring, but not after every + * invocation of dediprog_check_devicestring. It is only sent after the first + * dediprog_command_a(); dediprog_check_devicestring() sequence in each session. + * I'm tempted to call this one start_SPI_engine or finish_init. + */ +int dediprog_command_c(void) +{ + int ret; + + ret = usb_control_msg(dediprog_handle, 0x42, 0x4, 0x0, 0x0, NULL, 0x0, DEFAULT_TIMEOUT); + if (ret != 0x0) { + msg_perr("Unexpected response to Command C!\n"); + return 1; + } + return 0; +} + +/* Very strange. Seems to be a programmer keepalive or somesuch. + * Wait unsuccessfully for timeout ms to read one byte. + * Is usually called after setting voltage to 0. + */ +int dediprog_command_f(int timeout) +{ + int ret; + char buf[0x1]; + + memset(buf, 0, sizeof(buf)); + ret = usb_control_msg(dediprog_handle, 0xc2, 0x11, 0xff, 0xff, buf, 0x1, timeout); + if (ret != 0x0) { + msg_perr("Unexpected response to Command F!\n"); + return 1; + } + return 0; +} + +/* URB numbers refer to the first log ever captured. */ +int dediprog_init(void) +{ + struct usb_device *dev; + + msg_pspew("%s\n", __func__); + + /* Here comes the USB stuff. */ + usb_init(); + usb_find_busses(); + usb_find_devices(); + dev = get_device_by_vid_pid(0x0483, 0xdada); + if (!dev) { + msg_perr("Could not find a Dediprog SF100 on USB!\n"); + return 1; + } + msg_pdbg("Found USB device (%04x:%04x).\n", + dev->descriptor.idVendor, + dev->descriptor.idProduct); + dediprog_handle = usb_open(dev); + /* URB 6. Command A. */ + if (dediprog_command_a()) + return 1; + /* URB 7. Command A. */ + if (dediprog_command_a()) + return 1; + /* URB 8. Command Prepare Receive Device String. */ + /* URB 9. Command Receive Device String. */ + if (dediprog_check_devicestring()) + return 1; + /* URB 10. Command C. */ + if (dediprog_command_c()) + return 1; + /* URB 11. Command Set SPI Voltage. */ + if (dediprog_set_spi_voltage(0x10)) + return 1; + + /* FIXME: Enable this once the driver is hooked up to the SPI layer. */ +#if 0 + buses_supported = CHIP_BUSTYPE_SPI; + spi_controller = SPI_CONTROLLER_DEDIPROG; +#else + /* For now, just to make sure nothing is sent. */ + buses_supported = CHIP_BUSTYPE_NONE; +#endif + msg_pinfo("All probes will fail because this driver is not hooked up " + "to the SPI infrastructure yet."); + + /* Execute RDID by hand for now. */ + dediprog_do_stuff(); + + return 0; +} + +/* Leftovers from reverse engineering. Keep for documentation purposes until + * completely understood. + */ +int dediprog_do_stuff(void) +{ + char buf[0x4]; + /* SPI command processing starts here. */ + + /* URB 12. Command Send SPI. */ + /* URB 13. Command Receive SPI. */ + memset(buf, 0, sizeof(buf)); + /* JEDEC RDID */ + msg_pdbg("Sending RDID\n"); + buf[0] = JEDEC_RDID; + if (dediprog_spi_send_command(JEDEC_RDID_OUTSIZE, JEDEC_RDID_INSIZE, (unsigned char *)buf, (unsigned char *)buf)) + return 1; + msg_pdbg("Receiving response: "); + print_hex(buf, JEDEC_RDID_OUTSIZE); +#if 0 + /* URB 14-27 are more SPI commands. */ + /* URB 28. Command Set SPI Voltage. */ + if (dediprog_set_spi_voltage(0x0)) + return 1; + /* URB 29-38. Command F, unsuccessful wait. */ + if (dediprog_command_f(544)) + return 1; + /* URB 39. Command Set SPI Voltage. */ + if (dediprog_set_spi_voltage(0x10)) + return 1; + /* URB 40. Command Set SPI Speed. */ + if (dediprog_set_spi_speed(0x2)) + return 1; + /* URB 41 is just URB 28. */ + /* URB 42,44,46,48,51,53 is just URB 8. */ + /* URB 43,45,47,49,52,54 is just URB 9. */ + /* URB 50 is just URB 6/7. */ + /* URB 55-131 is just URB 29-38. (wait unsuccessfully for 4695 (maybe 4751) ms)*/ + /* URB 132,134 is just URB 6/7. */ + /* URB 133 is just URB 29-38. */ + /* URB 135 is just URB 8. */ + /* URB 136 is just URB 9. */ + /* URB 137 is just URB 11. */ + + /* Command I is probably Start Bulk Read. Data is u16 blockcount, u16 blocksize. */ + /* Command J is probably Start Bulk Write. Data is u16 blockcount, u16 blocksize. */ + /* Bulk transfer sizes for Command I/J are always 512 bytes, rest is filled with 0xff. */ +#endif + + msg_pinfo("All probes will fail because this driver is not hooked up " + "to the SPI infrastructure yet."); + return 0; +} + +int dediprog_shutdown(void) +{ + msg_pspew("%s\n", __func__); + + msg_pinfo("Should probably set SPI voltage to 0 on shutdown.\n"); + if (usb_close(dediprog_handle)) { + msg_perr("Couldn't close USB device!\n"); + return 1; + } + return 0; +}
Dediprog SF100 support.
Reverse engineered from USB logs. I never touched that programmer nor did I ever see the associated software. Disabled by default until it is complete. The driver needs to be hooked up to the SPI core before it will do anything besides init and diagnostics.
I successfully reverse engineered all commands, but some are still somewhat magic. Logs from "flashrom -p dediprog -V" are appreciated.
Probe and read should work, erase/write is expected to explode. The programmer will set voltage to 0 on exit.
Thanks a lot to Stefan Reinauer and Patrick Georgi for providing USB logs and for testing the result.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-dediprog/flash.h =================================================================== --- flashrom-dediprog/flash.h (Revision 866) +++ flashrom-dediprog/flash.h (Arbeitskopie) @@ -67,6 +67,9 @@ #if BUSPIRATE_SPI_SUPPORT == 1 PROGRAMMER_BUSPIRATESPI, #endif +#if DEDIPROG_SUPPORT == 1 + PROGRAMMER_DEDIPROG, +#endif PROGRAMMER_INVALID /* This must always be the last entry. */ };
@@ -470,6 +473,12 @@ int buspirate_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); int buspirate_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
+/* dediprog.c */ +int dediprog_init(void); +int dediprog_shutdown(void); +int dediprog_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr); +int dediprog_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len); + /* flashrom.c */ extern enum chipbustype buses_supported; struct decode_sizes { @@ -553,6 +562,9 @@ #if BUSPIRATE_SPI_SUPPORT == 1 SPI_CONTROLLER_BUSPIRATE, #endif +#if DEDIPROG_SUPPORT == 1 + SPI_CONTROLLER_DEDIPROG, +#endif SPI_CONTROLLER_INVALID /* This must always be the last entry. */ }; extern const int spi_programmer_count; Index: flashrom-dediprog/spi.c =================================================================== --- flashrom-dediprog/spi.c (Revision 866) +++ flashrom-dediprog/spi.c (Arbeitskopie) @@ -111,6 +111,15 @@ }, #endif
+#if DEDIPROG_SUPPORT == 1 + { /* SPI_CONTROLLER_DEDIPROG */ + .command = dediprog_spi_send_command, + .multicommand = default_spi_send_multicommand, + .read = dediprog_spi_read, + .write_256 = spi_chip_write_1, + }, +#endif + {}, /* This entry corresponds to SPI_CONTROLLER_INVALID. */ };
Index: flashrom-dediprog/Makefile =================================================================== --- flashrom-dediprog/Makefile (Revision 866) +++ flashrom-dediprog/Makefile (Arbeitskopie) @@ -96,6 +96,9 @@ # Always enable Bus Pirate SPI for now. CONFIG_BUSPIRATESPI ?= yes
+# Disable Dediprog SF100 until support is complete and tested. +CONFIG_DEDIPROG ?= no + # Disable wiki printing by default. It is only useful if you have wiki access. CONFIG_PRINT_WIKI ?= no
@@ -160,6 +163,12 @@ PROGRAMMER_OBJS += buspirate_spi.o endif
+ifeq ($(CONFIG_DEDIPROG), yes) +FEATURE_CFLAGS += -D'DEDIPROG_SUPPORT=1' +FEATURE_LIBS += -lusb +PROGRAMMER_OBJS += dediprog.o +endif + # Ugly, but there's no elif/elseif. ifeq ($(CONFIG_SERPROG), yes) LIB_OBJS += serial.o Index: flashrom-dediprog/flashrom.c =================================================================== --- flashrom-dediprog/flashrom.c (Revision 866) +++ flashrom-dediprog/flashrom.c (Arbeitskopie) @@ -44,7 +44,7 @@ * if more than one of them is selected. If only one is selected, it is clear * that the user wants that one to become the default. */ -#if NIC3COM_SUPPORT+GFXNVIDIA_SUPPORT+DRKAISER_SUPPORT+SATASII_SUPPORT+FT2232_SPI_SUPPORT+SERPROG_SUPPORT+BUSPIRATE_SPI_SUPPORT > 1 +#if NIC3COM_SUPPORT+GFXNVIDIA_SUPPORT+DRKAISER_SUPPORT+SATASII_SUPPORT+FT2232_SPI_SUPPORT+SERPROG_SUPPORT+BUSPIRATE_SPI_SUPPORT+DEDIPROG_SUPPORT > 1 #error Please enable either CONFIG_DUMMY or CONFIG_INTERNAL or disable support for all external programmers except one. #endif enum programmer programmer = @@ -69,6 +69,9 @@ #if BUSPIRATE_SPI_SUPPORT == 1 PROGRAMMER_BUSPIRATESPI #endif +#if DEDIPROG_SUPPORT == 1 + PROGRAMMER_DEDIPROG +#endif ; #endif
@@ -283,6 +286,25 @@ }, #endif
+#if DEDIPROG_SUPPORT == 1 + { + .name = "dediprog", + .init = dediprog_init, + .shutdown = dediprog_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 + {}, /* This entry corresponds to PROGRAMMER_INVALID. */ };
Index: flashrom-dediprog/dediprog.c =================================================================== --- flashrom-dediprog/dediprog.c (Revision 0) +++ flashrom-dediprog/dediprog.c (Revision 0) @@ -0,0 +1,388 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2010 Carl-Daniel Hailfinger + * + * 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; version 2 of the License. + * + * 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. + * + * 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 + */ + +#include <string.h> +#include <stdlib.h> +#include <ctype.h> +#include <sys/types.h> +#include <usb.h> +#include "flash.h" +#include "spi.h" + +#define DEFAULT_TIMEOUT 3000 +usb_dev_handle *dediprog_handle; + +int dediprog_do_stuff(void); + +void print_hex(void *buf, size_t len) +{ + size_t i; + + for (i = 0; i < len; i++) + msg_pdbg(" %02x", ((uint8_t *)buf)[i]); +} + +struct usb_device *get_device_by_vid_pid(uint16_t vid, uint16_t pid) +{ + struct usb_bus *bus; + struct usb_device *dev; + + for (bus = usb_get_busses(); bus; bus = bus->next) + for (dev = bus->devices; dev; dev = dev->next) + if ((dev->descriptor.idVendor == vid) && + (dev->descriptor.idProduct == pid)) + return dev; + + return NULL; +} + +//int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout); + +int dediprog_set_spi_voltage(uint16_t voltage) +{ + int ret; + unsigned int mv; + + switch (voltage) { + case 0x0: + /* Admittedly this one is an assumption. */ + mv = 0; + break; + case 0x12: + mv = 1800; + break; + case 0x11: + mv = 2500; + break; + case 0x10: + mv = 3500; + break; + default: + msg_perr("Unknown voltage selector 0x%x! Aborting.\n", voltage); + return 1; + } + msg_pdbg("Setting SPI voltage to %u.%03u V\n", mv / 1000, mv % 1000); + + ret = usb_control_msg(dediprog_handle, 0x42, 0x9, voltage, 0xff, NULL, 0x0, DEFAULT_TIMEOUT); + if (ret != 0x0) { + msg_perr("Command Set SPI Voltage 0x%x failed!\n", voltage); + return 1; + } + return 0; +} + +/* After dediprog_set_spi_speed, the original app always calls + * dediprog_set_spi_voltage(0) and then + * dediprog_check_devicestring() four times in a row. + * After that, dediprog_command_a() is called. + * This looks suspiciously like the microprocessor in the SF100 has to be + * restarted/reinitialized in case the speed changes. + */ +int dediprog_set_spi_speed(uint16_t speed) +{ + int ret; + unsigned int khz; + + /* Case 1 and 2 are in weird order. Probably an organically "grown" + * interface. + * Base frequency is 24000 kHz, divisors are (in order) + * 1, 3, 2, 8, 11, 16, 32, 64. + */ + switch (speed) { + case 0x0: + khz = 24000; + break; + case 0x1: + khz = 8000; + break; + case 0x2: + khz = 12000; + break; + case 0x3: + khz = 3000; + break; + case 0x4: + khz = 2180; + break; + case 0x5: + khz = 1500; + break; + case 0x6: + khz = 750; + break; + case 0x7: + khz = 375; + break; + default: + msg_perr("Unknown frequency selector 0x%x! Aborting.\n", speed); + return 1; + } + msg_pdbg("Setting SPI speed to %u kHz\n", khz); + + ret = usb_control_msg(dediprog_handle, 0x42, 0x61, speed, 0xff, NULL, 0x0, DEFAULT_TIMEOUT); + if (ret != 0x0) { + msg_perr("Command Set SPI Speed 0x%x failed!\n", speed); + return 1; + } + return 0; +} + +int dediprog_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) +{ + /* Maximum read length is 4 bytes for now. */ + return spi_read_chunked(flash, buf, start, len, 4); +} + +int dediprog_spi_send_command(unsigned int writecnt, unsigned int readcnt, + const unsigned char *writearr, unsigned char *readarr) +{ + int ret; + + /* Paranoid, but I don't want to be blamed if anything explodes. */ + if ((writecnt != 1) && (writecnt != 4)) + msg_perr("Untested writecnt=%i, aborting.\n", writecnt); + if (readcnt > 4) + msg_perr("Untested readcnt=%i, aborting.\n", readcnt); + if ((readcnt == 0) && (writecnt != 1)) + msg_perr("Untested writecnt=%i, readcnt=%i combination, " + "aborting.\n", writecnt, readcnt); + + ret = usb_control_msg(dediprog_handle, 0x42, 0x1, 0xff, readcnt ? 0x1 : 0x0, (char *)writearr, writecnt, DEFAULT_TIMEOUT); + if (ret != writecnt) { + msg_perr("Command Send SPI failed, ret=%i, expected %i!\n", + ret, writecnt); + return 1; + } + if (!readcnt) + return 0; + memset(readarr, 0, readcnt); + ret = usb_control_msg(dediprog_handle, 0xc2, 0x01, 0xbb8, 0x0000, (char *)readarr, readcnt, DEFAULT_TIMEOUT); + if (ret != readcnt) { + msg_perr("Command Receive SPI failed, ret=%i, expected %i!\n", + ret, readcnt); + return 1; + } + return 0; +} + +int dediprog_check_devicestring(void) +{ + int ret; + char buf[0x11]; + + /* Command Prepare Receive Device String. */ + memset(buf, 0, sizeof(buf)); + ret = usb_control_msg(dediprog_handle, 0xc3, 0x7, 0x0, 0xef03, buf, 0x1, DEFAULT_TIMEOUT); + /* The char casting is needed to stop gcc complaining about an always true comparison. */ + if ((ret != 0x1) || (buf[0] != (char)0xff)) { + msg_perr("Unexpected response to Command Prepare Receive Device" + " String!\n"); + return 1; + } + /* Command Receive Device String. */ + memset(buf, 0, sizeof(buf)); + ret = usb_control_msg(dediprog_handle, 0xc2, 0x8, 0xff, 0xff, buf, 0x10, DEFAULT_TIMEOUT); + if (ret != 0x10) { + msg_perr("Incomplete/failed Command Receive Device String!\n"); + return 1; + } + buf[0x10] = '\0'; + msg_pdbg("Found a %s\n", buf); + if (memcmp(buf, "SF100", 0x5)) { + msg_perr("Device not a SF100!\n"); + return 1; + } + /* Only these versions were tested. */ + if (memcmp(buf, "SF100 V:2.1.1 ", 0x10) && + memcmp(buf, "SF100 V:3.1.8 ", 0x10)) { + msg_perr("Unexpected firmware version!\n"); + return 1; + } + return 0; +} + +/* Command A seems to be some sort of device init. It is either followed by + * dediprog_check_devicestring (often) or Command A (often) or + * Command F (once). + */ +int dediprog_command_a(void) +{ + int ret; + char buf[0x1]; + + memset(buf, 0, sizeof(buf)); + ret = usb_control_msg(dediprog_handle, 0xc3, 0xb, 0x0, 0x0, buf, 0x1, DEFAULT_TIMEOUT); + if ((ret != 0x1) || (buf[0] != 0x6f)) { + msg_perr("Unexpected response to Command A!\n"); + return 1; + } + return 0; +} + +/* Command C is only sent after dediprog_check_devicestring, but not after every + * invocation of dediprog_check_devicestring. It is only sent after the first + * dediprog_command_a(); dediprog_check_devicestring() sequence in each session. + * I'm tempted to call this one start_SPI_engine or finish_init. + */ +int dediprog_command_c(void) +{ + int ret; + + ret = usb_control_msg(dediprog_handle, 0x42, 0x4, 0x0, 0x0, NULL, 0x0, DEFAULT_TIMEOUT); + if (ret != 0x0) { + msg_perr("Unexpected response to Command C!\n"); + return 1; + } + return 0; +} + +/* Very strange. Seems to be a programmer keepalive or somesuch. + * Wait unsuccessfully for timeout ms to read one byte. + * Is usually called after setting voltage to 0. + */ +int dediprog_command_f(int timeout) +{ + int ret; + char buf[0x1]; + + memset(buf, 0, sizeof(buf)); + ret = usb_control_msg(dediprog_handle, 0xc2, 0x11, 0xff, 0xff, buf, 0x1, timeout); + if (ret != 0x0) { + msg_perr("Unexpected response to Command F!\n"); + return 1; + } + return 0; +} + +/* URB numbers refer to the first log ever captured. */ +int dediprog_init(void) +{ + struct usb_device *dev; + + msg_pspew("%s\n", __func__); + + /* Here comes the USB stuff. */ + usb_init(); + usb_find_busses(); + usb_find_devices(); + dev = get_device_by_vid_pid(0x0483, 0xdada); + if (!dev) { + msg_perr("Could not find a Dediprog SF100 on USB!\n"); + return 1; + } + msg_pdbg("Found USB device (%04x:%04x).\n", + dev->descriptor.idVendor, + dev->descriptor.idProduct); + dediprog_handle = usb_open(dev); + /* URB 6. Command A. */ + if (dediprog_command_a()) + return 1; + /* URB 7. Command A. */ + if (dediprog_command_a()) + return 1; + /* URB 8. Command Prepare Receive Device String. */ + /* URB 9. Command Receive Device String. */ + if (dediprog_check_devicestring()) + return 1; + /* URB 10. Command C. */ + if (dediprog_command_c()) + return 1; + /* URB 11. Command Set SPI Voltage. */ + if (dediprog_set_spi_voltage(0x10)) + return 1; + + buses_supported = CHIP_BUSTYPE_SPI; + spi_controller = SPI_CONTROLLER_DEDIPROG; + + /* RE leftover, leave in until the driver is complete. */ +#if 0 + /* Execute RDID by hand if you want to test it. */ + dediprog_do_stuff(); +#endif + + return 0; +} + +/* Leftovers from reverse engineering. Keep for documentation purposes until + * completely understood. + */ +int dediprog_do_stuff(void) +{ + char buf[0x4]; + /* SPI command processing starts here. */ + + /* URB 12. Command Send SPI. */ + /* URB 13. Command Receive SPI. */ + memset(buf, 0, sizeof(buf)); + /* JEDEC RDID */ + msg_pdbg("Sending RDID\n"); + buf[0] = JEDEC_RDID; + if (dediprog_spi_send_command(JEDEC_RDID_OUTSIZE, JEDEC_RDID_INSIZE, (unsigned char *)buf, (unsigned char *)buf)) + return 1; + msg_pdbg("Receiving response: "); + print_hex(buf, JEDEC_RDID_INSIZE); +#if 0 + /* URB 14-27 are more SPI commands. */ + /* URB 28. Command Set SPI Voltage. */ + if (dediprog_set_spi_voltage(0x0)) + return 1; + /* URB 29-38. Command F, unsuccessful wait. */ + if (dediprog_command_f(544)) + return 1; + /* URB 39. Command Set SPI Voltage. */ + if (dediprog_set_spi_voltage(0x10)) + return 1; + /* URB 40. Command Set SPI Speed. */ + if (dediprog_set_spi_speed(0x2)) + return 1; + /* URB 41 is just URB 28. */ + /* URB 42,44,46,48,51,53 is just URB 8. */ + /* URB 43,45,47,49,52,54 is just URB 9. */ + /* URB 50 is just URB 6/7. */ + /* URB 55-131 is just URB 29-38. (wait unsuccessfully for 4695 (maybe 4751) ms)*/ + /* URB 132,134 is just URB 6/7. */ + /* URB 133 is just URB 29-38. */ + /* URB 135 is just URB 8. */ + /* URB 136 is just URB 9. */ + /* URB 137 is just URB 11. */ + + /* Command I is probably Start Bulk Read. Data is u16 blockcount, u16 blocksize. */ + /* Command J is probably Start Bulk Write. Data is u16 blockcount, u16 blocksize. */ + /* Bulk transfer sizes for Command I/J are always 512 bytes, rest is filled with 0xff. */ +#endif + + msg_pinfo("All probes will fail because this driver is not hooked up " + "to the SPI infrastructure yet."); + return 0; +} + +int dediprog_shutdown(void) +{ + msg_pspew("%s\n", __func__); + + /* URB 28. Command Set SPI Voltage to 0. */ + if (dediprog_set_spi_voltage(0x0)) + return 1; + + if (usb_close(dediprog_handle)) { + msg_perr("Couldn't close USB device!\n"); + return 1; + } + return 0; +}
On 1/19/10 4:01 AM, Carl-Daniel Hailfinger wrote:
Dediprog SF100 support.
Reverse engineered from USB logs. I never touched that programmer nor did I ever see the associated software. Disabled by default until it is complete. The driver needs to be hooked up to the SPI core before it will do anything besides init and diagnostics.
I successfully reverse engineered all commands, but some are still somewhat magic. Logs from "flashrom -p dediprog -V" are appreciated.
Probe and read should work, erase/write is expected to explode. The programmer will set voltage to 0 on exit.
Thanks a lot to Stefan Reinauer and Patrick Georgi for providing USB logs and for testing the result.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
MacPro:flashrom stepan$ ./flashrom -p dediprog flashrom v0.9.1-r869 Calibrating delay loop... OK. Found chip "ST M25P32" (4096 KB, SPI) at physical address 0xffc00000. No operations were specified.
Aside from the physical address making not much sense (for any non-direct programmer)
MacPro:flashrom stepan$ ./flashrom -p dediprog -r testimage.rom flashrom v0.9.1-r869 Calibrating delay loop... OK. Found chip "ST M25P32" (4096 KB, SPI) at physical address 0xffc00000. Reading flash... ^C
The reading does not seem to work yet, even after several minutes, the image is still zero bytes.
Stefan
On 19.01.2010 11:48, Stefan Reinauer wrote:
On 1/19/10 4:01 AM, Carl-Daniel Hailfinger wrote:
Dediprog SF100 support.
MacPro:flashrom stepan$ ./flashrom -p dediprog flashrom v0.9.1-r869 Calibrating delay loop... OK. Found chip "ST M25P32" (4096 KB, SPI) at physical address 0xffc00000. No operations were specified.
Nice.
Aside from the physical address making not much sense (for any non-direct programmer)
Indeed. We can tackle this later.
MacPro:flashrom stepan$ ./flashrom -p dediprog -r testimage.rom flashrom v0.9.1-r869 Calibrating delay loop... OK. Found chip "ST M25P32" (4096 KB, SPI) at physical address 0xffc00000. Reading flash... ^C
The reading does not seem to work yet, even after several minutes, the image is still zero bytes.
Hm. To be honest, reading is something I could not find in the logs. Then again, maybe some diagnostics in SPEW mode could help. Please run
flashrom -p dediprog -VV -r testimage.rom
with the following debug patch (you need to run "make distclean" before compiling it)
Mark 4 byte RDID as supported by Dediprog. Really abort if any unhandled command sizes are run. Add some debugging at SPEW level.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-dediprog_fixups_debug/spi.c =================================================================== --- flashrom-dediprog_fixups_debug/spi.c (Revision 870) +++ flashrom-dediprog_fixups_debug/spi.c (Arbeitskopie) @@ -335,6 +335,9 @@ #if BUSPIRATE_SPI_SUPPORT == 1 case SPI_CONTROLLER_BUSPIRATE: #endif +#if DEDIPROG_SUPPORT == 1 + case SPI_CONTROLLER_DEDIPROG: +#endif return probe_spi_rdid_generic(flash, 4); default: printf_debug("4b ID not supported on this SPI controller\n"); Index: flashrom-dediprog_fixups_debug/dediprog.c =================================================================== --- flashrom-dediprog_fixups_debug/dediprog.c (Revision 870) +++ flashrom-dediprog_fixups_debug/dediprog.c (Arbeitskopie) @@ -145,6 +145,7 @@
int dediprog_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) { + msg_pspew("%s, start=0x%x, len=0x%x\n", __func__, start, len); /* Maximum read length is 4 bytes for now. */ return spi_read_chunked(flash, buf, start, len, 4); } @@ -154,14 +155,21 @@ { int ret;
+ msg_pspew("%s, writecnt=%i, readcnt=%i\n", __func__, writecnt, readcnt); /* Paranoid, but I don't want to be blamed if anything explodes. */ - if ((writecnt != 1) && (writecnt != 4)) + if ((writecnt != 1) && (writecnt != 4)) { msg_perr("Untested writecnt=%i, aborting.\n", writecnt); - if (readcnt > 4) + return 1; + } + if (readcnt > 4) { msg_perr("Untested readcnt=%i, aborting.\n", readcnt); - if ((readcnt == 0) && (writecnt != 1)) + return 1; + } + if ((readcnt == 0) && (writecnt != 1)) { msg_perr("Untested writecnt=%i, readcnt=%i combination, " "aborting.\n", writecnt, readcnt); + return 1; + } ret = usb_control_msg(dediprog_handle, 0x42, 0x1, 0xff, readcnt ? 0x1 : 0x0, (char *)writearr, writecnt, DEFAULT_TIMEOUT); if (ret != writecnt) {
On 1/19/10 12:36 PM, Carl-Daniel Hailfinger wrote:
Hm. To be honest, reading is something I could not find in the logs.
I can provide a reading only log if that helps?
Then again, maybe some diagnostics in SPEW mode could help. Please run
flashrom -p dediprog -VV -r testimage.rom
with the following debug patch (you need to run "make distclean" before compiling it)
Mark 4 byte RDID as supported by Dediprog. Really abort if any unhandled command sizes are run. Add some debugging at SPEW level.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
/flashrom -p dediprog -VV -r testimage.rom flashrom v0.9.1-r869 dediprog_init Found USB device (0483:dada). Found a SF100 V:3.1.8 Setting SPI voltage to 3.500 V Calibrating delay loop... 515M loops per second, 100 myus = 135 us. OK. Probing for AMD Am29F010A/B, 128 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for AMD Am29F002(N)BB, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for AMD Am29F002(N)BT, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for AMD Am29F016D, 2048 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for AMD Am29F040B, 512 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for AMD Am29F080B, 1024 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for AMD Am29LV040B, 512 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for AMD Am29LV081B, 1024 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for ASD AE49F2008, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Atmel AT25DF021, 256 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT25DF041A, 512 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT25DF081, 1024 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT25DF161, 2048 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT25DF321, 4096 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT25DF321A, 4096 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT25DF641, 8192 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT25F512B, 64 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT25FS010, 128 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT25FS040, 512 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT26DF041, 512 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT26DF081A, 1024 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT26DF161, 2048 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT26DF161A, 2048 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT26F004, 512 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT29C512, 64 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Atmel AT29C010A, 128 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Atmel AT29C020, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Atmel AT29C040A, 512 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Atmel AT45CS1282, 16896 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT45DB011D, 128 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT45DB021D, 256 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT45DB041D, 512 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT45DB081D, 1024 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT45DB161D, 2048 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT45DB321C, 4224 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT45DB321D, 4096 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT45DB642D, 8192 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT49BV512, 64 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Atmel AT49F002(N), 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Atmel AT49F002(N)T, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for AMIC A25L40PT, 512 KB: dediprog_spi_send_command, writecnt=1, readcnt=4 RDID returned 0x20 0x20 0x16 0x10. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for AMIC A25L40PU, 512 KB: dediprog_spi_send_command, writecnt=1, readcnt=4 RDID returned 0x20 0x20 0x16 0x10. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for AMIC A29002B, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for AMIC A29002T, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for AMIC A29040B, 512 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for AMIC A49LF040A, 512 KB: skipped. Host bus type SPI and chip bus type LPC are incompatible. Probing for EMST F49B002UA, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Eon EN25B05, 64 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25B05T, 64 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25B10, 128 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25B10T, 128 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25B20, 256 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25B20T, 256 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25B40, 512 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25B40T, 512 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25B80, 1024 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25B80T, 1024 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25B16, 2048 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25B16T, 2048 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25B32, 4096 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25B32T, 4096 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25B64, 8192 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25B64T, 8192 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25D16, 2048 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25F05, 64 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25F10, 128 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25F20, 256 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25F40, 512 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25F80, 1024 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25F16, 2048 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Eon EN25F32, 4096 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for EON EN29F002(A)(N)B, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for EON EN29F002(A)(N)T, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Fujitsu MBM29F004BC, 512 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Fujitsu MBM29F004TC, 512 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Fujitsu MBM29F400BC, 512 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Fujitsu MBM29F400TC, 512 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Intel 28F001BX-B, 128 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Intel 28F001BX-T, 128 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Intel 82802AB, 512 KB: skipped. Host bus type SPI and chip bus type FWH are incompatible. Probing for Intel 82802AC, 1024 KB: skipped. Host bus type SPI and chip bus type FWH are incompatible. Probing for Macronix MX25L512, 64 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Macronix MX25L1005, 128 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Macronix MX25L2005, 256 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Macronix MX25L4005, 512 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Macronix MX25L8005, 1024 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Macronix MX25L1605, 2048 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Macronix MX25L1635D, 2048 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Macronix MX25L3205, 4096 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Macronix MX25L3235D, 4096 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Macronix MX25L6405, 8192 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Macronix MX25L12805, 16384 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Macronix MX29F001B, 128 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Macronix MX29F001T, 128 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Macronix MX29F002B, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Macronix MX29F002T, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Macronix MX29LV040, 512 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Numonyx M25PE10, 128 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Numonyx M25PE20, 256 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Numonyx M25PE40, 512 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Numonyx M25PE80, 1024 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Numonyx M25PE16, 2048 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for PMC Pm25LV010, 128 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for PMC Pm25LV016B, 2048 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for PMC Pm25LV020, 256 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for PMC Pm25LV040, 512 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for PMC Pm25LV080B, 1024 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for PMC Pm25LV512, 64 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for PMC Pm29F002T, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for PMC Pm29F002B, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for PMC Pm39LV010, 128 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for PMC Pm49FL002, 256 KB: skipped. Host bus type SPI and chip bus type LPC,FWH are incompatible. Probing for PMC Pm49FL004, 512 KB: skipped. Host bus type SPI and chip bus type LPC,FWH are incompatible. Probing for Sanyo LF25FW203A, 2048 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Sharp LHF00L04, 1024 KB: skipped. Host bus type SPI and chip bus type FWH are incompatible. Probing for Spansion S25FL008A, 1024 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Spansion S25FL016A, 2048 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for SST SST25VF016B, 2048 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for SST SST25VF032B, 4096 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for SST SST25VF040.REMS, 512 KB: dediprog_spi_send_command, writecnt=4, readcnt=2 REMS returned 00 00. probe_spi_rems: id1 0x0, id2 0x0 Probing for SST SST25VF040B, 512 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for SST SST25VF040B.REMS, 512 KB: dediprog_spi_send_command, writecnt=4, readcnt=2 REMS returned 00 00. probe_spi_rems: id1 0x0, id2 0x0 Probing for SST SST25VF080B, 1024 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for SST SST28SF040A, 512 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for SST SST29EE010, 128 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for SST SST29LE010, 128 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for SST SST29EE020A, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for SST SST29LE020, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for SST SST39SF010A, 128 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for SST SST39SF020A, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for SST SST39SF040, 512 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for SST SST39VF512, 64 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for SST SST39VF010, 128 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for SST SST39VF020, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for SST SST39VF040, 512 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for SST SST39VF080, 1024 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for SST SST49LF002A/B, 256 KB: skipped. Host bus type SPI and chip bus type FWH are incompatible. Probing for SST SST49LF003A/B, 384 KB: skipped. Host bus type SPI and chip bus type FWH are incompatible. Probing for SST SST49LF004A/B, 512 KB: skipped. Host bus type SPI and chip bus type FWH are incompatible. Probing for SST SST49LF004C, 512 KB: skipped. Host bus type SPI and chip bus type FWH are incompatible. Probing for SST SST49LF008A, 1024 KB: skipped. Host bus type SPI and chip bus type FWH are incompatible. Probing for SST SST49LF008C, 1024 KB: skipped. Host bus type SPI and chip bus type FWH are incompatible. Probing for SST SST49LF016C, 2048 KB: skipped. Host bus type SPI and chip bus type FWH are incompatible. Probing for SST SST49LF020, 256 KB: skipped. Host bus type SPI and chip bus type LPC are incompatible. Probing for SST SST49LF020A, 256 KB: skipped. Host bus type SPI and chip bus type LPC are incompatible. Probing for SST SST49LF040, 512 KB: skipped. Host bus type SPI and chip bus type LPC are incompatible. Probing for SST SST49LF040B, 512 KB: skipped. Host bus type SPI and chip bus type LPC are incompatible. Probing for SST SST49LF080A, 1024 KB: skipped. Host bus type SPI and chip bus type LPC are incompatible. Probing for SST SST49LF160C, 2048 KB: skipped. Host bus type SPI and chip bus type LPC are incompatible. Probing for ST M25P05-A, 64 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for ST M25P05.RES, 64 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. Probing for ST M25P10-A, 128 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for ST M25P10.RES, 128 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. Probing for ST M25P20, 256 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for ST M25P40, 512 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for ST M25P40-old, 512 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. Probing for ST M25P80, 1024 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for ST M25P16, 2048 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for ST M25P32, 4096 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 dediprog_spi_send_command, writecnt=1, readcnt=2 Chip status register is 00 Chip status register: Status Register Write Disable (SRWD) is not set Chip status register: Bit 6 is not set Chip status register: Bit 5 / Block Protect 3 (BP3) is not set Chip status register: Bit 4 / Block Protect 2 (BP2) is not set Chip status register: Bit 3 / Block Protect 1 (BP1) is not set Chip status register: Bit 2 / Block Protect 0 (BP0) is not set Chip status register: Write Enable Latch (WEL) is not set Chip status register: Write In Progress (WIP/BUSY) is not set Found chip "ST M25P32" (4096 KB, SPI) at physical address 0xffc00000. Probing for ST M25P64, 8192 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for ST M25P128, 16384 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for ST M29F002B, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for ST M29F002T/NT, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for ST M29F040B, 512 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for ST M29F400BT, 512 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for ST M29W010B, 128 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for ST M29W040B, 512 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for ST M50FLW040A, 512 KB: skipped. Host bus type SPI and chip bus type LPC,FWH are incompatible. Probing for ST M50FLW040B, 512 KB: skipped. Host bus type SPI and chip bus type LPC,FWH are incompatible. Probing for ST M50FLW080A, 1024 KB: skipped. Host bus type SPI and chip bus type LPC,FWH are incompatible. Probing for ST M50FLW080B, 1024 KB: skipped. Host bus type SPI and chip bus type LPC,FWH are incompatible. Probing for ST M50FW002, 256 KB: skipped. Host bus type SPI and chip bus type FWH are incompatible. Probing for ST M50FW016, 2048 KB: skipped. Host bus type SPI and chip bus type FWH are incompatible. Probing for ST M50FW040, 512 KB: skipped. Host bus type SPI and chip bus type FWH are incompatible. Probing for ST M50FW080, 1024 KB: skipped. Host bus type SPI and chip bus type FWH are incompatible. Probing for ST M50LPW116, 2048 KB: skipped. Host bus type SPI and chip bus type LPC are incompatible. Probing for SyncMOS S29C31004T, 512 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for SyncMOS S29C51001T, 128 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for SyncMOS S29C51002T, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for SyncMOS S29C51004T, 512 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for TI TMS29F002RB, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for TI TMS29F002RT, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Winbond W25x10, 128 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Winbond W25x20, 256 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Winbond W25x40, 512 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Winbond W25x80, 1024 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Winbond W25x16, 2048 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Winbond W25x32, 4096 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Winbond W25x64, 8192 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Winbond W29C011, 128 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Winbond W29C020C, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Winbond W29C040P, 512 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Winbond W29EE011, 128 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Winbond W39V040A, 512 KB: skipped. Host bus type SPI and chip bus type LPC are incompatible. Probing for Winbond W39V040B, 512 KB: skipped. Host bus type SPI and chip bus type LPC are incompatible. Probing for Winbond W39V040C, 512 KB: skipped. Host bus type SPI and chip bus type LPC are incompatible. Probing for Winbond W39V040FA, 512 KB: skipped. Host bus type SPI and chip bus type FWH are incompatible. Probing for Winbond W39V080A, 1024 KB: skipped. Host bus type SPI and chip bus type LPC are incompatible. Probing for Winbond W49F002U, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Winbond W49V002A, 256 KB: skipped. Host bus type SPI and chip bus type LPC are incompatible. Probing for Winbond W49V002FA, 256 KB: skipped. Host bus type SPI and chip bus type FWH are incompatible. Probing for Winbond W39V080FA, 1024 KB: skipped. Host bus type SPI and chip bus type FWH are incompatible. Probing for Winbond W39V080FA (dual mode), 512 KB: skipped. Host bus type SPI and chip bus type FWH are incompatible. Probing for Atmel unknown Atmel SPI chip, 0 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for EON unknown EON SPI chip, 0 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Macronix unknown Macronix SPI chip, 0 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for PMC unknown PMC SPI chip, 0 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for SST unknown SST SPI chip, 0 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for ST unknown ST SPI chip, 0 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Sanyo unknown Sanyo SPI chip, 0 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Generic unknown SPI chip (RDID), 0 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Generic unknown SPI chip (REMS), 0 KB: dediprog_spi_send_command, writecnt=4, readcnt=2 REMS returned 00 00. probe_spi_rems: id1 0x0, id2 0x0 Reading flash... dediprog_spi_read, start=0x0, len=0x400000 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 [...]
On 19.01.2010 12:43, Stefan Reinauer wrote:
On 1/19/10 12:36 PM, Carl-Daniel Hailfinger wrote:
Hm. To be honest, reading is something I could not find in the logs.
I can provide a reading only log if that helps?
Unfortunately that won't help. Reading uses USB bulk transfers without opcodes. This may sound strange, but the SF100 firmware seems to have a builtin mode where it issues the SPI READ opcode (or the FAST_READ opcode, no idea without a SPI sniffer log) if you send a special request without any opcode. As long as I have no idea about how to use this for partial reads, we can't use that mode.
Then again, maybe some diagnostics in SPEW mode could help. Please run
flashrom -p dediprog -VV -r testimage.rom
with the following debug patch (you need to run "make distclean" before compiling it)
Mark 4 byte RDID as supported by Dediprog. Really abort if any unhandled command sizes are run. Add some debugging at SPEW level.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
/flashrom -p dediprog -VV -r testimage.rom flashrom v0.9.1-r869 dediprog_init Found USB device (0483:dada). Found a SF100 V:3.1.8 Setting SPI voltage to 3.500 V [...] Probing for Atmel AT25DF021, 256 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 [...] Probing for AMIC A25L40PT, 512 KB: dediprog_spi_send_command, writecnt=1, readcnt=4 RDID returned 0x20 0x20 0x16 0x10. probe_spi_rdid_generic: id1 0x20, id2 0x2016 [...] Probing for ST M25P32, 4096 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 dediprog_spi_send_command, writecnt=1, readcnt=2 Chip status register is 00 Chip status register: Status Register Write Disable (SRWD) is not set Chip status register: Bit 6 is not set Chip status register: Bit 5 / Block Protect 3 (BP3) is not set Chip status register: Bit 4 / Block Protect 2 (BP2) is not set Chip status register: Bit 3 / Block Protect 1 (BP1) is not set Chip status register: Bit 2 / Block Protect 0 (BP0) is not set Chip status register: Write Enable Latch (WEL) is not set Chip status register: Write In Progress (WIP/BUSY) is not set Found chip "ST M25P32" (4096 KB, SPI) at physical address 0xffc00000. [...] Reading flash... dediprog_spi_read, start=0x0, len=0x400000 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 dediprog_spi_send_command, writecnt=4, readcnt=4 [...]
Good news: My patch works as designed. Read seems to work as well. Ack please? Bad news: The dediprog is dog slow. And with dog slow, I mean unbearably sloooooooow. Reading works, but for a 4 MByte chip it may take up to 35 minutes AFAICS, maybe more. The file specified by -r will only be filled with contents after the read is complete.
I see a speedup by a factor of 4 on the horizon, but I will implement that only after I get confirmation that read works correctly (would be pointless otherwise).
Regards, Carl-Daniel
On 1/19/10 1:08 PM, Carl-Daniel Hailfinger wrote:
On 19.01.2010 12:43, Stefan Reinauer wrote:
On 1/19/10 12:36 PM, Carl-Daniel Hailfinger wrote:
Hm. To be honest, reading is something I could not find in the logs.
I can provide a reading only log if that helps?
Unfortunately that won't help. Reading uses USB bulk transfers without opcodes. This may sound strange, but the SF100 firmware seems to have a builtin mode where it issues the SPI READ opcode (or the FAST_READ opcode, no idea without a SPI sniffer log) if you send a special request without any opcode. As long as I have no idea about how to use this for partial reads, we can't use that mode.
Well, then you need a log for a partial read?
Frankly, it would still be around 60-100 times faster to always read the whole chip and just through away what you don't need ;-)
Good news: My patch works as designed. Read seems to work as well. Ack please? Bad news: The dediprog is dog slow.
Not with the windows software. It looks like only your driver is slow, not the dediprog ;-) But hey, it's a start.
sloooooooow. Reading works, but for a 4 MByte chip it may take up to 35 minutes AFAICS, maybe more. The file specified by -r will only be filled with contents after the read is complete.
Maybe it shouldn't be created before that, either, then?
I see a speedup by a factor of 4 on the horizon, but I will implement that only after I get confirmation that read works correctly (would be pointless otherwise).
Requiring 10 minutes to read the chip is still kind of pointless, so I don't know if it's worth the effort if the driver can't be generally fixed.
Stefan
On 19.01.2010 13:14, Stefan Reinauer wrote:
On 1/19/10 1:08 PM, Carl-Daniel Hailfinger wrote:
On 19.01.2010 12:43, Stefan Reinauer wrote:
On 1/19/10 12:36 PM, Carl-Daniel Hailfinger wrote:
Hm. To be honest, reading is something I could not find in the logs.
I can provide a reading only log if that helps?
Unfortunately that won't help. Reading uses USB bulk transfers without opcodes. This may sound strange, but the SF100 firmware seems to have a builtin mode where it issues the SPI READ opcode (or the FAST_READ opcode, no idea without a SPI sniffer log) if you send a special request without any opcode. As long as I have no idea about how to use this for partial reads, we can't use that mode.
Well, then you need a log for a partial read?
A log of a partial read of the last few sectors would be a good start, but the big problem is that I don't know which opcode is sent to the chip. So if you have a Bus Pirate or any other Sniffer, reducing the SPI frequency to a point where the sniffer can keep up (at least for the first sector or so) would at least reveal the opcode used by the Dediprog. Then I could create an opcode filter which diverts reads to a separate bulk read function.
Frankly, it would still be around 60-100 times faster to always read the whole chip and just through away what you don't need ;-)
Hm yes. Right now not knowing the opcode sent to the chip is the biggest problem.
Good news: My patch works as designed. Read seems to work as well. Ack please? Bad news: The dediprog is dog slow.
Not with the windows software. It looks like only your driver is slow, not the dediprog ;-) But hey, it's a start.
The windows driver uses one control URB, then does bulk reads until the chip is completely read. With 512 bytes per bulk read, this means we have 8192 bulk transactions. That's fast. The flashrom driver uses control URBs for everything: One for sending the opcode, one for reading the result in 4 byte chunks. That means we send 2 million URBs down the wire and receive 2 million URBs. We probably spend 250 µs per transaction on USB 2.0, maybe more.
sloooooooow. Reading works, but for a 4 MByte chip it may take up to 35 minutes AFAICS, maybe more. The file specified by -r will only be filled with contents after the read is complete.
Maybe it shouldn't be created before that, either, then?
Not sure. Reading a chip for 35 minutes and then noticing that the file can't be created isn't exactly nice either.
I see a speedup by a factor of 4 on the horizon, but I will implement that only after I get confirmation that read works correctly (would be pointless otherwise).
Requiring 10 minutes to read the chip is still kind of pointless, so I don't know if it's worth the effort if the driver can't be generally fixed.
Get me a log of the SPI side (the first 1024 bytes or so are sufficient) with a matching log on the USB side and I can reach the same speeds as the windows driver.
As interim measure, I can increase read chunk size to 16 (speedup factor 4) once we know if read works. Once we know read chunk size 16 works, I can test bigger chunk sizes up to 64 (USB protocol limit). That would be a factor of 16 faster than the current implementation. Maybe not perfect, but it would definitely be usable. I need those chunk size tests anyway to implement write support.
Regards, Carl-Daniel
On 19.01.2010 14:36, Carl-Daniel Hailfinger wrote:
As interim measure, I can increase read chunk size to 16 (speedup factor 4) once we know if read works. Once we know read chunk size 16 works, I can test bigger chunk sizes up to 64 (USB protocol limit). That would be a factor of 16 faster than the current implementation. Maybe not perfect, but it would definitely be usable. I need those chunk size tests anyway to implement write support.
Tests of this patch are appreciated. Please run in verbose (-V) mode, but not SPEW mode (-VV) because SPEW will slow reading down. Some timings for a full read would be nice. If we're lucky, full read is around 5 minutes, but it should not take substantially longer than 10 minutes.
Mark 4 byte RDID as supported by Dediprog. Increase read size from 4 bytes to 16 bytes (speedup factor 4). Really abort if any unhandled command sizes are run. Add some debugging at SPEW level.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-dediprog_fixups_debug/spi.c =================================================================== --- flashrom-dediprog_fixups_debug/spi.c (Revision 870) +++ flashrom-dediprog_fixups_debug/spi.c (Arbeitskopie) @@ -335,6 +335,9 @@ #if BUSPIRATE_SPI_SUPPORT == 1 case SPI_CONTROLLER_BUSPIRATE: #endif +#if DEDIPROG_SUPPORT == 1 + case SPI_CONTROLLER_DEDIPROG: +#endif return probe_spi_rdid_generic(flash, 4); default: printf_debug("4b ID not supported on this SPI controller\n"); Index: flashrom-dediprog_fixups_debug/dediprog.c =================================================================== --- flashrom-dediprog_fixups_debug/dediprog.c (Revision 870) +++ flashrom-dediprog_fixups_debug/dediprog.c (Arbeitskopie) @@ -145,8 +145,9 @@
int dediprog_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) { - /* Maximum read length is 4 bytes for now. */ - return spi_read_chunked(flash, buf, start, len, 4); + msg_pspew("%s, start=0x%x, len=0x%x\n", __func__, start, len); + /* Maximum read length is 16 bytes for now. */ + return spi_read_chunked(flash, buf, start, len, 16); }
int dediprog_spi_send_command(unsigned int writecnt, unsigned int readcnt, @@ -154,14 +155,24 @@ { int ret;
+ msg_pspew("%s, writecnt=%i, readcnt=%i\n", __func__, writecnt, readcnt); /* Paranoid, but I don't want to be blamed if anything explodes. */ - if ((writecnt != 1) && (writecnt != 4)) + if ((writecnt != 1) && (writecnt != 4)) { msg_perr("Untested writecnt=%i, aborting.\n", writecnt); - if (readcnt > 4) + return 1; + } + /* readcnt > 16 may work, but 64 is definitely the max due to USB + * control URB restrictions. + */ + if (readcnt > 16) { msg_perr("Untested readcnt=%i, aborting.\n", readcnt); - if ((readcnt == 0) && (writecnt != 1)) + return 1; + } + if ((readcnt == 0) && (writecnt != 1)) { msg_perr("Untested writecnt=%i, readcnt=%i combination, " "aborting.\n", writecnt, readcnt); + return 1; + } ret = usb_control_msg(dediprog_handle, 0x42, 0x1, 0xff, readcnt ? 0x1 : 0x0, (char *)writearr, writecnt, DEFAULT_TIMEOUT); if (ret != writecnt) {
On 1/19/10 2:57 PM, Carl-Daniel Hailfinger wrote:
On 19.01.2010 14:36, Carl-Daniel Hailfinger wrote:
As interim measure, I can increase read chunk size to 16 (speedup factor 4) once we know if read works. Once we know read chunk size 16 works, I can test bigger chunk sizes up to 64 (USB protocol limit). That would be a factor of 16 faster than the current implementation. Maybe not perfect, but it would definitely be usable. I need those chunk size tests anyway to implement write support.
Tests of this patch are appreciated. Please run in verbose (-V) mode, but not SPEW mode (-VV) because SPEW will slow reading down. Some timings for a full read would be nice. If we're lucky, full read is around 5 minutes, but it should not take substantially longer than 10 minutes.
Mark 4 byte RDID as supported by Dediprog. Increase read size from 4 bytes to 16 bytes (speedup factor 4). Really abort if any unhandled command sizes are run. Add some debugging at SPEW level.
It assumes that an ID of 00 00 is a "generic SPI chip". Instead it means there is no chip connected.
./flashrom -pdediprog flashrom v0.9.1-r878 Calibrating delay loop... OK. Found chip "Generic unknown SPI chip (RDID)" (0 KB, SPI) at physical address 0x0. === This flash part has status NOT WORKING for operations: PROBE READ ERASE WRITE 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, -rV, -wV, -EV), and mention which mainboard or programmer you tested. Thanks for your help! === No operations were specified.
On 1/19/10 2:36 PM, Carl-Daniel Hailfinger wrote:
Get me a log of the SPI side (the first 1024 bytes or so are sufficient) with a matching log on the USB side and I can reach the same speeds as the windows driver.
I'm curious, what do you need the SPI side for?
Stefan
On 21.01.2010 23:40, Stefan Reinauer wrote:
On 1/19/10 2:36 PM, Carl-Daniel Hailfinger wrote:
Get me a log of the SPI side (the first 1024 bytes or so are sufficient) with a matching log on the USB side and I can reach the same speeds as the windows driver.
I'm curious, what do you need the SPI side for?
The SF100 has a built-in read function which does _not_ accept any opcode and is totally opaque. Since two different (incompatible) read opcodes exist for most chips, I'd really like to know which one is used by the Dediprog so I can create an opcode filter which redirects the correct read opcode to the SF100 special read function.
Regards, Carl-Daniel
On 19.01.2010 13:14, Stefan Reinauer wrote:
On 1/19/10 1:08 PM, Carl-Daniel Hailfinger wrote:
The file specified by -r will only be filled with contents after the read is complete.
Maybe it shouldn't be created before that, either, then?
Hm. If we read for a few minutes, then we notice that the file can't be created, users will be very unhappy. An alternative would be to remove the file if read failed, or create it with a temp name and move it into place at the end.
I see a speedup by a factor of 4 on the horizon, but I will implement that only after I get confirmation that read works correctly (would be pointless otherwise).
Requiring 10 minutes to read the chip is still kind of pointless, so I don't know if it's worth the effort if the driver can't be generally fixed.
Thanks to Patrick Georgi and his tireless log generation, I was able to find out how to get good speed out of the dumb mode of the SF100. Write now works (very slow, slower than the old read, but definitely fixable), but read speed should now be roughly half the speed of the windows driver. At least that's the prognosis. Given that we use control transfers instead of bulk transfers, we have more overhead, but 100% control over the SPI commands. The windows driver can't do that. Plus, we're firmware independent with my approach.
Changelog: Add write support. Speed up reads by a factor of 64 by switching block size from 4 to 256. Add support for 4 byte RDID.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-dediprog_bigchunks/spi.c =================================================================== --- flashrom-dediprog_bigchunks/spi.c (Revision 877) +++ flashrom-dediprog_bigchunks/spi.c (Arbeitskopie) @@ -335,6 +335,9 @@ #if BUSPIRATE_SPI_SUPPORT == 1 case SPI_CONTROLLER_BUSPIRATE: #endif +#if DEDIPROG_SUPPORT == 1 + case SPI_CONTROLLER_DEDIPROG: +#endif return probe_spi_rdid_generic(flash, 4); default: printf_debug("4b ID not supported on this SPI controller\n"); Index: flashrom-dediprog_bigchunks/dediprog.c =================================================================== --- flashrom-dediprog_bigchunks/dediprog.c (Revision 877) +++ flashrom-dediprog_bigchunks/dediprog.c (Arbeitskopie) @@ -145,8 +145,9 @@
int dediprog_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) { - /* Maximum read length is 4 bytes for now. */ - return spi_read_chunked(flash, buf, start, len, 4); + msg_pspew("%s, start=0x%x, len=0x%x\n", __func__, start, len); + /* Maximum read length is 16 bytes for now. */ + return spi_read_chunked(flash, buf, start, len, 256); }
int dediprog_spi_send_command(unsigned int writecnt, unsigned int readcnt, @@ -154,14 +155,17 @@ { int ret;
+ msg_pspew("%s, writecnt=%i, readcnt=%i\n", __func__, writecnt, readcnt); /* Paranoid, but I don't want to be blamed if anything explodes. */ - if ((writecnt != 1) && (writecnt != 4)) + if (writecnt > 7) { msg_perr("Untested writecnt=%i, aborting.\n", writecnt); - if (readcnt > 4) + return 1; + } + /* readcnt=513 was tested, but let's keep this sane. */ + if (readcnt > 256) { msg_perr("Untested readcnt=%i, aborting.\n", readcnt); - if ((readcnt == 0) && (writecnt != 1)) - msg_perr("Untested writecnt=%i, readcnt=%i combination, " - "aborting.\n", writecnt, readcnt); + return 1; + } ret = usb_control_msg(dediprog_handle, 0x42, 0x1, 0xff, readcnt ? 0x1 : 0x0, (char *)writearr, writecnt, DEFAULT_TIMEOUT); if (ret != writecnt) {
Am Donnerstag, den 21.01.2010, 10:26 +0100 schrieb Carl-Daniel Hailfinger:
- msg_pspew("%s, start=0x%x, len=0x%x\n", __func__, start, len);
- /* Maximum read length is 16 bytes for now. */
- return spi_read_chunked(flash, buf, start, len, 256);
You want to fix the comment, I suppose.
Regards, Michael Karcher
On 1/21/10 10:26 AM, Carl-Daniel Hailfinger wrote:
Add write support. Speed up reads by a factor of 64 by switching block size from 4 to 256. Add support for 4 byte RDID.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Acked-by: Stefan Reinauer stepan@coresystems.de
MacPro:flashrom stepan$ time ./flashrom -pdediprog -r testread.rom flashrom v0.9.1-r878 Calibrating delay loop... OK. Found chip "ST M25P32" (4096 KB, SPI) at physical address 0xffc00000. === This flash part has status UNTESTED for operations: ERASE 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, -rV, -wV, -EV), and mention which mainboard or programmer you tested. Thanks for your help! === Reading flash... Command Receive SPI failed, ret=-34, expected 256! done.
real 0m31.602s user 0m0.924s sys 0m0.794s
dd if=/dev/urandom of=testwrite.rom bs=1024 count=$((1024*4)) time ./flashrom -pdediprog -w testwrite.rom flashrom v0.9.1-r878 Calibrating delay loop... OK. Found chip "ST M25P32" (4096 KB, SPI) at physical address 0xffc00000. === This flash part has status UNTESTED for operations: ERASE 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, -rV, -wV, -EV), and mention which mainboard or programmer you tested. Thanks for your help! === Flash image seems to be a legacy BIOS. Disabling checks. Writing flash chip... Erasing flash before programming... Erasing flash chip... Command Receive SPI failed, ret=-34, expected 256! ERASE FAILED at 0x00000000! Expected=0xff, Read=0x00, failed byte count from 0x00000000-0x0000ffff: 0x16ea ERASE FAILED! ERASE FAILED at 0x00000000! Expected=0xff, Read=0x00, ^C
real 1m17.836s user 0m1.948s sys 0m2.206s
time ./flashrom -pdediprog -w testwrite.rom -VV flashrom v0.9.1-r878 dediprog_init Found USB device (0483:dada). Found a SF100 V:3.1.8 Setting SPI voltage to 3.500 V Calibrating delay loop... 761M loops per second, 100 myus = 200 us. OK. Probing for AMD Am29F010A/B, 128 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for AMD Am29F002(N)BB, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for AMD Am29F002(N)BT, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for AMD Am29F016D, 2048 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for AMD Am29F040B, 512 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for AMD Am29F080B, 1024 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for AMD Am29LV040B, 512 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for AMD Am29LV081B, 1024 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for ASD AE49F2008, 256 KB: skipped. Host bus type SPI and chip bus type Parallel are incompatible. Probing for Atmel AT25DF021, 256 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT25DF041A, 512 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT25DF081, 1024 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT25DF161, 2048 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT25DF321, 4096 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT25DF321A, 4096 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 Probing for Atmel AT25DF641, 8192 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 [...] Probing for ST M25P32, 4096 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 dediprog_spi_send_command, writecnt=1, readcnt=2 Chip status register is 00 Chip status register: Status Register Write Disable (SRWD) is not set Chip status register: Bit 6 is not set Chip status register: Bit 5 / Block Protect 3 (BP3) is not set Chip status register: Bit 4 / Block Protect 2 (BP2) is not set Chip status register: Bit 3 / Block Protect 1 (BP1) is not set Chip status register: Bit 2 / Block Protect 0 (BP0) is not set Chip status register: Write Enable Latch (WEL) is not set Chip status register: Write In Progress (WIP/BUSY) is not set Found chip "ST M25P32" (4096 KB, SPI) at physical address 0xffc00000. [...] Flash image seems to be a legacy BIOS. Disabling checks. Writing flash chip... dediprog_spi_send_command, writecnt=1, readcnt=2 Erasing flash before programming... Erasing flash chip... Looking at blockwise erase function 0... trying... 0x000000-0x00ffff, dediprog_spi_send_command, writecnt=1, readcnt=0 dediprog_spi_send_command, writecnt=4, readcnt=0 dediprog_spi_send_command, writecnt=1, readcnt=2 dediprog_spi_send_command, writecnt=1, readcnt=2 dediprog_spi_send_command, writecnt=1, readcnt=2 dediprog_spi_send_command, writecnt=1, readcnt=2 dediprog_spi_send_command, writecnt=1, readcnt=2 dediprog_spi_read, start=0x0, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 Command Receive SPI failed, ret=-34, expected 256! ERASE FAILED at 0x00000000! Expected=0xff, Read=0x00,dediprog_spi_read, start=0x100, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x200, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x300, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x400, len=0x100 [...] dediprog_spi_read, start=0xff00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 failed byte count from 0x00000000-0x0000ffff: 0x16ea ERASE FAILED!
Looking at blockwise erase function 1... trying... 0x000000-0x3fffff, dediprog_spi_send_command, writecnt=1, readcnt=2 dediprog_spi_send_command, writecnt=1, readcnt=0 dediprog_spi_send_command, writecnt=1, readcnt=0 dediprog_spi_send_command, writecnt=1, readcnt=2 dediprog_spi_read, start=0x0, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 ERASE FAILED at 0x00000000! Expected=0xff, Read=0x00,dediprog_spi_read, start=0x100, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x200, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x300, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x400, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x500, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x600, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x700, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x800, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x900, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0xa00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0xb00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0xc00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0xd00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0xe00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0xf00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x1000, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x1100, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x1200, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x1300, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x1400, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x1500, len=0x100 [...] dediprog_spi_read, start=0x3ff900, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x3ffa00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x3ffb00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x3ffc00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x3ffd00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x3ffe00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x3fff00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 failed byte count from 0x00000000-0x003fffff: 0x58000 ERASE FAILED!
Looking at blockwise erase function 2... not defined. Looking for another erase function. Looking at blockwise erase function 3... not defined. Looking for another erase function. Looking at blockwise erase function 4... not defined. Looking for another erase function. FAILED! ERASE FAILED! FAILED! Your flash chip is in an unknown state. Get help on IRC at irc.freenode.net (channel #flashrom) or mail flashrom@flashrom.org! ------------------------------------------------------------------------------- DO NOT REBOOT OR POWEROFF! dediprog_shutdown Setting SPI voltage to 0.000 V
real 1m58.392s user 0m2.733s sys 0m4.135s
On 21.01.2010 21:50, Stefan Reinauer wrote:
On 1/21/10 10:26 AM, Carl-Daniel Hailfinger wrote:
Add write support. Speed up reads by a factor of 64 by switching block size from 4 to 256. Add support for 4 byte RDID.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Acked-by: Stefan Reinauer stepan@coresystems.de
Thanks for the ack, I'll reuse it for the 16 byte variant. It seems that while Patrick is getting no error messages for 256 byte transfers, they explode for you. Since Patrick is also seeing corruption with large transfers, I hope we can use your machine to test the real limits and actually get error messages from the OS instead of corrupt data.
MacPro:flashrom stepan$ time ./flashrom -pdediprog -r testread.rom flashrom v0.9.1-r878 Found chip "ST M25P32" (4096 KB, SPI) at physical address 0xffc00000. Reading flash... Command Receive SPI failed, ret=-34, expected 256!
Mh. Would be interesting to know when it explodes.
done.
real 0m31.602s user 0m0.924s sys 0m0.794s
dd if=/dev/urandom of=testwrite.rom bs=1024 count=$((1024*4)) time ./flashrom -pdediprog -w testwrite.rom flashrom v0.9.1-r878 Found chip "ST M25P32" (4096 KB, SPI) at physical address 0xffc00000. Writing flash chip... Erasing flash before programming... Erasing flash chip... Command Receive SPI failed, ret=-34, expected 256!
Yes, the point of failure would be very interesting to know.
ERASE FAILED at 0x00000000! Expected=0xff, Read=0x00, failed byte count from 0x00000000-0x0000ffff: 0x16ea
Ah ok, there it is. So while Patrick was able to log 256 byte read transfers from the dediprog app, either the method doesn't work in the newer firmware (and I'd need a hand-crafted transfer log from your machine to verify) or this is just an effect of Windows having an inferior USB stack or libusb.
ERASE FAILED! ERASE FAILED at 0x00000000! Expected=0xff, Read=0x00, ^C
real 1m17.836s user 0m1.948s sys 0m2.206s
time ./flashrom -pdediprog -w testwrite.rom -VV flashrom v0.9.1-r878 dediprog_init Found USB device (0483:dada). Found a SF100 V:3.1.8 Setting SPI voltage to 3.500 V [...] Probing for ST M25P32, 4096 KB: dediprog_spi_send_command, writecnt=1, readcnt=3 RDID returned 0x20 0x20 0x16. probe_spi_rdid_generic: id1 0x20, id2 0x2016 dediprog_spi_send_command, writecnt=1, readcnt=2 Chip status register is 00 Chip status register: Status Register Write Disable (SRWD) is not set Chip status register: Bit 6 is not set Chip status register: Bit 5 / Block Protect 3 (BP3) is not set Chip status register: Bit 4 / Block Protect 2 (BP2) is not set Chip status register: Bit 3 / Block Protect 1 (BP1) is not set Chip status register: Bit 2 / Block Protect 0 (BP0) is not set Chip status register: Write Enable Latch (WEL) is not set Chip status register: Write In Progress (WIP/BUSY) is not set Found chip "ST M25P32" (4096 KB, SPI) at physical address 0xffc00000. [...] Writing flash chip... dediprog_spi_send_command, writecnt=1, readcnt=2 Erasing flash before programming... Erasing flash chip... Looking at blockwise erase function 0... trying... 0x000000-0x00ffff, dediprog_spi_send_command, writecnt=1, readcnt=0 dediprog_spi_send_command, writecnt=4, readcnt=0 dediprog_spi_send_command, writecnt=1, readcnt=2 dediprog_spi_send_command, writecnt=1, readcnt=2 dediprog_spi_send_command, writecnt=1, readcnt=2 dediprog_spi_send_command, writecnt=1, readcnt=2 dediprog_spi_send_command, writecnt=1, readcnt=2 dediprog_spi_read, start=0x0, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 Command Receive SPI failed, ret=-34, expected 256!
Perfect, thanks for the detailed log. Indeed, the very first large read fails.
ERASE FAILED at 0x00000000! Expected=0xff, Read=0x00,dediprog_spi_read, start=0x100, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x200, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x300, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x400, len=0x100 [...] dediprog_spi_read, start=0xff00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256
Very interesting. It seems this read doesn't get any error message but still fails.
failed byte count from 0x00000000-0x0000ffff: 0x16ea ERASE FAILED!
Looking at blockwise erase function 1... trying... 0x000000-0x3fffff, dediprog_spi_send_command, writecnt=1, readcnt=2 dediprog_spi_send_command, writecnt=1, readcnt=0 dediprog_spi_send_command, writecnt=1, readcnt=0 dediprog_spi_send_command, writecnt=1, readcnt=2 dediprog_spi_read, start=0x0, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256
Same here. Silent failure.
ERASE FAILED at 0x00000000! Expected=0xff, Read=0x00,dediprog_spi_read, start=0x100, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x200, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x300, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x400, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x500, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x600, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x700, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x800, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x900, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0xa00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0xb00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0xc00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0xd00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0xe00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0xf00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x1000, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x1100, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x1200, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x1300, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x1400, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x1500, len=0x100 [...] dediprog_spi_read, start=0x3ff900, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x3ffa00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x3ffb00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x3ffc00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x3ffd00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x3ffe00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 dediprog_spi_read, start=0x3fff00, len=0x100 dediprog_spi_send_command, writecnt=4, readcnt=256 failed byte count from 0x00000000-0x003fffff: 0x58000 ERASE FAILED!
Looking at blockwise erase function 2... not defined. Looking for another erase function. Looking at blockwise erase function 3... not defined. Looking for another erase function. Looking at blockwise erase function 4... not defined. Looking for another erase function. FAILED! ERASE FAILED! FAILED! dediprog_shutdown Setting SPI voltage to 0.000 V
real 1m58.392s user 0m2.733s sys 0m4.135s
Thanks a lot for the log. New patch.
Add write support. Speed up reads by a factor of 4 by switching block size from 4 to 16. Add support for 4 byte RDID.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-dediprog_bigchunks/spi.c =================================================================== --- flashrom-dediprog_bigchunks/spi.c (Revision 877) +++ flashrom-dediprog_bigchunks/spi.c (Arbeitskopie) @@ -335,6 +335,9 @@ #if BUSPIRATE_SPI_SUPPORT == 1 case SPI_CONTROLLER_BUSPIRATE: #endif +#if DEDIPROG_SUPPORT == 1 + case SPI_CONTROLLER_DEDIPROG: +#endif return probe_spi_rdid_generic(flash, 4); default: printf_debug("4b ID not supported on this SPI controller\n"); Index: flashrom-dediprog_bigchunks/dediprog.c =================================================================== --- flashrom-dediprog_bigchunks/dediprog.c (Revision 877) +++ flashrom-dediprog_bigchunks/dediprog.c (Arbeitskopie) @@ -145,8 +145,9 @@
int dediprog_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len) { - /* Maximum read length is 4 bytes for now. */ - return spi_read_chunked(flash, buf, start, len, 4); + msg_pspew("%s, start=0x%x, len=0x%x\n", __func__, start, len); + /* Chosen read length is 16 bytes for now. */ + return spi_read_chunked(flash, buf, start, len, 16); }
int dediprog_spi_send_command(unsigned int writecnt, unsigned int readcnt, @@ -154,19 +155,22 @@ { int ret;
+ msg_pspew("%s, writecnt=%i, readcnt=%i\n", __func__, writecnt, readcnt); /* Paranoid, but I don't want to be blamed if anything explodes. */ - if ((writecnt != 1) && (writecnt != 4)) + if (writecnt > 5) { msg_perr("Untested writecnt=%i, aborting.\n", writecnt); - if (readcnt > 4) + return 1; + } + /* 16 byte reads should work. */ + if (readcnt > 16) { msg_perr("Untested readcnt=%i, aborting.\n", readcnt); - if ((readcnt == 0) && (writecnt != 1)) - msg_perr("Untested writecnt=%i, readcnt=%i combination, " - "aborting.\n", writecnt, readcnt); + return 1; + } ret = usb_control_msg(dediprog_handle, 0x42, 0x1, 0xff, readcnt ? 0x1 : 0x0, (char *)writearr, writecnt, DEFAULT_TIMEOUT); if (ret != writecnt) { - msg_perr("Command Send SPI failed, ret=%i, expected %i!\n", - ret, writecnt); + msg_perr("Send SPI failed, expected %i, got %i %s!\n", + writecnt, ret, usb_strerror()); return 1; } if (!readcnt) @@ -174,8 +178,8 @@ memset(readarr, 0, readcnt); ret = usb_control_msg(dediprog_handle, 0xc2, 0x01, 0xbb8, 0x0000, (char *)readarr, readcnt, DEFAULT_TIMEOUT); if (ret != readcnt) { - msg_perr("Command Receive SPI failed, ret=%i, expected %i!\n", - ret, readcnt); + msg_perr("Receive SPI failed, expected %i, got %i %s!\n", + readcnt, ret, usb_strerror()); return 1; } return 0;
On 22.01.2010 03:44, Carl-Daniel Hailfinger wrote:
On 21.01.2010 21:50, Stefan Reinauer wrote:
On 1/21/10 10:26 AM, Carl-Daniel Hailfinger wrote:
Add write support. Speed up reads by a factor of 64 by switching block size from 4 to 256. Add support for 4 byte RDID.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Acked-by: Stefan Reinauer stepan@coresystems.de
Thanks for the ack, I'll reuse it for the 16 byte variant. It seems that while Patrick is getting no error messages for 256 byte transfers, they explode for you. Since Patrick is also seeing corruption with large transfers, I hope we can use your machine to test the real limits and actually get error messages from the OS instead of corrupt data. [...]
Add write support. Speed up reads by a factor of 4 by switching block size from 4 to 16. Add support for 4 byte RDID.
Add USB error decoding via usb_strerror as well.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Thanks for testing. As stated above I'm reusing your ack.
Acked-by: Stefan Reinauer stepan@coresystems.de
and committed in r879.
Regards, Carl-Daniel
On 22.01.2010 03:53, Carl-Daniel Hailfinger wrote:
On 22.01.2010 03:44, Carl-Daniel Hailfinger wrote:
Add write support. Speed up reads by a factor of 4 by switching block size from 4 to 16. Add support for 4 byte RDID.
Add USB error decoding via usb_strerror as well.
and committed in r879.
Just FYI. What's currently in the tree may be slow, but it should work reliably for reads and writes, and be 4x faster than the old code. I expect 5-10 minutes for read and erase (because erase does a read to verify), and too long (40 minutes, maybe more, maybe less) for write. Write hasn't seen any optimization yet.
16 byte non-opaque transfers still have to be figured out on the new
SF100 software/firmware. Does the new software/firmware have any size limitations for user-defined command streams? If not, a USB log of sending "03 00 00 00" and receiving 32 bytes, and a log of the same sequence receiving 64 bytes, both with the new firmware, would be very helpful.
Regards, Carl-Daniel
On 1/19/10 4:01 AM, Carl-Daniel Hailfinger wrote:
Dediprog SF100 support.
Reverse engineered from USB logs. I never touched that programmer nor did I ever see the associated software. Disabled by default until it is complete. The driver needs to be hooked up to the SPI core before it will do anything besides init and diagnostics.
I successfully reverse engineered all commands, but some are still somewhat magic. Logs from "flashrom -p dediprog -V" are appreciated.
Probe and read should work, erase/write is expected to explode. The programmer will set voltage to 0 on exit.
Thanks a lot to Stefan Reinauer and Patrick Georgi for providing USB logs and for testing the result.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Not all the way there yet, but awesome work, none the less Acked-by: Stefan Reinauer stepan@coresystems.de
Stefan
On 19.01.2010 11:50, Stefan Reinauer wrote:
On 1/19/10 4:01 AM, Carl-Daniel Hailfinger wrote:
Dediprog SF100 support.
Reverse engineered from USB logs. I never touched that programmer nor did I ever see the associated software. Disabled by default until it is complete. The driver needs to be hooked up to the SPI core before it will do anything besides init and diagnostics.
I successfully reverse engineered all commands, but some are still somewhat magic. Logs from "flashrom -p dediprog -V" are appreciated.
Probe and read should work, erase/write is expected to explode. The programmer will set voltage to 0 on exit.
Thanks a lot to Stefan Reinauer and Patrick Georgi for providing USB logs and for testing the result.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Not all the way there yet, but awesome work, none the less
Thanks!
Acked-by: Stefan Reinauer stepan@coresystems.de
And committed in r870.
Regards, Carl-Daniel