e35f2ac81bf8d5c010fa9e154737766c50072f26
[fw/openocd] / src / jtag / hla / hla_tcl.c
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 /***************************************************************************
4  *   Copyright (C) 2011 by Mathias Kuester                                 *
5  *   Mathias Kuester <kesmtp@freenet.de>                                   *
6  *                                                                         *
7  *   Copyright (C) 2012 by Spencer Oliver                                  *
8  *   spen@spen-soft.co.uk                                                  *
9  ***************************************************************************/
10
11 #ifdef HAVE_CONFIG_H
12 #include "config.h"
13 #endif
14
15 /* project specific includes */
16 #include <jtag/interface.h>
17 #include <transport/transport.h>
18 #include <helper/time_support.h>
19
20 static int jim_newtap_expected_id(struct jim_nvp *n, struct jim_getopt_info *goi,
21                                   struct jtag_tap *tap)
22 {
23         jim_wide w;
24         int e = jim_getopt_wide(goi, &w);
25         if (e != JIM_OK) {
26                 Jim_SetResultFormatted(goi->interp, "option: %s bad parameter",
27                                        n->name);
28                 return e;
29         }
30
31         uint32_t *p = realloc(tap->expected_ids,
32                               (tap->expected_ids_cnt + 1) * sizeof(uint32_t));
33         if (!p) {
34                 Jim_SetResultFormatted(goi->interp, "no memory");
35                 return JIM_ERR;
36         }
37
38         tap->expected_ids = p;
39         tap->expected_ids[tap->expected_ids_cnt++] = w;
40
41         return JIM_OK;
42 }
43
44 #define NTAP_OPT_IRLEN     0
45 #define NTAP_OPT_IRMASK    1
46 #define NTAP_OPT_IRCAPTURE 2
47 #define NTAP_OPT_ENABLED   3
48 #define NTAP_OPT_DISABLED  4
49 #define NTAP_OPT_EXPECTED_ID 5
50 #define NTAP_OPT_VERSION   6
51 #define NTAP_OPT_BYPASS    7
52
53 static int jim_hl_newtap_cmd(struct jim_getopt_info *goi)
54 {
55         struct jtag_tap *tap;
56         int x;
57         int e;
58         struct jim_nvp *n;
59         char *cp;
60         const struct jim_nvp opts[] = {
61                 { .name = "-irlen",       .value = NTAP_OPT_IRLEN },
62                 { .name = "-irmask",       .value = NTAP_OPT_IRMASK },
63                 { .name = "-ircapture",       .value = NTAP_OPT_IRCAPTURE },
64                 { .name = "-enable",       .value = NTAP_OPT_ENABLED },
65                 { .name = "-disable",       .value = NTAP_OPT_DISABLED },
66                 { .name = "-expected-id",       .value = NTAP_OPT_EXPECTED_ID },
67                 { .name = "-ignore-version",       .value = NTAP_OPT_VERSION },
68                 { .name = "-ignore-bypass",       .value = NTAP_OPT_BYPASS },
69                 { .name = NULL, .value = -1},
70         };
71
72         tap = calloc(1, sizeof(struct jtag_tap));
73         if (!tap) {
74                 Jim_SetResultFormatted(goi->interp, "no memory");
75                 return JIM_ERR;
76         }
77
78         /*
79          * we expect CHIP + TAP + OPTIONS
80          * */
81         if (goi->argc < 3) {
82                 Jim_SetResultFormatted(goi->interp,
83                                        "Missing CHIP TAP OPTIONS ....");
84                 free(tap);
85                 return JIM_ERR;
86         }
87
88         const char *tmp;
89         jim_getopt_string(goi, &tmp, NULL);
90         tap->chip = strdup(tmp);
91
92         jim_getopt_string(goi, &tmp, NULL);
93         tap->tapname = strdup(tmp);
94
95         /* name + dot + name + null */
96         x = strlen(tap->chip) + 1 + strlen(tap->tapname) + 1;
97         cp = malloc(x);
98         sprintf(cp, "%s.%s", tap->chip, tap->tapname);
99         tap->dotted_name = cp;
100
101         LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
102                   tap->chip, tap->tapname, tap->dotted_name, goi->argc);
103
104         while (goi->argc) {
105                 e = jim_getopt_nvp(goi, opts, &n);
106                 if (e != JIM_OK) {
107                         jim_getopt_nvp_unknown(goi, opts, 0);
108                         free(cp);
109                         free(tap);
110                         return e;
111                 }
112                 LOG_DEBUG("Processing option: %s", n->name);
113                 switch (n->value) {
114                 case NTAP_OPT_EXPECTED_ID:
115                         e = jim_newtap_expected_id(n, goi, tap);
116                         if (e != JIM_OK) {
117                                 free(cp);
118                                 free(tap);
119                                 return e;
120                         }
121                         break;
122                 case NTAP_OPT_IRLEN:
123                 case NTAP_OPT_IRMASK:
124                 case NTAP_OPT_IRCAPTURE:
125                         /* dummy read to ignore the next argument */
126                         jim_getopt_wide(goi, NULL);
127                         break;
128                 }               /* switch (n->value) */
129         }                       /* while (goi->argc) */
130
131         /* default is enabled-after-reset */
132         tap->enabled = !tap->disabled_after_reset;
133
134         jtag_tap_init(tap);
135         return JIM_OK;
136 }
137
138 int jim_hl_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
139 {
140         struct jim_getopt_info goi;
141         jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
142         return jim_hl_newtap_cmd(&goi);
143 }