- added autoprobe functionality
- corrected blocksize handling from GDB "info mem" command (thanks to Øyvind and Spen for these patches) git-svn-id: svn://svn.berlios.de/openocd/trunk@278 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
parent
8d6292d9a0
commit
c882cb0894
|
@ -57,6 +57,7 @@ int at91sam7_erase(struct flash_bank_s *bank, int first, int last);
|
|||
int at91sam7_protect(struct flash_bank_s *bank, int set, int first, int last);
|
||||
int at91sam7_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
|
||||
int at91sam7_probe(struct flash_bank_s *bank);
|
||||
int at91sam7_auto_probe(struct flash_bank_s *bank);
|
||||
int at91sam7_erase_check(struct flash_bank_s *bank);
|
||||
int at91sam7_protect_check(struct flash_bank_s *bank);
|
||||
int at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size);
|
||||
|
@ -76,6 +77,7 @@ flash_driver_t at91sam7_flash =
|
|||
.protect = at91sam7_protect,
|
||||
.write = at91sam7_write,
|
||||
.probe = at91sam7_probe,
|
||||
.auto_probe = at91sam7_auto_probe,
|
||||
.erase_check = at91sam7_erase_check,
|
||||
.protect_check = at91sam7_protect_check,
|
||||
.info = at91sam7_info
|
||||
|
@ -617,6 +619,7 @@ 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;
|
||||
|
@ -806,6 +809,7 @@ 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;
|
||||
|
||||
if (at91sam7_info->cidr == 0)
|
||||
{
|
||||
|
@ -818,9 +822,20 @@ int at91sam7_probe(struct flash_bank_s *bank)
|
|||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
at91sam7_info->probed = 1;
|
||||
|
||||
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;
|
||||
|
|
|
@ -60,6 +60,8 @@ typedef struct at91sam7_flash_bank_s
|
|||
u8 mck_valid;
|
||||
u32 mck_freq;
|
||||
|
||||
int probed;
|
||||
|
||||
} at91sam7_flash_bank_t;
|
||||
|
||||
/* AT91SAM7 control registers */
|
||||
|
|
|
@ -43,6 +43,7 @@ int cfi_erase(struct flash_bank_s *bank, int first, int last);
|
|||
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);
|
||||
|
@ -64,6 +65,7 @@ flash_driver_t cfi_flash =
|
|||
.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
|
||||
|
@ -617,6 +619,7 @@ int cfi_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **
|
|||
}
|
||||
|
||||
cfi_info = malloc(sizeof(cfi_flash_bank_t));
|
||||
cfi_info->probed = 0;
|
||||
bank->driver_priv = cfi_info;
|
||||
|
||||
cfi_info->write_algorithm = NULL;
|
||||
|
@ -1864,6 +1867,8 @@ int cfi_probe(struct flash_bank_s *bank)
|
|||
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
|
||||
*/
|
||||
|
@ -2072,9 +2077,19 @@ int cfi_probe(struct flash_bank_s *bank)
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -31,6 +31,7 @@ typedef struct cfi_flash_bank_s
|
|||
int x16_as_x8;
|
||||
int jedec_probe;
|
||||
int not_cfi;
|
||||
int probed;
|
||||
|
||||
u16 manufacturer;
|
||||
u16 device_id;
|
||||
|
|
|
@ -127,7 +127,7 @@ int flash_init_drivers(struct command_context_s *cmd_ctx)
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
flash_bank_t *get_flash_bank_by_num(int num)
|
||||
flash_bank_t *get_flash_bank_by_num_noprobe(int num)
|
||||
{
|
||||
flash_bank_t *p;
|
||||
int i = 0;
|
||||
|
@ -143,6 +143,24 @@ flash_bank_t *get_flash_bank_by_num(int num)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
flash_bank_t *get_flash_bank_by_num(int num)
|
||||
{
|
||||
flash_bank_t *p = get_flash_bank_by_num_noprobe(num);
|
||||
int retval;
|
||||
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
|
||||
retval = p->driver->auto_probe(p);
|
||||
|
||||
if (retval != ERROR_OK)
|
||||
{
|
||||
ERROR("auto_probe failed %d\n", retval);
|
||||
return NULL;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/* flash_bank <driver> <base> <size> <chip_width> <bus_width> <target> [driver_options ...]
|
||||
*/
|
||||
int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
||||
|
@ -305,7 +323,7 @@ int handle_flash_probe_command(struct command_context_s *cmd_ctx, char *cmd, cha
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
p = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
|
||||
p = get_flash_bank_by_num_noprobe(strtoul(args[0], NULL, 0));
|
||||
if (p)
|
||||
{
|
||||
if ((retval = p->driver->probe(p)) == ERROR_OK)
|
||||
|
@ -794,6 +812,14 @@ flash_bank_t *get_flash_bank_by_addr(target_t *target, u32 addr)
|
|||
/* cycle through bank list */
|
||||
for (c = flash_banks; c; c = c->next)
|
||||
{
|
||||
int retval;
|
||||
retval = c->driver->auto_probe(c);
|
||||
|
||||
if (retval != ERROR_OK)
|
||||
{
|
||||
ERROR("auto_probe failed %d\n", retval);
|
||||
return NULL;
|
||||
}
|
||||
/* check whether address belongs to this flash bank */
|
||||
if ((addr >= c->base) && (addr < c->base + c->size) && target == c->target)
|
||||
return c;
|
||||
|
|
|
@ -47,6 +47,7 @@ typedef struct flash_driver_s
|
|||
int (*erase_check)(struct flash_bank_s *bank);
|
||||
int (*protect_check)(struct flash_bank_s *bank);
|
||||
int (*info)(struct flash_bank_s *bank, char *buf, int buf_size);
|
||||
int (*auto_probe)(struct flash_bank_s *bank);
|
||||
} flash_driver_t;
|
||||
|
||||
typedef struct flash_bank_s
|
||||
|
|
|
@ -72,6 +72,7 @@ flash_driver_t lpc2000_flash =
|
|||
.protect = lpc2000_protect,
|
||||
.write = lpc2000_write,
|
||||
.probe = lpc2000_probe,
|
||||
.auto_probe = lpc2000_probe,
|
||||
.erase_check = lpc2000_erase_check,
|
||||
.protect_check = lpc2000_protect_check,
|
||||
.info = lpc2000_info
|
||||
|
|
|
@ -49,6 +49,7 @@ int stellaris_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, c
|
|||
int stellaris_erase(struct flash_bank_s *bank, int first, int last);
|
||||
int stellaris_protect(struct flash_bank_s *bank, int set, int first, int last);
|
||||
int stellaris_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
|
||||
int stellaris_auto_probe(struct flash_bank_s *bank);
|
||||
int stellaris_probe(struct flash_bank_s *bank);
|
||||
int stellaris_erase_check(struct flash_bank_s *bank);
|
||||
int stellaris_protect_check(struct flash_bank_s *bank);
|
||||
|
@ -70,6 +71,7 @@ flash_driver_t stellaris_flash =
|
|||
.protect = stellaris_protect,
|
||||
.write = stellaris_write,
|
||||
.probe = stellaris_probe,
|
||||
.auto_probe = stellaris_auto_probe,
|
||||
.erase_check = stellaris_erase_check,
|
||||
.protect_check = stellaris_protect_check,
|
||||
.info = stellaris_info
|
||||
|
@ -916,6 +918,8 @@ int stellaris_probe(struct flash_bank_s *bank)
|
|||
*/
|
||||
stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
|
||||
|
||||
stellaris_info->probed = 0;
|
||||
|
||||
if (stellaris_info->did1 == 0)
|
||||
{
|
||||
stellaris_read_part_info(bank);
|
||||
|
@ -927,5 +931,15 @@ int stellaris_probe(struct flash_bank_s *bank)
|
|||
return ERROR_FLASH_OPERATION_FAILED;
|
||||
}
|
||||
|
||||
stellaris_info->probed = 1;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int stellaris_auto_probe(struct flash_bank_s *bank)
|
||||
{
|
||||
stellaris_flash_bank_t *stellaris_info = bank->driver_priv;
|
||||
if (stellaris_info->probed)
|
||||
return ERROR_OK;
|
||||
return stellaris_probe(bank);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,8 @@ typedef struct stellaris_flash_bank_s
|
|||
u8 mck_valid;
|
||||
u32 mck_freq;
|
||||
|
||||
int probed;
|
||||
|
||||
} stellaris_flash_bank_t;
|
||||
|
||||
/* STELLARIS control registers */
|
||||
|
|
|
@ -60,6 +60,7 @@ flash_driver_t stm32x_flash =
|
|||
.protect = stm32x_protect,
|
||||
.write = stm32x_write,
|
||||
.probe = stm32x_probe,
|
||||
.auto_probe = stm32x_probe,
|
||||
.erase_check = stm32x_erase_check,
|
||||
.protect_check = stm32x_protect_check,
|
||||
.info = stm32x_info
|
||||
|
|
|
@ -70,6 +70,7 @@ flash_driver_t str7x_flash =
|
|||
.protect = str7x_protect,
|
||||
.write = str7x_write,
|
||||
.probe = str7x_probe,
|
||||
.auto_probe = str7x_probe,
|
||||
.erase_check = str7x_erase_check,
|
||||
.protect_check = str7x_protect_check,
|
||||
.info = str7x_info
|
||||
|
|
|
@ -78,6 +78,7 @@ flash_driver_t str9x_flash =
|
|||
.protect = str9x_protect,
|
||||
.write = str9x_write,
|
||||
.probe = str9x_probe,
|
||||
.auto_probe = str9x_probe,
|
||||
.erase_check = str9x_erase_check,
|
||||
.protect_check = str9x_protect_check,
|
||||
.info = str9x_info
|
||||
|
|
|
@ -87,6 +87,7 @@ flash_driver_t str9xpec_flash =
|
|||
.protect = str9xpec_protect,
|
||||
.write = str9xpec_write,
|
||||
.probe = str9xpec_probe,
|
||||
.auto_probe = str9xpec_probe,
|
||||
.erase_check = str9xpec_erase_check,
|
||||
.protect_check = str9xpec_protect_check,
|
||||
.info = str9xpec_info
|
||||
|
|
|
@ -57,6 +57,9 @@ tms470_write( struct flash_bank_s *bank,
|
|||
int
|
||||
tms470_probe( struct flash_bank_s *bank );
|
||||
|
||||
int
|
||||
tms470_auto_probe( struct flash_bank_s *bank );
|
||||
|
||||
int
|
||||
tms470_erase_check( struct flash_bank_s *bank );
|
||||
|
||||
|
@ -77,6 +80,7 @@ flash_driver_t tms470_flash =
|
|||
.protect = tms470_protect,
|
||||
.write = tms470_write,
|
||||
.probe = tms470_probe,
|
||||
.auto_probe = tms470_auto_probe,
|
||||
.erase_check = tms470_erase_check,
|
||||
.protect_check = tms470_protect_check,
|
||||
.info = tms470_info
|
||||
|
@ -1078,14 +1082,26 @@ 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)
|
||||
{
|
||||
tms470_read_part_info( bank );
|
||||
}
|
||||
|
||||
tms470_info->probed = 1;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int
|
||||
tms470_auto_probe( struct flash_bank_s * bank )
|
||||
{
|
||||
tms470_flash_bank_t * tms470_info = bank->driver_priv;
|
||||
if (tms470_info->probed)
|
||||
return ERROR_OK;
|
||||
return tms470_probe(bank);
|
||||
}
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
int
|
||||
|
|
|
@ -34,6 +34,8 @@ typedef struct tms470_flash_bank_s
|
|||
u32 rom_flash;
|
||||
u32 part_number;
|
||||
char * part_name;
|
||||
|
||||
int probed;
|
||||
} tms470_flash_bank_t;
|
||||
|
||||
#endif /* TMS470_DOT_H */
|
||||
|
|
|
@ -1364,6 +1364,22 @@ static int decode_xfer_read (char *buf, char **annex, int *ofs, unsigned int *le
|
|||
return 0;
|
||||
}
|
||||
|
||||
int gdb_calc_blocksize(flash_bank_t *bank)
|
||||
{
|
||||
int i;
|
||||
int block_size = 0xffffffff;
|
||||
|
||||
/* loop through all sectors and return smallest sector size */
|
||||
|
||||
for (i = 0; i < bank->num_sectors; i++)
|
||||
{
|
||||
if (bank->sectors[i].size < block_size)
|
||||
block_size = bank->sectors[i].size;
|
||||
}
|
||||
|
||||
return block_size;
|
||||
}
|
||||
|
||||
int gdb_query_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
|
||||
{
|
||||
command_context_t *cmd_ctx = connection->cmd_ctx;
|
||||
|
@ -1470,6 +1486,7 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
|
|||
int offset;
|
||||
int length;
|
||||
char *separator;
|
||||
int blocksize;
|
||||
|
||||
/* skip command character */
|
||||
packet += 23;
|
||||
|
@ -1486,10 +1503,14 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
|
|||
if (p == NULL)
|
||||
break;
|
||||
|
||||
/* if device has uneven sector sizes, eg. str7, lpc
|
||||
* we pass the smallest sector size to gdb memory map */
|
||||
blocksize = gdb_calc_blocksize(p);
|
||||
|
||||
xml_printf(&retval, &xml, &pos, &size, "<memory type=\"flash\" start=\"0x%x\" length=\"0x%x\">\n" \
|
||||
"<property name=\"blocksize\">0x%x</property>\n" \
|
||||
"</memory>\n", \
|
||||
p->base, p->size, p->size/p->num_sectors);
|
||||
p->base, p->size, blocksize);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue