src/target/mips_m4k : add fast read method 64/7564/9
authorFrançois LEGAL <devel@thom.fr.eu.org>
Wed, 29 Mar 2023 15:46:38 +0000 (17:46 +0200)
committerAntonio Borneo <borneo.antonio@gmail.com>
Fri, 7 Apr 2023 21:46:36 +0000 (21:46 +0000)
Add the fast read method to speed up flash verification
after programming. Works the same as fast write already
implemented.

Signed-off-by: François LEGAL <devel@thom.fr.eu.org>
Change-Id: I74611a3542a88212f0483ec8ee368aba3d1f03c7
Reviewed-on: https://review.openocd.org/c/openocd/+/7564
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
src/target/mips_m4k.c

index d3b07585ddc28ea96cd1f0014345096941788464..14e3f3b27ae655aec04dfba2d89b7f701dc464b7 100644 (file)
@@ -36,6 +36,8 @@ static int mips_m4k_internal_restore(struct target *target, int current,
 static int mips_m4k_halt(struct target *target);
 static int mips_m4k_bulk_write_memory(struct target *target, target_addr_t address,
                uint32_t count, const uint8_t *buffer);
+static int mips_m4k_bulk_read_memory(struct target *target, target_addr_t address,
+               uint32_t count, uint8_t *buffer);
 
 static int mips_m4k_examine_debug_reason(struct target *target)
 {
@@ -1021,6 +1023,12 @@ static int mips_m4k_read_memory(struct target *target, target_addr_t address,
        if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
                return ERROR_TARGET_UNALIGNED_ACCESS;
 
+       if (size == 4 && count > 32) {
+               int retval = mips_m4k_bulk_read_memory(target, address, count, buffer);
+               if (retval == ERROR_OK)
+                       return ERROR_OK;
+               LOG_WARNING("Falling back to non-bulk read");
+       }
        /* since we don't know if buffer is aligned, we allocate new mem that is always aligned */
        void *t = NULL;
 
@@ -1249,6 +1257,71 @@ static int mips_m4k_bulk_write_memory(struct target *target, target_addr_t addre
        return retval;
 }
 
+static int mips_m4k_bulk_read_memory(struct target *target, target_addr_t address,
+               uint32_t count, uint8_t *buffer)
+{
+       struct mips32_common *mips32 = target_to_mips32(target);
+       struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
+       struct working_area *fast_data_area;
+       int retval;
+       int write_t = 0;
+
+       LOG_DEBUG("address: " TARGET_ADDR_FMT ", count: 0x%8.8" PRIx32 "",
+                       address, count);
+
+       /* check alignment */
+       if (address & 0x3u)
+               return ERROR_TARGET_UNALIGNED_ACCESS;
+
+       if (!mips32->fast_data_area) {
+               /* Get memory for block read handler
+                * we preserve this area between calls and gain a speed increase
+                * of about 3kb/sec when reading flash
+                * this will be released/nulled by the system when the target is resumed or reset */
+               retval = target_alloc_working_area(target,
+                               MIPS32_FASTDATA_HANDLER_SIZE,
+                               &mips32->fast_data_area);
+               if (retval != ERROR_OK) {
+                       LOG_ERROR("No working area available");
+                       return retval;
+               }
+
+               /* reset fastadata state so the algo get reloaded */
+               ejtag_info->fast_access_save = -1;
+       }
+
+       fast_data_area = mips32->fast_data_area;
+
+       if (address < (fast_data_area->address + fast_data_area->size) &&
+                       fast_data_area->address < (address + count)) {
+               LOG_ERROR("fast_data (" TARGET_ADDR_FMT ") is within read area "
+                               "(" TARGET_ADDR_FMT "-" TARGET_ADDR_FMT ").",
+                               fast_data_area->address, address, address + count);
+               LOG_ERROR("Change work-area-phys or load_image address!");
+               return ERROR_FAIL;
+       }
+
+       /* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */
+       /* but byte array represents target endianness                      */
+       uint32_t *t = malloc(count * sizeof(uint32_t));
+       if (!t) {
+               LOG_ERROR("Out of memory");
+               return ERROR_FAIL;
+       }
+
+       retval = mips32_pracc_fastdata_xfer(ejtag_info, mips32->fast_data_area, write_t, address,
+                       count, t);
+
+       target_buffer_set_u32_array(target, buffer, count, t);
+
+       free(t);
+
+       if (retval != ERROR_OK)
+               LOG_ERROR("Fastdata access Failed");
+
+       return retval;
+}
+
 static int mips_m4k_verify_pointer(struct command_invocation *cmd,
                struct mips_m4k_common *mips_m4k)
 {

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)