[U-Boot-Users] Bug in cfi_flash.c
Mirco Fuchs
fuchs at ftz-leipzig.de
Wed Apr 26 14:20:31 CEST 2006
Hello,
there is a bug in cfi_flash.c in function flash_get_size(). The problem appears if the board
specific CFG_MAX_FLASH_SECT macro is smaller than the real number of sectors.
In this case i use a 32 MiB Spansion flash (S29GL256), but we only want respectivly can use
16 MiB of the flash because of the broken A24 line on the AT91RM9200. Therefore i defined
CFG_MAX_FLASH_SECT to 128, but the real value is 256. The structure allocation of
flash_info_t in flash.h defines the size of the protect array to CFG_MAX_FLASH_SECT (in
my case 128). The for-loop in flash_get_size() initialises this array, but it does it for all
sectors (erase_region_count) which is 256 in my case. This will cause the info->portwidth
variable (and of course all following too) to be overwritten.
flash.h
****************************************
typedef struct {
ulong size; /* total bank size in bytes */
ushort sector_count; /* number of erase units */
ulong flash_id; /* combined device & manufacturer code */
ulong start[CFG_MAX_FLASH_SECT]; /* physical sector start addresses */
uchar protect[CFG_MAX_FLASH_SECT]; /* sector protection status */
#ifdef CFG_FLASH_CFI
uchar portwidth; /* the width of the port */
uchar chipwidth; /* the width of the chip */
ushort buffer_size; /* # of bytes in write buffer */
ulong erase_blk_tout; /* maximum block erase timeout */
ulong write_tout; /* maximum write timeout */
ulong buffer_write_tout; /* maximum buffer write timeout */
ushort vendor; /* the primary vendor id */
ushort cmd_reset; /* Vendor specific reset command */
ushort interface; /* used for x8/x16 adjustments */
ushort legacy_unlock; /* support Intel legacy (un)locking */
#endif
} flash_info_t;
****************************************
cfi_flash.c, flash_get_size()
****************************************
debug ("erase_region_count = %d erase_region_size = %d\n",
erase_region_count, erase_region_size);
for (j = 0; j < erase_region_count; j++) {
info->start[sect_cnt] = sector;
sector += (erase_region_size * size_ratio);
/*
* Only read protection status from supported devices (intel...)
*/
switch (info->vendor) {
case CFI_CMDSET_INTEL_EXTENDED:
case CFI_CMDSET_INTEL_STANDARD:
info->protect[sect_cnt] =
flash_isset (info, sect_cnt,
FLASH_OFFSET_PROTECT,
FLASH_STATUS_PROTECT);
break;
default:
info->protect[sect_cnt] = 0; /* default: not protected */
}
sect_cnt++;
}
}
******************************************
regards
Mirco
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.denx.de/pipermail/u-boot/attachments/20060426/c147a8c4/attachment.htm
More information about the U-Boot
mailing list