Changeset 927 for trunk/flashrom.c


Ignore:
Timestamp:
Mar 8, 2010 1:42:32 AM (3 years ago)
Author:
hailfinger
Message:

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.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@…>
Acked-by: Sean Nelson <audiohacked@…>
Acked-by: David Hendricks <dhendrix@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/flashrom.c

    r908 r927  
    619619        free(readbuf); 
    620620        return ret; 
     621} 
     622 
     623/** 
     624 * Check if the buffer @have can be programmed to the content of @want without 
     625 * erasing. This is only possible if all chunks of size @gran are either kept 
     626 * as-is or changed from an all-ones state to any other state. 
     627 * The following write granularities (enum @gran) are known: 
     628 * - 1 bit. Each bit can be cleared individually. 
     629 * - 1 byte. A byte can be written once. Further writes to an already written 
     630 *   byte cause the contents to be either undefined or to stay unchanged. 
     631 * - 128 bytes. If less than 128 bytes are written, the rest will be 
     632 *   erased. Each write to a 128-byte region will trigger an automatic erase 
     633 *   before anything is written. Very uncommon behaviour and unsupported by 
     634 *   this function. 
     635 * - 256 bytes. If less than 256 bytes are written, the contents of the 
     636 *   unwritten bytes are undefined. 
     637 * 
     638 * @have        buffer with current content 
     639 * @want        buffer with desired content 
     640 * @len         length of the verified area 
     641 * @gran        write granularity (enum, not count) 
     642 * @return      0 if no erase is needed, 1 otherwise 
     643 */ 
     644int need_erase(uint8_t *have, uint8_t *want, int len, enum write_granularity gran) 
     645{ 
     646        int result = 0; 
     647        int i, j, limit; 
     648 
     649        switch (gran) { 
     650        case write_gran_1bit: 
     651                for (i = 0; i < len; i++) 
     652                        if ((have[i] & want[i]) != want[i]) { 
     653                                result = 1; 
     654                                break; 
     655                        } 
     656                break; 
     657        case write_gran_1byte: 
     658                for (i = 0; i < len; i++) 
     659                        if ((have[i] != want[i]) && (have[i] != 0xff)) { 
     660                                result = 1; 
     661                                break; 
     662                        } 
     663                break; 
     664        case write_gran_256bytes: 
     665                for (j = 0; j < len / 256; j++) { 
     666                        limit = min (256, len - j * 256); 
     667                        /* Are have and want identical? */ 
     668                        if (!memcmp(have + j * 256, want + j * 256, limit)) 
     669                                continue; 
     670                        /* have needs to be in erased state. */ 
     671                        for (i = 0; i < limit; i++) 
     672                                if (have[i] != 0xff) { 
     673                                        result = 1; 
     674                                        break; 
     675                                } 
     676                        if (result) 
     677                                break; 
     678                } 
     679                break; 
     680        } 
     681        return result; 
    621682} 
    622683 
Note: See TracChangeset for help on using the changeset viewer.