On 15.10.2007 01:28, Harald Gutmann wrote:
> Am Montag, 15. Oktober 2007 01:06:00 schrieb Carl-Daniel Hailfinger:
>   
>> Great, thanks! The code I have also is not polished, so even if your
>> code is ugly, it is better than no code. We can clean up that stuff
>> together.
>>     
>
> yes, that's right!
> here it is.
>
> the patch is done with:
> Revision: 2850
>   
I have rearranged some code, so your patch does no longer apply, but it
should be easy to fix.

> diff -ubrN ../../flashrom.original/board_enable.c flashrom.new/board_enable.c
> --- ../../flashrom.original/board_enable.c    2007-10-15 01:14:29.000000000 
> +0200
> +++ flashrom.new/board_enable.c       2007-10-14 20:28:41.000000000 +0200
>   

This is now in spi.c

> @@ -37,7 +37,7 @@
>  #define JEDEC_RDID_OUTSIZE   0x01
>  #define JEDEC_RDID_INSIZE    0x03
>  
> -static uint16_t it8716f_flashport = 0;
> +uint16_t it8716f_flashport = 0;
>  
>  /* Generic Super I/O helper functions */
>  uint8_t regval(uint16_t port, uint8_t reg)
> @@ -111,7 +111,7 @@
>     whereas the IT8716F splits commands internally into address and 
> non-address
>     commands with the address in inverse wire order. That's why the register
>     ordering in case 4 and 5 may seem strange. */
> -static int it8716f_spi_command(uint16_t port, unsigned char writecnt, 
> unsigned char readcnt, const unsigned char *writearr, unsigned char *readarr)
> +int it8716f_spi_command(uint16_t port, unsigned char writecnt, unsigned char 
> readcnt, const unsigned char *writearr, unsigned char *readarr)
>  {
>       uint8_t busy, writeenc;
>       do {
> diff -ubrN ../../flashrom.original/board_enable.h flashrom.new/board_enable.h
> --- ../../flashrom.original/board_enable.h    1970-01-01 01:00:00.000000000 
> +0100
> +++ flashrom.new/board_enable.h       2007-10-14 21:09:18.000000000 +0200
>   

Perhaps move to spi.h?

> @@ -0,0 +1,7 @@
> +#ifndef boardenableh
> +#define boardenableh
> +uint16_t it8716f_flashport;
> +uint8_t regval(uint16_t port, uint8_t reg);
> +void regwrite(uint16_t port, uint8_t reg, uint8_t val);
> +int it8716f_spi_command(uint16_t port, unsigned char writecnt, unsigned char 
> readcnt, const unsigned char *writearr, unsigned char *readarr);
> +#endif
> diff -ubrN ../../flashrom.original/flashchips.c flashrom.new/flashchips.c
> --- ../../flashrom.original/flashchips.c      2007-10-15 01:14:28.000000000 
> +0200
> +++ flashrom.new/flashchips.c 2007-10-15 01:24:58.000000000 +0200
> @@ -39,7 +39,7 @@
>       {"Mx29f002",    MX_ID,          MX_29F002,      256, 64 * 1024,
>        probe_29f002,  erase_29f002,   write_29f002},
>       {"MX25L4005",   MX_ID,          MX_25L4005,     512, 4 * 1024,
> -      probe_spi,     NULL,           NULL},
> +      probe_spi,     erase_25l4005,  write_25l4005},
>       {"SST29EE020A", SST_ID,         SST_29EE020A,   256, 128,
>        probe_jedec,   erase_chip_jedec, write_jedec},
>       {"SST28SF040A", SST_ID,         SST_28SF040,    512, 256,
>   

OK

> diff -ubrN ../../flashrom.original/flash.h flashrom.new/flash.h
> --- ../../flashrom.original/flash.h   2007-10-15 01:14:28.000000000 +0200
> +++ flashrom.new/flash.h      2007-10-14 19:13:52.000000000 +0200
> @@ -294,4 +294,10 @@
>  /* w49f002u.c */
>  int write_49f002(struct flashchip *flash, uint8_t *buf);
>  
> +/* mx25l4005.c */
> +// probe
> +int write_25l4005(struct flashchip *flash, uint8_t *buf);
> +int erase_25l4005(struct flashchip *flash);
> +int read_25l4005(struct flashchip *flash, uint8_t *buf);
> +
>  #endif                               /* !__FLASH_H__ */
>   

OK

> diff -ubrN ../../flashrom.original/Makefile flashrom.new/Makefile
> --- ../../flashrom.original/Makefile  2007-10-15 01:14:29.000000000 +0200
> +++ flashrom.new/Makefile     2007-10-15 01:20:16.000000000 +0200
> @@ -24,7 +24,7 @@
>       am29f040b.o mx29f002.o sst39sf020.o m29f400bt.o w49f002u.o \
>       82802ab.o msys_doc.o pm49fl004.o sst49lf040.o sst49lfxxxc.o \
>       sst_fwhub.o layout.o lbtable.o flashchips.o flashrom.o \
> -     sharplhf00l04.o w29ee011.o
> +     sharplhf00l04.o w29ee011.o mx25l4005.o
>  
>  all: pciutils dep $(PROGRAM)
>  
> @@ -33,7 +33,7 @@
>       $(STRIP) $(STRIP_ARGS) $(PROGRAM)
>  
>  clean:
> -     rm -f *.o *~
> +     rm -f *.o *~ flashrom
>  
>  distclean: clean
>       rm -f $(PROGRAM) .dependencies
>   

Skip the make clean changes. We have make distclean.

> diff -ubrN ../../flashrom.original/mx25l4005.c flashrom.new/mx25l4005.c
> --- ../../flashrom.original/mx25l4005.c       1970-01-01 01:00:00.000000000 
> +0100
> +++ flashrom.new/mx25l4005.c  2007-10-15 01:17:56.000000000 +0200
> @@ -0,0 +1,57 @@
> +#include <stdint.h>
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include "flash.h"
> +#include "board_enable.h"
> +
> +static void check_n_write_enable() {
> +     uint8_t result[3] = {0, 0, 0};
> +     uint8_t command[5] = {0x06, 0, 0, 0, 0};
> +     // Send WREN (Write Enable)
> +     it8716f_spi_command(it8716f_flashport, 1, 0, command, result);
>   

generic_spi_command

> +     uint8_t reg=regval(it8716f_flashport,0x24);
> +     reg|=(1<<4);
> +     regwrite(it8716f_flashport,0x24,reg);
>   

I have absolutely no idea what you are trying to do here. According to
my data sheet, your code does the following:
* Enable multiple byte mode, set clock to 33/2 MHz, read the last JEDEC
command sent to the flash chip
* Set bit 4 of the last JEDEC command
* Enable multiple byte mode, set clock to 33/2 MHz, write the modified
JEDEC command

Please note that none of these three lines send or receive anything
from/to the chip.

> +
> +}
> +
> +static void write_disable() {
> +     uint8_t result[3] = {0, 0, 0};
> +     uint8_t command[5] = {0x04, 0, 0, 0, 0};
> +     // Send WRDI (Write Disable)
> +     it8716f_spi_command(it8716f_flashport, 1, 0, command, result);
>   

generic_spi_command
> +     uint8_t reg=regval(it8716f_flashport,0x24);
> +     reg&=~(1<<4);
> +     regwrite(it8716f_flashport,0x24,reg);
>   

Same as above: What are you trying to do?

> +}
> +
> +void write256b(int block, uint8_t *buf, uint8_t *bios ) {
> +     check_n_write_enable();
> +     outb(0x06,it8716f_flashport+1);
> +     outb((3<<4),it8716f_flashport);
> +     int i;
> +     for (i=0;i<256;++i) {
> +             bios[256*block+i]=buf[256*block+i];
> +     }
> +     outb(0,it8716f_flashport);
> +     write_disable();
> +     usleep (1000);
>   

Check the chip status register instead fo waiting.

> +}
>   

OK, but we probably need a generic_spi_command_prepare and
generic_spi_command_stop

> +
> +int write_25l4005(struct flashchip *flash, uint8_t *buf) {
> +     int total_size=1024*flash->total_size;
> +     int i;
> +     for (i=0;i<total_size/256;++i) {
> +             write256b(i, buf, (uint8_t*)flash->virtual_memory);
> +     }
> +return 0;
> +}
>   

OK

> +
> +int erase_25l4005(struct flashchip *flash) {
> +check_n_write_enable();
> +uint8_t result[3]={0, 0, 0};
> +uint8_t command[5]={0xc7, 0, 0, 0, 0};
> +it8716f_spi_command(it8716f_flashport, 1, 0, command, result);
>   

generic_spi_command

> +write_disable();
> +sleep (3);
> +// the chip needs some time, until it responses again.
> +return 0;
>   

Can you instead read the flash chip status register in a loop? That way,
you don't have to hardcode the sleep duration.
> +}
>   

Overall, I like it.

My version of the write patch follows. Please test.

Index: flash.h
===================================================================
--- flash.h     (Revision 2864)
+++ flash.h     (Arbeitskopie)
@@ -296,4 +296,10 @@
 /* w49f002u.c */
 int write_49f002(struct flashchip *flash, uint8_t *buf);
 
+/* mx25l4005.c */
+// probe
+int write_25l4005(struct flashchip *flash, uint8_t *buf);
+int erase_25l4005(struct flashchip *flash);
+int read_25l4005(struct flashchip *flash, uint8_t *buf);
+
 #endif                         /* !__FLASH_H__ */
Index: flashchips.c
===================================================================
--- flashchips.c        (Revision 2864)
+++ flashchips.c        (Arbeitskopie)
@@ -39,7 +39,7 @@
        {"Mx29f002",    MX_ID,          MX_29F002,      256, 64 * 1024,
         probe_29f002,  erase_29f002,   write_29f002},
        {"MX25L4005",   MX_ID,          MX_25L4005,     512, 4 * 1024,
-        probe_spi,     NULL,           NULL},
+        probe_spi,     erase_25l4005,  write_25l4005},
        {"SST29EE020A", SST_ID,         SST_29EE020A,   256, 128,
         probe_jedec,   erase_chip_jedec, write_jedec},
        {"SST28SF040A", SST_ID,         SST_28SF040,    512, 256,
Index: spi.c
===================================================================
--- spi.c       (Revision 2864)
+++ spi.c       (Arbeitskopie)
@@ -34,8 +34,16 @@
 #define JEDEC_RDID_OUTSIZE     0x01
 #define JEDEC_RDID_INSIZE      0x03
 
-static uint16_t it8716f_flashport = 0;
+#define JEDEC_WREN     {0x06}
+#define JEDEC_WREN_OUTSIZE     0x01
+#define JEDEC_WREN_INSIZE      0x00
 
+#define JEDEC_WRDI     {0x04}
+#define JEDEC_WRDI_OUTSIZE     0x01
+#define JEDEC_WRDI_INSIZE      0x00
+
+uint16_t it8716f_flashport = 0;
+
 /* Generic Super I/O helper functions */
 uint8_t regval(uint16_t port, uint8_t reg)
 {
@@ -170,7 +178,7 @@
        return 0;
 }
 
-static int generic_spi_command(unsigned char writecnt, unsigned char readcnt, 
const unsigned char *writearr, unsigned char *readarr)
+int generic_spi_command(unsigned char writecnt, unsigned char readcnt, const 
unsigned char *writearr, unsigned char *readarr)
 {
        if (it8716f_flashport)
                return it8716f_spi_command(it8716f_flashport, writecnt, 
readcnt, writearr, readarr);
@@ -188,6 +196,25 @@
        return 0;
 }
 
+void generic_spi_write_enable()
+{
+       const unsigned char cmd[] = JEDEC_WREN;
+       unsigned char result[] = {0, 0, 0};
+
+       // Send WREN (Write Enable)
+       generic_spi_command(JEDEC_WREN_OUTSIZE, JEDEC_WREN_INSIZE, cmd, result);
+
+}
+
+void generic_spi_write_disable()
+{
+       const unsigned char cmd[] = JEDEC_WRDI;
+       unsigned char result[] = {0, 0, 0};
+
+       // Send WRDI (Write Disable)
+       generic_spi_command(JEDEC_WRDI_OUTSIZE, JEDEC_WRDI_INSIZE, cmd, result);
+}
+
 int probe_spi(struct flashchip *flash)
 {
        unsigned char readarr[3];
Index: Makefile
===================================================================
--- Makefile    (Revision 2864)
+++ Makefile    (Arbeitskopie)
@@ -24,7 +24,7 @@
        am29f040b.o mx29f002.o sst39sf020.o m29f400bt.o w49f002u.o \
        82802ab.o msys_doc.o pm49fl004.o sst49lf040.o sst49lfxxxc.o \
        sst_fwhub.o layout.o lbtable.o flashchips.o flashrom.o \
-       sharplhf00l04.o w29ee011.o spi.o
+       sharplhf00l04.o w29ee011.o spi.o mx25l4005.o
 
 all: pciutils dep $(PROGRAM)
 
Index: spi.h
===================================================================
--- spi.h       (Revision 0)
+++ spi.h       (Revision 0)
@@ -0,0 +1,9 @@
+#ifndef __SPI_H__
+#define __SPI_H__ 1
+
+uint16_t it8716f_flashport;
+int generic_spi_command(unsigned char writecnt, unsigned char readcnt, const 
unsigned char *writearr, unsigned char *readarr);
+void generic_spi_write_enable();
+void generic_spi_write_disable();
+
+#endif
Index: mx25l4005.c
===================================================================
--- mx25l4005.c (Revision 0)
+++ mx25l4005.c (Revision 0)
@@ -0,0 +1,39 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "flash.h"
+#include "spi.h"
+
+
+void write256b(int block, uint8_t *buf, uint8_t *bios ) {
+       generic_spi_write_enable();
+       outb(0x06,it8716f_flashport+1);
+       outb((3<<4),it8716f_flashport);
+       int i;
+       for (i=0;i<256;++i) {
+               bios[256*block+i]=buf[256*block+i];
+       }
+       outb(0,it8716f_flashport);
+       generic_spi_write_disable();
+       usleep (1000);
+}
+
+int write_25l4005(struct flashchip *flash, uint8_t *buf) {
+       int total_size=1024*flash->total_size;
+       int i;
+       for (i=0;i<total_size/256;++i) {
+               write256b(i, buf, (uint8_t*)flash->virtual_memory);
+       }
+return 0;
+}
+
+int erase_25l4005(struct flashchip *flash) {
+       generic_spi_write_enable();
+       uint8_t result[3]={0, 0, 0};
+       uint8_t command[5]={0xc7, 0, 0, 0, 0};
+       generic_spi_command(1, 0, command, result);
+       generic_spi_write_disable();
+       // the chip needs some time, until it responses again.
+       sleep (3);
+       return 0;
+}




-- 
linuxbios mailing list
linuxbios@linuxbios.org
http://www.linuxbios.org/mailman/listinfo/linuxbios

Reply via email to