retval = ((flash_read16(addr) & cword.w) == cword.w);
break;
case FLASH_CFI_32BIT:
- retval = ((flash_read16(addr) & cword.l) == cword.l);
+ retval = ((flash_read32(addr) & cword.l) == cword.l);
break;
case FLASH_CFI_64BIT:
retval = ((flash_read64(addr) & cword.ll) == cword.ll);
}
if (!flag) {
unmap_physmem(dstaddr, info->portwidth);
- return 2;
+ return ERR_NOT_ERASED;
}
/* Disable interrupts which might cause a timeout here */
int retcode;
void *src = cp;
void *dst = map_physmem(dest, len, MAP_NOCACHE);
+ void *dst2 = dst;
+ int flag = 0;
+ switch (info->portwidth) {
+ case FLASH_CFI_8BIT:
+ cnt = len;
+ break;
+ case FLASH_CFI_16BIT:
+ cnt = len >> 1;
+ break;
+ case FLASH_CFI_32BIT:
+ cnt = len >> 2;
+ break;
+ case FLASH_CFI_64BIT:
+ cnt = len >> 3;
+ break;
+ default:
+ retcode = ERR_INVAL;
+ goto out_unmap;
+ }
+
+ while ((cnt-- > 0) && (flag == 0)) {
+ switch (info->portwidth) {
+ case FLASH_CFI_8BIT:
+ flag = ((flash_read8(dst2) & flash_read8(src)) ==
+ flash_read8(src));
+ src += 1, dst2 += 1;
+ break;
+ case FLASH_CFI_16BIT:
+ flag = ((flash_read16(dst2) & flash_read16(src)) ==
+ flash_read16(src));
+ src += 2, dst2 += 2;
+ break;
+ case FLASH_CFI_32BIT:
+ flag = ((flash_read32(dst2) & flash_read32(src)) ==
+ flash_read32(src));
+ src += 4, dst2 += 4;
+ break;
+ case FLASH_CFI_64BIT:
+ flag = ((flash_read64(dst2) & flash_read64(src)) ==
+ flash_read64(src));
+ src += 8, dst2 += 8;
+ break;
+ }
+ }
+ if (!flag) {
+ retcode = ERR_NOT_ERASED;
+ goto out_unmap;
+ }
+
+ src = cp;
sector = find_sector (info, dest);
switch (info->vendor) {
return;
}
+/*-----------------------------------------------------------------------
+ * This is used in a few places in write_buf() to show programming
+ * progress. Making it a function is nasty because it needs to do side
+ * effect updates to digit and dots. Repeated code is nasty too, so
+ * we define it once here.
+ */
+#ifdef CONFIG_FLASH_SHOW_PROGRESS
+#define FLASH_SHOW_PROGRESS(scale, dots, digit, dots_sub) \
+ dots -= dots_sub; \
+ if ((scale > 0) && (dots <= 0)) { \
+ if ((digit % 5) == 0) \
+ printf ("%d", digit / 5); \
+ else \
+ putc ('.'); \
+ digit--; \
+ dots += scale; \
+ }
+#else
+#define FLASH_SHOW_PROGRESS(scale, dots, digit, dots_sub)
+#endif
+
/*-----------------------------------------------------------------------
* Copy memory to flash, returns:
* 0 - OK
int aln;
cfiword_t cword;
int i, rc;
-
#ifdef CFG_FLASH_USE_BUFFER_WRITE
int buffered_size;
#endif
+#ifdef CONFIG_FLASH_SHOW_PROGRESS
+ int digit = CONFIG_FLASH_SHOW_PROGRESS;
+ int scale = 0;
+ int dots = 0;
+
+ /*
+ * Suppress if there are fewer than CONFIG_FLASH_SHOW_PROGRESS writes.
+ */
+ if (cnt >= CONFIG_FLASH_SHOW_PROGRESS) {
+ scale = (int)((cnt + CONFIG_FLASH_SHOW_PROGRESS - 1) /
+ CONFIG_FLASH_SHOW_PROGRESS);
+ }
+#endif
+
/* get lower aligned address */
wp = (addr & ~(info->portwidth - 1));
return rc;
wp += i;
+ FLASH_SHOW_PROGRESS(scale, dots, digit, i);
}
/* handle the aligned part */
wp += i;
src += i;
cnt -= i;
+ FLASH_SHOW_PROGRESS(scale, dots, digit, i);
}
#else
while (cnt >= info->portwidth) {
return rc;
wp += info->portwidth;
cnt -= info->portwidth;
+ FLASH_SHOW_PROGRESS(scale, dots, digit, info->portwidth);
}
#endif /* CFG_FLASH_USE_BUFFER_WRITE */
+
if (cnt == 0) {
return (0);
}
switch (info->vendor) {
case CFI_CMDSET_INTEL_STANDARD:
case CFI_CMDSET_INTEL_EXTENDED:
- flash_read_jedec_ids_intel(info);
+ cmdset_intel_read_jedec_ids(info);
break;
case CFI_CMDSET_AMD_STANDARD:
case CFI_CMDSET_AMD_EXTENDED:
- flash_read_jedec_ids_amd(info);
+ cmdset_amd_read_jedec_ids(info);
break;
default:
break;
{
int cfi_offset;
- flash_write_cmd (info, 0, 0, info->cmd_reset);
+ /* We do not yet know what kind of commandset to use, so we issue
+ the reset command in both Intel and AMD variants, in the hope
+ that AMD flash roms ignore the Intel command. */
+ flash_write_cmd (info, 0, 0, AMD_CMD_RESET);
+ flash_write_cmd (info, 0, 0, FLASH_CMD_RESET);
+
for (cfi_offset=0;
cfi_offset < sizeof(flash_offset_cfi) / sizeof(uint);
cfi_offset++) {