mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-28 23:43:42 +02:00
Write granularity is chip specific
The following write granularities exist according to my datasheet survey: - 1 bit. Each bit can be cleared individually. - 1 byte. A byte can be written once. Further writes to an already written byte cause the contents to be either undefined or to stay unchanged. - 128 bytes. If less than 128 bytes are written, the rest will be erased. Each write to a 128-byte region will trigger an automatic erase before anything is written. Very uncommon behaviour. - 256 bytes. If less than 256 bytes are written, the contents of the unwritten bytes are undefined. Note that chips with default 256-byte writes, which keep the original contents for unwritten bytes, have a granularity of 1 byte. Handle 1-bit, 1-byte and 256-byte write granularity. Corresponding to flashrom svn r927. Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> Acked-by: Sean Nelson <audiohacked@gmail.com> Acked-by: David Hendricks <dhendrix@google.com>
This commit is contained in:
parent
7f0c3ec56b
commit
e8e369fcc3
6
flash.h
6
flash.h
@ -512,6 +512,11 @@ int dediprog_spi_send_command(unsigned int writecnt, unsigned int readcnt, const
|
|||||||
int dediprog_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
int dediprog_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
|
||||||
|
|
||||||
/* flashrom.c */
|
/* flashrom.c */
|
||||||
|
enum write_granularity {
|
||||||
|
write_gran_1bit,
|
||||||
|
write_gran_1byte,
|
||||||
|
write_gran_256bytes,
|
||||||
|
};
|
||||||
extern enum chipbustype buses_supported;
|
extern enum chipbustype buses_supported;
|
||||||
struct decode_sizes {
|
struct decode_sizes {
|
||||||
uint32_t parallel;
|
uint32_t parallel;
|
||||||
@ -538,6 +543,7 @@ int max(int a, int b);
|
|||||||
char *extract_param(char **haystack, char *needle, char *delim);
|
char *extract_param(char **haystack, char *needle, char *delim);
|
||||||
int check_erased_range(struct flashchip *flash, int start, int len);
|
int check_erased_range(struct flashchip *flash, int start, int len);
|
||||||
int verify_range(struct flashchip *flash, uint8_t *cmpbuf, int start, int len, char *message);
|
int verify_range(struct flashchip *flash, uint8_t *cmpbuf, int start, int len, char *message);
|
||||||
|
int need_erase(uint8_t *have, uint8_t *want, int len, enum write_granularity gran);
|
||||||
char *strcat_realloc(char *dest, const char *src);
|
char *strcat_realloc(char *dest, const char *src);
|
||||||
void print_version(void);
|
void print_version(void);
|
||||||
int selfcheck(void);
|
int selfcheck(void);
|
||||||
|
61
flashrom.c
61
flashrom.c
@ -620,6 +620,67 @@ out_free:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the buffer @have can be programmed to the content of @want without
|
||||||
|
* erasing. This is only possible if all chunks of size @gran are either kept
|
||||||
|
* as-is or changed from an all-ones state to any other state.
|
||||||
|
* The following write granularities (enum @gran) are known:
|
||||||
|
* - 1 bit. Each bit can be cleared individually.
|
||||||
|
* - 1 byte. A byte can be written once. Further writes to an already written
|
||||||
|
* byte cause the contents to be either undefined or to stay unchanged.
|
||||||
|
* - 128 bytes. If less than 128 bytes are written, the rest will be
|
||||||
|
* erased. Each write to a 128-byte region will trigger an automatic erase
|
||||||
|
* before anything is written. Very uncommon behaviour and unsupported by
|
||||||
|
* this function.
|
||||||
|
* - 256 bytes. If less than 256 bytes are written, the contents of the
|
||||||
|
* unwritten bytes are undefined.
|
||||||
|
*
|
||||||
|
* @have buffer with current content
|
||||||
|
* @want buffer with desired content
|
||||||
|
* @len length of the verified area
|
||||||
|
* @gran write granularity (enum, not count)
|
||||||
|
* @return 0 if no erase is needed, 1 otherwise
|
||||||
|
*/
|
||||||
|
int need_erase(uint8_t *have, uint8_t *want, int len, enum write_granularity gran)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
int i, j, limit;
|
||||||
|
|
||||||
|
switch (gran) {
|
||||||
|
case write_gran_1bit:
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
if ((have[i] & want[i]) != want[i]) {
|
||||||
|
result = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case write_gran_1byte:
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
if ((have[i] != want[i]) && (have[i] != 0xff)) {
|
||||||
|
result = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case write_gran_256bytes:
|
||||||
|
for (j = 0; j < len / 256; j++) {
|
||||||
|
limit = min (256, len - j * 256);
|
||||||
|
/* Are have and want identical? */
|
||||||
|
if (!memcmp(have + j * 256, want + j * 256, limit))
|
||||||
|
continue;
|
||||||
|
/* have needs to be in erased state. */
|
||||||
|
for (i = 0; i < limit; i++)
|
||||||
|
if (have[i] != 0xff) {
|
||||||
|
result = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (result)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* This function generates various test patterns useful for testing controller
|
/* This function generates various test patterns useful for testing controller
|
||||||
* and chip communication as well as chip behaviour.
|
* and chip communication as well as chip behaviour.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user