aboutsummaryrefslogtreecommitdiff
path: root/src/target
diff options
context:
space:
mode:
authordrath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2007-06-15 14:10:23 +0000
committerdrath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60>2007-06-15 14:10:23 +0000
commit3d026ce94393e5e53cccb5d5364f9d500d5b3733 (patch)
tree493a91caf9c2cab8e4109219b89eb132b6f8d717 /src/target
parent972ca49d3a5e285492e4c1680289f819f26eaec3 (diff)
- added support for pseudo image type "mem", currently only used for etm analysis: "etm image <target#> <dummy base address> mem"
git-svn-id: svn://svn.berlios.de/openocd/trunk@173 b42882b7-edfa-0310-969c-e2dbd0fdcd60
Diffstat (limited to 'src/target')
-rw-r--r--src/target/etm.c22
-rw-r--r--src/target/image.c61
-rw-r--r--src/target/image.h7
3 files changed, 68 insertions, 22 deletions
diff --git a/src/target/etm.c b/src/target/etm.c
index a775bbd1..dd6e6025 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 <file> ['bin'|'ihex'|'elf'] [base address]");
+ command_print(cmd_ctx, "usage: etm image <file> [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 0cac1c10..6239b994 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 074b9069..7aa119ca 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 */