mirror of
git://git.code.sf.net/p/openocd/code
synced 2025-07-19 13:02:18 +10:00
Pavel Chromy: memory leak in at91sam7 flash driver, possible incorrect pointer conversion in gpnvm command handling,
uninitialized buffer issue in handle_flash_info_command in flash.c, some formatting. git-svn-id: svn://svn.berlios.de/openocd/trunk@446 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
parent
6d95014674
commit
f14f84ca1e
@ -77,7 +77,7 @@ flash_driver_t at91sam7_flash =
|
||||
.protect = at91sam7_protect,
|
||||
.write = at91sam7_write,
|
||||
.probe = at91sam7_probe,
|
||||
.auto_probe = at91sam7_auto_probe,
|
||||
.auto_probe = at91sam7_probe,
|
||||
.erase_check = at91sam7_erase_check,
|
||||
.protect_check = at91sam7_protect_check,
|
||||
.info = at91sam7_info
|
||||
@ -145,7 +145,7 @@ u32 at91sam7_get_flash_status(flash_bank_t *bank, u8 flashplane)
|
||||
return fsr;
|
||||
}
|
||||
|
||||
/** Read clock configuration and set at91sam7_info->usec_clocks*/
|
||||
/* Read clock configuration and set at91sam7_info->usec_clocks*/
|
||||
void at91sam7_read_clock_info(flash_bank_t *bank)
|
||||
{
|
||||
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
|
||||
@ -314,6 +314,9 @@ int at91sam7_read_part_info(struct flash_bank_s *bank)
|
||||
u32 cidr, status;
|
||||
int sectornum;
|
||||
|
||||
if (at91sam7_info->cidr != 0)
|
||||
return ERROR_OK; /* already probed, multiple probes may cause memory leak, not allowed */
|
||||
|
||||
/* Read and parse chip identification register */
|
||||
target_read_u32(target, DBGU_CIDR, &cidr);
|
||||
|
||||
@ -554,7 +557,6 @@ int at91sam7_read_part_info(struct flash_bank_s *bank)
|
||||
}
|
||||
|
||||
WARNING("at91sam7 flash only tested for AT91SAM7Sxx series");
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
@ -579,22 +581,16 @@ int at91sam7_protect_check(struct flash_bank_s *bank)
|
||||
|
||||
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
|
||||
|
||||
if (at91sam7_info->cidr == 0)
|
||||
{
|
||||
return ERROR_FLASH_BANK_NOT_PROBED;
|
||||
}
|
||||
|
||||
if (bank->target->state != TARGET_HALTED)
|
||||
{
|
||||
return ERROR_TARGET_NOT_HALTED;
|
||||
}
|
||||
|
||||
if (at91sam7_info->cidr == 0)
|
||||
{
|
||||
at91sam7_read_part_info(bank);
|
||||
}
|
||||
|
||||
if (at91sam7_info->cidr == 0)
|
||||
{
|
||||
WARNING("Cannot identify target as an AT91SAM");
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
for (flashplane=0;flashplane<at91sam7_info->num_planes;flashplane++)
|
||||
{
|
||||
status = at91sam7_get_flash_status(bank, flashplane);
|
||||
@ -619,7 +615,6 @@ int at91sam7_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, ch
|
||||
|
||||
at91sam7_info = malloc(sizeof(at91sam7_flash_bank_t));
|
||||
bank->driver_priv = at91sam7_info;
|
||||
at91sam7_info->probed = 0;
|
||||
|
||||
/* part wasn't probed for info yet */
|
||||
at91sam7_info->cidr = 0;
|
||||
@ -634,22 +629,16 @@ int at91sam7_erase(struct flash_bank_s *bank, int first, int last)
|
||||
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
|
||||
u8 flashplane;
|
||||
|
||||
if (at91sam7_info->cidr == 0)
|
||||
{
|
||||
return ERROR_FLASH_BANK_NOT_PROBED;
|
||||
}
|
||||
|
||||
if (bank->target->state != TARGET_HALTED)
|
||||
{
|
||||
return ERROR_TARGET_NOT_HALTED;
|
||||
}
|
||||
|
||||
if (at91sam7_info->cidr == 0)
|
||||
{
|
||||
at91sam7_read_part_info(bank);
|
||||
}
|
||||
|
||||
if (at91sam7_info->cidr == 0)
|
||||
{
|
||||
WARNING("Cannot identify target as an AT91SAM");
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
if ((first < 0) || (last < first) || (last >= bank->num_sectors))
|
||||
{
|
||||
if ((first == 0) && (last == (at91sam7_info->num_lockbits-1)))
|
||||
@ -683,6 +672,11 @@ int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last)
|
||||
|
||||
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
|
||||
|
||||
if (at91sam7_info->cidr == 0)
|
||||
{
|
||||
return ERROR_FLASH_BANK_NOT_PROBED;
|
||||
}
|
||||
|
||||
if (bank->target->state != TARGET_HALTED)
|
||||
{
|
||||
return ERROR_TARGET_NOT_HALTED;
|
||||
@ -693,17 +687,6 @@ int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last)
|
||||
return ERROR_FLASH_SECTOR_INVALID;
|
||||
}
|
||||
|
||||
if (at91sam7_info->cidr == 0)
|
||||
{
|
||||
at91sam7_read_part_info(bank);
|
||||
}
|
||||
|
||||
if (at91sam7_info->cidr == 0)
|
||||
{
|
||||
WARNING("Cannot identify target as an AT91SAM");
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
at91sam7_read_clock_info(bank);
|
||||
|
||||
for (lockregion=first;lockregion<=last;lockregion++)
|
||||
@ -738,22 +721,16 @@ int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
|
||||
u32 first_page, last_page, pagen, buffer_pos;
|
||||
u8 flashplane;
|
||||
|
||||
if (at91sam7_info->cidr == 0)
|
||||
{
|
||||
return ERROR_FLASH_BANK_NOT_PROBED;
|
||||
}
|
||||
|
||||
if (bank->target->state != TARGET_HALTED)
|
||||
{
|
||||
return ERROR_TARGET_NOT_HALTED;
|
||||
}
|
||||
|
||||
if (at91sam7_info->cidr == 0)
|
||||
{
|
||||
at91sam7_read_part_info(bank);
|
||||
}
|
||||
|
||||
if (at91sam7_info->cidr == 0)
|
||||
{
|
||||
WARNING("Cannot identify target as an AT91SAM");
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
if (offset + count > bank->size)
|
||||
return ERROR_FLASH_DST_OUT_OF_BANK;
|
||||
|
||||
@ -809,56 +786,34 @@ int at91sam7_probe(struct flash_bank_s *bank)
|
||||
* if this is an at91sam7, it has the configured flash
|
||||
*/
|
||||
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
|
||||
at91sam7_info->probed = 0;
|
||||
int retval;
|
||||
|
||||
if (at91sam7_info->cidr != 0)
|
||||
{
|
||||
return ERROR_OK; /* already probed */
|
||||
}
|
||||
|
||||
if (bank->target->state != TARGET_HALTED)
|
||||
{
|
||||
return ERROR_TARGET_NOT_HALTED;
|
||||
}
|
||||
|
||||
if (at91sam7_info->cidr == 0)
|
||||
{
|
||||
at91sam7_read_part_info(bank);
|
||||
}
|
||||
|
||||
if (at91sam7_info->cidr == 0)
|
||||
{
|
||||
WARNING("Cannot identify target as an AT91SAM");
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
at91sam7_info->probed = 1;
|
||||
retval = at91sam7_read_part_info(bank);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
int at91sam7_auto_probe(struct flash_bank_s *bank)
|
||||
{
|
||||
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
|
||||
if (at91sam7_info->probed)
|
||||
return ERROR_OK;
|
||||
return at91sam7_probe(bank);
|
||||
}
|
||||
|
||||
int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size)
|
||||
{
|
||||
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)
|
||||
{
|
||||
printed = snprintf(buf, buf_size, "Cannot identify target as an AT91SAM\n");
|
||||
buf += printed;
|
||||
buf_size -= printed;
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
return ERROR_FLASH_BANK_NOT_PROBED;
|
||||
}
|
||||
|
||||
printed = snprintf(buf, buf_size, "\nat91sam7 information: Chip is %s\n",at91sam7_info->target_name);
|
||||
@ -894,7 +849,7 @@ int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size)
|
||||
buf_size -= printed;
|
||||
}
|
||||
|
||||
printed = snprintf(buf, buf_size, "securitybit: %i, nvmbits: 0x%1.1x\n", at91sam7_info->securitybit, at91sam7_info->nvmbits);
|
||||
printed = snprintf(buf, buf_size, "securitybit: %i, nvmbits(%i): 0x%1.1x\n", at91sam7_info->securitybit, at91sam7_info->num_nvmbits, at91sam7_info->nvmbits);
|
||||
buf += printed;
|
||||
buf_size -= printed;
|
||||
|
||||
@ -919,6 +874,7 @@ int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd,
|
||||
u32 status;
|
||||
char *value;
|
||||
at91sam7_flash_bank_t *at91sam7_info;
|
||||
int retval;
|
||||
|
||||
if (argc < 3)
|
||||
{
|
||||
@ -926,38 +882,19 @@ int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd,
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
|
||||
bank = get_flash_bank_by_num_noprobe(strtoul(args[0], NULL, 0));
|
||||
bit = atoi(args[1]);
|
||||
value = args[2];
|
||||
|
||||
if (!bank)
|
||||
if (bank == NULL)
|
||||
{
|
||||
command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
|
||||
return ERROR_OK;
|
||||
return ERROR_FLASH_BANK_INVALID;
|
||||
}
|
||||
|
||||
at91sam7_info = bank->driver_priv;
|
||||
|
||||
if (bank->target->state != TARGET_HALTED)
|
||||
if (bank->driver != &at91sam7_flash)
|
||||
{
|
||||
return ERROR_TARGET_NOT_HALTED;
|
||||
}
|
||||
|
||||
if (at91sam7_info->cidr == 0)
|
||||
{
|
||||
at91sam7_read_part_info(bank);
|
||||
}
|
||||
|
||||
if (at91sam7_info->cidr == 0)
|
||||
{
|
||||
WARNING("Cannot identify target as an AT91SAM");
|
||||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
if ((bit<0) || (at91sam7_info->num_nvmbits <= bit))
|
||||
{
|
||||
command_print(cmd_ctx, "gpnvm bit '#%s' is out of bounds for target %s", args[1],at91sam7_info->target_name);
|
||||
return ERROR_OK;
|
||||
command_print(cmd_ctx, "not an at91sam7 flash bank '%s'", args[0]);
|
||||
return ERROR_FLASH_BANK_INVALID;
|
||||
}
|
||||
|
||||
if (strcmp(value, "set") == 0)
|
||||
@ -973,6 +910,28 @@ int at91sam7_handle_gpnvm_command(struct command_context_s *cmd_ctx, char *cmd,
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
at91sam7_info = bank->driver_priv;
|
||||
|
||||
if (bank->target->state != TARGET_HALTED)
|
||||
{
|
||||
ERROR("target has to be halted to perform flash operation");
|
||||
return ERROR_TARGET_NOT_HALTED;
|
||||
}
|
||||
|
||||
if (at91sam7_info->cidr == 0)
|
||||
{
|
||||
retval = at91sam7_read_part_info(bank);
|
||||
if (retval != ERROR_OK) {
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
if ((bit<0) || (at91sam7_info->num_nvmbits <= bit))
|
||||
{
|
||||
command_print(cmd_ctx, "gpnvm bit '#%s' is out of bounds for target %s", args[1],at91sam7_info->target_name);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/* Configure the flash controller timing */
|
||||
at91sam7_read_clock_info(bank);
|
||||
at91sam7_set_flash_mode(bank, 0, FMR_TIMING_NVBITS);
|
||||
|
@ -60,8 +60,6 @@ typedef struct at91sam7_flash_bank_s
|
||||
u8 mck_valid;
|
||||
u32 mck_freq;
|
||||
|
||||
int probed;
|
||||
|
||||
} at91sam7_flash_bank_t;
|
||||
|
||||
/* AT91SAM7 control registers */
|
||||
|
@ -93,7 +93,7 @@ static int flash_driver_write(struct flash_bank_s *bank, u8 *buffer, u32 offset,
|
||||
retval=bank->driver->write(bank, buffer, offset, count);
|
||||
if (retval!=ERROR_OK)
|
||||
{
|
||||
ERROR("error writing to flash at address 0x%08x at offset 0x%8.8x", bank->base, offset);
|
||||
ERROR("error writing to flash at address 0x%08x at offset 0x%8.8x (%d)", bank->base, offset, retval);
|
||||
}
|
||||
|
||||
return retval;
|
||||
@ -106,7 +106,7 @@ static int flash_driver_erase(struct flash_bank_s *bank, int first, int last)
|
||||
retval=bank->driver->erase(bank, first, last);
|
||||
if (retval!=ERROR_OK)
|
||||
{
|
||||
ERROR("failed erasing sectors %d to %d", first, last);
|
||||
ERROR("failed erasing sectors %d to %d (%d)", first, last, retval);
|
||||
}
|
||||
|
||||
return retval;
|
||||
@ -119,7 +119,7 @@ int flash_driver_protect(struct flash_bank_s *bank, int set, int first, int last
|
||||
retval=bank->driver->protect(bank, set, first, last);
|
||||
if (retval!=ERROR_OK)
|
||||
{
|
||||
ERROR("failed setting protection for areas %d to %d", first, last);
|
||||
ERROR("failed setting protection for areas %d to %d (%d)", first, last, retval);
|
||||
}
|
||||
|
||||
return retval;
|
||||
@ -311,6 +311,7 @@ int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char
|
||||
flash_bank_t *p;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int retval;
|
||||
|
||||
if (argc != 1)
|
||||
{
|
||||
@ -351,8 +352,11 @@ int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char
|
||||
erase_state, protect_state);
|
||||
}
|
||||
|
||||
p->driver->info(p, buf, 1024);
|
||||
*buf = '\0'; /* initialize buffer, otherwise it migh contain garbage if driver function fails */
|
||||
retval = p->driver->info(p, buf, sizeof(buf));
|
||||
command_print(cmd_ctx, "%s", buf);
|
||||
if (retval != ERROR_OK)
|
||||
ERROR("error retrieving flash info (%d)", retval);
|
||||
}
|
||||
}
|
||||
|
||||
@ -918,7 +922,6 @@ int handle_flash_auto_erase_command(struct command_context_s *cmd_ctx, char *cmd
|
||||
if (argc != 1)
|
||||
{
|
||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||
|
||||
}
|
||||
|
||||
if (strcmp(args[0], "on") == 0)
|
||||
|
@ -80,6 +80,7 @@ extern void flash_set_dirty(void);
|
||||
extern int flash_get_bank_count();
|
||||
|
||||
extern flash_bank_t *get_flash_bank_by_num(int num);
|
||||
extern flash_bank_t *get_flash_bank_by_num_noprobe(int num);
|
||||
extern flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr);
|
||||
|
||||
#define ERROR_FLASH_BANK_INVALID (-900)
|
||||
|
Loading…
Reference in New Issue
Block a user