summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias K <kesmtp@freenet.de>2011-03-03 11:01:46 +0100
committerØyvind Harboe <oyvind.harboe@zylin.com>2011-03-17 14:18:16 +0100
commit4332bc32e4a65b0b5b169a143febeb02e6517f39 (patch)
tree18d344b6313555dc93ee12aebc71fc6da9cf7a90
parent9f17b30f8847ba50e7a8ef03ca37cc116e915740 (diff)
downloadopenocd+libswd-4332bc32e4a65b0b5b169a143febeb02e6517f39.tar.gz
openocd+libswd-4332bc32e4a65b0b5b169a143febeb02e6517f39.tar.bz2
openocd+libswd-4332bc32e4a65b0b5b169a143febeb02e6517f39.tar.xz
openocd+libswd-4332bc32e4a65b0b5b169a143febeb02e6517f39.zip
target: allow targets to override memory alignment
Targets can implement read/write_buffer to handle alignment.
-rw-r--r--src/target/target.c30
-rw-r--r--src/target/target_type.h6
2 files changed, 32 insertions, 4 deletions
diff --git a/src/target/target.c b/src/target/target.c
index be42b338..13d358d7 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -46,6 +46,10 @@
#include "image.h"
+static int target_read_buffer_default(struct target *target, uint32_t address,
+ uint32_t size, uint8_t *buffer);
+static int target_write_buffer_default(struct target *target, uint32_t address,
+ uint32_t size, uint8_t *buffer);
static int target_array2mem(Jim_Interp *interp, struct target *target,
int argc, Jim_Obj *const *argv);
static int target_mem2array(Jim_Interp *interp, struct target *target,
@@ -865,6 +869,13 @@ static int target_init_one(struct command_context *cmd_ctx,
type->read_phys_memory = type->read_memory;
type->virt2phys = identity_virt2phys;
}
+
+ if (target->type->read_buffer == NULL)
+ target->type->read_buffer = target_read_buffer_default;
+
+ if (target->type->write_buffer == NULL)
+ target->type->write_buffer = target_write_buffer_default;
+
return ERROR_OK;
}
@@ -1333,7 +1344,6 @@ int target_arch_state(struct target *target)
*/
int target_write_buffer(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer)
{
- int retval;
LOG_DEBUG("writing buffer of %i byte at 0x%8.8x",
(int)size, (unsigned)address);
@@ -1356,6 +1366,13 @@ int target_write_buffer(struct target *target, uint32_t address, uint32_t size,
return ERROR_FAIL;
}
+ return target->type->write_buffer(target, address, size, buffer);
+}
+
+static int target_write_buffer_default(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer)
+{
+ int retval = ERROR_OK;
+
if (((address % 2) == 0) && (size == 2))
{
return target_write_memory(target, address, 2, 1, buffer);
@@ -1406,7 +1423,7 @@ int target_write_buffer(struct target *target, uint32_t address, uint32_t size,
return retval;
}
- return ERROR_OK;
+ return retval;
}
/* Single aligned words are guaranteed to use 16 or 32 bit access
@@ -1415,7 +1432,6 @@ int target_write_buffer(struct target *target, uint32_t address, uint32_t size,
*/
int target_read_buffer(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer)
{
- int retval;
LOG_DEBUG("reading buffer of %i byte at 0x%8.8x",
(int)size, (unsigned)address);
@@ -1438,6 +1454,13 @@ int target_read_buffer(struct target *target, uint32_t address, uint32_t size, u
return ERROR_FAIL;
}
+ return target->type->read_buffer(target, address, size, buffer);
+}
+
+static int target_read_buffer_default(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer)
+{
+ int retval = ERROR_OK;
+
if (((address % 2) == 0) && (size == 2))
{
return target_read_memory(target, address, 2, 1, buffer);
@@ -3695,7 +3718,6 @@ static Jim_Nvp nvp_config_opts[] = {
{ .name = "-variant", .value = TCFG_VARIANT },
{ .name = "-coreid", .value = TCFG_COREID },
{ .name = "-chain-position", .value = TCFG_CHAIN_POSITION },
-
{ .name = NULL, .value = -1 }
};
diff --git a/src/target/target_type.h b/src/target/target_type.h
index bfa7f937..15598b2f 100644
--- a/src/target/target_type.h
+++ b/src/target/target_type.h
@@ -119,6 +119,12 @@ struct target_type
*/
int (*write_memory)(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
+ /* Default implementation will do some fancy alignment to improve performance, target can override */
+ int (*read_buffer)(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer);
+
+ /* Default implementation will do some fancy alignment to improve performance, target can override */
+ int (*write_buffer)(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer);
+
/**
* Write target memory in multiples of 4 bytes, optimized for
* writing large quantities of data. Do @b not call this