- 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
*/ */
@ -2071,10 +2076,20 @@ 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
@ -185,7 +186,7 @@ int lpc2000_build_sector_list(struct flash_bank_s *bank)
bank->num_sectors = num_sectors; bank->num_sectors = num_sectors;
bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors); bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
for (i = 0; i < num_sectors; i++) for (i = 0; i < num_sectors; i++)
{ {
if ((i >= 0) && (i < 8)) if ((i >= 0) && (i < 8))

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

File diff suppressed because it is too large Load Diff

View File

@ -1,39 +1,41 @@
/*************************************************************************** /***************************************************************************
* (c) Copyright 2007, 2008 by Christopher Kilgour * * (c) Copyright 2007, 2008 by Christopher Kilgour *
* techie |_at_| whiterocker |_dot_| com * * techie |_at_| whiterocker |_dot_| com *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. * * GNU General Public License for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the * * along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef TMS470_DOT_H #ifndef TMS470_DOT_H
#define TMS470_DOT_H #define TMS470_DOT_H
#include "flash.h" #include "flash.h"
typedef struct tms470_flash_bank_s typedef struct tms470_flash_bank_s
{ {
unsigned ordinal; unsigned ordinal;
/* device identification register */ /* device identification register */
u32 device_ident_reg; u32 device_ident_reg;
u32 silicon_version; u32 silicon_version;
u32 technology_family; u32 technology_family;
u32 rom_flash; u32 rom_flash;
u32 part_number; u32 part_number;
char * part_name; char * part_name;
} tms470_flash_bank_t;
int probed;
#endif /* TMS470_DOT_H */ } tms470_flash_bank_t;
#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++;
} }