From 3d026ce94393e5e53cccb5d5364f9d500d5b3733 Mon Sep 17 00:00:00 2001 From: drath Date: Fri, 15 Jun 2007 14:10:23 +0000 Subject: [PATCH] - added support for pseudo image type "mem", currently only used for etm analysis: "etm image mem" git-svn-id: svn://svn.berlios.de/openocd/trunk@173 b42882b7-edfa-0310-969c-e2dbd0fdcd60 --- src/openocd.c | 2 +- src/target/etm.c | 22 ++++++++--------- src/target/image.c | 61 ++++++++++++++++++++++++++++++++++++++-------- src/target/image.h | 7 +++++- 4 files changed, 69 insertions(+), 23 deletions(-) diff --git a/src/openocd.c b/src/openocd.c index ac8e2fea0..76cc3d8d6 100644 --- a/src/openocd.c +++ b/src/openocd.c @@ -18,7 +18,7 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#define OPENOCD_VERSION "Open On-Chip Debugger (2007-06-14 12:00 CEST)" +#define OPENOCD_VERSION "Open On-Chip Debugger (2007-06-15 16:00 CEST)" #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/src/target/etm.c b/src/target/etm.c index a775bbd1f..dd6e6025d 100644 --- a/src/target/etm.c +++ b/src/target/etm.c @@ -1313,7 +1313,7 @@ int handle_etm_image_command(struct command_context_s *cmd_ctx, char *cmd, char if (argc < 1) { - command_print(cmd_ctx, "usage: etm image ['bin'|'ihex'|'elf'] [base address]"); + command_print(cmd_ctx, "usage: etm image [base address] [type]"); return ERROR_OK; } @@ -1342,18 +1342,18 @@ int handle_etm_image_command(struct command_context_s *cmd_ctx, char *cmd, char etm_ctx->image->base_address_set = 0; etm_ctx->image->start_address_set = 0; - for (i = 1; i < argc; i++) + /* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */ + if (argc >= 2) { - /* optional argument could be image type */ - if (identify_image_type(&etm_ctx->image->type, args[i], args[0]) == ERROR_IMAGE_TYPE_UNKNOWN) - { - /* if it wasn't a valid image type, treat it as the base address */ - etm_ctx->image->base_address_set = 1; - etm_ctx->image->base_address = strtoul(args[i], NULL, 0); - } + etm_ctx->image->base_address_set = 1; + etm_ctx->image->base_address = strtoul(args[1], NULL, 0); } - - if (image_open(etm_ctx->image, args[0], FILEIO_READ) != ERROR_OK) + else + { + etm_ctx->image->base_address_set = 0; + } + + if (image_open(etm_ctx->image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK) { command_print(cmd_ctx, "image opening error: %s", etm_ctx->image->error_str); free(etm_ctx->image); diff --git a/src/target/image.c b/src/target/image.c index 0cac1c10a..6239b9949 100644 --- a/src/target/image.c +++ b/src/target/image.c @@ -422,19 +422,18 @@ int image_elf_read_section(image_t *image, int section, u32 offset, u32 size, u8 return ERROR_OK; } -int image_open(image_t *image, void *source, char *type_string) +int image_open(image_t *image, char *url, char *type_string) { int retval = ERROR_OK; - if ((retval = identify_image_type(image, type_string, source)) != ERROR_OK) + if ((retval = identify_image_type(image, type_string, url)) != ERROR_OK) { return retval; - } + } if (image->type == IMAGE_BINARY) { image_binary_t *image_binary; - char *url = source; image_binary = image->type_private = malloc(sizeof(image_binary_t)); @@ -459,7 +458,6 @@ int image_open(image_t *image, void *source, char *type_string) else if (image->type == IMAGE_IHEX) { image_ihex_t *image_ihex; - char *url = source; image_ihex = image->type_private = malloc(sizeof(image_ihex_t)); @@ -482,7 +480,6 @@ int image_open(image_t *image, void *source, char *type_string) else if (image->type == IMAGE_ELF) { image_elf_t *image_elf; - char *url = source; image_elf = image->type_private = malloc(sizeof(image_elf_t)); @@ -505,11 +502,18 @@ int image_open(image_t *image, void *source, char *type_string) else if (image->type == IMAGE_MEMORY) { image_memory_t *image_memory; - target_t *target = source; + + image->num_sections = 1; + image->sections = malloc(sizeof(image_section_t)); + image->sections[0].base_address = 0x0; + image->sections[0].size = 0xffffffff; + image->sections[0].flags = 0; image_memory = image->type_private = malloc(sizeof(image_memory_t)); - image_memory->target = target; + image_memory->target = get_target_by_num(strtoul(url, NULL, 0));; + image_memory->cache = NULL; + image_memory->cache_address = 0x0; } return retval; @@ -558,7 +562,41 @@ int image_read_section(image_t *image, int section, u32 offset, u32 size, u8 *bu } else if (image->type == IMAGE_MEMORY) { - /* TODO: handle target memory pseudo image */ + image_memory_t *image_memory = image->type_private; + u32 address = image->sections[section].base_address + offset; + + *size_read = 0; + + while ((size - *size_read) > 0) + { + u32 size_in_cache; + + if (!image_memory->cache + || (address < image_memory->cache_address) + || (address >= (image_memory->cache_address + IMAGE_MEMORY_CACHE_SIZE))) + { + if (!image_memory->cache) + image_memory->cache = malloc(IMAGE_MEMORY_CACHE_SIZE); + + if (target_read_buffer(image_memory->target, address & ~(IMAGE_MEMORY_CACHE_SIZE - 1), + IMAGE_MEMORY_CACHE_SIZE, image_memory->cache) != ERROR_OK) + { + free(image_memory->cache); + return ERROR_IMAGE_TEMPORARILY_UNAVAILABLE; + } + image_memory->cache_address = address & ~(IMAGE_MEMORY_CACHE_SIZE - 1); + } + + size_in_cache = (image_memory->cache_address + IMAGE_MEMORY_CACHE_SIZE) - address; + + memcpy(buffer + *size_read, + image_memory->cache + (address - image_memory->cache_address), + (size_in_cache > size) ? size : size_in_cache + ); + + *size_read += (size_in_cache > size) ? size : size_in_cache; + address += (size_in_cache > size) ? size : size_in_cache; + } } return ERROR_OK; @@ -595,7 +633,10 @@ int image_close(image_t *image) } else if (image->type == IMAGE_MEMORY) { - /* do nothing for now */ + image_memory_t *image_memory = image->type_private; + + if (image_memory->cache) + free(image_memory->cache); } if (image->type_private) diff --git a/src/target/image.h b/src/target/image.h index 074b90690..7aa119caa 100644 --- a/src/target/image.h +++ b/src/target/image.h @@ -27,6 +27,8 @@ #define IMAGE_MAX_ERROR_STRING (256) #define IMAGE_MAX_SECTIONS (128) +#define IMAGE_MEMORY_CACHE_SIZE (128) + typedef enum image_type { IMAGE_BINARY, /* plain binary */ @@ -74,6 +76,8 @@ typedef struct image_ihex_s typedef struct image_memory_s { target_t *target; + u8 *cache; + u32 cache_address; } image_memory_t; typedef struct fileio_elf_s @@ -85,11 +89,12 @@ typedef struct fileio_elf_s u8 endianness; } image_elf_t; -extern int image_open(image_t *image, void *source, char *type_string); +extern int image_open(image_t *image, char *url, char *type_string); extern int image_read_section(image_t *image, int section, u32 offset, u32 size, u8 *buffer, u32 *size_read); extern int image_close(image_t *image); #define ERROR_IMAGE_FORMAT_ERROR (-1400) #define ERROR_IMAGE_TYPE_UNKNOWN (-1401) +#define ERROR_IMAGE_TEMPORARILY_UNAVAILABLE (-1402) #endif /* IMAGE_H */