
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