jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / target / mips_m4k.c
index d3b07585ddc28ea96cd1f0014345096941788464..ad98089614cd6e4577fefe5d5b057ad3996baa83 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)
 {
@@ -98,17 +100,19 @@ static int mips_m4k_debug_entry(struct target *target)
        /* attempt to find halt reason */
        mips_m4k_examine_debug_reason(target);
 
+       mips32_cpu_probe(target);
+
        mips32_read_config_regs(target);
 
        /* default to mips32 isa, it will be changed below if required */
        mips32->isa_mode = MIPS32_ISA_MIPS32;
 
        /* other than mips32 only and isa bit set ? */
-       if (mips32->isa_imp && buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1))
+       if (mips32->isa_imp && buf_get_u32(mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].value, 0, 1))
                mips32->isa_mode = mips32->isa_imp == 2 ? MIPS32_ISA_MIPS16E : MIPS32_ISA_MMIPS32;
 
        LOG_DEBUG("entered debug state at PC 0x%" PRIx32 ", target->state: %s",
-                       buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32),
+                       buf_get_u32(mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].value, 0, 32),
                        target_state_name(target));
 
        return ERROR_OK;
@@ -138,7 +142,7 @@ static int mips_m4k_halt_smp(struct target *target)
                        ret = mips_m4k_halt(curr);
 
                if (ret != ERROR_OK) {
-                       LOG_ERROR("halt failed target->coreid: %" PRId32, curr->coreid);
+                       LOG_TARGET_ERROR(curr, "halt failed.");
                        retval = ret;
                }
        }
@@ -408,8 +412,8 @@ static int mips_m4k_restore_smp(struct target *target, uint32_t address, int han
                                                   handle_breakpoints, 0);
 
                        if (ret != ERROR_OK) {
-                               LOG_ERROR("target->coreid :%" PRId32 " failed to resume at address :0x%" PRIx32,
-                                                 curr->coreid, address);
+                               LOG_TARGET_ERROR(curr, "failed to resume at address: 0x%" PRIx32,
+                                               address);
                                retval = ret;
                        }
                }
@@ -439,18 +443,18 @@ static int mips_m4k_internal_restore(struct target *target, int current,
        /* current = 1: continue on current pc, otherwise continue at <address> */
        if (!current) {
                mips_m4k_isa_filter(mips32->isa_imp, &address);
-               buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
-               mips32->core_cache->reg_list[MIPS32_PC].dirty = true;
-               mips32->core_cache->reg_list[MIPS32_PC].valid = true;
+               buf_set_u32(mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].value, 0, 32, address);
+               mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].dirty = true;
+               mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].valid = true;
        }
 
        if ((mips32->isa_imp > 1) &&  debug_execution)  /* if more than one isa supported */
-               buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1, mips32->isa_mode);
+               buf_set_u32(mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].value, 0, 1, mips32->isa_mode);
 
        if (!current)
                resume_pc = address;
        else
-               resume_pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);
+               resume_pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].value, 0, 32);
 
        mips32_restore_context(target);
 
@@ -533,15 +537,15 @@ static int mips_m4k_step(struct target *target, int current,
        /* current = 1: continue on current pc, otherwise continue at <address> */
        if (!current) {
                mips_m4k_isa_filter(mips32->isa_imp, &address);
-               buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
-               mips32->core_cache->reg_list[MIPS32_PC].dirty = true;
-               mips32->core_cache->reg_list[MIPS32_PC].valid = true;
+               buf_set_u32(mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].value, 0, 32, address);
+               mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].dirty = true;
+               mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].valid = true;
        }
 
        /* the front-end may request us not to handle breakpoints */
        if (handle_breakpoints) {
                breakpoint = breakpoint_find(target,
-                               buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32));
+                               buf_get_u32(mips32->core_cache->reg_list[MIPS32_REGLIST_C0_PC_INDEX].value, 0, 32));
                if (breakpoint)
                        mips_m4k_unset_breakpoint(target, breakpoint);
        }
@@ -1021,6 +1025,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 +1259,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)