- 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_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;

View File

@ -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 */

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_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
*/
@ -2071,10 +2076,20 @@ 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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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
@ -185,7 +186,7 @@ int lpc2000_build_sector_list(struct flash_bank_s *bank)
bank->num_sectors = num_sectors;
bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
for (i = 0; i < num_sectors; i++)
{
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_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);
}

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

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