summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleksij Rempel <linux@rempel-privat.de>2015-05-18 09:53:10 +0200
committerOleksij Rempel <linux@rempel-privat.de>2015-07-01 08:51:54 +0200
commit2fbd9f3d774ff2ba1531918cdbd59373a65d85d9 (patch)
treeace948bf5772912efe55aa87376921d197aa9e76
parentf62e8dcbcf3fc5df504c465642044a20bf2ad892 (diff)
downloadopenocd-2fbd9f3d774ff2ba1531918cdbd59373a65d85d9.tar.gz
openocd-2fbd9f3d774ff2ba1531918cdbd59373a65d85d9.tar.xz
cortex_a: add cortex_a_[read|write]_buffer
Change-Id: I82011822d913aa7228f5c6262b540156494bedfe Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
-rw-r--r--src/target/cortex_a.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c
index df6c0d29..e160b7db 100644
--- a/src/target/cortex_a.c
+++ b/src/target/cortex_a.c
@@ -2714,6 +2714,74 @@ static int cortex_a_write_memory(struct target *target, uint32_t address,
return retval;
}
+static int cortex_a_read_buffer(struct target *target, uint32_t address,
+ uint32_t count, uint8_t *buffer)
+{
+ uint32_t size;
+
+ /* Align up to maximum 4 bytes. The loop condition makes sure the next pass
+ * will have something to do with the size we leave to it. */
+ for (size = 1; size < 4 && count >= size * 2 + (address & size); size *= 2) {
+ if (address & size) {
+ int retval = target_read_memory(target, address, size, 1, buffer);
+ if (retval != ERROR_OK)
+ return retval;
+ address += size;
+ count -= size;
+ buffer += size;
+ }
+ }
+
+ /* Read the data with as large access size as possible. */
+ for (; size > 0; size /= 2) {
+ uint32_t aligned = count - count % size;
+ if (aligned > 0) {
+ int retval = target_read_memory(target, address, size, aligned / size, buffer);
+ if (retval != ERROR_OK)
+ return retval;
+ address += aligned;
+ count -= aligned;
+ buffer += aligned;
+ }
+ }
+
+ return ERROR_OK;
+}
+
+static int cortex_a_write_buffer(struct target *target, uint32_t address,
+ uint32_t count, const uint8_t *buffer)
+{
+ uint32_t size;
+
+ /* Align up to maximum 4 bytes. The loop condition makes sure the next pass
+ * will have something to do with the size we leave to it. */
+ for (size = 1; size < 4 && count >= size * 2 + (address & size); size *= 2) {
+ if (address & size) {
+ int retval = target_write_memory(target, address, size, 1, buffer);
+ if (retval != ERROR_OK)
+ return retval;
+ address += size;
+ count -= size;
+ buffer += size;
+ }
+ }
+
+ /* Write the data with as large access size as possible. */
+ for (; size > 0; size /= 2) {
+ uint32_t aligned = count - count % size;
+ if (aligned > 0) {
+ int retval = target_write_memory(target, address, size, aligned / size, buffer);
+ if (retval != ERROR_OK)
+ return retval;
+ address += aligned;
+ count -= aligned;
+ buffer += aligned;
+ }
+ }
+
+ return ERROR_OK;
+}
+
static int cortex_a_handle_target_request(void *priv)
{
struct target *target = priv;
@@ -3194,6 +3262,9 @@ struct target_type cortexa_target = {
.read_memory = cortex_a_read_memory,
.write_memory = cortex_a_write_memory,
+ .read_buffer = cortex_a_read_buffer,
+ .write_buffer = cortex_a_write_buffer,
+
.checksum_memory = arm_checksum_memory,
.blank_check_memory = arm_blank_check_memory,