2010/6/2 Carl-Daniel Hailfinger <[email protected]> > Hi, > > On 01.06.2010 11:54, rayer wrote: > > it still hangs while autodetecting flash chip at AE49F2008 (is > > displayed as last probed), > > only with -c option it works. > > Does it really work with -c CHIPNAME or do you need -f as well? > > I found a bug in the bitbanging SPI core (buffer confusion) and fixed it. > This version also reduces reach chunk size to 256 bytes instead of 65536 > bytes. That makes buffer management more efficient (only one round of > memory allocations). > > Idwer will build a new .exe
http://khepri.coresystems.de/~idwer/flashrom/r1025-patchwork-1441/flashrom.exe , and it would be great if you could test it with > flashrom -p rayer_bitbang_spi -V > and make a photo or screenshot of the run. I will add more debugging if > it still hangs. > > -snip- > > Add support for RayeR SPIPGM hardware as described in > http://rayer.ic.cz/elektro/spipgm.htm > > To use the RayeR driver, run > flashrom -p rayer_bitbang_spi -V > > Known bugs/limitations: > - Won't compile/work on non-x86 architectures. > - Will always use direct port I/O access. > > > Signed-off-by: Carl-Daniel Hailfinger <[email protected]> > > Index: flashrom-bitbang_spi_rayer/flash.h > =================================================================== > --- flashrom-bitbang_spi_rayer/flash.h (Revision 1025) > +++ flashrom-bitbang_spi_rayer/flash.h (Arbeitskopie) > @@ -81,6 +81,9 @@ > #if CONFIG_DEDIPROG == 1 > PROGRAMMER_DEDIPROG, > #endif > +#if CONFIG_RAYER_BITBANG_SPI == 1 > + PROGRAMMER_RAYER_BITBANG_SPI, > +#endif > PROGRAMMER_INVALID /* This must always be the last entry. */ > }; > > @@ -128,13 +131,14 @@ > void programmer_delay(int usecs); > > enum bitbang_spi_master { > +#if CONFIG_RAYER_BITBANG_SPI == 1 > + BITBANG_SPI_MASTER_RAYER, > +#endif > BITBANG_SPI_INVALID /* This must always be the last entry. */ > }; > > extern const int bitbang_spi_master_count; > > -extern enum bitbang_spi_master bitbang_spi_master; > - > struct bitbang_spi_master_entry { > void (*set_cs) (int val); > void (*set_sck) (int val); > @@ -524,10 +528,19 @@ > int ft2232_spi_read(struct flashchip *flash, uint8_t *buf, int start, int > len); > int ft2232_spi_write_256(struct flashchip *flash, uint8_t *buf); > > +/* rayer_bitbang_spi.c */ > +#if CONFIG_RAYER_BITBANG_SPI == 1 > +int rayer_bitbang_spi_init(void); > +void rayer_bitbang_set_cs(int val); > +void rayer_bitbang_set_sck(int val); > +void rayer_bitbang_set_mosi(int val); > +int rayer_bitbang_get_miso(void); > +#endif > + > /* bitbang_spi.c */ > extern int bitbang_spi_half_period; > extern const struct bitbang_spi_master_entry bitbang_spi_master_table[]; > -int bitbang_spi_init(void); > +int bitbang_spi_init(enum bitbang_spi_master master); > int bitbang_spi_send_command(unsigned int writecnt, unsigned int readcnt, > const unsigned char *writearr, unsigned char *readarr); > int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int > len); > int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf); > @@ -643,6 +656,9 @@ > #if CONFIG_DEDIPROG == 1 > SPI_CONTROLLER_DEDIPROG, > #endif > +#if CONFIG_RAYER_BITBANG_SPI == 1 > + SPI_CONTROLLER_RAYER_BITBANG, > +#endif > SPI_CONTROLLER_INVALID /* This must always be the last entry. */ > }; > extern const int spi_programmer_count; > Index: flashrom-bitbang_spi_rayer/spi25.c > =================================================================== > --- flashrom-bitbang_spi_rayer/spi25.c (Revision 1025) > +++ flashrom-bitbang_spi_rayer/spi25.c (Arbeitskopie) > @@ -192,6 +192,9 @@ > #if CONFIG_DEDIPROG == 1 > case SPI_CONTROLLER_DEDIPROG: > #endif > +#if CONFIG_RAYER_BITBANG_SPI == 1 > + case SPI_CONTROLLER_RAYER_BITBANG: > +#endif > return probe_spi_rdid_generic(flash, 4); > default: > msg_cinfo("4b ID not supported on this SPI controller\n"); > Index: flashrom-bitbang_spi_rayer/hwaccess.h > =================================================================== > --- flashrom-bitbang_spi_rayer/hwaccess.h (Revision 1025) > +++ flashrom-bitbang_spi_rayer/hwaccess.h (Arbeitskopie) > @@ -169,6 +169,10 @@ > #define __DARWIN__ > #endif > > +/* Clarification about OUTB/OUTW/OUTL argument order: > + * OUT[BWL](val, port) > + */ > + > #if defined(__FreeBSD__) || defined(__DragonFly__) > #include <machine/cpufunc.h> > #define off64_t off_t > Index: flashrom-bitbang_spi_rayer/bitbang_spi.c > =================================================================== > --- flashrom-bitbang_spi_rayer/bitbang_spi.c (Revision 1025) > +++ flashrom-bitbang_spi_rayer/bitbang_spi.c (Arbeitskopie) > @@ -32,11 +32,20 @@ > enum bitbang_spi_master bitbang_spi_master = BITBANG_SPI_INVALID; > > const struct bitbang_spi_master_entry bitbang_spi_master_table[] = { > - {}, /* This entry corresponds to BITBANG_SPI_INVALID. */ > +#if CONFIG_RAYER_BITBANG_SPI == 1 > + { > + .set_cs = rayer_bitbang_set_cs, > + .set_sck = rayer_bitbang_set_sck, > + .set_mosi = rayer_bitbang_set_mosi, > + .get_miso = rayer_bitbang_get_miso, > + }, > +#endif > + {}, /* This entry corresponds to SPI_BITBANG_INVALID. */ > }; > > const int bitbang_spi_master_count = ARRAY_SIZE(bitbang_spi_master_table); > > +/* Note that CS# is active low, so val=0 means the chip is active. */ > void bitbang_spi_set_cs(int val) > { > bitbang_spi_master_table[bitbang_spi_master].set_cs(val); > @@ -57,10 +66,19 @@ > return bitbang_spi_master_table[bitbang_spi_master].get_miso(); > } > > -int bitbang_spi_init(void) > +int bitbang_spi_init(enum bitbang_spi_master master) > { > + bitbang_spi_master = master; > + > + if (bitbang_spi_master == BITBANG_SPI_INVALID) { > + msg_perr("Invalid bitbang SPI master. \n" > + "Please report a bug at [email protected]\n", > + __func__); > + return 1; > + } > bitbang_spi_set_cs(1); > bitbang_spi_set_sck(0); > + bitbang_spi_set_mosi(0); > buses_supported = CHIP_BUSTYPE_SPI; > return 0; > } > @@ -87,6 +105,7 @@ > { > static unsigned char *bufout = NULL; > static unsigned char *bufin = NULL; > + unsigned char *tmp; > static int oldbufsize = 0; > int bufsize; > int i; > @@ -98,20 +117,34 @@ > bufsize = max(writecnt + readcnt, 260); > /* Never shrink. realloc() calls are expensive. */ > if (bufsize > oldbufsize) { > - bufout = realloc(bufout, bufsize); > - if (!bufout) { > + tmp = realloc(bufout, bufsize); > + if (!tmp) { > msg_perr("Out of memory!\n"); > + if (bufout) > + free(bufout); > + bufout = NULL; > if (bufin) > free(bufin); > + bufin = NULL; > + oldbufsize = 0; > exit(1); > - } > - bufin = realloc(bufout, bufsize); > - if (!bufin) { > + } else > + bufout = tmp; > + > + tmp = realloc(bufin, bufsize); > + if (!tmp) { > msg_perr("Out of memory!\n"); > + if (bufin) > + free(bufin); > + bufin = NULL; > if (bufout) > free(bufout); > + bufout = NULL; > + oldbufsize = 0; > exit(1); > - } > + } else > + bufin = tmp; > + > oldbufsize = bufsize; > } > > @@ -135,8 +168,13 @@ > > int bitbang_spi_read(struct flashchip *flash, uint8_t *buf, int start, int > len) > { > - /* Maximum read length is unlimited, use 64k bytes. */ > - return spi_read_chunked(flash, buf, start, len, 64 * 1024); > + /* Maximum read length is unlimited in theory. > + * The current implementation can handle reads of up to 65536 > bytes. > + * Please note that you need two buffers of 2n+4 bytes each for a > read > + * of n bytes, resulting in a total memory requirement of 4n+8 > bytes. > + * To conserve memory, read in chunks of 256 bytes. > + */ > + return spi_read_chunked(flash, buf, start, len, 256); > } > > int bitbang_spi_write_256(struct flashchip *flash, uint8_t *buf) > Index: flashrom-bitbang_spi_rayer/spi.c > =================================================================== > --- flashrom-bitbang_spi_rayer/spi.c (Revision 1025) > +++ flashrom-bitbang_spi_rayer/spi.c (Arbeitskopie) > @@ -122,6 +122,15 @@ > }, > #endif > > +#if CONFIG_RAYER_BITBANG_SPI == 1 > + { /* SPI_CONTROLLER_RAYER_BITBANG */ > + .command = bitbang_spi_send_command, > + .multicommand = default_spi_send_multicommand, > + .read = bitbang_spi_read, > + .write_256 = bitbang_spi_write_256, > + }, > +#endif > + > {}, /* This entry corresponds to SPI_CONTROLLER_INVALID. */ > }; > > Index: flashrom-bitbang_spi_rayer/Makefile > =================================================================== > --- flashrom-bitbang_spi_rayer/Makefile (Revision 1025) > +++ flashrom-bitbang_spi_rayer/Makefile (Arbeitskopie) > @@ -85,8 +85,15 @@ > # Always enable serprog for now. Needs to be disabled on Windows. > CONFIG_SERPROG ?= yes > > -# Bitbanging SPI infrastructure is not used yet. > +# RayeR SPIPGM hardware support > +CONFIG_RAYER_BITBANG_SPI ?= yes > + > +# Bitbanging SPI infrastructure, default off unless needed. > +ifeq ($(CONFIG_RAYER_BITBANG_SPI), yes) > +CONFIG_BITBANG_SPI = yes > +else > CONFIG_BITBANG_SPI ?= no > +endif > > # Always enable 3Com NICs for now. > CONFIG_NIC3COM ?= yes > @@ -138,6 +145,13 @@ > endif > endif > > +ifeq ($(CONFIG_RAYER_BITBANG_SPI), yes) > +FEATURE_CFLAGS += -D'CONFIG_RAYER_BITBANG_SPI=1' > +PROGRAMMER_OBJS += rayer_bitbang_spi.o > +# Actually, NEED_PCI is wrong. NEED_IOPORT_ACCESS would be more correct. > +NEED_PCI := yes > +endif > + > ifeq ($(CONFIG_BITBANG_SPI), yes) > FEATURE_CFLAGS += -D'CONFIG_BITBANG_SPI=1' > PROGRAMMER_OBJS += bitbang_spi.o > Index: flashrom-bitbang_spi_rayer/flashrom.c > =================================================================== > --- flashrom-bitbang_spi_rayer/flashrom.c (Revision 1025) > +++ flashrom-bitbang_spi_rayer/flashrom.c (Arbeitskopie) > @@ -48,7 +48,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 > CONFIG_NIC3COM+CONFIG_NICREALTEK+CONFIG_GFXNVIDIA+CONFIG_DRKAISER+CONFIG_SATASII+CONFIG_ATAHPT+CONFIG_FT2232_SPI+CONFIG_SERPROG+CONFIG_BUSPIRATE_SPI+CONFIG_DEDIPROG > > 1 > +#if > CONFIG_NIC3COM+CONFIG_NICREALTEK+CONFIG_GFXNVIDIA+CONFIG_DRKAISER+CONFIG_SATASII+CONFIG_ATAHPT+CONFIG_FT2232_SPI+CONFIG_SERPROG+CONFIG_BUSPIRATE_SPI+CONFIG_DEDIPROG+CONFIG_RAYER_BITBANG_SPI > > 1 > #error Please enable either CONFIG_DUMMY or CONFIG_INTERNAL or disable > support for all programmers except one. > #endif > enum programmer programmer = > @@ -83,6 +83,9 @@ > #if CONFIG_DEDIPROG == 1 > PROGRAMMER_DEDIPROG > #endif > +#if CONFIG_RAYER_BITBANG_SPI == 1 > + PROGRAMMER_RAYER_BITBANG_SPI > +#endif > ; > #endif > > @@ -373,6 +376,25 @@ > }, > #endif > > +#if CONFIG_RAYER_BITBANG_SPI == 1 > + { > + .name = "rayer_bitbang_spi", > + .init = rayer_bitbang_spi_init, > + .shutdown = noop_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-bitbang_spi_rayer/rayer_bitbang_spi.c > =================================================================== > --- flashrom-bitbang_spi_rayer/rayer_bitbang_spi.c (Revision 0) > +++ flashrom-bitbang_spi_rayer/rayer_bitbang_spi.c (Revision 0) > @@ -0,0 +1,112 @@ > +/* > + * This file is part of the flashrom project. > + * > + * Copyright (C) 2009,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 > + */ > + > +/* Driver for the SPIPGM hardware by "RayeR" Martin Rehak. > + * See http://rayer.ic.cz/elektro/spipgm.htm for schematics and > instructions. > + */ > + > +/* This driver uses non-portable direct I/O port accesses which won't work > on > + * any non-x86 platform, and even on x86 there is a high chance there will > be > + * collisions with any loaded parallel port drivers. > + * The big advantage of direct port I/O is OS independence and speed > because > + * most OS parport drivers will perform many unnecessary accesses although > + * this driver just treats the parallel port as a GPIO set. > + */ > +#if defined(__i386__) || defined(__x86_64__) > + > +#include "flash.h" > + > +/* We have two sets of pins, out and in. The numbers for both sets are > + * independent and are bitshift values, not real pin numbers. > + */ > +/* Pins for master->slave direction */ > +#define SPI_CS_PIN 5 > +#define SPI_SCK_PIN 6 > +#define SPI_MOSI_PIN 7 > +/* Pins for slave->master direction */ > +#define SPI_MISO_PIN 6 > + > +static int lpt_iobase; > + > +/* FIXME: All rayer_bitbang_set_* functions could use caching of the value > + * stored at port lpt_iobase to avoid unnecessary INB. In theory, only one > + * INB(lpt_iobase) would be needed on programmer init to get the initial > + * value. > + */ > + > +void rayer_bitbang_set_cs(int val) > +{ > + uint8_t tmp; > + > + tmp = INB(lpt_iobase); > + tmp &= ~(1 << SPI_CS_PIN); > + tmp |= (val << SPI_CS_PIN); > + OUTB(tmp, lpt_iobase); > +} > + > +void rayer_bitbang_set_sck(int val) > +{ > + uint8_t tmp; > + > + tmp = INB(lpt_iobase); > + tmp &= ~(1 << SPI_SCK_PIN); > + tmp |= (val << SPI_SCK_PIN); > + OUTB(tmp, lpt_iobase); > +} > + > +void rayer_bitbang_set_mosi(int val) > +{ > + uint8_t tmp; > + > + tmp = INB(lpt_iobase); > + tmp &= ~(1 << SPI_MOSI_PIN); > + tmp |= (val << SPI_MOSI_PIN); > + OUTB(tmp, lpt_iobase); > +} > + > +int rayer_bitbang_get_miso(void) > +{ > + uint8_t tmp; > + > + tmp = INB(lpt_iobase + 1); > + tmp = (tmp >> SPI_MISO_PIN) & 0x1; > + return tmp; > +} > + > +int rayer_bitbang_spi_init(void) > +{ > + /* Pick a default value for now. */ > + lpt_iobase = 0x378; > + > + msg_pdbg("Using port 0x%x as I/O base for parallel port access.\n", > + lpt_iobase); > + > + get_io_perms(); > + > + if (bitbang_spi_init(BITBANG_SPI_MASTER_RAYER)) > + return 1; > + > + spi_controller = SPI_CONTROLLER_RAYER_BITBANG; > + > + return 0; > +} > + > +#else > +#error PCI port I/O access is not supported on this architecture yet. > +#endif > > > -- > http://www.hailfinger.org/ > > > _______________________________________________ > flashrom mailing list > [email protected] > http://www.flashrom.org/mailman/listinfo/flashrom >
_______________________________________________ flashrom mailing list [email protected] http://www.flashrom.org/mailman/listinfo/flashrom
