int cfi_protect(struct flash_bank_s *bank, int set, int first, int last);
int cfi_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
int cfi_probe(struct flash_bank_s *bank);
+int cfi_auto_probe(struct flash_bank_s *bank);
int cfi_erase_check(struct flash_bank_s *bank);
int cfi_protect_check(struct flash_bank_s *bank);
int cfi_info(struct flash_bank_s *bank, char *buf, int buf_size);
.protect = cfi_protect,
.write = cfi_write,
.probe = cfi_probe,
+ .auto_probe = cfi_auto_probe,
.erase_check = cfi_erase_check,
.protect_check = cfi_protect_check,
.info = cfi_info
{CFI_MFR_SST, 0x00D5, cfi_fixup_non_cfi, NULL},
{CFI_MFR_SST, 0x00D6, cfi_fixup_non_cfi, NULL},
{CFI_MFR_SST, 0x00D7, cfi_fixup_non_cfi, NULL},
+ {CFI_MFR_SST, 0x2780, cfi_fixup_non_cfi, NULL},
{CFI_MFR_ST, 0x00D5, cfi_fixup_non_cfi, NULL},
{CFI_MFR_ST, 0x00D6, cfi_fixup_non_cfi, NULL},
{CFI_MFR_AMD, 0x2223, cfi_fixup_non_cfi, NULL},
{CFI_MFR_SST, 0x00D5, cfi_fixup_0002_unlock_addresses, &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]},
{CFI_MFR_SST, 0x00D6, cfi_fixup_0002_unlock_addresses, &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]},
{CFI_MFR_SST, 0x00D7, cfi_fixup_0002_unlock_addresses, &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]},
+ {CFI_MFR_SST, 0x2780, cfi_fixup_0002_unlock_addresses, &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]},
{CFI_MFR_ATMEL, 0x00C8, cfi_fixup_atmel_reversed_erase_regions, NULL},
{CFI_MFR_ANY, CFI_ID_ANY, cfi_fixup_0002_erase_regions, NULL},
{0, 0, NULL, NULL}
int cfi_register_commands(struct command_context_s *cmd_ctx)
{
- /*command_t *cfi_cmd = */register_command(cmd_ctx, NULL, "cfi", NULL, COMMAND_ANY, NULL);
+ /*command_t *cfi_cmd = */
+ register_command(cmd_ctx, NULL, "cfi", NULL, COMMAND_ANY, "flash bank cfi <base> <size> <chip_width> <bus_width> <targetNum> [jedec_probe/x16_as_x8]");
/*
register_command(cmd_ctx, cfi_cmd, "part_id", cfi_handle_part_id_command, COMMAND_EXEC,
"print part id of cfi flash bank <num>");
if ((strtoul(args[4], NULL, 0) > CFI_MAX_CHIP_WIDTH)
|| (strtoul(args[3], NULL, 0) > CFI_MAX_BUS_WIDTH))
{
- ERROR("chip and bus width have to specified in byte");
+ ERROR("chip and bus width have to specified in bytes");
return ERROR_FLASH_BANK_INVALID;
}
cfi_info = malloc(sizeof(cfi_flash_bank_t));
+ cfi_info->probed = 0;
bank->driver_priv = cfi_info;
-
- cfi_info->write_algorithm = NULL;
- cfi_info->erase_check_algorithm = NULL;
+
+ cfi_info->write_algorithm = NULL;
+ cfi_info->erase_check_algorithm = NULL;
cfi_info->x16_as_x8 = 0;
cfi_info->jedec_probe = 0;
/* FIXME Replace this by a simple memcpy() - still unsure about sideeffects */
static void cfi_add_byte(struct flash_bank_s *bank, u8 *word, u8 byte)
{
- target_t *target = bank->target;
+ //target_t *target = bank->target;
int i;
armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
armv4_5_info.core_state = ARMV4_5_STATE_ARM;
+ /* If we are setting up the write_algorith, we need target_code_src */
+ /* if not we only need target_code_size. */
+ /* */
+ /* However, we don't want to create multiple code paths, so we */
+ /* do the unecessary evaluation of target_code_src, which the */
+ /* compiler will probably nicely optimize away if not needed */
+
+ /* prepare algorithm code for target endian */
+ switch (bank->bus_width)
+ {
+ case 1 :
+ target_code_src = word_8_code;
+ target_code_size = sizeof(word_8_code);
+ break;
+ case 2 :
+ target_code_src = word_16_code;
+ target_code_size = sizeof(word_16_code);
+ break;
+ case 4 :
+ target_code_src = word_32_code;
+ target_code_size = sizeof(word_32_code);
+ break;
+ default:
+ ERROR("Unsupported bank buswidth %d, can't do block memory writes", bank->bus_width);
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+
/* flash write code */
if (!cfi_info->write_algorithm)
{
- /* prepare algorithm code for target endian */
- switch (bank->bus_width)
- {
- case 1 :
- target_code_src = word_8_code;
- target_code_size = sizeof(word_8_code);
- break;
- case 2 :
- target_code_src = word_16_code;
- target_code_size = sizeof(word_16_code);
- break;
- case 4 :
- target_code_src = word_32_code;
- target_code_size = sizeof(word_32_code);
- break;
- default:
- ERROR("Unsupported bank buswidth %d, can't do block memory writes", bank->bus_width);
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- }
if ( target_code_size > sizeof(target_code) )
{
WARNING("Internal error - target code buffer to small. Increase CFI_MAX_INTEL_CODESIZE and recompile.");
cfi_flash_bank_t *cfi_info = bank->driver_priv;
target_t *target = bank->target;
u8 command[8];
- int i;
/* Calculate buffer size and boundary mask */
u32 buffersize = 1UL << cfi_info->max_buf_write_size;
u32 unlock1 = 0x555;
u32 unlock2 = 0x2aa;
+ cfi_info->probed = 0;
+
/* JEDEC standard JESD21C uses 0x5555 and 0x2aaa as unlock addresses,
* while CFI compatible AMD/Spansion flashes use 0x555 and 0x2aa
*/
}
}
}
+
+ cfi_info->probed = 1;
return ERROR_OK;
}
+int cfi_auto_probe(struct flash_bank_s *bank)
+{
+ cfi_flash_bank_t *cfi_info = bank->driver_priv;
+ if (cfi_info->probed)
+ return ERROR_OK;
+ return cfi_probe(bank);
+}
+
int cfi_erase_check(struct flash_bank_s *bank)
{
cfi_flash_bank_t *cfi_info = bank->driver_priv;