flash/cfi_flash: Use virtual sector start address, not phys

include/flash.h was commented to say that the address in
flash_info->start was a physical address.  However, from u-boot's
point of view, and looking at most flash code, it makes more
sense for this to be a virtual address.  So I corrected the
comment to indicate that this was a virtual address.

The only flash driver that was actually treating the address
as physical was the mtd/cfi_flash driver.  However, this code
was using it inconsistently as it actually directly dereferenced
the "start" element, while it used map_physmem to get a
virtual address in other places.  I changed this driver so
that the code which initializes the info->start field calls
map_physmem to get a virtual address, eliminating the need for
further map_physmem calls.  The code is now consistent.

The *only* place a physical address should be used is when defining the
flash banks list that is used to initialize the flash_info struct,
usually found in the board config file.

Signed-off-by: Becky Bruce <beckyb@kernel.crashing.org>
Signed-off-by: Stefan Roese <sr@denx.de>
master
Becky Bruce 16 years ago committed by Stefan Roese
parent 9d8811c5bd
commit 09ce9921a7
  1. 53
      drivers/mtd/cfi_flash.c
  2. 2
      include/flash.h

@ -305,17 +305,12 @@ flash_map (flash_info_t * info, flash_sect_t sect, uint offset)
{ {
unsigned int byte_offset = offset * info->portwidth; unsigned int byte_offset = offset * info->portwidth;
return map_physmem(info->start[sect] + byte_offset, return (void *)(info->start[sect] + byte_offset);
flash_sector_size(info, sect) - byte_offset,
MAP_NOCACHE);
} }
static inline void flash_unmap(flash_info_t *info, flash_sect_t sect, static inline void flash_unmap(flash_info_t *info, flash_sect_t sect,
unsigned int offset, void *addr) unsigned int offset, void *addr)
{ {
unsigned int byte_offset = offset * info->portwidth;
unmap_physmem(addr, flash_sector_size(info, sect) - byte_offset);
} }
/*----------------------------------------------------------------------- /*-----------------------------------------------------------------------
@ -802,13 +797,11 @@ static flash_sect_t find_sector (flash_info_t * info, ulong addr)
static int flash_write_cfiword (flash_info_t * info, ulong dest, static int flash_write_cfiword (flash_info_t * info, ulong dest,
cfiword_t cword) cfiword_t cword)
{ {
void *dstaddr; void *dstaddr = (void *)dest;
int flag; int flag;
flash_sect_t sect = 0; flash_sect_t sect = 0;
char sect_found = 0; char sect_found = 0;
dstaddr = map_physmem(dest, info->portwidth, MAP_NOCACHE);
/* Check if Flash is (sufficiently) erased */ /* Check if Flash is (sufficiently) erased */
switch (info->portwidth) { switch (info->portwidth) {
case FLASH_CFI_8BIT: case FLASH_CFI_8BIT:
@ -827,10 +820,8 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
flag = 0; flag = 0;
break; break;
} }
if (!flag) { if (!flag)
unmap_physmem(dstaddr, info->portwidth);
return ERR_NOT_ERASED; return ERR_NOT_ERASED;
}
/* Disable interrupts which might cause a timeout here */ /* Disable interrupts which might cause a timeout here */
flag = disable_interrupts (); flag = disable_interrupts ();
@ -873,8 +864,6 @@ static int flash_write_cfiword (flash_info_t * info, ulong dest,
if (flag) if (flag)
enable_interrupts (); enable_interrupts ();
unmap_physmem(dstaddr, info->portwidth);
if (!sect_found) if (!sect_found)
sect = find_sector (info, dest); sect = find_sector (info, dest);
@ -890,7 +879,7 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
int cnt; int cnt;
int retcode; int retcode;
void *src = cp; void *src = cp;
void *dst = map_physmem(dest, len, MAP_NOCACHE); void *dst = dest;
void *dst2 = dst; void *dst2 = dst;
int flag = 0; int flag = 0;
uint offset = 0; uint offset = 0;
@ -1052,7 +1041,6 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
} }
out_unmap: out_unmap:
unmap_physmem(dst, len);
return retcode; return retcode;
} }
#endif /* CONFIG_SYS_FLASH_USE_BUFFER_WRITE */ #endif /* CONFIG_SYS_FLASH_USE_BUFFER_WRITE */
@ -1301,7 +1289,7 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
/* handle unaligned start */ /* handle unaligned start */
if ((aln = addr - wp) != 0) { if ((aln = addr - wp) != 0) {
cword.l = 0; cword.l = 0;
p = map_physmem(wp, info->portwidth, MAP_NOCACHE); p = (uchar *)wp;
for (i = 0; i < aln; ++i) for (i = 0; i < aln; ++i)
flash_add_byte (info, &cword, flash_read8(p + i)); flash_add_byte (info, &cword, flash_read8(p + i));
@ -1313,7 +1301,6 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
flash_add_byte (info, &cword, flash_read8(p + i)); flash_add_byte (info, &cword, flash_read8(p + i));
rc = flash_write_cfiword (info, wp, cword); rc = flash_write_cfiword (info, wp, cword);
unmap_physmem(p, info->portwidth);
if (rc != 0) if (rc != 0)
return rc; return rc;
@ -1372,14 +1359,13 @@ int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
* handle unaligned tail bytes * handle unaligned tail bytes
*/ */
cword.l = 0; cword.l = 0;
p = map_physmem(wp, info->portwidth, MAP_NOCACHE); p = (uchar *)wp;
for (i = 0; (i < info->portwidth) && (cnt > 0); ++i) { for (i = 0; (i < info->portwidth) && (cnt > 0); ++i) {
flash_add_byte (info, &cword, *src++); flash_add_byte (info, &cword, *src++);
--cnt; --cnt;
} }
for (; i < info->portwidth; ++i) for (; i < info->portwidth; ++i)
flash_add_byte (info, &cword, flash_read8(p + i)); flash_add_byte (info, &cword, flash_read8(p + i));
unmap_physmem(p, info->portwidth);
return flash_write_cfiword (info, wp, cword); return flash_write_cfiword (info, wp, cword);
} }
@ -1618,7 +1604,7 @@ static void flash_read_jedec_ids (flash_info_t * info)
* board_flash_get_legacy needs to fill in at least: * board_flash_get_legacy needs to fill in at least:
* info->portwidth, info->chipwidth and info->interface for Jedec probing. * info->portwidth, info->chipwidth and info->interface for Jedec probing.
*/ */
static int flash_detect_legacy(ulong base, int banknum) static int flash_detect_legacy(phys_addr_t base, int banknum)
{ {
flash_info_t *info = &flash_info[banknum]; flash_info_t *info = &flash_info[banknum];
@ -1634,7 +1620,10 @@ static int flash_detect_legacy(ulong base, int banknum)
for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++) { for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++) {
info->vendor = modes[i]; info->vendor = modes[i];
info->start[0] = base; info->start[0] =
(ulong)map_physmem(base,
info->portwith,
MAP_NOCACHE);
if (info->portwidth == FLASH_CFI_8BIT if (info->portwidth == FLASH_CFI_8BIT
&& info->interface == FLASH_CFI_X8X16) { && info->interface == FLASH_CFI_X8X16) {
info->addr_unlock1 = 0x2AAA; info->addr_unlock1 = 0x2AAA;
@ -1648,8 +1637,11 @@ static int flash_detect_legacy(ulong base, int banknum)
info->manufacturer_id, info->manufacturer_id,
info->device_id, info->device_id,
info->device_id2); info->device_id2);
if (jedec_flash_match(info, base)) if (jedec_flash_match(info, info->start[0]))
break; break;
else
unmap_physmem(info->start[0],
MAP_NOCACHE);
} }
} }
@ -1671,7 +1663,7 @@ static int flash_detect_legacy(ulong base, int banknum)
return 0; /* use CFI */ return 0; /* use CFI */
} }
#else #else
static inline int flash_detect_legacy(ulong base, int banknum) static inline int flash_detect_legacy(phys_addr_t base, int banknum)
{ {
return 0; /* use CFI */ return 0; /* use CFI */
} }
@ -1826,12 +1818,12 @@ static void flash_fixup_stm(flash_info_t *info, struct cfi_qry *qry)
* The following code cannot be run from FLASH! * The following code cannot be run from FLASH!
* *
*/ */
ulong flash_get_size (ulong base, int banknum) ulong flash_get_size (phys_addr_t base, int banknum)
{ {
flash_info_t *info = &flash_info[banknum]; flash_info_t *info = &flash_info[banknum];
int i, j; int i, j;
flash_sect_t sect_cnt; flash_sect_t sect_cnt;
unsigned long sector; phys_addr_t sector;
unsigned long tmp; unsigned long tmp;
int size_ratio; int size_ratio;
uchar num_erase_regions; uchar num_erase_regions;
@ -1847,7 +1839,7 @@ ulong flash_get_size (ulong base, int banknum)
info->legacy_unlock = 0; info->legacy_unlock = 0;
#endif #endif
info->start[0] = base; info->start[0] = (ulong)map_physmem(base, info->portwidth, MAP_NOCACHE);
if (flash_detect_cfi (info, &qry)) { if (flash_detect_cfi (info, &qry)) {
info->vendor = le16_to_cpu(qry.p_id); info->vendor = le16_to_cpu(qry.p_id);
@ -1939,7 +1931,10 @@ ulong flash_get_size (ulong base, int banknum)
printf("ERROR: too many flash sectors\n"); printf("ERROR: too many flash sectors\n");
break; break;
} }
info->start[sect_cnt] = sector; info->start[sect_cnt] =
(ulong)map_physmem(sector,
info->portwidth,
MAP_NOCACHE);
sector += (erase_region_size * size_ratio); sector += (erase_region_size * size_ratio);
/* /*
@ -2016,7 +2011,7 @@ unsigned long flash_init (void)
char *s = getenv("unlock"); char *s = getenv("unlock");
#endif #endif
#define BANK_BASE(i) (((unsigned long [CFI_MAX_FLASH_BANKS])CONFIG_SYS_FLASH_BANKS_LIST)[i]) #define BANK_BASE(i) (((phys_addr_t [CFI_MAX_FLASH_BANKS])CONFIG_SYS_FLASH_BANKS_LIST)[i])
/* Init: no FLASHes known */ /* Init: no FLASHes known */
for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) { for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {

@ -33,7 +33,7 @@ typedef struct {
ulong size; /* total bank size in bytes */ ulong size; /* total bank size in bytes */
ushort sector_count; /* number of erase units */ ushort sector_count; /* number of erase units */
ulong flash_id; /* combined device & manufacturer code */ ulong flash_id; /* combined device & manufacturer code */
ulong start[CONFIG_SYS_MAX_FLASH_SECT]; /* physical sector start addresses */ ulong start[CONFIG_SYS_MAX_FLASH_SECT]; /* virtual sector start address */
uchar protect[CONFIG_SYS_MAX_FLASH_SECT]; /* sector protection status */ uchar protect[CONFIG_SYS_MAX_FLASH_SECT]; /* sector protection status */
#ifdef CONFIG_SYS_FLASH_CFI #ifdef CONFIG_SYS_FLASH_CFI
uchar portwidth; /* the width of the port */ uchar portwidth; /* the width of the port */

Loading…
Cancel
Save