diff options
author | hailfinger <hailfinger@2b7e53f0-3cfb-0310-b3e9-8179ed1497e1> | 2010-05-21 23:09:42 +0000 |
---|---|---|
committer | hailfinger <hailfinger@2b7e53f0-3cfb-0310-b3e9-8179ed1497e1> | 2010-05-21 23:09:42 +0000 |
commit | 27f835653173e2363aaeb97e94227abeb5b0d90a (patch) | |
tree | 73c903182e7400386453acfbd7c738b3361849ff /spi25.c | |
parent | 52c8333d041ec66b4bf2b66edecdc13c85ae93e2 (diff) | |
download | flashrom-27f835653173e2363aaeb97e94227abeb5b0d90a.tar.gz |
Every SPI programmer driver had its own completely different chip write
implementation, and all of them were insufficiently commented.
Create spi_write_chunked as a copy of spi_read_chunked and convert all
SPI programmers to use it.
No functional changes except:
- Bus Pirate uses 12 Byte writes instead of 8 Byte writes
- SB600 uses 5 Byte writes instead of 1 Byte writes
Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Acked-by: Michael Karcher <flashrom@mkarcher.dialup.fu-berlin.de>
Acked-by: David Hendricks <dhendrix@google.com>
git-svn-id: https://code.coreboot.org/svn/flashrom/trunk@1005 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'spi25.c')
-rw-r--r-- | spi25.c | 50 |
1 files changed, 48 insertions, 2 deletions
@@ -1,7 +1,7 @@ /* * This file is part of the flashrom project. * - * Copyright (C) 2007, 2008, 2009 Carl-Daniel Hailfinger + * Copyright (C) 2007, 2008, 2009, 2010 Carl-Daniel Hailfinger * Copyright (C) 2008 coresystems GmbH * * This program is free software; you can redistribute it and/or modify @@ -874,7 +874,7 @@ int spi_nbyte_read(int address, uint8_t *bytes, int len) } /* - * Read a complete flash chip. + * Read a part of the 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 start, int len, int chunksize) @@ -913,6 +913,52 @@ int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, } /* + * Write a part of the flash chip. + * Each page is written separately in chunks with a maximum size of chunksize. + */ +int spi_write_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, int chunksize) +{ + int rc = 0; + int i, j, starthere, lenhere; + /* FIXME: page_size is the wrong variable. We need max_writechunk_size + * in struct flashchip to do this properly. All chips using + * spi_chip_write_256 have page_size set to max_writechunk_size, so + * we're OK for now. + */ + int page_size = flash->page_size; + int towrite; + + /* 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) { + towrite = min(chunksize, lenhere - j); + rc = spi_nbyte_program(starthere + j, buf + starthere - start + j, towrite); + if (rc) + break; + while (spi_read_status_register() & JEDEC_RDSR_BIT_WIP) + programmer_delay(10); + } + if (rc) + break; + } + + return rc; +} + +/* * Program chip using byte programming. (SLOW!) * This is for chips which can only handle one byte writes * and for chips where memory mapped programming is impossible |