- 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:
mifi 2008-01-27 14:05:59 +00:00
parent 8d6292d9a0
commit c882cb0894
16 changed files with 1455 additions and 1335 deletions

View File

@ -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_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_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
int at91sam7_probe(struct flash_bank_s *bank); 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_erase_check(struct flash_bank_s *bank);
int at91sam7_protect_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); 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, .protect = at91sam7_protect,
.write = at91sam7_write, .write = at91sam7_write,
.probe = at91sam7_probe, .probe = at91sam7_probe,
.auto_probe = at91sam7_auto_probe,
.erase_check = at91sam7_erase_check, .erase_check = at91sam7_erase_check,
.protect_check = at91sam7_protect_check, .protect_check = at91sam7_protect_check,
.info = at91sam7_info .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)); at91sam7_info = malloc(sizeof(at91sam7_flash_bank_t));
bank->driver_priv = at91sam7_info; bank->driver_priv = at91sam7_info;
at91sam7_info->probed = 0;
/* part wasn't probed for info yet */ /* part wasn't probed for info yet */
at91sam7_info->cidr = 0; 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 * if this is an at91sam7, it has the configured flash
*/ */
at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv; at91sam7_flash_bank_t *at91sam7_info = bank->driver_priv;
at91sam7_info->probed = 0;
if (at91sam7_info->cidr == 0) if (at91sam7_info->cidr == 0)
{ {
@ -818,9 +822,20 @@ int at91sam7_probe(struct flash_bank_s *bank)
return ERROR_FLASH_OPERATION_FAILED; return ERROR_FLASH_OPERATION_FAILED;
} }
at91sam7_info->probed = 1;
return ERROR_OK; 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 at91sam7_info(struct flash_bank_s *bank, char *buf, int buf_size)
{ {
int printed, flashplane; int printed, flashplane;

View File

@ -60,6 +60,8 @@ typedef struct at91sam7_flash_bank_s
u8 mck_valid; u8 mck_valid;
u32 mck_freq; u32 mck_freq;
int probed;
} at91sam7_flash_bank_t; } at91sam7_flash_bank_t;
/* AT91SAM7 control registers */ /* AT91SAM7 control registers */

View File

@ -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_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_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
int cfi_probe(struct flash_bank_s *bank); 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_erase_check(struct flash_bank_s *bank);
int cfi_protect_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); 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, .protect = cfi_protect,
.write = cfi_write, .write = cfi_write,
.probe = cfi_probe, .probe = cfi_probe,
.auto_probe = cfi_auto_probe,
.erase_check = cfi_erase_check, .erase_check = cfi_erase_check,
.protect_check = cfi_protect_check, .protect_check = cfi_protect_check,
.info = cfi_info .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 = malloc(sizeof(cfi_flash_bank_t));
cfi_info->probed = 0;
bank->driver_priv = cfi_info; bank->driver_priv = cfi_info;
cfi_info->write_algorithm = NULL; cfi_info->write_algorithm = NULL;
@ -1864,6 +1867,8 @@ int cfi_probe(struct flash_bank_s *bank)
u32 unlock1 = 0x555; u32 unlock1 = 0x555;
u32 unlock2 = 0x2aa; u32 unlock2 = 0x2aa;
cfi_info->probed = 0;
/* JEDEC standard JESD21C uses 0x5555 and 0x2aaa as unlock addresses, /* JEDEC standard JESD21C uses 0x5555 and 0x2aaa as unlock addresses,
* while CFI compatible AMD/Spansion flashes use 0x555 and 0x2aa * 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; 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) int cfi_erase_check(struct flash_bank_s *bank)
{ {
cfi_flash_bank_t *cfi_info = bank->driver_priv; cfi_flash_bank_t *cfi_info = bank->driver_priv;

View File

@ -31,6 +31,7 @@ typedef struct cfi_flash_bank_s
int x16_as_x8; int x16_as_x8;
int jedec_probe; int jedec_probe;
int not_cfi; int not_cfi;
int probed;
u16 manufacturer; u16 manufacturer;
u16 device_id; u16 device_id;

View File

@ -127,7 +127,7 @@ int flash_init_drivers(struct command_context_s *cmd_ctx)
return ERROR_OK; 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; flash_bank_t *p;
int i = 0; int i = 0;
@ -143,6 +143,24 @@ flash_bank_t *get_flash_bank_by_num(int num)
return NULL; 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 ...] /* 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) 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; 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 (p)
{ {
if ((retval = p->driver->probe(p)) == ERROR_OK) 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 */ /* cycle through bank list */
for (c = flash_banks; c; c = c->next) 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 */ /* check whether address belongs to this flash bank */
if ((addr >= c->base) && (addr < c->base + c->size) && target == c->target) if ((addr >= c->base) && (addr < c->base + c->size) && target == c->target)
return c; return c;

View File

@ -47,6 +47,7 @@ typedef struct flash_driver_s
int (*erase_check)(struct flash_bank_s *bank); int (*erase_check)(struct flash_bank_s *bank);
int (*protect_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 (*info)(struct flash_bank_s *bank, char *buf, int buf_size);
int (*auto_probe)(struct flash_bank_s *bank);
} flash_driver_t; } flash_driver_t;
typedef struct flash_bank_s typedef struct flash_bank_s

View File

@ -72,6 +72,7 @@ flash_driver_t lpc2000_flash =
.protect = lpc2000_protect, .protect = lpc2000_protect,
.write = lpc2000_write, .write = lpc2000_write,
.probe = lpc2000_probe, .probe = lpc2000_probe,
.auto_probe = lpc2000_probe,
.erase_check = lpc2000_erase_check, .erase_check = lpc2000_erase_check,
.protect_check = lpc2000_protect_check, .protect_check = lpc2000_protect_check,
.info = lpc2000_info .info = lpc2000_info

View File

@ -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_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_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_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_probe(struct flash_bank_s *bank);
int stellaris_erase_check(struct flash_bank_s *bank); int stellaris_erase_check(struct flash_bank_s *bank);
int stellaris_protect_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, .protect = stellaris_protect,
.write = stellaris_write, .write = stellaris_write,
.probe = stellaris_probe, .probe = stellaris_probe,
.auto_probe = stellaris_auto_probe,
.erase_check = stellaris_erase_check, .erase_check = stellaris_erase_check,
.protect_check = stellaris_protect_check, .protect_check = stellaris_protect_check,
.info = stellaris_info .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_flash_bank_t *stellaris_info = bank->driver_priv;
stellaris_info->probed = 0;
if (stellaris_info->did1 == 0) if (stellaris_info->did1 == 0)
{ {
stellaris_read_part_info(bank); stellaris_read_part_info(bank);
@ -927,5 +931,15 @@ int stellaris_probe(struct flash_bank_s *bank)
return ERROR_FLASH_OPERATION_FAILED; return ERROR_FLASH_OPERATION_FAILED;
} }
stellaris_info->probed = 1;
return ERROR_OK; 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);
}

View File

@ -49,6 +49,8 @@ typedef struct stellaris_flash_bank_s
u8 mck_valid; u8 mck_valid;
u32 mck_freq; u32 mck_freq;
int probed;
} stellaris_flash_bank_t; } stellaris_flash_bank_t;
/* STELLARIS control registers */ /* STELLARIS control registers */

View File

@ -60,6 +60,7 @@ flash_driver_t stm32x_flash =
.protect = stm32x_protect, .protect = stm32x_protect,
.write = stm32x_write, .write = stm32x_write,
.probe = stm32x_probe, .probe = stm32x_probe,
.auto_probe = stm32x_probe,
.erase_check = stm32x_erase_check, .erase_check = stm32x_erase_check,
.protect_check = stm32x_protect_check, .protect_check = stm32x_protect_check,
.info = stm32x_info .info = stm32x_info

View File

@ -70,6 +70,7 @@ flash_driver_t str7x_flash =
.protect = str7x_protect, .protect = str7x_protect,
.write = str7x_write, .write = str7x_write,
.probe = str7x_probe, .probe = str7x_probe,
.auto_probe = str7x_probe,
.erase_check = str7x_erase_check, .erase_check = str7x_erase_check,
.protect_check = str7x_protect_check, .protect_check = str7x_protect_check,
.info = str7x_info .info = str7x_info

View File

@ -78,6 +78,7 @@ flash_driver_t str9x_flash =
.protect = str9x_protect, .protect = str9x_protect,
.write = str9x_write, .write = str9x_write,
.probe = str9x_probe, .probe = str9x_probe,
.auto_probe = str9x_probe,
.erase_check = str9x_erase_check, .erase_check = str9x_erase_check,
.protect_check = str9x_protect_check, .protect_check = str9x_protect_check,
.info = str9x_info .info = str9x_info

View File

@ -87,6 +87,7 @@ flash_driver_t str9xpec_flash =
.protect = str9xpec_protect, .protect = str9xpec_protect,
.write = str9xpec_write, .write = str9xpec_write,
.probe = str9xpec_probe, .probe = str9xpec_probe,
.auto_probe = str9xpec_probe,
.erase_check = str9xpec_erase_check, .erase_check = str9xpec_erase_check,
.protect_check = str9xpec_protect_check, .protect_check = str9xpec_protect_check,
.info = str9xpec_info .info = str9xpec_info

View File

@ -57,6 +57,9 @@ tms470_write( struct flash_bank_s *bank,
int int
tms470_probe( struct flash_bank_s *bank ); tms470_probe( struct flash_bank_s *bank );
int
tms470_auto_probe( struct flash_bank_s *bank );
int int
tms470_erase_check( struct flash_bank_s *bank ); tms470_erase_check( struct flash_bank_s *bank );
@ -77,6 +80,7 @@ flash_driver_t tms470_flash =
.protect = tms470_protect, .protect = tms470_protect,
.write = tms470_write, .write = tms470_write,
.probe = tms470_probe, .probe = tms470_probe,
.auto_probe = tms470_auto_probe,
.erase_check = tms470_erase_check, .erase_check = tms470_erase_check,
.protect_check = tms470_protect_check, .protect_check = tms470_protect_check,
.info = tms470_info .info = tms470_info
@ -1078,14 +1082,26 @@ tms470_probe( struct flash_bank_s * bank )
{ {
tms470_flash_bank_t * tms470_info = bank->driver_priv; tms470_flash_bank_t * tms470_info = bank->driver_priv;
tms470_info->probed = 0;
if (!tms470_info->device_ident_reg) if (!tms470_info->device_ident_reg)
{ {
tms470_read_part_info( bank ); tms470_read_part_info( bank );
} }
tms470_info->probed = 1;
return ERROR_OK; 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 int

View File

@ -34,6 +34,8 @@ typedef struct tms470_flash_bank_s
u32 rom_flash; u32 rom_flash;
u32 part_number; u32 part_number;
char * part_name; char * part_name;
int probed;
} tms470_flash_bank_t; } tms470_flash_bank_t;
#endif /* TMS470_DOT_H */ #endif /* TMS470_DOT_H */

View File

@ -1364,6 +1364,22 @@ static int decode_xfer_read (char *buf, char **annex, int *ofs, unsigned int *le
return 0; 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) int gdb_query_packet(connection_t *connection, target_t *target, char *packet, int packet_size)
{ {
command_context_t *cmd_ctx = connection->cmd_ctx; 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 offset;
int length; int length;
char *separator; char *separator;
int blocksize;
/* skip command character */ /* skip command character */
packet += 23; packet += 23;
@ -1486,10 +1503,14 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
if (p == NULL) if (p == NULL)
break; 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" \ xml_printf(&retval, &xml, &pos, &size, "<memory type=\"flash\" start=\"0x%x\" length=\"0x%x\">\n" \
"<property name=\"blocksize\">0x%x</property>\n" \ "<property name=\"blocksize\">0x%x</property>\n" \
"</memory>\n", \ "</memory>\n", \
p->base, p->size, p->size/p->num_sectors); p->base, p->size, blocksize);
i++; i++;
} }