Author: hailfinger
Date: 2009-06-16 10:55:44 +0200 (Tue, 16 Jun 2009)
New Revision: 596

Modified:
   trunk/flash.h
   trunk/flashrom.c
   trunk/ichspi.c
   trunk/it87spi.c
   trunk/sb600spi.c
   trunk/spi.c
   trunk/wbsio_spi.c
Log:
This patch gives us arbitrary range reads at byte boundaries for every
single chip supported by flashrom.
That means you can tell flashrom to read exactly bytes 12345-56789
(start 12345, length 44445) and it will not fetch a single byte more.

Uwe tested this on one LPC, one SPI, and one parallel flash board.

Signed-off-by: Carl-Daniel Hailfinger <[email protected]>
Acked-by: Uwe Hermann <[email protected]>


Modified: trunk/flash.h
===================================================================
--- trunk/flash.h       2009-06-15 17:23:36 UTC (rev 595)
+++ trunk/flash.h       2009-06-16 08:55:44 UTC (rev 596)
@@ -167,7 +167,7 @@
        int probe_timing;
        int (*erase) (struct flashchip *flash);
        int (*write) (struct flashchip *flash, uint8_t *buf);
-       int (*read) (struct flashchip *flash, uint8_t *buf);
+       int (*read) (struct flashchip *flash, uint8_t *buf, int start, int len);
 
        /* Some flash devices have an additional register space. */
        chipaddr virtual_memory;
@@ -362,7 +362,7 @@
 extern int verbose;
 #define printf_debug(x...) { if (verbose) printf(x); }
 void map_flash_registers(struct flashchip *flash);
-int read_memmapped(struct flashchip *flash, uint8_t *buf);
+int read_memmapped(struct flashchip *flash, uint8_t *buf, int start, int len);
 int min(int a, int b);
 int max(int a, int b);
 int check_erased_range(struct flashchip *flash, int start, int len);
@@ -408,13 +408,13 @@
 int spi_block_erase_d8(const struct flashchip *flash, unsigned long addr);
 int spi_chip_write_1(struct flashchip *flash, uint8_t *buf);
 int spi_chip_write_256(struct flashchip *flash, uint8_t *buf);
-int spi_chip_read(struct flashchip *flash, uint8_t *buf);
+int spi_chip_read(struct flashchip *flash, uint8_t *buf, int start, int len);
 uint8_t spi_read_status_register(void);
 int spi_disable_blockprotect(void);
 void spi_byte_program(int address, uint8_t byte);
 int spi_nbyte_program(int address, uint8_t *bytes, int len);
 int spi_nbyte_read(int address, uint8_t *bytes, int len);
-int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int chunksize);
+int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int start, int 
len, int chunksize);
 int spi_aai_write(struct flashchip *flash, uint8_t *buf);
 uint32_t spi_get_valid_read_addr(void);
 
@@ -440,7 +440,7 @@
 int ich_init_opcodes(void);
 int ich_spi_command(unsigned int writecnt, unsigned int readcnt,
                    const unsigned char *writearr, unsigned char *readarr);
-int ich_spi_read(struct flashchip *flash, uint8_t * buf);
+int ich_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
 int ich_spi_write_256(struct flashchip *flash, uint8_t * buf);
 
 /* it87spi.c */
@@ -451,14 +451,14 @@
 int it87xx_probe_spi_flash(const char *name);
 int it8716f_spi_command(unsigned int writecnt, unsigned int readcnt,
                        const unsigned char *writearr, unsigned char *readarr);
-int it8716f_spi_chip_read(struct flashchip *flash, uint8_t *buf);
+int it8716f_spi_chip_read(struct flashchip *flash, uint8_t *buf, int start, 
int len);
 int it8716f_spi_chip_write_1(struct flashchip *flash, uint8_t *buf);
 int it8716f_spi_chip_write_256(struct flashchip *flash, uint8_t *buf);
 
 /* sb600spi.c */
 int sb600_spi_command(unsigned int writecnt, unsigned int readcnt,
                      const unsigned char *writearr, unsigned char *readarr);
-int sb600_spi_read(struct flashchip *flash, uint8_t *buf);
+int sb600_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
 int sb600_spi_write_1(struct flashchip *flash, uint8_t *buf);
 uint8_t sb600_read_status_register(void);
 extern uint8_t *sb600_spibar;
@@ -557,7 +557,7 @@
 int wbsio_check_for_spi(const char *name);
 int wbsio_spi_command(unsigned int writecnt, unsigned int readcnt,
                      const unsigned char *writearr, unsigned char *readarr);
-int wbsio_spi_read(struct flashchip *flash, uint8_t *buf);
+int wbsio_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
 int wbsio_spi_write_1(struct flashchip *flash, uint8_t *buf);
 
 /* stm50flw0x0x.c */

Modified: trunk/flashrom.c
===================================================================
--- trunk/flashrom.c    2009-06-15 17:23:36 UTC (rev 595)
+++ trunk/flashrom.c    2009-06-16 08:55:44 UTC (rev 596)
@@ -194,9 +194,9 @@
        flash->virtual_registers = (chipaddr)programmer_map_flash_region("flash 
chip registers", (0xFFFFFFFF - 0x400000 - size + 1), size);
 }
 
-int read_memmapped(struct flashchip *flash, uint8_t *buf)
+int read_memmapped(struct flashchip *flash, uint8_t *buf, int start, int len)
 {
-       chip_readn(buf, flash->virtual_memory, flash->total_size * 1024);
+       chip_readn(buf, flash->virtual_memory + start, len);
                
        return 0;
 }
@@ -393,7 +393,7 @@
                fprintf(stderr, "ERROR: flashrom has no read function for this 
flash chip.\n");
                return 1;
        } else
-               flash->read(flash, buf2);
+               flash->read(flash, buf2, 0, total_size);
 
        printf("Verifying flash... ");
 
@@ -446,7 +446,7 @@
                fprintf(stderr, "ERROR: flashrom has no read function for this 
flash chip.\n");
                return 1;
        } else
-               flash->read(flash, buf);
+               flash->read(flash, buf, 0, size);
 
        if (exclude_end_position - exclude_start_position > 0)
                memset(buf + exclude_start_position, 0,
@@ -482,7 +482,7 @@
                fprintf(stderr, "ERROR: flashrom has no read function for this 
flash chip.\n");
                return 1;
        } else
-               flash->read(flash, buf);
+               flash->read(flash, buf, 0, size);
 
        for (erasedbytes = 0; erasedbytes < size; erasedbytes++)
                if (0xff != buf[erasedbytes]) {
@@ -915,6 +915,7 @@
         * completely once all flash chips can do rom layouts. stepan
         */
 
+       /* FIXME: This code is totally broken. It treats exclude ranges as 
include ranges. */
        // ////////////////////////////////////////////////////////////
        if (exclude_end_position - exclude_start_position > 0)
                chip_readn(buf + exclude_start_position,

Modified: trunk/ichspi.c
===================================================================
--- trunk/ichspi.c      2009-06-15 17:23:36 UTC (rev 595)
+++ trunk/ichspi.c      2009-06-16 08:55:44 UTC (rev 596)
@@ -647,14 +647,14 @@
        return 0;
 }
 
-int ich_spi_read(struct flashchip *flash, uint8_t * buf)
+int ich_spi_read(struct flashchip *flash, uint8_t * buf, int start, int len)
 {
        int maxdata = 64;
 
        if (spi_controller == SPI_CONTROLLER_VIA)
                maxdata = 16;
 
-       return spi_read_chunked(flash, buf, maxdata);
+       return spi_read_chunked(flash, buf, start, len, maxdata);
 }
 
 int ich_spi_write_256(struct flashchip *flash, uint8_t * buf)

Modified: trunk/it87spi.c
===================================================================
--- trunk/it87spi.c     2009-06-15 17:23:36 UTC (rev 595)
+++ trunk/it87spi.c     2009-06-16 08:55:44 UTC (rev 596)
@@ -257,15 +257,15 @@
  * IT8716F only allows maximum of 512 kb SPI mapped to LPC memory cycles
  * Need to read this big flash using firmware cycles 3 byte at a time.
  */
-int it8716f_spi_chip_read(struct flashchip *flash, uint8_t *buf)
+int it8716f_spi_chip_read(struct flashchip *flash, uint8_t *buf, int start, 
int len)
 {
        int total_size = 1024 * flash->total_size;
        fast_spi = 0;
 
        if ((programmer == PROGRAMMER_IT87SPI) || (total_size > 512 * 1024)) {
-               spi_read_chunked(flash, buf, 3);
+               spi_read_chunked(flash, buf, start, len, 3);
        } else {
-               read_memmapped(flash, buf);
+               read_memmapped(flash, buf, start, len);
        }
 
        return 0;

Modified: trunk/sb600spi.c
===================================================================
--- trunk/sb600spi.c    2009-06-15 17:23:36 UTC (rev 595)
+++ trunk/sb600spi.c    2009-06-16 08:55:44 UTC (rev 596)
@@ -39,10 +39,10 @@
 struct sb600_spi_controller *spi_bar = NULL;
 uint8_t *sb600_spibar;
 
-int sb600_spi_read(struct flashchip *flash, uint8_t *buf)
+int sb600_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len)
 {
        /* Maximum read length is 8 bytes. */
-       return spi_read_chunked(flash, buf, 8);
+       return spi_read_chunked(flash, buf, start, len, 8);
 }
 
 uint8_t sb600_read_status_register(void)

Modified: trunk/spi.c
===================================================================
--- trunk/spi.c 2009-06-15 17:23:36 UTC (rev 595)
+++ trunk/spi.c 2009-06-16 08:55:44 UTC (rev 596)
@@ -678,19 +678,31 @@
  * Read a complete flash chip.
  * Each page is read separately in chunks with a maximum size of chunksize.
  */
-int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int chunksize)
+int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int start, int 
len, int chunksize)
 {
        int rc = 0;
-       int i, j;
-       int total_size = flash->total_size * 1024;
+       int i, j, starthere, lenhere;
        int page_size = flash->page_size;
        int toread;
 
-       for (j = 0; j < total_size / page_size; j++) {
-               for (i = 0; i < page_size; i += chunksize) {
-                       toread = min(chunksize, page_size - i);
-                       rc = spi_nbyte_read(j * page_size + i,
-                                           buf + j * page_size + i, toread);
+       /* Warning: This loop has a very unusual condition and body.
+        * The loop needs to go through each page with at least one affected
+        * byte. The lowest page number is (start / page_size) since that
+        * division rounds down. The highest page number we want is the page
+        * where the last byte of the range lives. That last byte has the
+        * address (start + len - 1), thus the highest page number is
+        * (start + len - 1) / page_size. Since we want to include that last
+        * page as well, the loop condition uses <=.
+        */
+       for (i = start / page_size; i <= (start + len - 1) / page_size; i++) {
+               /* Byte position of the first byte in the range in this page. */
+               /* starthere is an offset to the base address of the chip. */
+               starthere = max(start, i * page_size);
+               /* Length of bytes in the range in this page. */
+               lenhere = min(start + len, (i + 1) * page_size) - starthere;
+               for (j = 0; j < lenhere; j += chunksize) {
+                       toread = min(chunksize, lenhere - j);
+                       rc = spi_nbyte_read(starthere + j, buf + starthere - 
start + j, toread);
                        if (rc)
                                break;
                }
@@ -701,19 +713,19 @@
        return rc;
 }
 
-int spi_chip_read(struct flashchip *flash, uint8_t *buf)
+int spi_chip_read(struct flashchip *flash, uint8_t *buf, int start, int len)
 {
        switch (spi_controller) {
        case SPI_CONTROLLER_IT87XX:
-               return it8716f_spi_chip_read(flash, buf);
+               return it8716f_spi_chip_read(flash, buf, start, len);
        case SPI_CONTROLLER_SB600:
-               return sb600_spi_read(flash, buf);
+               return sb600_spi_read(flash, buf, start, len);
        case SPI_CONTROLLER_ICH7:
        case SPI_CONTROLLER_ICH9:
        case SPI_CONTROLLER_VIA:
-               return ich_spi_read(flash, buf);
+               return ich_spi_read(flash, buf, start, len);
        case SPI_CONTROLLER_WBSIO:
-               return wbsio_spi_read(flash, buf);
+               return wbsio_spi_read(flash, buf, start, len);
        default:
                printf_debug
                    ("%s called, but no SPI chipset/strapping detected\n",

Modified: trunk/wbsio_spi.c
===================================================================
--- trunk/wbsio_spi.c   2009-06-15 17:23:36 UTC (rev 595)
+++ trunk/wbsio_spi.c   2009-06-16 08:55:44 UTC (rev 596)
@@ -173,7 +173,7 @@
        return 0;
 }
 
-int wbsio_spi_read(struct flashchip *flash, uint8_t *buf)
+int wbsio_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len)
 {
        int size = flash->total_size * 1024;
 
@@ -182,7 +182,7 @@
                return 1;
        }
 
-       read_memmapped(flash, buf);
+       read_memmapped(flash, buf, start, len);
        return 0;
 }
 


-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to