u32 cidr, status;
int sectornum;
- if (bank->target->state != TARGET_HALTED)
- {
- return ERROR_TARGET_NOT_HALTED;
- }
-
/* Read and parse chip identification register */
target_read_u32(target, DBGU_CIDR, &cidr);
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
+ if (bank->target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
if (at91sam7_info->cidr == 0)
{
at91sam7_read_part_info(bank);
u32 first_page, last_page, pagen, buffer_pos;
u8 flashplane;
+ if (bank->target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
if (at91sam7_info->cidr == 0)
{
at91sam7_read_part_info(bank);
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
at91sam7_info->probed = 0;
+ if (bank->target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
if (at91sam7_info->cidr == 0)
{
at91sam7_read_part_info(bank);
int printed, flashplane;
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
+ if (bank->target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
at91sam7_read_part_info(bank);
if (at91sam7_info->cidr == 0)
#include "replacements.h"
#include "cfi.h"
+#include "non_cfi.h"
#include "flash.h"
#include "target.h"
};
/* CFI fixups foward declarations */
-void cfi_fixup_non_cfi(flash_bank_t *flash, void *param);
void cfi_fixup_0002_erase_regions(flash_bank_t *flash, void *param);
void cfi_fixup_0002_unlock_addresses(flash_bank_t *flash, void *param);
void cfi_fixup_atmel_reversed_erase_regions(flash_bank_t *flash, void *param);
/* 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;
- // NOTE:
- // The data to flash must not be changed in endian! We write a bytestrem in
- // target byte order already. Only the control and status byte lane of the flash
- // WSM is interpreted by the CPU in different ways, when read a u16 or u32
- // word (data seems to be in the upper or lower byte lane for u16 accesses).
+ /* NOTE:
+ * The data to flash must not be changed in endian! We write a bytestrem in
+ * target byte order already. Only the control and status byte lane of the flash
+ * WSM is interpreted by the CPU in different ways, when read a u16 or u32
+ * word (data seems to be in the upper or lower byte lane for u16 accesses).
+ */
- //if (target->endianness == TARGET_LITTLE_ENDIAN)
- //{
+#if 0
+ if (target->endianness == TARGET_LITTLE_ENDIAN)
+ {
+#endif
/* shift bytes */
for (i = 0; i < bank->bus_width - 1; i++)
word[i] = word[i + 1];
word[bank->bus_width - 1] = byte;
- //}
- //else
- //{
- // /* shift bytes */
- // for (i = bank->bus_width - 1; i > 0; i--)
- // word[i] = word[i - 1];
- // word[0] = byte;
- //}
+#if 0
+ }
+ else
+ {
+ /* shift bytes */
+ for (i = bank->bus_width - 1; i > 0; i--)
+ word[i] = word[i - 1];
+ word[0] = byte;
+ }
+#endif
}
/* Convert code image to target endian */
cfi_intel_clear_status_register(bank);
ERROR("Execution of flash algorythm failed. Can't fall back. Please report.");
retval = ERROR_FLASH_OPERATION_FAILED;
- //retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- // FIXME To allow fall back or recovery, we must save the actual status
- // somewhere, so that a higher level code can start recovery.
+ /* retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; */
+ /* FIXME To allow fall back or recovery, we must save the actual status
+ somewhere, so that a higher level code can start recovery. */
goto cleanup;
}
return cfi_intel_write_words(bank, word, wordcount, address);
break;
case 2:
- //return cfi_spansion_write_words(bank, word, address);
+ /* return cfi_spansion_write_words(bank, word, address); */
ERROR("cfi primary command set %i unimplemented - FIXME", cfi_info->pri_id);
break;
default:
int i;
int retval;
+ if (bank->target->state != TARGET_HALTED)
+ return ERROR_TARGET_NOT_HALTED;
+
if (offset + count > bank->size)
return ERROR_FLASH_DST_OUT_OF_BANK;
u32 unlock1 = 0x555;
u32 unlock2 = 0x2aa;
+ if (bank->target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
cfi_info->probed = 0;
/* JEDEC standard JESD21C uses 0x5555 and 0x2aaa as unlock addresses,
int i;
int retval;
+ if (bank->target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
if (!cfi_info->erase_check_algorithm)
{
u32 erase_check_code[] =
{
cfi_flash_bank_t *cfi_info = bank->driver_priv;
+ if (bank->target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
if (cfi_info->qry[0] != 'Q')
return ERROR_FLASH_BANK_NOT_PROBED;
return p;
}
}
- ERROR("Flash bank %d does not exist", num);
+ ERROR("flash bank %d does not exist", num);
return NULL;
}
char *name;
int (*register_commands)(struct command_context_s *cmd_ctx);
int (*flash_bank_command)(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
- /* low level flash erase. Only invoke from flash_driver_erase()
- *
- * Will only be invoked when target is halted.
- */
+
+ /* use flash_driver_erase() wrapper to invoke */
int (*erase)(struct flash_bank_s *bank, int first, int last);
- /* invoked only from flash_driver_protect().
- *
- * Only invoked if target is halted
- */
+
+ /* use flash_driver_protect() wrapper to invoke */
int (*protect)(struct flash_bank_s *bank, int set, int first, int last);
- /* low level flash write. Will only be invoked if the target is halted.
- * use the flash_driver_write() wrapper to invoke.
- */
+
+ /* use the flash_driver_write() wrapper to invoke. */
int (*write)(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
+
int (*probe)(struct flash_bank_s *bank);
int (*erase_check)(struct flash_bank_s *bank);
int (*protect_check)(struct flash_bank_s *bank);
u32 result_table[2];
int status_code;
+ if (bank->target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
param_table[0] = first;
param_table[1] = last;
param_table[2] = lpc2000_info->cclk;
int i;
working_area_t *download_area;
+ if (bank->target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
/* allocate a working area */
if (target_alloc_working_area(target, lpc2000_info->cmd51_max_buffer, &download_area) != ERROR_OK)
{
u32 param_table[5];
u32 result_table[2];
int status_code;
- lpc2000_flash_bank_t *lpc2000_info;
if (argc < 1)
{
return ERROR_OK;
}
- lpc2000_info = bank->driver_priv;
if (bank->target->state != TARGET_HALTED)
{
return ERROR_TARGET_NOT_HALTED;
int stellaris_flash_command(struct flash_bank_s *bank,u8 cmd,u16 pagen)
{
u32 fmc;
-// stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
target_t *target = bank->target;
fmc = FMC_WRKEY | cmd;
return ERROR_FLASH_OPERATION_FAILED;
}
+ if (did1 == 0)
+ {
+ WARNING("Cannot identify target as a Stellaris");
+ return ERROR_FLASH_OPERATION_FAILED;
+ }
+
ver = did1 >> 28;
fam = (did1 >> 24) & 0xF;
if(((ver != 0) && (ver != 1)) || (fam != 0))
WARNING("Unknown did1 version/family, cannot positively identify target as a Stellaris");
}
- if (did1 == 0)
- {
- WARNING("Cannot identify target as a Stellaris");
- return ERROR_FLASH_OPERATION_FAILED;
- }
-
for (i=0;StellarisParts[i].partno;i++)
{
if (StellarisParts[i].partno==((did1>>16)&0xFF))
stellaris_info->pages_in_lockregion = 2;
target_read_u32(target, SCB_BASE|FMPPE, &stellaris_info->lockbits);
- // Read main and master clock freqency register
+ /* Read main and master clock freqency register */
stellaris_read_clock_info(bank);
status = stellaris_get_flash_status(bank);
stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
+ if (bank->target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
if (stellaris_info->did1 == 0)
{
stellaris_read_part_info(bank);
stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
target_t *target = bank->target;
+ if (bank->target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
if (stellaris_info->did1 == 0)
{
stellaris_read_part_info(bank);
int stellaris_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 wcount)
{
-// stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
target_t *target = bank->target;
u32 buffer_size = 8192;
working_area_t *source;
u32 flash_cris,flash_fmc;
u32 retval;
+ if (bank->target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
DEBUG("(bank=%08X buffer=%08X offset=%08X count=%08X)",
(unsigned int)bank, (unsigned int)buffer, offset, count);
target_write_u32(target, FLASH_FMA, address);
target_write_buffer(target, FLASH_FMD, 4, buffer);
target_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_WRITE);
- //DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE);
+ /* DEBUG("0x%x 0x%x 0x%x",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */
/* Wait until write complete */
do
{
/* we can't probe on an stellaris
* if this is an stellaris, it has the configured flash
*/
- stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
- stellaris_info->probed = 0;
-
- if (stellaris_info->did1 == 0)
+ if (bank->target->state != TARGET_HALTED)
{
- stellaris_read_part_info(bank);
+ return ERROR_TARGET_NOT_HALTED;
}
- if (stellaris_info->did1 == 0)
- {
- WARNING("Cannot identify target as a LMI Stellaris");
- return ERROR_FLASH_OPERATION_FAILED;
- }
-
- stellaris_info->probed = 1;
-
- return ERROR_OK;
+ /* stellaris_read_part_info() already takes care about error checking and reporting */
+ return stellaris_read_part_info(bank);
}
int stellaris_auto_probe(struct flash_bank_s *bank)
{
stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
- if (stellaris_info->probed)
+ if (stellaris_info->did1)
return ERROR_OK;
return stellaris_probe(bank);
}
u8 mck_valid;
u32 mck_freq;
- int probed;
-
} stellaris_flash_bank_t;
/* STELLARIS control registers */
{
return ERROR_TARGET_NOT_HALTED;
}
-
+
buffer = malloc(256);
for (i = first; i <= last; i++)
int i;
u32 status;
+ if (bank->target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
/* unlock flash registers */
target_write_u32(target, STM32_FLASH_KEYR, KEY1);
target_write_u32(target, STM32_FLASH_KEYR, KEY2);
u8 status;
u32 retval;
+ if (bank->target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
if (offset & 0x1)
{
WARNING("offset 0x%x breaks required 2-byte alignment", offset);
u16 num_sectors;
u32 device_id;
+ if (bank->target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
stm32x_info->probed = 0;
/* read stm32 device id register */
u32 retval;
u32 b0_sectors = 0, b1_sectors = 0;
+ if (bank->target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
for (i = first; i <= last; i++)
{
if (str7x_info->sector_bank[i] == 0)
u32 check_address = offset;
int i;
+ if (bank->target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
if (offset & 0x7)
{
WARNING("offset 0x%x breaks required 8-byte alignment", offset);
while (dwords_remaining > 0)
{
- // command
+ /* command */
cmd = FLASH_DWPG;
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
- // address
+ /* address */
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
- // data word 1
+ /* data word 1 */
target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), 4, 1, buffer + bytes_written);
bytes_written += 4;
- // data word 2
+ /* data word 2 */
target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), 4, 1, buffer + bytes_written);
bytes_written += 4;
bytes_written++;
}
- // command
+ /* command */
cmd = FLASH_DWPG;
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
- // address
+ /* address */
target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
- // data word 1
+ /* data word 1 */
target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), 4, 1, last_dword);
bytes_written += 4;
- // data word 2
+ /* data word 2 */
target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), 4, 1, last_dword + 4);
bytes_written += 4;
u32 adr;
u8 status;
+ if (bank->target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
for (i = first; i <= last; i++)
{
adr = bank->base + bank->sectors[i].offset;
- /* erase sectors */
+ /* erase sectors */
target_write_u16(target, adr, 0x20);
target_write_u16(target, adr, 0xD0);
u32 bank_adr;
int i;
+ if (bank->target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
if (offset & 0x1)
{
WARNING("offset 0x%x breaks required 2-byte alignment", offset);
u32 part_number;
char *part_name;
- if (target->state != TARGET_HALTED)
- {
- WARNING("Cannot communicate... target not halted.");
- return ERROR_TARGET_NOT_HALTED;
- }
+ /* we shall not rely on the caller in this test, this function allocates memory,
+ thus and executing the code more than once may cause memory leak */
+ if (tms470_info->device_ident_reg)
+ return ERROR_OK;
/* read and parse the device identification register */
target_read_u32(target, 0xFFFFFFF0, &device_ident_reg);
tms470_flash_bank_t *tms470_info = bank->driver_priv;
int sector, result = ERROR_OK;
- if (!tms470_info->device_ident_reg)
+ if (bank->target->state != TARGET_HALTED)
{
- tms470_read_part_info(bank);
+ return ERROR_TARGET_NOT_HALTED;
}
+ tms470_read_part_info(bank);
+
if ((first < 0) || (first >= bank->num_sectors) || (last < 0) || (last >= bank->num_sectors) || (first > last))
{
ERROR("Sector range %d to %d invalid.", first, last);
u32 fmmac2, fmbsea, fmbseb;
int sector;
- if (!tms470_info->device_ident_reg)
+ if (target->state != TARGET_HALTED)
{
- tms470_read_part_info(bank);
+ return ERROR_TARGET_NOT_HALTED;
}
+ tms470_read_part_info(bank);
+
if ((first < 0) || (first >= bank->num_sectors) || (last < 0) || (last >= bank->num_sectors) || (first > last))
{
ERROR("Sector range %d to %d invalid.", first, last);
u32 glbctrl, fmbac2, orig_fmregopt, fmbsea, fmbseb, fmmaxpp, fmmstat;
int i, result = ERROR_OK;
- if (!tms470_info->device_ident_reg)
+ if (target->state != TARGET_HALTED)
{
- tms470_read_part_info(bank);
+ return ERROR_TARGET_NOT_HALTED;
}
+ tms470_read_part_info(bank);
+
INFO("Writing %d bytes starting at 0x%08x", count, bank->base + offset);
/* set GLBCTRL.4 */
int tms470_probe(struct flash_bank_s *bank)
{
- tms470_flash_bank_t *tms470_info = bank->driver_priv;
-
- tms470_info->probed = 0;
-
- if (!tms470_info->device_ident_reg)
+ if (bank->target->state != TARGET_HALTED)
{
- tms470_read_part_info(bank);
+ WARNING("Cannot communicate... target not halted.");
+ return ERROR_TARGET_NOT_HALTED;
}
- tms470_info->probed = 1;
-
- return ERROR_OK;
+ return tms470_read_part_info(bank);
}
int tms470_auto_probe(struct flash_bank_s *bank)
{
tms470_flash_bank_t *tms470_info = bank->driver_priv;
- if (tms470_info->probed)
+ if (tms470_info->device_ident_reg)
return ERROR_OK;
return tms470_probe(bank);
}
u32 fmmac2, fmbac2, glbctrl, orig_fmregopt;
static u8 buffer[64 * 1024];
+ if (target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
if (!tms470_info->device_ident_reg)
{
tms470_read_part_info(bank);
int sector, result = ERROR_OK;
u32 fmmac2, fmbsea, fmbseb;
+ if (target->state != TARGET_HALTED)
+ {
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
if (!tms470_info->device_ident_reg)
{
tms470_read_part_info(bank);
u32 part_number;
char * part_name;
- int probed;
} tms470_flash_bank_t;
#endif /* TMS470_DOT_H */