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/+/8289
-- gerrit commit 00ca39fb1ca4bd5a7b359f8742409ecadee515da Author: Bernhard Rosenkränzer <b...@baylibre.com> Date: Sat May 18 18:44:01 2024 +0200 target: Add *_no_addrincr() functions Add target_read_memory_no_addrincr(), target_read_phys_memory_no_addrincr(), target_write_memory_no_addrincr(), target_write_phys_memory_no_addrincr() This is the second in a series of 4 patches replacing https://review.openocd.org/c/openocd/+/8259 Change-Id: Ie154060b7f627b6e17fcc23f6e5cf36ba1b22322 Signed-off-by: Bernhard Rosenkränzer <b...@baylibre.com> Cc: Antonio Borneo <borneo.anto...@gmail.com> diff --git a/src/target/target.c b/src/target/target.c index 5b8c57aca5..c4ae6a216e 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -1248,6 +1248,29 @@ int target_read_memory(struct target *target, return target->type->read_memory(target, address, size, count, buffer, ADDR_AUTOINCR); } +int target_read_memory_no_addrincr(struct target *target, + target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer) +{ + if (!target_was_examined(target)) { + LOG_ERROR("Target not examined yet"); + return ERROR_FAIL; + } + if (!target->type->read_memory) { + LOG_ERROR("Target %s doesn't support read_memory", target_name(target)); + return ERROR_FAIL; + } + int ret = target->type->read_memory(target, address, size, count, buffer, ADDR_NO_AUTOINCR); + if (ret == ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED) { + LOG_DEBUG("Target %s doesn't support read_memory without address auto-increment, simulating", target_name(target)); + for(uint32_t i = 0; i < count; i++) { + ret = target->type->read_memory(target, address, size, 1, buffer, ADDR_AUTOINCR); + if (ret != ERROR_OK) + return ret; + } + } + return ret; +} + int target_read_phys_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer) { @@ -1262,6 +1285,29 @@ int target_read_phys_memory(struct target *target, return target->type->read_phys_memory(target, address, size, count, buffer, ADDR_AUTOINCR); } +int target_read_phys_memory_no_addrincr(struct target *target, + target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer) +{ + if (!target_was_examined(target)) { + LOG_ERROR("Target not examined yet"); + return ERROR_FAIL; + } + if (!target->type->read_phys_memory) { + LOG_ERROR("Target %s doesn't support read_phys_memory", target_name(target)); + return ERROR_FAIL; + } + int ret = target->type->read_phys_memory(target, address, size, count, buffer, ADDR_NO_AUTOINCR); + if (ret == ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED) { + LOG_DEBUG("Target %s doesn't support read_phys_memory without address auto-increment, simulating", target_name(target)); + for(uint32_t i = 0; i < count; i++) { + ret = target->type->read_phys_memory(target, address, size, 1, buffer, ADDR_AUTOINCR); + if (ret != ERROR_OK) + return ret; + } + } + return ret; +} + int target_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer) { @@ -1276,6 +1322,29 @@ int target_write_memory(struct target *target, return target->type->write_memory(target, address, size, count, buffer, ADDR_AUTOINCR); } +int target_write_memory_no_addrincr(struct target *target, + target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer) +{ + if (!target_was_examined(target)) { + LOG_ERROR("Target not examined yet"); + return ERROR_FAIL; + } + if (!target->type->write_memory) { + LOG_ERROR("Target %s doesn't support write_memory", target_name(target)); + return ERROR_FAIL; + } + int ret = target->type->write_memory(target, address, size, count, buffer, ADDR_NO_AUTOINCR); + if (ret == ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED) { + LOG_DEBUG("Target %s doesn't support write_memory without address auto-increment, simulating", target_name(target)); + for(uint32_t i = 0; i < count; i++) { + ret = target->type->write_memory(target, address, size, 1, buffer, ADDR_AUTOINCR); + if (ret != ERROR_OK) + return ret; + } + } + return ret; +} + int target_write_phys_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer) { @@ -1290,6 +1359,29 @@ int target_write_phys_memory(struct target *target, return target->type->write_phys_memory(target, address, size, count, buffer, ADDR_AUTOINCR); } +int target_write_phys_memory_no_addrincr(struct target *target, + target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer) +{ + if (!target_was_examined(target)) { + LOG_ERROR("Target not examined yet"); + return ERROR_FAIL; + } + if (!target->type->write_phys_memory) { + LOG_ERROR("Target %s doesn't support write_phys_memory", target_name(target)); + return ERROR_FAIL; + } + int ret = target->type->write_phys_memory(target, address, size, count, buffer, ADDR_NO_AUTOINCR); + if (ret == ERROR_TARGET_NOAUTOINCR_NOT_SUPPORTED) { + LOG_DEBUG("Target %s doesn't support write_phys_memory without address auto-increment, simulating", target_name(target)); + for(uint32_t i = 0; i < count; i++) { + ret = target->type->write_phys_memory(target, address, size, 1, buffer, ADDR_AUTOINCR); + if (ret != ERROR_OK) + return ret; + } + } + return ret; +} + int target_add_breakpoint(struct target *target, struct breakpoint *breakpoint) { diff --git a/src/target/target.h b/src/target/target.h index 274abfb0fb..c34b83bcf7 100644 --- a/src/target/target.h +++ b/src/target/target.h @@ -604,6 +604,16 @@ int target_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer); int target_read_phys_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer); +/** + * Read @a count items of @a size bytes from the memory of @a target at + * the @a address given without incrementing the address. + * + * This routine is a wrapper for target->type->read_memory. + */ +int target_read_memory_no_addrincr(struct target *target, + target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer); +int target_read_phys_memory_no_addrincr(struct target *target, + target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer); /** * Write @a count items of @a size bytes to the memory of @a target at * the @a address given. @a address must be aligned to @a size @@ -625,6 +635,27 @@ int target_write_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer); int target_write_phys_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer); +/** + * Write @a count items of @a size bytes to the memory of @a target at + * the @a address given, without incrementing the address. + * @a address must be aligned to @a size in target memory. + * + * The endianness is the same in the host and target memory for this + * function. + * + * \todo TODO: + * Really @a buffer should have been defined as "const void *" and + * @a buffer should have been aligned to @a size in the host memory. + * + * This is not enforced via e.g. assert's today and e.g. the + * target_write_buffer fn breaks this assumption. + * + * This routine is wrapper for target->type->write_memory. + */ +int target_write_memory_no_addrincr(struct target *target, + target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer); +int target_write_phys_memory_no_addrincr(struct target *target, + target_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer); /* * Write to target memory using the virtual address. --