jtag: tcl: Add cget -idcode
[fw/openocd] / src / jtag / tcl.c
index c74df5ed793faccba9e6e2d880a7feb6f45ff5f3..71d220b82c0bb9847b7ffff5f0e18551bcf9ac5c 100644 (file)
@@ -23,9 +23,7 @@
  *   GNU General Public License for more details.                          *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -33,6 +31,7 @@
 #endif
 
 #include "jtag.h"
+#include "swd.h"
 #include "minidriver.h"
 #include "interface.h"
 #include "interfaces.h"
@@ -43,6 +42,7 @@
 #endif
 
 #include <helper/time_support.h>
+#include "transport/transport.h"
 
 /**
  * @file
@@ -58,8 +58,6 @@ static const Jim_Nvp nvp_jtag_tap_event[] = {
        { .name = NULL, .value = -1 }
 };
 
-extern struct jtag_interface *jtag_interface;
-
 struct jtag_tap *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)
 {
        const char *cp = Jim_GetString(o, NULL);
@@ -170,7 +168,10 @@ static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args
                return JIM_ERR;
 
        num_fields = (argc-2)/2;
-       assert(num_fields > 0);
+       if (num_fields <= 0) {
+               Jim_SetResultString(interp, "drscan: no scan fields supplied", -1);
+               return JIM_ERR;
+       }
        fields = malloc(sizeof(struct scan_field) * num_fields);
        for (i = 2; i < argc; i += 2) {
                long bits;
@@ -204,7 +205,7 @@ static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args
 
                Jim_GetLong(interp, args[i], &bits);
                str = buf_to_str(fields[field_count].in_value, bits, 16);
-               free((void *)fields[field_count].out_value);
+               free(fields[field_count].in_value);
 
                Jim_ListAppendElement(interp, list, Jim_NewStringObj(interp, str, strlen(str)));
                free(str);
@@ -306,11 +307,13 @@ static const struct command_registration jtag_command_handlers_to_move[] = {
 
 
 enum jtag_tap_cfg_param {
-       JCFG_EVENT
+       JCFG_EVENT,
+       JCFG_IDCODE,
 };
 
 static Jim_Nvp nvp_config_opts[] = {
        { .name = "-event",      .value = JCFG_EVENT },
+       { .name = "-idcode",     .value = JCFG_IDCODE },
 
        { .name = NULL,          .value = -1 }
 };
@@ -403,8 +406,23 @@ static int jtag_tap_configure_cmd(Jim_GetOptInfo *goi, struct jtag_tap *tap)
                                if (e != JIM_OK)
                                        return e;
                                break;
+                       case JCFG_IDCODE:
+                               if (goi->isconfigure) {
+                                       Jim_SetResultFormatted(goi->interp,
+                                                       "not settable: %s", n->name);
+                                       return JIM_ERR;
+                               } else {
+                                       if (goi->argc != 0) {
+                                               Jim_WrongNumArgs(goi->interp,
+                                                               goi->argc, goi->argv,
+                                                               "NO PARAMS");
+                                               return JIM_ERR;
+                                       }
+                               }
+                               Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, tap->idcode));
+                               break;
                        default:
-                               Jim_SetResultFormatted(goi->interp, "unknown event: %s", n->name);
+                               Jim_SetResultFormatted(goi->interp, "unknown value: %s", n->name);
                                return JIM_ERR;
                }
        }
@@ -432,20 +450,15 @@ static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi,
                return e;
        }
 
-       unsigned expected_len = sizeof(uint32_t) * pTap->expected_ids_cnt;
-       uint32_t *new_expected_ids = malloc(expected_len + sizeof(uint32_t));
-       if (new_expected_ids == NULL) {
+       uint32_t *p = realloc(pTap->expected_ids,
+                             (pTap->expected_ids_cnt + 1) * sizeof(uint32_t));
+       if (!p) {
                Jim_SetResultFormatted(goi->interp, "no memory");
                return JIM_ERR;
        }
 
-       memcpy(new_expected_ids, pTap->expected_ids, expected_len);
-
-       new_expected_ids[pTap->expected_ids_cnt] = w;
-
-       free(pTap->expected_ids);
-       pTap->expected_ids = new_expected_ids;
-       pTap->expected_ids_cnt++;
+       pTap->expected_ids = p;
+       pTap->expected_ids[pTap->expected_ids_cnt++] = w;
 
        return JIM_OK;
 }
@@ -466,7 +479,6 @@ static int jim_newtap_ir_param(Jim_Nvp *n, Jim_GetOptInfo *goi,
        if (e != JIM_OK) {
                Jim_SetResultFormatted(goi->interp,
                        "option: %s bad parameter", n->name);
-               free((void *)pTap->dotted_name);
                return e;
        }
        switch (n->value) {
@@ -537,11 +549,13 @@ static int jim_newtap_cmd(Jim_GetOptInfo *goi)
                free(pTap);
                return JIM_ERR;
        }
-       Jim_GetOpt_String(goi, &cp, NULL);
-       pTap->chip = strdup(cp);
 
-       Jim_GetOpt_String(goi, &cp, NULL);
-       pTap->tapname = strdup(cp);
+       const char *tmp;
+       Jim_GetOpt_String(goi, &tmp, NULL);
+       pTap->chip = strdup(tmp);
+
+       Jim_GetOpt_String(goi, &tmp, NULL);
+       pTap->tapname = strdup(tmp);
 
        /* name + dot + name + null */
        x = strlen(pTap->chip) + 1 + strlen(pTap->tapname) + 1;
@@ -552,8 +566,15 @@ static int jim_newtap_cmd(Jim_GetOptInfo *goi)
        LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
                pTap->chip, pTap->tapname, pTap->dotted_name, goi->argc);
 
+       if (!transport_is_jtag()) {
+               /* SWD doesn't require any JTAG tap parameters */
+               pTap->enabled = true;
+               jtag_tap_init(pTap);
+               return JIM_OK;
+       }
+
        /* IEEE specifies that the two LSBs of an IR scan are 01, so make
-        * that the default.  The "-irlen" and "-irmask" options are only
+        * that the default.  The "-ircapture" and "-irmask" options are only
         * needed to cope with nonstandard TAPs, or to specify more bits.
         */
        pTap->ir_capture_mask = 0x03;
@@ -563,7 +584,7 @@ static int jim_newtap_cmd(Jim_GetOptInfo *goi)
                e = Jim_GetOpt_Nvp(goi, opts, &n);
                if (e != JIM_OK) {
                        Jim_GetOpt_NvpUnknown(goi, opts, 0);
-                       free((void *)pTap->dotted_name);
+                       free(cp);
                        free(pTap);
                        return e;
                }
@@ -578,7 +599,7 @@ static int jim_newtap_cmd(Jim_GetOptInfo *goi)
                    case NTAP_OPT_EXPECTED_ID:
                            e = jim_newtap_expected_id(n, goi, pTap);
                            if (JIM_OK != e) {
-                                   free((void *)pTap->dotted_name);
+                                   free(cp);
                                    free(pTap);
                                    return e;
                            }
@@ -588,7 +609,7 @@ static int jim_newtap_cmd(Jim_GetOptInfo *goi)
                    case NTAP_OPT_IRCAPTURE:
                            e = jim_newtap_ir_param(n, goi, pTap);
                            if (JIM_OK != e) {
-                                   free((void *)pTap->dotted_name);
+                                   free(cp);
                                    free(pTap);
                                    return e;
                            }
@@ -672,6 +693,7 @@ static int jim_jtag_arp_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 
 static int jim_jtag_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 {
+       int e = ERROR_OK;
        Jim_GetOptInfo goi;
        Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
        if (goi.argc != 0) {
@@ -679,7 +701,11 @@ static int jim_jtag_arp_init_reset(Jim_Interp *interp, int argc, Jim_Obj *const
                return JIM_ERR;
        }
        struct command_context *context = current_command_context(interp);
-       int e = jtag_init_reset(context);
+       if (transport_is_jtag())
+               e = jtag_init_reset(context);
+       else if (transport_is_swd())
+               e = swd_init_reset(context);
+
        if (e != ERROR_OK) {
                Jim_Obj *eObj = Jim_NewIntObj(goi.interp, e);
                Jim_SetResultFormatted(goi.interp, "error: %#s", eObj);
@@ -885,7 +911,7 @@ static const struct command_registration jtag_subcommand_handlers[] = {
        },
        {
                .name = "configure",
-               .mode = COMMAND_EXEC,
+               .mode = COMMAND_ANY,
                .jim_handler = jim_jtag_configure,
                .help = "Provide a Tcl handler for the specified "
                        "TAP event.",
@@ -1115,17 +1141,12 @@ COMMAND_HANDLER(handle_irscan_command)
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
-       size_t fields_len = sizeof(struct scan_field) * num_fields;
-       fields = malloc(fields_len);
-       memset(fields, 0, fields_len);
+       fields = calloc(num_fields, sizeof(*fields));
 
        int retval;
        for (i = 0; i < num_fields; i++) {
                tap = jtag_tap_by_string(CMD_ARGV[i*2]);
                if (tap == NULL) {
-                       int j;
-                       for (j = 0; j < i; j++)
-                               free((void *)fields[j].out_value);
                        free(fields);
                        command_print(CMD_CTX, "Tap: %s unknown", CMD_ARGV[i*2]);
 
@@ -1133,14 +1154,14 @@ COMMAND_HANDLER(handle_irscan_command)
                }
                int field_size = tap->ir_length;
                fields[i].num_bits = field_size;
-               fields[i].out_value = malloc(DIV_ROUND_UP(field_size, 8));
+               uint8_t *v = malloc(DIV_ROUND_UP(field_size, 8));
 
-               uint32_t value;
-               retval = parse_u32(CMD_ARGV[i * 2 + 1], &value);
+               uint64_t value;
+               retval = parse_u64(CMD_ARGV[i * 2 + 1], &value);
                if (ERROR_OK != retval)
                        goto error_return;
-               void *v = (void *)fields[i].out_value;
-               buf_set_u32(v, 0, field_size, value);
+               buf_set_u64(v, 0, field_size, value);
+               fields[i].out_value = v;
                fields[i].in_value = NULL;
        }
 
@@ -1244,7 +1265,7 @@ COMMAND_HANDLER(handle_wait_srst_deassert)
 
        LOG_USER("Waiting for srst assert + deassert for at most %dms", timeout_ms);
        int asserted_yet;
-       long long then = timeval_ms();
+       int64_t then = timeval_ms();
        while (jtag_srst_asserted(&asserted_yet) == ERROR_OK) {
                if ((timeval_ms() - then) > timeout_ms) {
                        LOG_ERROR("Timed out");