This is an automated email from Gerrit. "Bernhard Rosenkränzer <b...@baylibre.com>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8288
-- gerrit commit 3f9f339e3b4ae4f207018a824b9fdb0216fbf468 Author: Bernhard Rosenkränzer <b...@baylibre.com> Date: Sat May 18 16:41:23 2024 +0200 target: Add `addr_autoincr` parameter to {read,write}_{phys,}_memory Add addr_autoincr to allow repeated read/writes of the same memory area, replacing the `riscv repeat_read` command from the RISC-V fork. This is the first in a series of 4 patches replacing https://review.openocd.org/c/openocd/+/8259 Change-Id: Ifcd5f5a822d0022a3a143a69fc80dc69d49df668 Signed-off-by: Bernhard Rosenkränzer <b...@baylibre.com> Cc: Antonio Borneo <borneo.anto...@gmail.com> diff --git a/src/target/aarch64.c b/src/target/aarch64.c index 6a70b2ddf8..d5bc1509f3 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -2485,10 +2485,13 @@ static int aarch64_read_cpu_memory(struct target *target, static int aarch64_read_phys_memory(struct target *target, target_addr_t address, uint32_t size, - uint32_t count, uint8_t *buffer) + uint32_t count, uint8_t *buffer, bool addr_autoincr) { int retval = ERROR_COMMAND_SYNTAX_ERROR; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + if (count && buffer) { /* read memory through APB-AP */ retval = aarch64_mmu_modify(target, 0); @@ -2500,11 +2503,14 @@ static int aarch64_read_phys_memory(struct target *target, } static int aarch64_read_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr) { int mmu_enabled = 0; int retval; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + /* determine if MMU was enabled on target stop */ retval = aarch64_mmu(target, &mmu_enabled); if (retval != ERROR_OK) @@ -2521,10 +2527,13 @@ static int aarch64_read_memory(struct target *target, target_addr_t address, static int aarch64_write_phys_memory(struct target *target, target_addr_t address, uint32_t size, - uint32_t count, const uint8_t *buffer) + uint32_t count, const uint8_t *buffer, bool addr_autoincr) { int retval = ERROR_COMMAND_SYNTAX_ERROR; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + if (count && buffer) { /* write memory through APB-AP */ retval = aarch64_mmu_modify(target, 0); @@ -2537,11 +2546,14 @@ static int aarch64_write_phys_memory(struct target *target, } static int aarch64_write_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr) { int mmu_enabled = 0; int retval; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + /* determine if MMU was enabled on target stop */ retval = aarch64_mmu(target, &mmu_enabled); if (retval != ERROR_OK) diff --git a/src/target/arc_mem.c b/src/target/arc_mem.c index 3264b663b6..4742a3cc05 100644 --- a/src/target/arc_mem.c +++ b/src/target/arc_mem.c @@ -153,11 +153,14 @@ static int arc_mem_write_block8(struct target *target, uint32_t addr, /* ----- Exported functions ------------------------------------------------ */ int arc_mem_write(struct target *target, target_addr_t address, uint32_t size, - uint32_t count, const uint8_t *buffer) + uint32_t count, const uint8_t *buffer, bool addr_autoincr) { int retval = ERROR_OK; void *tunnel = NULL; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + LOG_DEBUG("address: 0x%08" TARGET_PRIxADDR ", size: %" PRIu32 ", count: %" PRIu32, address, size, count); @@ -235,13 +238,15 @@ static int arc_mem_read_block(struct target *target, target_addr_t addr, } int arc_mem_read(struct target *target, target_addr_t address, uint32_t size, - uint32_t count, uint8_t *buffer) + uint32_t count, uint8_t *buffer, bool addr_autoincr) { int retval = ERROR_OK; void *tunnel_he; uint8_t *tunnel_te; uint32_t words_to_read, bytes_to_read; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; LOG_DEBUG("Read memory: addr=0x%08" TARGET_PRIxADDR ", size=%" PRIu32 ", count=%" PRIu32, address, size, count); diff --git a/src/target/arc_mem.h b/src/target/arc_mem.h index 861823d227..c29469b738 100644 --- a/src/target/arc_mem.h +++ b/src/target/arc_mem.h @@ -13,9 +13,9 @@ /* ----- Exported functions ------------------------------------------------ */ int arc_mem_read(struct target *target, target_addr_t address, uint32_t size, - uint32_t count, uint8_t *buffer); + uint32_t count, uint8_t *buffer, bool addr_autoincr); int arc_mem_write(struct target *target, target_addr_t address, uint32_t size, - uint32_t count, const uint8_t *buffer); + uint32_t count, const uint8_t *buffer, bool addr_autoincr); #endif /* OPENOCD_TARGET_ARC_MEM_H */ diff --git a/src/target/arm11.c b/src/target/arm11.c index 50aaa86f12..3eab40b8b0 100644 --- a/src/target/arm11.c +++ b/src/target/arm11.c @@ -878,9 +878,10 @@ static int arm11_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, - uint8_t *buffer) + uint8_t *buffer, + bool addr_autoincr) { - return arm11_read_memory_inner(target, address, size, count, buffer, false); + return arm11_read_memory_inner(target, address, size, count, buffer, !addr_autoincr); } /* @@ -1032,13 +1033,13 @@ static int arm11_write_memory_inner(struct target *target, static int arm11_write_memory(struct target *target, target_addr_t address, uint32_t size, - uint32_t count, const uint8_t *buffer) + uint32_t count, const uint8_t *buffer, bool addr_autoincr) { /* pointer increment matters only for multi-unit writes ... * not e.g. to a "reset the chip" controller. */ return arm11_write_memory_inner(target, address, size, - count, buffer, count == 1); + count, buffer, (count == 1) || !addr_autoincr); } /* target break-/watchpoint control diff --git a/src/target/arm720t.c b/src/target/arm720t.c index beab632c25..abba3cb17b 100644 --- a/src/target/arm720t.c +++ b/src/target/arm720t.c @@ -265,7 +265,7 @@ static int arm720_virt2phys(struct target *target, } static int arm720t_read_memory(struct target *target, - target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer) + target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr) { int retval; struct arm720t_common *arm720t = target_to_arm720(target); @@ -276,7 +276,7 @@ static int arm720t_read_memory(struct target *target, if (retval != ERROR_OK) return retval; } - retval = arm7_9_read_memory(target, address, size, count, buffer); + retval = arm7_9_read_memory(target, address, size, count, buffer, addr_autoincr); if (arm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) { retval = arm720t_enable_mmu_caches(target, 0, 1, 0); @@ -288,19 +288,19 @@ static int arm720t_read_memory(struct target *target, } static int arm720t_read_phys_memory(struct target *target, - target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer) + target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr) { struct arm720t_common *arm720t = target_to_arm720(target); - return armv4_5_mmu_read_physical(target, &arm720t->armv4_5_mmu, address, size, count, buffer); + return armv4_5_mmu_read_physical(target, &arm720t->armv4_5_mmu, address, size, count, buffer, addr_autoincr); } static int arm720t_write_phys_memory(struct target *target, - target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer) + target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr) { struct arm720t_common *arm720t = target_to_arm720(target); - return armv4_5_mmu_write_physical(target, &arm720t->armv4_5_mmu, address, size, count, buffer); + return armv4_5_mmu_write_physical(target, &arm720t->armv4_5_mmu, address, size, count, buffer, addr_autoincr); } static int arm720t_soft_reset_halt(struct target *target) diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index ad814e0541..4412a5eac6 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -30,6 +30,7 @@ #include "algorithm.h" #include "register.h" #include "armv4_5.h" +#include <target/target_type.h> /** * @file @@ -2103,7 +2104,8 @@ int arm7_9_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, - uint8_t *buffer) + uint8_t *buffer, + bool addr_autoincr) { struct arm7_9_common *arm7_9 = target_to_arm7_9(target); struct arm *arm = &arm7_9->arm; @@ -2115,6 +2117,9 @@ int arm7_9_read_memory(struct target *target, int retval; int last_reg = 0; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count); @@ -2273,7 +2278,8 @@ int arm7_9_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, - const uint8_t *buffer) + const uint8_t *buffer, + bool addr_autoincr) { struct arm7_9_common *arm7_9 = target_to_arm7_9(target); struct arm *arm = &arm7_9->arm; @@ -2287,6 +2293,9 @@ int arm7_9_write_memory(struct target *target, int retval; int last_reg = 0; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + #ifdef _DEBUG_ARM7_9_ LOG_DEBUG("address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x", address, size, count); #endif @@ -2487,31 +2496,33 @@ int arm7_9_write_memory_opt(struct target *target, target_addr_t address, uint32_t size, uint32_t count, - const uint8_t *buffer) + const uint8_t *buffer, + bool addr_autoincr) { struct arm7_9_common *arm7_9 = target_to_arm7_9(target); int retval; if (size == 4 && count > 32 && arm7_9->bulk_write_memory) { /* Attempt to do a bulk write */ - retval = arm7_9->bulk_write_memory(target, address, count, buffer); + retval = arm7_9->bulk_write_memory(target, address, count, buffer, addr_autoincr); if (retval == ERROR_OK) return ERROR_OK; } - return arm7_9->write_memory(target, address, size, count, buffer); + return arm7_9->write_memory(target, address, size, count, buffer, addr_autoincr); } int arm7_9_write_memory_no_opt(struct target *target, uint32_t address, uint32_t size, uint32_t count, - const uint8_t *buffer) + const uint8_t *buffer, + bool addr_autoincr) { struct arm7_9_common *arm7_9 = target_to_arm7_9(target); - return arm7_9->write_memory(target, address, size, count, buffer); + return arm7_9->write_memory(target, address, size, count, buffer, addr_autoincr); } static int dcc_count; @@ -2586,11 +2597,15 @@ static const uint32_t dcc_code[] = { int arm7_9_bulk_write_memory(struct target *target, target_addr_t address, uint32_t count, - const uint8_t *buffer) + const uint8_t *buffer, + bool addr_autoincr) { int retval; struct arm7_9_common *arm7_9 = target_to_arm7_9(target); + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + if (address % 4 != 0) return ERROR_TARGET_UNALIGNED_ACCESS; @@ -2613,7 +2628,7 @@ int arm7_9_bulk_write_memory(struct target *target, /* write DCC code to working area, using the non-optimized * memory write to avoid ending up here again */ retval = arm7_9_write_memory_no_opt(target, - arm7_9->dcc_working_area->address, 4, 6, dcc_code_buf); + arm7_9->dcc_working_area->address, 4, 6, dcc_code_buf, addr_autoincr); if (retval != ERROR_OK) return retval; } diff --git a/src/target/arm7_9_common.h b/src/target/arm7_9_common.h index 92d0fd51a2..71770f6da0 100644 --- a/src/target/arm7_9_common.h +++ b/src/target/arm7_9_common.h @@ -113,13 +113,13 @@ struct arm7_9_common { * do the bulk writes. */ int (*write_memory)(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer); + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr); /** * Write target memory in multiples of 4 bytes, optimized for * writing large quantities of data. */ int (*bulk_write_memory)(struct target *target, target_addr_t address, - uint32_t count, const uint8_t *buffer); + uint32_t count, const uint8_t *buffer, bool addr_autoincr); }; static inline struct arm7_9_common *target_to_arm7_9(struct target *target) @@ -150,15 +150,15 @@ int arm7_9_resume(struct target *target, int current, target_addr_t address, int arm7_9_step(struct target *target, int current, target_addr_t address, int handle_breakpoints); int arm7_9_read_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer); + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr); int arm7_9_write_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer); + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr); int arm7_9_write_memory_opt(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer); + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr); int arm7_9_write_memory_no_opt(struct target *target, uint32_t address, - uint32_t size, uint32_t count, const uint8_t *buffer); + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr); int arm7_9_bulk_write_memory(struct target *target, target_addr_t address, - uint32_t count, const uint8_t *buffer); + uint32_t count, const uint8_t *buffer, bool addr_autoincr); int arm7_9_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_prams, diff --git a/src/target/arm920t.c b/src/target/arm920t.c index 53b4d9d15f..955e29025d 100644 --- a/src/target/arm920t.c +++ b/src/target/arm920t.c @@ -558,11 +558,11 @@ static int arm920_virt2phys(struct target *target, /** Reads a buffer, in the specified word size, with current MMU settings. */ int arm920t_read_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr) { int retval; - retval = arm7_9_read_memory(target, address, size, count, buffer); + retval = arm7_9_read_memory(target, address, size, count, buffer, addr_autoincr); return retval; } @@ -570,27 +570,27 @@ int arm920t_read_memory(struct target *target, target_addr_t address, static int arm920t_read_phys_memory(struct target *target, target_addr_t address, uint32_t size, - uint32_t count, uint8_t *buffer) + uint32_t count, uint8_t *buffer, bool addr_autoincr) { struct arm920t_common *arm920t = target_to_arm920(target); return armv4_5_mmu_read_physical(target, &arm920t->armv4_5_mmu, - address, size, count, buffer); + address, size, count, buffer, addr_autoincr); } static int arm920t_write_phys_memory(struct target *target, target_addr_t address, uint32_t size, - uint32_t count, const uint8_t *buffer) + uint32_t count, const uint8_t *buffer, bool addr_autoincr) { struct arm920t_common *arm920t = target_to_arm920(target); return armv4_5_mmu_write_physical(target, &arm920t->armv4_5_mmu, - address, size, count, buffer); + address, size, count, buffer, addr_autoincr); } /** Writes a buffer, in the specified word size, with current MMU settings. */ int arm920t_write_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr) { int retval; const uint32_t cache_mask = ~0x1f; /* cache line size : 32 byte */ @@ -659,7 +659,7 @@ int arm920t_write_memory(struct target *target, target_addr_t address, retval = armv4_5_mmu_write_physical(target, &arm920t->armv4_5_mmu, pa & cache_mask, 1, - sizeof(data), &data[0]); + sizeof(data), &data[0], addr_autoincr); if (retval != ERROR_OK) return retval; } @@ -687,11 +687,11 @@ int arm920t_write_memory(struct target *target, target_addr_t address, */ retval = armv4_5_mmu_write_physical(target, &arm920t->armv4_5_mmu, pa, size, - count, buffer); + count, buffer, addr_autoincr); if (retval != ERROR_OK) return retval; } else { - retval = arm7_9_write_memory(target, address, size, count, buffer); + retval = arm7_9_write_memory(target, address, size, count, buffer, addr_autoincr); if (retval != ERROR_OK) return retval; } diff --git a/src/target/arm920t.h b/src/target/arm920t.h index eba768ffff..da4fdcaffd 100644 --- a/src/target/arm920t.h +++ b/src/target/arm920t.h @@ -45,9 +45,9 @@ struct arm920t_tlb_entry { int arm920t_arch_state(struct target *target); int arm920t_soft_reset_halt(struct target *target); int arm920t_read_memory(struct target *target, - target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer); + target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr); int arm920t_write_memory(struct target *target, - target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer); + target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr); int arm920t_post_debug_entry(struct target *target); void arm920t_pre_restore_context(struct target *target); int arm920t_get_ttb(struct target *target, uint32_t *result); diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c index add90c9978..e91d64944d 100644 --- a/src/target/arm926ejs.c +++ b/src/target/arm926ejs.c @@ -584,7 +584,7 @@ int arm926ejs_soft_reset_halt(struct target *target) /** Writes a buffer, in the specified word size, with current MMU settings. */ int arm926ejs_write_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr) { int retval; struct arm926ejs_common *arm926ejs = target_to_arm926(target); @@ -618,11 +618,11 @@ int arm926ejs_write_memory(struct target *target, target_addr_t address, return retval; /* write directly to physical memory bypassing any read only MMU bits, etc. */ - retval = armv4_5_mmu_write_physical(target, &arm926ejs->armv4_5_mmu, pa, size, count, buffer); + retval = armv4_5_mmu_write_physical(target, &arm926ejs->armv4_5_mmu, pa, size, count, buffer, addr_autoincr); if (retval != ERROR_OK) return retval; } else { - retval = arm7_9_write_memory(target, address, size, count, buffer); + retval = arm7_9_write_memory(target, address, size, count, buffer, addr_autoincr); if (retval != ERROR_OK) return retval; } @@ -645,22 +645,22 @@ int arm926ejs_write_memory(struct target *target, target_addr_t address, static int arm926ejs_write_phys_memory(struct target *target, target_addr_t address, uint32_t size, - uint32_t count, const uint8_t *buffer) + uint32_t count, const uint8_t *buffer, bool addr_autoincr) { struct arm926ejs_common *arm926ejs = target_to_arm926(target); return armv4_5_mmu_write_physical(target, &arm926ejs->armv4_5_mmu, - address, size, count, buffer); + address, size, count, buffer, addr_autoincr); } static int arm926ejs_read_phys_memory(struct target *target, target_addr_t address, uint32_t size, - uint32_t count, uint8_t *buffer) + uint32_t count, uint8_t *buffer, bool addr_autoincr) { struct arm926ejs_common *arm926ejs = target_to_arm926(target); return armv4_5_mmu_read_physical(target, &arm926ejs->armv4_5_mmu, - address, size, count, buffer); + address, size, count, buffer, addr_autoincr); } int arm926ejs_init_arch_info(struct target *target, struct arm926ejs_common *arm926ejs, diff --git a/src/target/arm926ejs.h b/src/target/arm926ejs.h index 479128e615..8bf6e08c01 100644 --- a/src/target/arm926ejs.h +++ b/src/target/arm926ejs.h @@ -37,7 +37,8 @@ int arm926ejs_init_arch_info(struct target *target, struct arm926ejs_common *arm926ejs, struct jtag_tap *tap); int arm926ejs_arch_state(struct target *target); int arm926ejs_write_memory(struct target *target, - target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer); + target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer, + bool addr_autoincr); int arm926ejs_soft_reset_halt(struct target *target); extern const struct command_registration arm926ejs_command_handlers[]; diff --git a/src/target/arm946e.c b/src/target/arm946e.c index 03f7e443fb..b86eb35e71 100644 --- a/src/target/arm946e.c +++ b/src/target/arm946e.c @@ -499,7 +499,7 @@ static uint32_t arm946e_invalidate_icache(struct target *target, uint32_t addres /** Writes a buffer, in the specified word size, with current MMU settings. */ static int arm946e_write_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr) { int retval; @@ -513,7 +513,7 @@ static int arm946e_write_memory(struct target *target, target_addr_t address, /** * Write memory */ - retval = arm7_9_write_memory_opt(target, address, size, count, buffer); + retval = arm7_9_write_memory_opt(target, address, size, count, buffer, addr_autoincr); if (retval != ERROR_OK) return retval; @@ -547,13 +547,13 @@ static int arm946e_write_memory(struct target *target, target_addr_t address, } static int arm946e_read_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr) { int retval; LOG_DEBUG("-"); - retval = arm7_9_read_memory(target, address, size, count, buffer); + retval = arm7_9_read_memory(target, address, size, count, buffer, addr_autoincr); if (retval != ERROR_OK) return retval; diff --git a/src/target/armv4_5_mmu.c b/src/target/armv4_5_mmu.c index 0c09cb4ca7..aa26d22795 100644 --- a/src/target/armv4_5_mmu.c +++ b/src/target/armv4_5_mmu.c @@ -11,6 +11,7 @@ #include <helper/log.h> #include "target.h" +#include <target/target_type.h> #include "armv4_5_mmu.h" int armv4_5_mmu_translate_va(struct target *target, @@ -26,7 +27,7 @@ int armv4_5_mmu_translate_va(struct target *target, retval = armv4_5_mmu_read_physical(target, armv4_5_mmu, (ttb & 0xffffc000) | ((va & 0xfff00000) >> 18), - 4, 1, (uint8_t *)&first_lvl_descriptor); + 4, 1, (uint8_t *)&first_lvl_descriptor, ADDR_AUTOINCR); if (retval != ERROR_OK) return retval; first_lvl_descriptor = target_buffer_get_u32(target, (uint8_t *)&first_lvl_descriptor); @@ -54,14 +55,14 @@ int armv4_5_mmu_translate_va(struct target *target, /* coarse page table */ retval = armv4_5_mmu_read_physical(target, armv4_5_mmu, (first_lvl_descriptor & 0xfffffc00) | ((va & 0x000ff000) >> 10), - 4, 1, (uint8_t *)&second_lvl_descriptor); + 4, 1, (uint8_t *)&second_lvl_descriptor, ADDR_AUTOINCR); if (retval != ERROR_OK) return retval; } else if ((first_lvl_descriptor & 0x3) == 3) { /* fine page table */ retval = armv4_5_mmu_read_physical(target, armv4_5_mmu, (first_lvl_descriptor & 0xfffff000) | ((va & 0x000ffc00) >> 8), - 4, 1, (uint8_t *)&second_lvl_descriptor); + 4, 1, (uint8_t *)&second_lvl_descriptor, ADDR_AUTOINCR); if (retval != ERROR_OK) return retval; } @@ -103,7 +104,7 @@ int armv4_5_mmu_translate_va(struct target *target, int armv4_5_mmu_read_physical(struct target *target, struct armv4_5_mmu_common *armv4_5_mmu, uint32_t address, - uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr) { int retval; @@ -117,7 +118,7 @@ int armv4_5_mmu_read_physical(struct target *target, if (retval != ERROR_OK) return retval; - retval = armv4_5_mmu->read_memory(target, address, size, count, buffer); + retval = armv4_5_mmu->read_memory(target, address, size, count, buffer, addr_autoincr); if (retval != ERROR_OK) return retval; @@ -133,7 +134,7 @@ int armv4_5_mmu_read_physical(struct target *target, int armv4_5_mmu_write_physical(struct target *target, struct armv4_5_mmu_common *armv4_5_mmu, uint32_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr) { int retval; @@ -147,7 +148,7 @@ int armv4_5_mmu_write_physical(struct target *target, if (retval != ERROR_OK) return retval; - retval = armv4_5_mmu->write_memory(target, address, size, count, buffer); + retval = armv4_5_mmu->write_memory(target, address, size, count, buffer, addr_autoincr); if (retval != ERROR_OK) return retval; diff --git a/src/target/armv4_5_mmu.h b/src/target/armv4_5_mmu.h index 774f1056eb..b2a201ab20 100644 --- a/src/target/armv4_5_mmu.h +++ b/src/target/armv4_5_mmu.h @@ -14,9 +14,10 @@ struct target; struct armv4_5_mmu_common { int (*get_ttb)(struct target *target, uint32_t *result); - int (*read_memory)(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer); + int (*read_memory)(struct target *target, target_addr_t address, uint32_t size, + uint32_t count, uint8_t *buffer, bool addr_autoincr); int (*write_memory)(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer); + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr); int (*disable_mmu_caches)(struct target *target, int mmu, int d_u_cache, int i_cache); int (*enable_mmu_caches)(struct target *target, int mmu, int d_u_cache, int i_cache); struct armv4_5_cache_common armv4_5_cache; @@ -30,11 +31,11 @@ int armv4_5_mmu_translate_va(struct target *target, int armv4_5_mmu_read_physical(struct target *target, struct armv4_5_mmu_common *armv4_5_mmu, - uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer); + uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr); int armv4_5_mmu_write_physical(struct target *target, struct armv4_5_mmu_common *armv4_5_mmu, - uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer); + uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr); enum { ARMV4_5_MMU_ENABLED = 0x1, diff --git a/src/target/armv7a.h b/src/target/armv7a.h index 6b9c2a68f4..97fd9fb204 100644 --- a/src/target/armv7a.h +++ b/src/target/armv7a.h @@ -81,7 +81,7 @@ struct armv7a_mmu_common { uint32_t ttbr_range[2]; int (*read_physical_memory)(struct target *target, target_addr_t address, uint32_t size, - uint32_t count, uint8_t *buffer); + uint32_t count, uint8_t *buffer, bool addr_autoincr); struct armv7a_cache_common armv7a_cache; uint32_t mmu_enabled; }; diff --git a/src/target/armv7a_mmu.c b/src/target/armv7a_mmu.c index c4d294eae3..fb235eea53 100644 --- a/src/target/armv7a_mmu.c +++ b/src/target/armv7a_mmu.c @@ -21,6 +21,8 @@ #include "arm_opcodes.h" #include "cortex_a.h" +#include <target/target_type.h> + #define SCTLR_BIT_AFE (1 << 29) /* V7 method VA TO PA */ @@ -243,7 +245,7 @@ COMMAND_HANDLER(armv7a_mmu_dump_table) */ cache->flush_all_data_cache(target); - retval = mmu->read_physical_memory(target, ttb, 4, max_pt_idx+1, (uint8_t *)first_lvl_ptbl); + retval = mmu->read_physical_memory(target, ttb, 4, max_pt_idx + 1, (uint8_t *)first_lvl_ptbl, ADDR_AUTOINCR); if (retval != ERROR_OK) { LOG_ERROR("Failed to read first-level page table!"); return retval; @@ -297,7 +299,7 @@ COMMAND_HANDLER(armv7a_mmu_dump_table) /* page table, always 1KB long */ pt2 = malloc(1024); retval = mmu->read_physical_memory(target, second_lvl_ptbl, - 4, 256, (uint8_t *)pt2); + 4, 256, (uint8_t *)pt2, ADDR_AUTOINCR); if (retval != ERROR_OK) { LOG_ERROR("Failed to read second-level page table!"); return ERROR_FAIL; diff --git a/src/target/armv8.h b/src/target/armv8.h index f5aa211097..86b34f3629 100644 --- a/src/target/armv8.h +++ b/src/target/armv8.h @@ -176,7 +176,7 @@ struct armv8_mmu_common { uint32_t ttbr_range[2]; int (*read_physical_memory)(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer); + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr); struct armv8_cache_common armv8_cache; uint32_t mmu_enabled; }; diff --git a/src/target/avr32_ap7k.c b/src/target/avr32_ap7k.c index bbbf236592..332c23b087 100644 --- a/src/target/avr32_ap7k.c +++ b/src/target/avr32_ap7k.c @@ -421,10 +421,13 @@ static int avr32_ap7k_remove_watchpoint(struct target *target, } static int avr32_ap7k_read_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr) { struct avr32_ap7k_common *ap7k = target_to_ap7k(target); + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, @@ -461,10 +464,13 @@ static int avr32_ap7k_read_memory(struct target *target, target_addr_t address, } static int avr32_ap7k_write_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr) { struct avr32_ap7k_common *ap7k = target_to_ap7k(target); + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index 78fd4482c3..b461fcfd29 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -2728,10 +2728,13 @@ static int cortex_a_read_cpu_memory(struct target *target, static int cortex_a_read_phys_memory(struct target *target, target_addr_t address, uint32_t size, - uint32_t count, uint8_t *buffer) + uint32_t count, uint8_t *buffer, bool addr_autoincr) { int retval; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + if (!count || !buffer) return ERROR_COMMAND_SYNTAX_ERROR; @@ -2747,10 +2750,13 @@ static int cortex_a_read_phys_memory(struct target *target, } static int cortex_a_read_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr) { int retval; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + /* cortex_a handles unaligned memory access */ LOG_DEBUG("Reading memory at address " TARGET_ADDR_FMT "; size %" PRIu32 "; count %" PRIu32, address, size, count); @@ -2764,10 +2770,13 @@ static int cortex_a_read_memory(struct target *target, target_addr_t address, static int cortex_a_write_phys_memory(struct target *target, target_addr_t address, uint32_t size, - uint32_t count, const uint8_t *buffer) + uint32_t count, const uint8_t *buffer, bool addr_autoincr) { int retval; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + if (!count || !buffer) return ERROR_COMMAND_SYNTAX_ERROR; @@ -2783,10 +2792,13 @@ static int cortex_a_write_phys_memory(struct target *target, } static int cortex_a_write_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr) { int retval; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + /* cortex_a handles unaligned memory access */ LOG_DEBUG("Writing memory at address " TARGET_ADDR_FMT "; size %" PRIu32 "; count %" PRIu32, address, size, count); diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index c225b1aa9d..43f199fe9e 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -2146,10 +2146,13 @@ void cortex_m_enable_watchpoints(struct target *target) } static int cortex_m_read_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr) { struct armv7m_common *armv7m = target_to_armv7m(target); + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + if (armv7m->arm.arch == ARM_ARCH_V6M) { /* armv6m does not handle unaligned memory access */ if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) @@ -2160,10 +2163,13 @@ static int cortex_m_read_memory(struct target *target, target_addr_t address, } static int cortex_m_write_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr) { struct armv7m_common *armv7m = target_to_armv7m(target); + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + if (armv7m->arm.arch == ARM_ARCH_V6M) { /* armv6m does not handle unaligned memory access */ if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) diff --git a/src/target/dsp563xx.c b/src/target/dsp563xx.c index 80cca1ed50..f269662e0b 100644 --- a/src/target/dsp563xx.c +++ b/src/target/dsp563xx.c @@ -1599,12 +1599,16 @@ static int dsp563xx_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, - uint8_t *buffer) + uint8_t *buffer, + bool addr_autoincr) { int err; uint32_t i, i1; uint8_t *buffer_y, *buffer_x; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + /* if size equals zero we are called from target read memory * and have to handle the parameter here */ if ((size == 0) && (count != 0)) { @@ -1667,11 +1671,13 @@ static int dsp563xx_read_memory_default(struct target *target, target_addr_t address, uint32_t size, uint32_t count, - uint8_t *buffer) + uint8_t *buffer, + bool addr_autoincr) { return dsp563xx_read_memory(target, - dsp563xx_get_default_memory(), address, size, count, buffer); + dsp563xx_get_default_memory(), address, size, count, buffer, + addr_autoincr); } static int dsp563xx_read_buffer_default(struct target *target, @@ -1681,7 +1687,7 @@ static int dsp563xx_read_buffer_default(struct target *target, { return dsp563xx_read_memory(target, dsp563xx_get_default_memory(), address, size, 0, - buffer); + buffer, ADDR_AUTOINCR); } static int dsp563xx_write_memory_core(struct target *target, @@ -1773,12 +1779,16 @@ static int dsp563xx_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, - const uint8_t *buffer) + const uint8_t *buffer, + bool addr_autoincr) { int err; uint32_t i, i1; uint8_t *buffer_y, *buffer_x; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + /* if size equals zero we are called from target write memory * and have to handle the parameter here */ if ((size == 0) && (count != 0)) { @@ -1841,10 +1851,11 @@ static int dsp563xx_write_memory_default(struct target *target, target_addr_t address, uint32_t size, uint32_t count, - const uint8_t *buffer) + const uint8_t *buffer, + bool addr_autoincr) { return dsp563xx_write_memory(target, - dsp563xx_get_default_memory(), address, size, count, buffer); + dsp563xx_get_default_memory(), address, size, count, buffer, addr_autoincr); } static int dsp563xx_write_buffer_default(struct target *target, @@ -1853,7 +1864,7 @@ static int dsp563xx_write_buffer_default(struct target *target, const uint8_t *buffer) { return dsp563xx_write_memory(target, dsp563xx_get_default_memory(), address, size, 0, - buffer); + buffer, ADDR_AUTOINCR); } /* @@ -2144,7 +2155,7 @@ COMMAND_HANDLER(dsp563xx_mem_command) if (read_mem == 1) { err = dsp563xx_read_memory(target, mem_type, address, sizeof(uint32_t), - count, buffer); + count, buffer, ADDR_AUTOINCR); if (err == ERROR_OK) target_handle_md_output(CMD, target, address, sizeof(uint32_t), count, buffer); @@ -2161,7 +2172,8 @@ COMMAND_HANDLER(dsp563xx_mem_command) address, sizeof(uint32_t), count, - buffer); + buffer, + ADDR_AUTOINCR); } free(buffer); diff --git a/src/target/dsp5680xx.c b/src/target/dsp5680xx.c index c90bca3c1f..c49de4f04c 100644 --- a/src/target/dsp5680xx.c +++ b/src/target/dsp5680xx.c @@ -1152,8 +1152,11 @@ static int dsp5680xx_read_32_single(struct target *t, uint32_t a, } static int dsp5680xx_read(struct target *t, target_addr_t a, uint32_t size, - uint32_t count, uint8_t *buf) + uint32_t count, uint8_t *buf, bool addr_autoincr) { + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + struct target *target = t; uint32_t address = a; @@ -1304,7 +1307,7 @@ static int dsp5680xx_write_8(struct target *t, uint32_t a, uint32_t c, if ((count == 1) || (count % 2)) { retval = dsp5680xx_read(target, address + iter, 1, 1, - (uint8_t *) &data_old); + (uint8_t *)&data_old, ADDR_AUTOINCR); err_check_propagate(retval); if (count == 1) data_old = (((data_old & 0xff) << 8) | data[0]); /* preserve upper byte */ @@ -1403,12 +1406,16 @@ static int dsp5680xx_write_32(struct target *t, uint32_t a, uint32_t c, * @param size Bytes (1), Half words (2), Words (4). * @param count In bytes. * @param b buffer + * @param addr_autoinc Whether or not to auto-increment the address * * @return */ static int dsp5680xx_write(struct target *target, target_addr_t a, uint32_t size, uint32_t count, - const uint8_t *b) + const uint8_t *b, bool addr_autoincr) { + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + /* TODO Cannot write 32bit to odd address, will write 0x12345678 as 0x5678 0x0012 */ uint32_t address = a; @@ -1449,7 +1456,7 @@ static int dsp5680xx_write_buffer(struct target *t, target_addr_t a, uint32_t si const uint8_t *b) { check_halt_and_debug(t); - return dsp5680xx_write(t, a, 1, size, b); + return dsp5680xx_write(t, a, 1, size, b, ADDR_AUTOINCR); } /** @@ -1467,7 +1474,7 @@ static int dsp5680xx_read_buffer(struct target *target, target_addr_t address, u { check_halt_and_debug(target); /* The "/2" solves the byte/word addressing issue.*/ - return dsp5680xx_read(target, address, 2, size / 2, buffer); + return dsp5680xx_read(target, address, 2, size / 2, buffer, ADDR_AUTOINCR); } /** @@ -1544,7 +1551,7 @@ static int dsp5680xx_f_sim_reset(struct target *target) sim_addr = MC568013_SIM_BASE_ADDR + S_FILE_DATA_OFFSET; retval = dsp5680xx_write(target, sim_addr, 1, 2, - (const uint8_t *)&sim_cmd); + (const uint8_t *)&sim_cmd, ADDR_AUTOINCR); err_check_propagate(retval); } return retval; @@ -1983,7 +1990,7 @@ int dsp5680xx_f_wr(struct target *t, const uint8_t *b, uint32_t a, uint32_t coun if (!is_flash_lock) { retval = dsp5680xx_write(target, ram_addr, 1, len * 2, - (uint8_t *) pgm_write_pflash); + (uint8_t *)pgm_write_pflash, ADDR_AUTOINCR); err_check_propagate(retval); retval = dsp5680xx_execute_queue(); err_check_propagate(retval); diff --git a/src/target/esirisc.c b/src/target/esirisc.c index 0f76b5982e..541bf1bda2 100644 --- a/src/target/esirisc.c +++ b/src/target/esirisc.c @@ -353,12 +353,15 @@ static int esirisc_wait_debug_active(struct esirisc_common *esirisc, int ms) } static int esirisc_read_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr) { struct esirisc_common *esirisc = target_to_esirisc(target); struct esirisc_jtag *jtag_info = &esirisc->jtag_info; int retval; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + LOG_DEBUG("-"); int num_bits = 8 * size; @@ -402,12 +405,15 @@ static int esirisc_read_memory(struct target *target, target_addr_t address, } static int esirisc_write_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr) { struct esirisc_common *esirisc = target_to_esirisc(target); struct esirisc_jtag *jtag_info = &esirisc->jtag_info; int retval; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + LOG_DEBUG("-"); int num_bits = 8 * size; diff --git a/src/target/feroceon.c b/src/target/feroceon.c index 1e7eb0961f..b11e6b6491 100644 --- a/src/target/feroceon.c +++ b/src/target/feroceon.c @@ -449,7 +449,7 @@ static int feroceon_examine_debug_reason(struct target *target) } static int feroceon_bulk_write_memory(struct target *target, - target_addr_t address, uint32_t count, const uint8_t *buffer) + target_addr_t address, uint32_t count, const uint8_t *buffer, bool addr_autoincr) { int retval; struct arm *arm = target->arch_info; @@ -509,7 +509,7 @@ static int feroceon_bulk_write_memory(struct target *target, /* write DCC code to working area, using the non-optimized * memory write to avoid ending up here again */ retval = arm7_9_write_memory_no_opt(target, - arm7_9->dcc_working_area->address, 4, dcc_size/4, dcc_code_buf); + arm7_9->dcc_working_area->address, 4, dcc_size / 4, dcc_code_buf, addr_autoincr); if (retval != ERROR_OK) return retval; } diff --git a/src/target/hla_target.c b/src/target/hla_target.c index c1bda996ce..ae36663ece 100644 --- a/src/target/hla_target.c +++ b/src/target/hla_target.c @@ -591,10 +591,13 @@ static int adapter_step(struct target *target, int current, static int adapter_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, - uint8_t *buffer) + uint8_t *buffer, bool addr_autoincr) { struct hl_interface_s *adapter = target_to_adapter(target); + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + if (!count || !buffer) return ERROR_COMMAND_SYNTAX_ERROR; @@ -606,10 +609,13 @@ static int adapter_read_memory(struct target *target, target_addr_t address, static int adapter_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, - const uint8_t *buffer) + const uint8_t *buffer, bool addr_autoincr) { struct hl_interface_s *adapter = target_to_adapter(target); + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + if (!count || !buffer) return ERROR_COMMAND_SYNTAX_ERROR; diff --git a/src/target/ls1_sap.c b/src/target/ls1_sap.c index 9bd00c0e5f..2f989b6d86 100644 --- a/src/target/ls1_sap.c +++ b/src/target/ls1_sap.c @@ -170,8 +170,12 @@ static void ls1_sap_memory_write(struct jtag_tap *tap, uint32_t size, } static int ls1_sap_read_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t size, uint32_t count, uint8_t *buffer, + bool addr_autoincr) { + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + LOG_DEBUG("Reading memory at physical address 0x%" TARGET_PRIxADDR "; size %" PRIu32 "; count %" PRIu32, address, size, count); @@ -192,8 +196,11 @@ static int ls1_sap_read_memory(struct target *target, target_addr_t address, static int ls1_sap_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, - const uint8_t *buffer) + const uint8_t *buffer, bool addr_autoincr) { + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + LOG_DEBUG("Writing memory at physical address 0x%" TARGET_PRIxADDR "; size %" PRIu32 "; count %" PRIu32, address, size, count); diff --git a/src/target/mem_ap.c b/src/target/mem_ap.c index 61a9475e64..98b807ad22 100644 --- a/src/target/mem_ap.c +++ b/src/target/mem_ap.c @@ -234,10 +234,14 @@ static int mem_ap_get_gdb_reg_list(struct target *target, struct reg **reg_list[ } static int mem_ap_read_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t size, uint32_t count, uint8_t *buffer, + bool addr_autoincr) { struct mem_ap *mem_ap = target->arch_info; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + LOG_DEBUG("Reading memory at physical address " TARGET_ADDR_FMT "; size %" PRIu32 "; count %" PRIu32, address, size, count); @@ -249,10 +253,13 @@ static int mem_ap_read_memory(struct target *target, target_addr_t address, static int mem_ap_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, - const uint8_t *buffer) + const uint8_t *buffer, bool addr_autoincr) { struct mem_ap *mem_ap = target->arch_info; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + LOG_DEBUG("Writing memory at physical address " TARGET_ADDR_FMT "; size %" PRIu32 "; count %" PRIu32, address, size, count); diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c index ad98089614..ea55fcfe4a 100644 --- a/src/target/mips_m4k.c +++ b/src/target/mips_m4k.c @@ -1005,11 +1005,14 @@ static void mips_m4k_enable_watchpoints(struct target *target) } static int mips_m4k_read_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr) { struct mips32_common *mips32 = target_to_mips32(target); struct mips_ejtag *ejtag_info = &mips32->ejtag_info; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + LOG_DEBUG("address: " TARGET_ADDR_FMT ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count); @@ -1070,11 +1073,14 @@ static int mips_m4k_read_memory(struct target *target, target_addr_t address, } static int mips_m4k_write_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr) { struct mips32_common *mips32 = target_to_mips32(target); struct mips_ejtag *ejtag_info = &mips32->ejtag_info; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + LOG_DEBUG("address: " TARGET_ADDR_FMT ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count); diff --git a/src/target/mips_mips64.c b/src/target/mips_mips64.c index 9921e93807..6f604b66df 100644 --- a/src/target/mips_mips64.c +++ b/src/target/mips_mips64.c @@ -878,13 +878,16 @@ static int mips_mips64_remove_watchpoint(struct target *target, } static int mips_mips64_read_memory(struct target *target, uint64_t address, - uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr) { struct mips64_common *mips64 = target->arch_info; struct mips_ejtag *ejtag_info = &mips64->ejtag_info; int retval; void *t; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + if (target->state != TARGET_HALTED) { LOG_TARGET_ERROR(target, "not halted"); return ERROR_TARGET_NOT_HALTED; @@ -1007,12 +1010,15 @@ static int mips_mips64_bulk_write_memory(struct target *target, } static int mips_mips64_write_memory(struct target *target, uint64_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr) { struct mips64_common *mips64 = target->arch_info; struct mips_ejtag *ejtag_info = &mips64->ejtag_info; int retval; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + if (target->state != TARGET_HALTED) { LOG_TARGET_ERROR(target, "not halted"); return ERROR_TARGET_NOT_HALTED; diff --git a/src/target/openrisc/or1k.c b/src/target/openrisc/or1k.c index 8c38610805..fd3f1c7613 100644 --- a/src/target/openrisc/or1k.c +++ b/src/target/openrisc/or1k.c @@ -1018,11 +1018,14 @@ static int or1k_remove_watchpoint(struct target *target, } static int or1k_read_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr) { struct or1k_common *or1k = target_to_or1k(target); struct or1k_du *du_core = or1k_to_du(or1k); + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + LOG_DEBUG("Read memory at 0x%08" TARGET_PRIxADDR ", size: %" PRIu32 ", count: 0x%08" PRIx32, address, size, count); if (target->state != TARGET_HALTED) { @@ -1045,11 +1048,14 @@ static int or1k_read_memory(struct target *target, target_addr_t address, } static int or1k_write_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr) { struct or1k_common *or1k = target_to_or1k(target); struct or1k_du *du_core = or1k_to_du(or1k); + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + LOG_DEBUG("Write memory at 0x%08" TARGET_PRIxADDR ", size: %" PRIu32 ", count: 0x%08" PRIx32, address, size, count); if (target->state != TARGET_HALTED) { diff --git a/src/target/riscv/riscv-011.c b/src/target/riscv/riscv-011.c index be296cdd8c..1fe79f1c03 100644 --- a/src/target/riscv/riscv-011.c +++ b/src/target/riscv/riscv-011.c @@ -2155,8 +2155,11 @@ static int setup_write_memory(struct target *target, uint32_t size) } static int write_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr) { + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + riscv011_info_t *info = get_info(target); jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE); diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 2f4a8fe2e6..666174a020 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -64,7 +64,7 @@ static int register_write_direct(struct target *target, unsigned number, static int read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer, uint32_t increment); static int write_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer); + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr); /** * Since almost everything can be accomplish by scanning the dbus register, all @@ -1262,7 +1262,7 @@ static int scratch_write64(struct target *target, scratch_mem_t *scratch, value >> 48, value >> 56 }; - if (write_memory(target, scratch->debug_address, 4, 2, buffer) != ERROR_OK) + if (write_memory(target, scratch->debug_address, 4, 2, buffer, ADDR_AUTOINCR) != ERROR_OK) return ERROR_FAIL; } break; @@ -3979,8 +3979,11 @@ error: } static int write_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr) { + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + if (size != 1 && size != 2 && size != 4 && size != 8 && size != 16) { LOG_ERROR("BUG: Unsupported size for memory write: %d", size); return ERROR_FAIL; diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 9cd4922d20..a3f2848212 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -1689,8 +1689,10 @@ static int riscv_virt2phys(struct target *target, target_addr_t virtual, target_ } static int riscv_read_phys_memory(struct target *target, target_addr_t phys_address, - uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr) { + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; RISCV_INFO(r); if (riscv_select_current_hart(target) != ERROR_OK) return ERROR_FAIL; @@ -1698,8 +1700,11 @@ static int riscv_read_phys_memory(struct target *target, target_addr_t phys_addr } static int riscv_read_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr) { + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + if (count == 0) { LOG_WARNING("0-length read from 0x%" TARGET_PRIxADDR, address); return ERROR_OK; @@ -1717,17 +1722,20 @@ static int riscv_read_memory(struct target *target, target_addr_t address, } static int riscv_write_phys_memory(struct target *target, target_addr_t phys_address, - uint32_t size, uint32_t count, const uint8_t *buffer) + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr) { if (riscv_select_current_hart(target) != ERROR_OK) return ERROR_FAIL; struct target_type *tt = get_target_type(target); - return tt->write_memory(target, phys_address, size, count, buffer); + return tt->write_memory(target, phys_address, size, count, buffer, addr_autoincr); } static int riscv_write_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr) { + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + if (count == 0) { LOG_WARNING("0-length write to 0x%" TARGET_PRIxADDR, address); return ERROR_OK; @@ -1741,7 +1749,7 @@ static int riscv_write_memory(struct target *target, target_addr_t address, address = physical_addr; struct target_type *tt = get_target_type(target); - return tt->write_memory(target, address, size, count, buffer); + return tt->write_memory(target, address, size, count, buffer, ADDR_AUTOINCR); } static const char *riscv_get_gdb_arch(const struct target *target) @@ -2162,7 +2170,7 @@ static int sample_memory(struct target *target) result = riscv_read_phys_memory( target, r->sample_config.bucket[i].address, r->sample_config.bucket[i].size_bytes, 1, - r->sample_buf.buf + r->sample_buf.used + 1); + r->sample_buf.buf + r->sample_buf.used + 1, ADDR_AUTOINCR); if (result == ERROR_OK) r->sample_buf.used += 1 + r->sample_config.bucket[i].size_bytes; else diff --git a/src/target/stm8.c b/src/target/stm8.c index 227101b6f0..d40892d4f4 100644 --- a/src/target/stm8.c +++ b/src/target/stm8.c @@ -735,10 +735,13 @@ static int stm8_write_flash(struct target *target, enum mem_type type, static int stm8_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, - const uint8_t *buffer) + const uint8_t *buffer, bool addr_autoincr) { struct stm8_common *stm8 = target_to_stm8(target); + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32, @@ -768,8 +771,11 @@ static int stm8_write_memory(struct target *target, target_addr_t address, } static int stm8_read_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr) { + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + LOG_DEBUG("address: 0x%8.8" TARGET_PRIxADDR ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32, diff --git a/src/target/target.c b/src/target/target.c index 5168305dee..5b8c57aca5 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -1245,7 +1245,7 @@ int target_read_memory(struct target *target, LOG_ERROR("Target %s doesn't support read_memory", target_name(target)); return ERROR_FAIL; } - return target->type->read_memory(target, address, size, count, buffer); + return target->type->read_memory(target, address, size, count, buffer, ADDR_AUTOINCR); } int target_read_phys_memory(struct target *target, @@ -1259,7 +1259,7 @@ int target_read_phys_memory(struct target *target, LOG_ERROR("Target %s doesn't support read_phys_memory", target_name(target)); return ERROR_FAIL; } - return target->type->read_phys_memory(target, address, size, count, buffer); + return target->type->read_phys_memory(target, address, size, count, buffer, ADDR_AUTOINCR); } int target_write_memory(struct target *target, @@ -1273,7 +1273,7 @@ int target_write_memory(struct target *target, LOG_ERROR("Target %s doesn't support write_memory", target_name(target)); return ERROR_FAIL; } - return target->type->write_memory(target, address, size, count, buffer); + return target->type->write_memory(target, address, size, count, buffer, ADDR_AUTOINCR); } int target_write_phys_memory(struct target *target, @@ -1287,7 +1287,7 @@ int target_write_phys_memory(struct target *target, LOG_ERROR("Target %s doesn't support write_phys_memory", target_name(target)); return ERROR_FAIL; } - return target->type->write_phys_memory(target, address, size, count, buffer); + return target->type->write_phys_memory(target, address, size, count, buffer, ADDR_AUTOINCR); } int target_add_breakpoint(struct target *target, diff --git a/src/target/target.h b/src/target/target.h index d5c0e0e8c7..274abfb0fb 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -799,6 +799,7 @@ int target_profiling_default(struct target *target, uint32_t *samples, uint32_t #define ERROR_TARGET_ALGO_EXIT (-313) #define ERROR_TARGET_SIZE_NOT_SUPPORTED (-314) #define ERROR_TARGET_PACKING_NOT_SUPPORTED (-315) +#define ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED (-316) extern bool get_target_reset_nag(void); diff --git a/src/target/target_type.h b/src/target/target_type.h index bc42c2d16e..3bf5d6f2b9 100644 --- a/src/target/target_type.h +++ b/src/target/target_type.h @@ -116,13 +116,13 @@ struct target_type { * directly, use target_read_memory() instead. */ int (*read_memory)(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer); + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr); /** * Target memory write callback. Do @b not call this function * directly, use target_write_memory() instead. */ int (*write_memory)(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer); + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr); /* Default implementation will do some fancy alignment to improve performance, target can override */ int (*read_buffer)(struct target *target, target_addr_t address, @@ -260,13 +260,13 @@ struct target_type { * Default implementation is to call read_memory. */ int (*read_phys_memory)(struct target *target, target_addr_t phys_address, - uint32_t size, uint32_t count, uint8_t *buffer); + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr); /* * same as read_phys_memory, except that it writes... */ int (*write_phys_memory)(struct target *target, target_addr_t phys_address, - uint32_t size, uint32_t count, const uint8_t *buffer); + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr); int (*mmu)(struct target *target, int *enabled); @@ -350,4 +350,7 @@ extern struct target_type testee_target; extern struct target_type xscale_target; extern struct target_type xtensa_chip_target; +#define ADDR_NO_AUTOINCR false +#define ADDR_AUTOINCR true + #endif /* OPENOCD_TARGET_TARGET_TYPE_H */ diff --git a/src/target/x86_32_common.c b/src/target/x86_32_common.c index ecaf52b3ab..8cc9ede1a7 100644 --- a/src/target/x86_32_common.c +++ b/src/target/x86_32_common.c @@ -133,11 +133,15 @@ int x86_32_common_virt2phys(struct target *t, target_addr_t address, target_addr } int x86_32_common_read_phys_mem(struct target *t, target_addr_t phys_address, - uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t size, uint32_t count, uint8_t *buffer, + bool addr_autoincr) { struct x86_32_common *x86_32 = target_to_x86_32(t); int error; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + error = read_phys_mem(t, phys_address, size, count, buffer); if (error != ERROR_OK) return error; @@ -217,12 +221,16 @@ static int read_phys_mem(struct target *t, uint32_t phys_address, } int x86_32_common_write_phys_mem(struct target *t, target_addr_t phys_address, - uint32_t size, uint32_t count, const uint8_t *buffer) + uint32_t size, uint32_t count, const uint8_t *buffer, + bool addr_autoincr) { struct x86_32_common *x86_32 = target_to_x86_32(t); int error = ERROR_OK; uint8_t *newbuffer = NULL; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + check_not_halted(t); if (!count || !buffer || !phys_address) { LOG_ERROR("%s invalid params count=0x%" PRIx32 ", buf=%p, addr=" TARGET_ADDR_FMT, @@ -468,7 +476,7 @@ int calcaddr_physfromlin(struct target *t, target_addr_t addr, target_addr_t *ph uint32_t pdpt_base = cr3 & 0xFFFFF000; /* lower 12 bits of CR3 must always be 0 */ uint32_t pdpt_index = (addr & 0xC0000000) >> 30; /* A[31:30] index to PDPT */ uint32_t pdpt_addr = pdpt_base + (8 * pdpt_index); - if (x86_32_common_read_phys_mem(t, pdpt_addr, 4, 2, entry_buffer) != ERROR_OK) { + if (x86_32_common_read_phys_mem(t, pdpt_addr, 4, 2, entry_buffer, ADDR_AUTOINCR) != ERROR_OK) { LOG_ERROR("%s couldn't read page directory pointer table entry at 0x%08" PRIx32, __func__, pdpt_addr); return ERROR_FAIL; @@ -483,7 +491,7 @@ int calcaddr_physfromlin(struct target *t, target_addr_t addr, target_addr_t *ph uint32_t pd_base = pdpt_entry & 0xFFFFF000; /* A[31:12] is PageTable/Page Base Address */ uint32_t pd_index = (addr & 0x3FE00000) >> 21; /* A[29:21] index to PD entry with PAE */ uint32_t pd_addr = pd_base + (8 * pd_index); - if (x86_32_common_read_phys_mem(t, pd_addr, 4, 2, entry_buffer) != ERROR_OK) { + if (x86_32_common_read_phys_mem(t, pd_addr, 4, 2, entry_buffer, ADDR_AUTOINCR) != ERROR_OK) { LOG_ERROR("%s couldn't read page directory entry at 0x%08" PRIx32, __func__, pd_addr); return ERROR_FAIL; @@ -508,7 +516,7 @@ int calcaddr_physfromlin(struct target *t, target_addr_t addr, target_addr_t *ph uint32_t pt_base = (uint32_t)(pd_entry & 0x00000000FFFFF000); /*[31:12]*/ uint32_t pt_index = (addr & 0x001FF000) >> 12; /*[20:12]*/ uint32_t pt_addr = pt_base + (8 * pt_index); - if (x86_32_common_read_phys_mem(t, pt_addr, 4, 2, entry_buffer) != ERROR_OK) { + if (x86_32_common_read_phys_mem(t, pt_addr, 4, 2, entry_buffer, ADDR_AUTOINCR) != ERROR_OK) { LOG_ERROR("%s couldn't read page table entry at 0x%08" PRIx32, __func__, pt_addr); return ERROR_FAIL; } @@ -527,7 +535,7 @@ int calcaddr_physfromlin(struct target *t, target_addr_t addr, target_addr_t *ph uint32_t pd_base = cr3 & 0xFFFFF000; /* lower 12 bits of CR3 must always be 0 */ uint32_t pd_index = (addr & 0xFFC00000) >> 22; /* A[31:22] index to PD entry */ uint32_t pd_addr = pd_base + (4 * pd_index); - if (x86_32_common_read_phys_mem(t, pd_addr, 4, 1, entry_buffer) != ERROR_OK) { + if (x86_32_common_read_phys_mem(t, pd_addr, 4, 1, entry_buffer, ADDR_AUTOINCR) != ERROR_OK) { LOG_ERROR("%s couldn't read page directory entry at 0x%08" PRIx32, __func__, pd_addr); return ERROR_FAIL; } @@ -549,7 +557,7 @@ int calcaddr_physfromlin(struct target *t, target_addr_t addr, target_addr_t *ph uint32_t pt_base = pd_entry & 0xFFFFF000; /* A[31:12] is PageTable/Page Base Address */ uint32_t pt_index = (addr & 0x003FF000) >> 12; /* A[21:12] index to page table entry */ uint32_t pt_addr = pt_base + (4 * pt_index); - if (x86_32_common_read_phys_mem(t, pt_addr, 4, 1, entry_buffer) != ERROR_OK) { + if (x86_32_common_read_phys_mem(t, pt_addr, 4, 1, entry_buffer, ADDR_AUTOINCR) != ERROR_OK) { LOG_ERROR("%s couldn't read page table entry at 0x%08" PRIx32, __func__, pt_addr); return ERROR_FAIL; } @@ -566,10 +574,14 @@ int calcaddr_physfromlin(struct target *t, target_addr_t addr, target_addr_t *ph } int x86_32_common_read_memory(struct target *t, target_addr_t addr, - uint32_t size, uint32_t count, uint8_t *buf) + uint32_t size, uint32_t count, uint8_t *buf, bool addr_autoincr) { int retval = ERROR_OK; struct x86_32_common *x86_32 = target_to_x86_32(t); + + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + LOG_DEBUG("addr=" TARGET_ADDR_FMT ", size=%" PRIu32 ", count=0x%" PRIx32 ", buf=%p", addr, size, count, buf); check_not_halted(t); @@ -600,7 +612,7 @@ int x86_32_common_read_memory(struct target *t, target_addr_t addr, */ if (retval == ERROR_OK - && x86_32_common_read_phys_mem(t, physaddr, size, count, buf) != ERROR_OK) { + && x86_32_common_read_phys_mem(t, physaddr, size, count, buf, ADDR_AUTOINCR) != ERROR_OK) { LOG_ERROR("%s failed to read memory from physical address " TARGET_ADDR_FMT, __func__, physaddr); } @@ -612,7 +624,7 @@ int x86_32_common_read_memory(struct target *t, target_addr_t addr, } } else { /* paging is off - linear address is physical address */ - if (x86_32_common_read_phys_mem(t, addr, size, count, buf) != ERROR_OK) { + if (x86_32_common_read_phys_mem(t, addr, size, count, buf, ADDR_AUTOINCR) != ERROR_OK) { LOG_ERROR("%s failed to read memory from address " TARGET_ADDR_FMT, __func__, addr); retval = ERROR_FAIL; @@ -623,7 +635,8 @@ int x86_32_common_read_memory(struct target *t, target_addr_t addr, } int x86_32_common_write_memory(struct target *t, target_addr_t addr, - uint32_t size, uint32_t count, const uint8_t *buf) + uint32_t size, uint32_t count, const uint8_t *buf, + bool addr_autoincr) { int retval = ERROR_OK; struct x86_32_common *x86_32 = target_to_x86_32(t); @@ -655,7 +668,7 @@ int x86_32_common_write_memory(struct target *t, target_addr_t addr, * This should be fixed together with bulk memory reads */ if (retval == ERROR_OK - && x86_32_common_write_phys_mem(t, physaddr, size, count, buf) != ERROR_OK) { + && x86_32_common_write_phys_mem(t, physaddr, size, count, buf, addr_autoincr) != ERROR_OK) { LOG_ERROR("%s failed to write memory to physical address " TARGET_ADDR_FMT, __func__, physaddr); } @@ -668,7 +681,7 @@ int x86_32_common_write_memory(struct target *t, target_addr_t addr, } else { /* paging is off - linear address is physical address */ - if (x86_32_common_write_phys_mem(t, addr, size, count, buf) != ERROR_OK) { + if (x86_32_common_write_phys_mem(t, addr, size, count, buf, addr_autoincr) != ERROR_OK) { LOG_ERROR("%s failed to write memory to address " TARGET_ADDR_FMT, __func__, addr); retval = ERROR_FAIL; diff --git a/src/target/x86_32_common.h b/src/target/x86_32_common.h index 7392447a68..ebbdbe7cfc 100644 --- a/src/target/x86_32_common.h +++ b/src/target/x86_32_common.h @@ -302,13 +302,13 @@ int x86_32_common_init_arch_info(struct target *target, int x86_32_common_mmu(struct target *t, int *enabled); int x86_32_common_virt2phys(struct target *t, target_addr_t address, target_addr_t *physical); int x86_32_common_read_phys_mem(struct target *t, target_addr_t phys_address, - uint32_t size, uint32_t count, uint8_t *buffer); + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr); int x86_32_common_write_phys_mem(struct target *t, target_addr_t phys_address, - uint32_t size, uint32_t count, const uint8_t *buffer); + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr); int x86_32_common_read_memory(struct target *t, target_addr_t addr, - uint32_t size, uint32_t count, uint8_t *buf); + uint32_t size, uint32_t count, uint8_t *buf, bool addr_autoincr); int x86_32_common_write_memory(struct target *t, target_addr_t addr, - uint32_t size, uint32_t count, const uint8_t *buf); + uint32_t size, uint32_t count, const uint8_t *buf, bool addr_autoincr); int x86_32_common_read_io(struct target *t, uint32_t addr, uint32_t size, uint8_t *buf); int x86_32_common_write_io(struct target *t, uint32_t addr, diff --git a/src/target/xscale.c b/src/target/xscale.c index fbf43516d0..be77cd5690 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -1768,13 +1768,16 @@ dirty: } static int xscale_read_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr) { struct xscale_common *xscale = target_to_xscale(target); uint32_t *buf32; uint32_t i; int retval; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + LOG_DEBUG("address: " TARGET_ADDR_FMT ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32, address, size, @@ -1854,13 +1857,13 @@ static int xscale_read_memory(struct target *target, target_addr_t address, } static int xscale_read_phys_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, uint8_t *buffer) + uint32_t size, uint32_t count, uint8_t *buffer, bool addr_autoincr) { struct xscale_common *xscale = target_to_xscale(target); /* with MMU inactive, there are only physical addresses */ if (!xscale->armv4_5_mmu.mmu_enabled) - return xscale_read_memory(target, address, size, count, buffer); + return xscale_read_memory(target, address, size, count, buffer, addr_autoincr); /** \todo: provide a non-stub implementation of this routine. */ LOG_ERROR("%s: %s is not implemented. Disable MMU?", @@ -1869,11 +1872,14 @@ static int xscale_read_phys_memory(struct target *target, target_addr_t address, } static int xscale_write_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr) { struct xscale_common *xscale = target_to_xscale(target); int retval; + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + LOG_DEBUG("address: " TARGET_ADDR_FMT ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32, address, size, @@ -1953,13 +1959,13 @@ static int xscale_write_memory(struct target *target, target_addr_t address, } static int xscale_write_phys_memory(struct target *target, target_addr_t address, - uint32_t size, uint32_t count, const uint8_t *buffer) + uint32_t size, uint32_t count, const uint8_t *buffer, bool addr_autoincr) { struct xscale_common *xscale = target_to_xscale(target); /* with MMU inactive, there are only physical addresses */ if (!xscale->armv4_5_mmu.mmu_enabled) - return xscale_write_memory(target, address, size, count, buffer); + return xscale_write_memory(target, address, size, count, buffer, addr_autoincr); /** \todo: provide a non-stub implementation of this routine. */ LOG_ERROR("%s: %s is not implemented. Disable MMU?", diff --git a/src/target/xtensa/xtensa.c b/src/target/xtensa/xtensa.c index fb7748aa2d..6671869ab8 100644 --- a/src/target/xtensa/xtensa.c +++ b/src/target/xtensa/xtensa.c @@ -17,6 +17,8 @@ #include <helper/align.h> #include <target/register.h> #include <target/algorithm.h> +#include <target/target.h> +#include <target/target_type.h> #include "xtensa_chip.h" #include "xtensa.h" @@ -1930,8 +1932,12 @@ static bool xtensa_memory_op_validate_range(struct xtensa *xtensa, target_addr_t return true; } -int xtensa_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer) +int xtensa_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, + uint8_t *buffer, bool addr_autoincr) { + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + struct xtensa *xtensa = target_to_xtensa(target); /* We are going to read memory in 32-bit increments. This may not be what the calling * function expects, so we may need to allocate a temp buffer and read into that first. */ @@ -1998,7 +2004,7 @@ int xtensa_read_memory(struct target *target, target_addr_t address, uint32_t si /* Disable fast memory access instructions and retry before reporting an error */ LOG_TARGET_DEBUG(target, "Disabling LDDR32.P/SDDR32.P"); xtensa->probe_lsddr32p = 0; - res = xtensa_read_memory(target, address, size, count, albuff); + res = xtensa_read_memory(target, address, size, count, albuff, ADDR_AUTOINCR); bswap = false; } else { LOG_TARGET_WARNING(target, "Failed reading %d bytes at address "TARGET_ADDR_FMT, @@ -2016,15 +2022,19 @@ int xtensa_read_memory(struct target *target, target_addr_t address, uint32_t si int xtensa_read_buffer(struct target *target, target_addr_t address, uint32_t count, uint8_t *buffer) { /* xtensa_read_memory can also read unaligned stuff. Just pass through to that routine. */ - return xtensa_read_memory(target, address, 1, count, buffer); + return xtensa_read_memory(target, address, 1, count, buffer, ADDR_AUTOINCR); } int xtensa_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, - const uint8_t *buffer) + const uint8_t *buffer, + bool addr_autoincr) { + if (addr_autoincr == ADDR_NO_AUTOINCR) + return ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED; + /* This memory write function can get thrown nigh everything into it, from * aligned uint32 writes to unaligned uint8ths. The Xtensa memory doesn't always * accept anything but aligned uint32 writes, though. That is why we convert @@ -2169,7 +2179,7 @@ int xtensa_write_memory(struct target *target, /* Disable fast memory access instructions and retry before reporting an error */ LOG_TARGET_INFO(target, "Disabling LDDR32.P/SDDR32.P"); xtensa->probe_lsddr32p = 0; - res = xtensa_write_memory(target, address, size, count, buffer); + res = xtensa_write_memory(target, address, size, count, buffer, ADDR_AUTOINCR); } else { LOG_TARGET_WARNING(target, "Failed writing %d bytes at address "TARGET_ADDR_FMT, count * size, address); @@ -2221,7 +2231,7 @@ int xtensa_write_memory(struct target *target, int xtensa_write_buffer(struct target *target, target_addr_t address, uint32_t count, const uint8_t *buffer) { /* xtensa_write_memory can handle everything. Just pass on to that. */ - return xtensa_write_memory(target, address, 1, count, buffer); + return xtensa_write_memory(target, address, 1, count, buffer, ADDR_AUTOINCR); } int xtensa_checksum_memory(struct target *target, target_addr_t address, uint32_t count, uint32_t *checksum) @@ -3094,7 +3104,7 @@ static int xtensa_gdbqc_qxtreg(struct target *target, const char *packet, char * */ unsigned int memop_size = (xtensa->spill_loc & 3) ? 1 : 4; int status = xtensa_read_memory(target, xtensa->spill_loc, memop_size, - xtensa->spill_bytes / memop_size, xtensa->spill_buf); + xtensa->spill_bytes / memop_size, xtensa->spill_buf, ADDR_AUTOINCR); if (status != ERROR_OK) { LOG_ERROR("Spill memory save"); error = XT_QERR_MEM; @@ -3122,7 +3132,7 @@ static int xtensa_gdbqc_qxtreg(struct target *target, const char *packet, char * goto xtensa_gdbqc_qxtreg_fail; } status = xtensa_write_memory(target, xtensa->spill_loc, memop_size, - reglen / memop_size, regbuf); + reglen / memop_size, regbuf, ADDR_AUTOINCR); if (status != ERROR_OK) { LOG_ERROR("TIE value store"); error = XT_QERR_MEM; @@ -3155,7 +3165,7 @@ static int xtensa_gdbqc_qxtreg(struct target *target, const char *packet, char * strcpy(*response_p, "OK"); } else { /* TIE read succeeded; copy result from spill memory */ - status = xtensa_read_memory(target, xtensa->spill_loc, memop_size, reglen, regbuf); + status = xtensa_read_memory(target, xtensa->spill_loc, memop_size, reglen, regbuf, ADDR_AUTOINCR); if (status != ERROR_OK) { LOG_TARGET_ERROR(target, "TIE result read"); tieop_status = status; @@ -3170,7 +3180,7 @@ static int xtensa_gdbqc_qxtreg(struct target *target, const char *packet, char * /* Restore spill memory first, then report any previous errors */ status = xtensa_write_memory(target, xtensa->spill_loc, memop_size, - xtensa->spill_bytes / memop_size, xtensa->spill_buf); + xtensa->spill_bytes / memop_size, xtensa->spill_buf, ADDR_AUTOINCR); if (status != ERROR_OK) { LOG_ERROR("Spill memory restore"); error = XT_QERR_MEM; diff --git a/src/target/xtensa/xtensa.h b/src/target/xtensa/xtensa.h index a220021a68..d7fd5b5711 100644 --- a/src/target/xtensa/xtensa.h +++ b/src/target/xtensa/xtensa.h @@ -390,13 +390,19 @@ int xtensa_do_resume(struct target *target); int xtensa_step(struct target *target, int current, target_addr_t address, int handle_breakpoints); int xtensa_do_step(struct target *target, int current, target_addr_t address, int handle_breakpoints); int xtensa_mmu_is_enabled(struct target *target, int *enabled); -int xtensa_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer); +int xtensa_read_memory(struct target *target, + target_addr_t address, + uint32_t size, + uint32_t count, + uint8_t *buffer, + bool addr_autoincr); int xtensa_read_buffer(struct target *target, target_addr_t address, uint32_t count, uint8_t *buffer); int xtensa_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, - const uint8_t *buffer); + const uint8_t *buffer, + bool addr_autoincr); int xtensa_write_buffer(struct target *target, target_addr_t address, uint32_t count, const uint8_t *buffer); int xtensa_checksum_memory(struct target *target, target_addr_t address, uint32_t count, uint32_t *checksum); int xtensa_assert_reset(struct target *target); --