target/xtensa: remove needless target_was_examined check
[openocd.git] / src / target / xtensa / xtensa.c
index a6e50ccc71f8a4c4811c36ac8bb8adbe1c5ba292..b57e2d6601fe98f242e655272c67b2511b5abb6b 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
+// SPDX-License-Identifier: GPL-2.0-or-later
 
 /***************************************************************************
  *   Generic Xtensa target API for OpenOCD                                 *
 #define XT_REG_A3         (xtensa_regs[XT_REG_IDX_AR3].reg_num)
 #define XT_REG_A4         (xtensa_regs[XT_REG_IDX_AR4].reg_num)
 
-#define XT_PS_REG_NUM_BASE          (0xc0U)    /* (EPS2 - 2), for adding DBGLEVEL */
-#define XT_PC_REG_NUM_BASE          (0xb0U)    /* (EPC1 - 1), for adding DBGLEVEL */
+#define XT_PS_REG_NUM               (0xe6U)
+#define XT_EPS_REG_NUM_BASE         (0xc0U)    /* (EPS2 - 2), for adding DBGLEVEL */
+#define XT_EPC_REG_NUM_BASE         (0xb0U)    /* (EPC1 - 1), for adding DBGLEVEL */
 #define XT_PC_REG_NUM_VIRTUAL       (0xffU)    /* Marker for computing PC (EPC[DBGLEVEL) */
 #define XT_PC_DBREG_NUM_BASE        (0x20U)    /* External (i.e., GDB) access */
 
@@ -245,7 +246,7 @@ struct xtensa_reg_desc xtensa_regs[XT_NUM_REGS] = {
        XT_MK_REG_DESC("ar63", 0x3F, XT_REG_GENERAL, 0),
        XT_MK_REG_DESC("windowbase", 0x48, XT_REG_SPECIAL, 0),
        XT_MK_REG_DESC("windowstart", 0x49, XT_REG_SPECIAL, 0),
-       XT_MK_REG_DESC("ps", 0xE6, XT_REG_SPECIAL, 0),  /* PS (not mapped through EPS[]) */
+       XT_MK_REG_DESC("ps", XT_PS_REG_NUM, XT_REG_SPECIAL, 0), /* PS (not mapped through EPS[]) */
        XT_MK_REG_DESC("ibreakenable", 0x60, XT_REG_SPECIAL, 0),
        XT_MK_REG_DESC("ddr", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD),
        XT_MK_REG_DESC("ibreaka0", 0x80, XT_REG_SPECIAL, 0),
@@ -498,17 +499,20 @@ static void xtensa_queue_exec_ins(struct xtensa *xtensa, uint32_t ins)
 
 static void xtensa_queue_exec_ins_wide(struct xtensa *xtensa, uint8_t *ops, uint8_t oplen)
 {
-       if ((oplen > 0) && (oplen <= 64)) {
-               uint32_t opsw[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };  /* 8 DIRx regs: max width 64B */
-               uint8_t oplenw = (oplen + 3) / 4;
-               if (xtensa->target->endianness == TARGET_BIG_ENDIAN)
-                       buf_bswap32((uint8_t *)opsw, ops, oplenw * 4);
-               else
-                       memcpy(opsw, ops, oplen);
+       const int max_oplen = 64;       /* 8 DIRx regs: max width 64B */
+       if ((oplen > 0) && (oplen <= max_oplen)) {
+               uint8_t ops_padded[max_oplen];
+               memcpy(ops_padded, ops, oplen);
+               memset(ops_padded + oplen, 0, max_oplen - oplen);
+               unsigned int oplenw = DIV_ROUND_UP(oplen, sizeof(uint32_t));
                for (int32_t i = oplenw - 1; i > 0; i--)
-                       xtensa_queue_dbg_reg_write(xtensa, XDMREG_DIR0 + i, opsw[i]);
+                       xtensa_queue_dbg_reg_write(xtensa,
+                               XDMREG_DIR0 + i,
+                               target_buffer_get_u32(xtensa->target, &ops_padded[sizeof(uint32_t)*i]));
                /* Write DIR0EXEC last */
-               xtensa_queue_dbg_reg_write(xtensa, XDMREG_DIR0EXEC, opsw[0]);
+               xtensa_queue_dbg_reg_write(xtensa,
+                       XDMREG_DIR0EXEC,
+                       target_buffer_get_u32(xtensa->target, &ops_padded[0]));
        }
 }
 
@@ -627,7 +631,7 @@ static int xtensa_write_dirty_registers(struct target *target)
                                                        /* reg number of PC for debug interrupt depends on NDEBUGLEVEL
                                                         **/
                                                        reg_num =
-                                                               (XT_PC_REG_NUM_BASE +
+                                                               (XT_EPC_REG_NUM_BASE +
                                                                xtensa->core_config->debug.irq_level);
                                                xtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, reg_num, XT_REG_A3));
                                        }
@@ -797,8 +801,7 @@ int xtensa_examine(struct target *target)
                return ERROR_TARGET_FAILURE;
        }
        LOG_DEBUG("OCD_ID = %08" PRIx32, xtensa->dbg_mod.device_id);
-       if (!target_was_examined(target))
-               target_set_examined(target);
+       target_set_examined(target);
        xtensa_smpbreak_write(xtensa, xtensa->smp_break);
        return ERROR_OK;
 }
@@ -956,7 +959,6 @@ int xtensa_assert_reset(struct target *target)
        struct xtensa *xtensa = target_to_xtensa(target);
 
        LOG_TARGET_DEBUG(target, "target_number=%i, begin", target->target_number);
-       target->state = TARGET_RESET;
        xtensa_queue_pwr_reg_write(xtensa,
                XDMREG_PWRCTL,
                PWRCTL_JTAGDEBUGUSE(xtensa) | PWRCTL_DEBUGWAKEUP(xtensa) | PWRCTL_MEMWAKEUP(xtensa) |
@@ -965,8 +967,12 @@ int xtensa_assert_reset(struct target *target)
        int res = xtensa_dm_queue_execute(&xtensa->dbg_mod);
        if (res != ERROR_OK)
                return res;
+
+       /* registers are now invalid */
        xtensa->reset_asserted = true;
-       return res;
+       register_cache_invalidate(xtensa->core_cache);
+       target->state = TARGET_RESET;
+       return ERROR_OK;
 }
 
 int xtensa_deassert_reset(struct target *target)
@@ -1099,7 +1105,10 @@ int xtensa_fetch_all_regs(struct target *target)
                        case XT_REG_SPECIAL:
                                if (reg_num == XT_PC_REG_NUM_VIRTUAL) {
                                        /* reg number of PC for debug interrupt depends on NDEBUGLEVEL */
-                                       reg_num = (XT_PC_REG_NUM_BASE + xtensa->core_config->debug.irq_level);
+                                       reg_num = XT_EPC_REG_NUM_BASE + xtensa->core_config->debug.irq_level;
+                               } else if (reg_num == xtensa_regs[XT_REG_IDX_PS].reg_num) {
+                                       /* reg number of PS for debug interrupt depends on NDEBUGLEVEL */
+                                       reg_num = XT_EPS_REG_NUM_BASE + xtensa->core_config->debug.irq_level;
                                } else if (reg_num == xtensa_regs[XT_REG_IDX_CPENABLE].reg_num) {
                                        /* CPENABLE already read/updated; don't re-read */
                                        reg_fetched = false;
@@ -1620,7 +1629,6 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in
 
        target->debug_reason = DBG_REASON_SINGLESTEP;
        target->state = TARGET_HALTED;
-       target_call_event_callbacks(target, TARGET_EVENT_HALTED);
        LOG_DEBUG("Done stepping, PC=%" PRIX32, cur_pc);
 
        if (cause & DEBUGCAUSE_DB) {
@@ -1648,7 +1656,12 @@ int xtensa_do_step(struct target *target, int current, target_addr_t address, in
 
 int xtensa_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)
 {
-       return xtensa_do_step(target, current, address, handle_breakpoints);
+       int retval = xtensa_do_step(target, current, address, handle_breakpoints);
+       if (retval != ERROR_OK)
+               return retval;
+       target_call_event_callbacks(target, TARGET_EVENT_HALTED);
+
+       return ERROR_OK;
 }
 
 /**
@@ -1729,15 +1742,12 @@ int xtensa_read_memory(struct target *target, target_addr_t address, uint32_t si
                }
        }
 
-       if (addrstart_al == address && addrend_al == address + (size * count)) {
-               albuff = buffer;
-       } else {
-               albuff = malloc(addrend_al - addrstart_al);
-               if (!albuff) {
-                       LOG_TARGET_ERROR(target, "Out of memory allocating %" TARGET_PRIdADDR " bytes!",
-                               addrend_al - addrstart_al);
-                       return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
-               }
+       unsigned int alloc_bytes = ALIGN_UP(addrend_al - addrstart_al, sizeof(uint32_t));
+       albuff = calloc(alloc_bytes, 1);
+       if (!albuff) {
+               LOG_TARGET_ERROR(target, "Out of memory allocating %" PRId64 " bytes!",
+                       addrend_al - addrstart_al);
+               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
 
        /* We're going to use A3 here */
@@ -1774,9 +1784,9 @@ int xtensa_read_memory(struct target *target, target_addr_t address, uint32_t si
        if (res != ERROR_OK) {
                if (xtensa->probe_lsddr32p != 0) {
                        /* Disable fast memory access instructions and retry before reporting an error */
-                       LOG_TARGET_INFO(target, "Disabling LDDR32.P/SDDR32.P");
+                       LOG_TARGET_DEBUG(target, "Disabling LDDR32.P/SDDR32.P");
                        xtensa->probe_lsddr32p = 0;
-                       res = xtensa_read_memory(target, address, size, count, buffer);
+                       res = xtensa_read_memory(target, address, size, count, albuff);
                        bswap = false;
                } else {
                        LOG_TARGET_WARNING(target, "Failed reading %d bytes at address "TARGET_ADDR_FMT,
@@ -1786,11 +1796,8 @@ int xtensa_read_memory(struct target *target, target_addr_t address, uint32_t si
 
        if (bswap)
                buf_bswap32(albuff, albuff, addrend_al - addrstart_al);
-       if (albuff != buffer) {
-               memcpy(buffer, albuff + (address & 3), (size * count));
-               free(albuff);
-       }
-
+       memcpy(buffer, albuff + (address & 3), (size * count));
+       free(albuff);
        return res;
 }
 
@@ -1846,7 +1853,7 @@ int xtensa_write_memory(struct target *target,
                albuff = malloc(addrend_al - addrstart_al);
        }
        if (!albuff) {
-               LOG_TARGET_ERROR(target, "Out of memory allocating %" TARGET_PRIdADDR " bytes!",
+               LOG_TARGET_ERROR(target, "Out of memory allocating %" PRId64 " bytes!",
                        addrend_al - addrstart_al);
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
@@ -2499,6 +2506,12 @@ static int xtensa_build_reg_cache(struct target *target)
                        unsigned int j;
                        for (j = 0; j < reg_cache->num_regs; j++) {
                                if (!strcmp(reg_cache->reg_list[j].name, xtensa->contiguous_regs_desc[i]->name)) {
+                                       /*      Register number field is not filled above.
+                                               Here we are assigning the corresponding index from the contiguous reg list.
+                                               These indexes are in the same order with gdb g-packet request/response.
+                                               Some more changes may be required for sparse reg lists.
+                                       */
+                                       reg_cache->reg_list[j].number = i;
                                        xtensa->contiguous_regs_list[i] = &(reg_cache->reg_list[j]);
                                        LOG_TARGET_DEBUG(target,
                                                "POPULATE contiguous regs list: %-16s, dbreg_num 0x%04x",
@@ -3438,8 +3451,8 @@ COMMAND_HELPER(xtensa_cmd_xtreg_do, struct xtensa *xtensa)
                else
                        rptr->flags = 0;
 
-               if ((rptr->reg_num == (XT_PS_REG_NUM_BASE + xtensa->core_config->debug.irq_level)) &&
-                       (xtensa->core_config->core_type == XT_LX) && (rptr->type == XT_REG_SPECIAL)) {
+               if (rptr->reg_num == (XT_EPS_REG_NUM_BASE + xtensa->core_config->debug.irq_level) &&
+                       xtensa->core_config->core_type == XT_LX && rptr->type == XT_REG_SPECIAL) {
                        xtensa->eps_dbglevel_idx = XT_NUM_REGS + xtensa->num_optregs - 1;
                        LOG_DEBUG("Setting PS (%s) index to %d", rptr->name, xtensa->eps_dbglevel_idx);
                }

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)