config: add init_targets proc that is executed just before init
[openocd.git] / src / target / xscale.c
index ddc73d20cd6538ae858718b65b849c2fc5aeb648..32c656bba721d368c387ed4d0ab6575c12246608 100644 (file)
@@ -160,8 +160,7 @@ static int xscale_verify_pointer(struct command_context *cmd_ctx,
 
 static int xscale_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state)
 {
-       if (tap == NULL)
-               return ERROR_FAIL;
+       assert (tap != NULL);
 
        if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr)
        {
@@ -245,7 +244,7 @@ static int xscale_read_dcsr(struct target *target)
 static void xscale_getbuf(jtag_callback_data_t arg)
 {
        uint8_t *in = (uint8_t *)arg;
-       *((uint32_t *)in) = buf_get_u32(in, 0, 32);
+       *((uint32_t *)arg) = buf_get_u32(in, 0, 32);
 }
 
 static int xscale_receive(struct target *target, uint32_t *buffer, int num_words)
@@ -896,7 +895,7 @@ static int xscale_debug_entry(struct target *target)
        struct arm *armv4_5 = &xscale->armv4_5_common;
        uint32_t pc;
        uint32_t buffer[10];
-       int i;
+       unsigned i;
        int retval;
        uint32_t moe;
 
@@ -965,6 +964,11 @@ static int xscale_debug_entry(struct target *target)
                r->valid = true;
        }
 
+       /* mark xscale regs invalid to ensure they are retrieved from the
+        * debug handler if requested  */
+       for (i = 0; i < xscale->reg_cache->num_regs; i++)
+          xscale->reg_cache->reg_list[i].valid = 0;
+
        /* examine debug reason */
        xscale_read_dcsr(target);
        moe = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 2, 3);
@@ -1040,21 +1044,20 @@ static int xscale_debug_entry(struct target *target)
        xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (xscale->cp15_control_reg & 0x1000U) ? 1 : 0;
 
        /* tracing enabled, read collected trace data */
-       if (xscale->trace.buffer_enabled)
+       if (xscale->trace.mode != XSCALE_TRACE_DISABLED)
        {
                xscale_read_trace(target);
-               xscale->trace.buffer_fill--;
 
-               /* resume if we're still collecting trace data */
-               if ((xscale->arch_debug_reason == XSCALE_DBG_REASON_TB_FULL)
-                       && (xscale->trace.buffer_fill > 0))
+               /* Resume if entered debug due to buffer fill and we're still collecting
+                * trace data.  Note that a debug exception due to trace buffer full
+                * can only happen in fill mode. */
+               if (xscale->arch_debug_reason == XSCALE_DBG_REASON_TB_FULL)
                {
+                 if (--xscale->trace.fill_counter > 0)
                        xscale_resume(target, 1, 0x0, 1, 0);
                }
-               else
-               {
-                       xscale->trace.buffer_enabled = 0;
-               }
+               else    /* entered debug for other reason; reset counter */
+                 xscale->trace.fill_counter = 0;
        }
 
        return ERROR_OK;
@@ -1158,6 +1161,20 @@ static void xscale_enable_breakpoints(struct target *target)
        }
 }
 
+static void xscale_free_trace_data(struct xscale_common *xscale)
+{
+   struct xscale_trace_data *td = xscale->trace.data;
+   while (td)
+   {
+         struct xscale_trace_data *next_td = td->next;
+         if (td->entries)
+                free(td->entries);
+         free(td);
+         td = next_td;
+   }
+   xscale->trace.data = NULL;
+}
+
 static int xscale_resume(struct target *target, int current,
                uint32_t address, int handle_breakpoints, int debug_execution)
 {
@@ -1206,7 +1223,7 @@ static int xscale_resume(struct target *target, int current,
                if (breakpoint != NULL)
                {
                        uint32_t next_pc;
-                       int saved_trace_buffer_enabled;
+                       enum trace_mode saved_trace_mode;
 
                        /* there's a breakpoint at the current PC, we have to step over it */
                        LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
@@ -1249,14 +1266,14 @@ static int xscale_resume(struct target *target, int current,
                                        buf_get_u32(armv4_5->pc->value, 0, 32));
 
                        /* disable trace data collection in xscale_debug_entry() */
-                       saved_trace_buffer_enabled = xscale->trace.buffer_enabled;
-                       xscale->trace.buffer_enabled = 0;
+                       saved_trace_mode = xscale->trace.mode;
+                       xscale->trace.mode = XSCALE_TRACE_DISABLED;
 
                        /* wait for and process debug entry */
                        xscale_debug_entry(target);
 
                        /* re-enable trace buffer, if enabled previously */
-                       xscale->trace.buffer_enabled = saved_trace_buffer_enabled;
+                       xscale->trace.mode = saved_trace_mode;
 
                        LOG_DEBUG("disable single-step");
                        xscale_disable_single_step(target);
@@ -1275,8 +1292,21 @@ static int xscale_resume(struct target *target, int current,
 
        /* send resume request (command 0x30 or 0x31)
         * clean the trace buffer if it is to be enabled (0x62) */
-       if (xscale->trace.buffer_enabled)
+       if (xscale->trace.mode != XSCALE_TRACE_DISABLED)
        {
+               if (xscale->trace.mode == XSCALE_TRACE_FILL)
+               {
+                  /* If trace enabled in fill mode and starting collection of new set
+                       * of buffers, initialize buffer counter and free previous buffers */
+                  if (xscale->trace.fill_counter == 0)
+                  {
+                         xscale->trace.fill_counter = xscale->trace.buffer_fill;
+                         xscale_free_trace_data(xscale);
+                  }
+               }
+               else     /* wrap mode; free previous buffer */
+                  xscale_free_trace_data(xscale);
+
                xscale_send_u32(target, 0x62);
                xscale_send_u32(target, 0x31);
        }
@@ -1352,7 +1382,7 @@ static int xscale_step_inner(struct target *target, int current,
 
        /* send resume request (command 0x30 or 0x31)
         * clean the trace buffer if it is to be enabled (0x62) */
-       if (xscale->trace.buffer_enabled)
+       if (xscale->trace.mode != XSCALE_TRACE_DISABLED)
        {
                if ((retval = xscale_send_u32(target, 0x62)) != ERROR_OK)
                        return retval;
@@ -1529,6 +1559,9 @@ static int xscale_deassert_reset(struct target *target)
                breakpoint = breakpoint->next;
        }
 
+       xscale->trace.mode = XSCALE_TRACE_DISABLED;
+       xscale_free_trace_data(xscale);
+
        register_cache_invalidate(xscale->armv4_5_common.core_cache);
 
        /* FIXME mark hardware watchpoints got unset too.  Also,
@@ -1975,6 +2008,7 @@ static int xscale_write_memory(struct target *target, uint32_t address,
                if ((retval = xscale_send_u32(target, 0x60)) != ERROR_OK)
                        return retval;
 
+               LOG_ERROR("data abort writing memory");
                return ERROR_TARGET_DATA_ABORT;
        }
 
@@ -2002,25 +2036,33 @@ static int xscale_bulk_write_memory(struct target *target, uint32_t address,
        return xscale_write_memory(target, address, 4, count, buffer);
 }
 
-static uint32_t xscale_get_ttb(struct target *target)
+static int xscale_get_ttb(struct target *target, uint32_t *result)
 {
        struct xscale_common *xscale = target_to_xscale(target);
        uint32_t ttb;
+       int retval;
 
-       xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_TTB]);
+       retval = xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_TTB]);
+       if (retval != ERROR_OK)
+               return retval;
        ttb = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_TTB].value, 0, 32);
 
-       return ttb;
+       *result = ttb;
+
+       return ERROR_OK;
 }
 
-static void xscale_disable_mmu_caches(struct target *target, int mmu,
+static int xscale_disable_mmu_caches(struct target *target, int mmu,
                int d_u_cache, int i_cache)
 {
        struct xscale_common *xscale = target_to_xscale(target);
        uint32_t cp15_control;
+       int retval;
 
        /* read cp15 control register */
-       xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
+       retval = xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
+       if (retval !=ERROR_OK)
+               return retval;
        cp15_control = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
 
        if (mmu)
@@ -2029,11 +2071,17 @@ static void xscale_disable_mmu_caches(struct target *target, int mmu,
        if (d_u_cache)
        {
                /* clean DCache */
-               xscale_send_u32(target, 0x50);
-               xscale_send_u32(target, xscale->cache_clean_address);
+               retval = xscale_send_u32(target, 0x50);
+               if (retval !=ERROR_OK)
+                       return retval;
+               retval = xscale_send_u32(target, xscale->cache_clean_address);
+               if (retval !=ERROR_OK)
+                       return retval;
 
                /* invalidate DCache */
-               xscale_send_u32(target, 0x51);
+               retval = xscale_send_u32(target, 0x51);
+               if (retval !=ERROR_OK)
+                       return retval;
 
                cp15_control &= ~0x4U;
        }
@@ -2041,25 +2089,33 @@ static void xscale_disable_mmu_caches(struct target *target, int mmu,
        if (i_cache)
        {
                /* invalidate ICache */
-               xscale_send_u32(target, 0x52);
+               retval = xscale_send_u32(target, 0x52);
+               if (retval !=ERROR_OK)
+                       return retval;
                cp15_control &= ~0x1000U;
        }
 
        /* write new cp15 control register */
-       xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);
+       retval = xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);
+       if (retval !=ERROR_OK)
+               return retval;
 
        /* execute cpwait to ensure outstanding operations complete */
-       xscale_send_u32(target, 0x53);
+       retval = xscale_send_u32(target, 0x53);
+       return retval;
 }
 
-static void xscale_enable_mmu_caches(struct target *target, int mmu,
+static int xscale_enable_mmu_caches(struct target *target, int mmu,
                int d_u_cache, int i_cache)
 {
        struct xscale_common *xscale = target_to_xscale(target);
        uint32_t cp15_control;
+       int retval;
 
        /* read cp15 control register */
-       xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
+       retval = xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);
+       if (retval !=ERROR_OK)
+               return retval;
        cp15_control = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);
 
        if (mmu)
@@ -2072,10 +2128,13 @@ static void xscale_enable_mmu_caches(struct target *target, int mmu,
                cp15_control |= 0x1000U;
 
        /* write new cp15 control register */
-       xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);
+       retval = xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);
+       if (retval !=ERROR_OK)
+               return retval;
 
        /* execute cpwait to ensure outstanding operations complete */
-       xscale_send_u32(target, 0x53);
+       retval = xscale_send_u32(target, 0x53);
+       return retval;
 }
 
 static int xscale_set_breakpoint(struct target *target,
@@ -2112,9 +2171,9 @@ static int xscale_set_breakpoint(struct target *target,
                        breakpoint->set = 2;    /* breakpoint set on second breakpoint register */
                }
                else
-               {
+               {       /* bug: availability previously verified in xscale_add_breakpoint() */
                        LOG_ERROR("BUG: no hardware comparator available");
-                       return ERROR_OK;
+                       return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
                }
        }
        else if (breakpoint->type == BKPT_SOFT)
@@ -2140,7 +2199,7 @@ static int xscale_set_breakpoint(struct target *target,
                                return retval;
                        }
                        /* write the bkpt instruction in target endianness (arm7_9->arm_bkpt is host endian) */
-                       if ((retval = target_write_u32(target, breakpoint->address, xscale->thumb_bkpt)) != ERROR_OK)
+                       if ((retval = target_write_u16(target, breakpoint->address, xscale->thumb_bkpt)) != ERROR_OK)
                        {
                                return retval;
                        }
@@ -2163,13 +2222,13 @@ static int xscale_add_breakpoint(struct target *target,
 
        if ((breakpoint->type == BKPT_HARD) && (xscale->ibcr_available < 1))
        {
-               LOG_INFO("no breakpoint unit available for hardware breakpoint");
+               LOG_ERROR("no breakpoint unit available for hardware breakpoint");
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
 
        if ((breakpoint->length != 2) && (breakpoint->length != 4))
        {
-               LOG_INFO("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
+               LOG_ERROR("only breakpoints of two (Thumb) or four (ARM) bytes length supported");
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
 
@@ -2178,7 +2237,7 @@ static int xscale_add_breakpoint(struct target *target,
                xscale->ibcr_available--;
        }
 
-       return ERROR_OK;
+       return xscale_set_breakpoint(target, breakpoint);
 }
 
 static int xscale_unset_breakpoint(struct target *target,
@@ -2247,7 +2306,7 @@ static int xscale_remove_breakpoint(struct target *target, struct breakpoint *br
 
        if (target->state != TARGET_HALTED)
        {
-               LOG_WARNING("target not halted");
+               LOG_ERROR("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
@@ -2266,18 +2325,16 @@ static int xscale_set_watchpoint(struct target *target,
                struct watchpoint *watchpoint)
 {
        struct xscale_common *xscale = target_to_xscale(target);
-       uint8_t enable = 0;
+       uint32_t enable = 0;
        struct reg *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON];
        uint32_t dbcon_value = buf_get_u32(dbcon->value, 0, 32);
 
        if (target->state != TARGET_HALTED)
        {
-               LOG_WARNING("target not halted");
+               LOG_ERROR("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       xscale_get_reg(dbcon);
-
        switch (watchpoint->rw)
        {
                case WPT_READ:
@@ -2293,6 +2350,24 @@ static int xscale_set_watchpoint(struct target *target,
                        LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
        }
 
+       /* For watchpoint across more than one word, both DBR registers must
+          be enlisted, with the second used as a mask. */
+       if (watchpoint->length > 4)
+       {
+          if (xscale->dbr0_used || xscale->dbr1_used) 
+          {
+                 LOG_ERROR("BUG: sufficient hardware comparators unavailable");
+                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+          }
+
+          /* Write mask value to DBR1, based on the length argument.
+               * Address bits ignored by the comparator are those set in mask. */
+          xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR1],
+                                                 watchpoint->length - 1);
+          xscale->dbr1_used = 1;
+          enable |= 0x100;                     /* DBCON[M] */
+       }
+
        if (!xscale->dbr0_used)
        {
                xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR0], watchpoint->address);
@@ -2312,7 +2387,7 @@ static int xscale_set_watchpoint(struct target *target,
        else
        {
                LOG_ERROR("BUG: no hardware comparator available");
-               return ERROR_OK;
+               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
 
        return ERROR_OK;
@@ -2325,16 +2400,44 @@ static int xscale_add_watchpoint(struct target *target,
 
        if (xscale->dbr_available < 1)
        {
-               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+          LOG_ERROR("no more watchpoint registers available");
+          return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        }
 
-       if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
+       if (watchpoint->value)
+          LOG_WARNING("xscale does not support value, mask arguments; ignoring");
+
+       /* check that length is a power of two */
+       for (uint32_t len = watchpoint->length; len != 1; len /= 2)
        {
-               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+          if (len % 2)
+          {
+                 LOG_ERROR("xscale requires that watchpoint length is a power of two");
+                 return ERROR_COMMAND_ARGUMENT_INVALID;
+          }
        }
 
-       xscale->dbr_available--;
+       if (watchpoint->length == 4) /* single word watchpoint */
+       {
+          xscale->dbr_available--; /* one DBR reg used */
+          return ERROR_OK;
+       }
 
+       /* watchpoints across multiple words require both DBR registers */
+       if (xscale->dbr_available < 2)
+       {
+          LOG_ERROR("insufficient watchpoint registers available");
+          return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+       }
+       
+       if (watchpoint->length > watchpoint->address)
+       {
+          LOG_ERROR("xscale does not support watchpoints with length "
+                                "greater than address");
+          return ERROR_COMMAND_ARGUMENT_INVALID;
+       }
+          
+       xscale->dbr_available = 0;
        return ERROR_OK;
 }
 
@@ -2359,7 +2462,14 @@ static int xscale_unset_watchpoint(struct target *target,
 
        if (watchpoint->set == 1)
        {
-               dbcon_value &= ~0x3;
+          if (watchpoint->length > 4)
+          {
+                 dbcon_value &= ~0x103; /* clear DBCON[M] as well */
+                 xscale->dbr1_used = 0; /* DBR1 was used for mask */
+          }
+          else
+                 dbcon_value &= ~0x3;
+
                xscale_set_reg_u32(dbcon, dbcon_value);
                xscale->dbr0_used = 0;
        }
@@ -2380,7 +2490,7 @@ static int xscale_remove_watchpoint(struct target *target, struct watchpoint *wa
 
        if (target->state != TARGET_HALTED)
        {
-               LOG_WARNING("target not halted");
+               LOG_ERROR("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
@@ -2389,6 +2499,9 @@ static int xscale_remove_watchpoint(struct target *target, struct watchpoint *wa
                xscale_unset_watchpoint(target, watchpoint);
        }
 
+       if (watchpoint->length > 4)
+          xscale->dbr_available++;     /* both DBR regs now available */
+       
        xscale->dbr_available++;
 
        return ERROR_OK;
@@ -3036,11 +3149,11 @@ static int xscale_init_arch_info(struct target *target,
 
        xscale->vector_catch = 0x1;
 
-       xscale->trace.capture_status = TRACE_IDLE;
        xscale->trace.data = NULL;
        xscale->trace.image = NULL;
-       xscale->trace.buffer_enabled = 0;
+       xscale->trace.mode = XSCALE_TRACE_DISABLED;
        xscale->trace.buffer_fill = 0;
+       xscale->trace.fill_counter = 0;
 
        /* prepare ARMv4/5 specific information */
        armv4_5->arch_info = xscale;
@@ -3173,21 +3286,18 @@ static int xscale_virt2phys(struct target *target,
                uint32_t virtual, uint32_t *physical)
 {
        struct xscale_common *xscale = target_to_xscale(target);
-       int type;
        uint32_t cb;
-       int domain;
-       uint32_t ap;
 
        if (xscale->common_magic != XSCALE_COMMON_MAGIC) {
                LOG_ERROR(xscale_not);
                return ERROR_TARGET_INVALID;
        }
 
-       uint32_t ret = armv4_5_mmu_translate_va(target, &xscale->armv4_5_mmu, virtual, &type, &cb, &domain, &ap);
-       if (type == -1)
-       {
-               return ret;
-       }
+       uint32_t ret;
+       int retval = armv4_5_mmu_translate_va(target, &xscale->armv4_5_mmu,
+                       virtual, &cb, &ret);
+       if (retval != ERROR_OK)
+               return retval;
        *physical = ret;
        return ERROR_OK;
 }
@@ -3385,47 +3495,54 @@ COMMAND_HANDLER(xscale_handle_trace_buffer_command)
                return ERROR_OK;
        }
 
-       if ((CMD_ARGC >= 1) && (strcmp("enable", CMD_ARGV[0]) == 0))
-       {
-               struct xscale_trace_data *td, *next_td;
-               xscale->trace.buffer_enabled = 1;
-
-               /* free old trace data */
-               td = xscale->trace.data;
-               while (td)
-               {
-                       next_td = td->next;
-
-                       if (td->entries)
-                               free(td->entries);
-                       free(td);
-                       td = next_td;
-               }
-               xscale->trace.data = NULL;
-       }
-       else if ((CMD_ARGC >= 1) && (strcmp("disable", CMD_ARGV[0]) == 0))
-       {
-               xscale->trace.buffer_enabled = 0;
-       }
-
-       if ((CMD_ARGC >= 2) && (strcmp("fill", CMD_ARGV[1]) == 0))
+       if (CMD_ARGC >= 1)
        {
-               uint32_t fill = 1;
-               if (CMD_ARGC >= 3)
-                       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], fill);
-               xscale->trace.buffer_fill = fill;
+          if (strcmp("enable", CMD_ARGV[0]) == 0)
+                 xscale->trace.mode = XSCALE_TRACE_WRAP; /* default */
+          else if (strcmp("disable", CMD_ARGV[0]) == 0)
+                 xscale->trace.mode = XSCALE_TRACE_DISABLED;
+          else
+                 return ERROR_INVALID_ARGUMENTS;
+       }
+
+       if (CMD_ARGC >= 2 && xscale->trace.mode != XSCALE_TRACE_DISABLED)
+       {
+          if (strcmp("fill", CMD_ARGV[1]) == 0)
+          {
+                 int buffcount = 1;                    /* default */
+                 if (CMD_ARGC >= 3)
+                        COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], buffcount);
+                 if (buffcount < 1)                    /* invalid */
+                 {
+                        command_print(CMD_CTX, "fill buffer count must be > 0");
+                        xscale->trace.mode = XSCALE_TRACE_DISABLED;
+                        return ERROR_INVALID_ARGUMENTS;
+                 }
+                 xscale->trace.buffer_fill = buffcount;
+                 xscale->trace.mode = XSCALE_TRACE_FILL;
+          }
+          else if (strcmp("wrap", CMD_ARGV[1]) == 0)
+                 xscale->trace.mode = XSCALE_TRACE_WRAP;
+          else
+          {
+                 xscale->trace.mode = XSCALE_TRACE_DISABLED;
+                 return ERROR_INVALID_ARGUMENTS;
+          }
        }
-       else if ((CMD_ARGC >= 2) && (strcmp("wrap", CMD_ARGV[1]) == 0))
+       
+       if (xscale->trace.mode != XSCALE_TRACE_DISABLED)
        {
-               xscale->trace.buffer_fill = -1;
+          char fill_string[12];
+          sprintf(fill_string, "fill %" PRId32, xscale->trace.buffer_fill); 
+          command_print(CMD_CTX, "trace buffer enabled (%s)",
+                                        (xscale->trace.mode == XSCALE_TRACE_FILL)
+                                        ? fill_string : "wrap");
        }
-
-       command_print(CMD_CTX, "trace buffer %s (%s)",
-               (xscale->trace.buffer_enabled) ? "enabled" : "disabled",
-               (xscale->trace.buffer_fill > 0) ? "fill" : "wrap");
-
+       else
+          command_print(CMD_CTX, "trace buffer disabled");
+          
        dcsr_value = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32);
-       if (xscale->trace.buffer_fill >= 0)
+       if (xscale->trace.mode == XSCALE_TRACE_FILL)
                xscale_write_dcsr_sw(target, (dcsr_value & 0xfffffffc) | 2);
        else
                xscale_write_dcsr_sw(target, dcsr_value & 0xfffffffc);
@@ -3693,7 +3810,7 @@ static const struct command_registration xscale_exec_command_handlers[] = {
                .mode = COMMAND_EXEC,
                .help = "display trace buffer status, enable or disable "
                        "tracing, and optionally reconfigure trace mode",
-               .usage = "['enable'|'disable' ['fill' number|'wrap']]",
+               .usage = "['enable'|'disable' ['fill' [number]|'wrap']]",
        },
        {
                .name = "dump_trace",

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)