f5a67dd118227291c58db9486e63b300bfbb4a33
[fw/openocd] / src / jtag / drivers / jtag_dpi.c
1 /*
2  * JTAG to DPI driver
3  *
4  * Copyright (C) 2013 Franck Jullien, <elec4fun@gmail.com>
5  *
6  * Copyright (C) 2019-2020, Ampere Computing LLC
7  *
8  * See file CREDITS for list of people who contributed to this
9  * project.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License as
13  * published by the Free Software Foundation; either version 2 of
14  * the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <jtag/interface.h>
30 #ifdef HAVE_ARPA_INET_H
31 #include <arpa/inet.h>
32 #endif
33
34 #ifndef _WIN32
35 #include <netinet/tcp.h>
36 #endif
37
38 #define SERVER_ADDRESS  "127.0.0.1"
39 #define SERVER_PORT     5555
40
41 static uint16_t server_port = SERVER_PORT;
42 static char *server_address;
43
44 static int sockfd;
45 static struct sockaddr_in serv_addr;
46
47 static uint8_t *last_ir_buf;
48 static int last_ir_num_bits;
49
50 static int write_sock(char *buf, size_t len)
51 {
52         if (buf == NULL) {
53                 LOG_ERROR("%s: NULL 'buf' argument, file %s, line %d",
54                         __func__, __FILE__, __LINE__);
55                 return ERROR_FAIL;
56         }
57         if (write(sockfd, buf, len) != (ssize_t)len) {
58                 LOG_ERROR("%s: %s, file %s, line %d", __func__,
59                         strerror(errno), __FILE__, __LINE__);
60                 return ERROR_FAIL;
61         }
62         return ERROR_OK;
63 }
64
65 static int read_sock(char *buf, size_t len)
66 {
67         if (buf == NULL) {
68                 LOG_ERROR("%s: NULL 'buf' argument, file %s, line %d",
69                         __func__, __FILE__, __LINE__);
70                 return ERROR_FAIL;
71         }
72         if (read(sockfd, buf, len) != (ssize_t)len) {
73                 LOG_ERROR("%s: %s, file %s, line %d", __func__,
74                         strerror(errno), __FILE__, __LINE__);
75                 return ERROR_FAIL;
76         }
77         return ERROR_OK;
78 }
79
80 /**
81  * jtag_dpi_reset - ask to reset the JTAG device
82  * @param trst 1 if TRST is to be asserted
83  * @param srst 1 if SRST is to be asserted
84  */
85 static int jtag_dpi_reset(int trst, int srst)
86 {
87         char *buf = "reset\n";
88         int ret = ERROR_OK;
89
90         LOG_DEBUG_IO("JTAG DRIVER DEBUG: reset trst: %i srst %i", trst, srst);
91
92         if (trst == 1) {
93                 /* reset the JTAG TAP controller */
94                 ret = write_sock(buf, strlen(buf));
95                 if (ret != ERROR_OK) {
96                         LOG_ERROR("write_sock() fail, file %s, line %d",
97                                 __FILE__, __LINE__);
98                 }
99         }
100
101         if (srst == 1) {
102                 /* System target reset not supported */
103                 LOG_ERROR("DPI SRST not supported");
104                 ret = ERROR_FAIL;
105         }
106
107         return ret;
108 }
109
110 /**
111  * jtag_dpi_scan - launches a DR-scan or IR-scan
112  * @param cmd the command to launch
113  *
114  * Launch a JTAG IR-scan or DR-scan
115  *
116  * Returns ERROR_OK if OK, ERROR_xxx if a read/write error occurred.
117  */
118 static int jtag_dpi_scan(struct scan_command *cmd)
119 {
120         char buf[20];
121         uint8_t *data_buf;
122         int num_bits, bytes;
123         int ret = ERROR_OK;
124
125         num_bits = jtag_build_buffer(cmd, &data_buf);
126         if (data_buf == NULL) {
127                 LOG_ERROR("jtag_build_buffer call failed, data_buf == NULL, "
128                         "file %s, line %d", __FILE__, __LINE__);
129                 return ERROR_FAIL;
130         }
131
132         bytes = DIV_ROUND_UP(num_bits, 8);
133         if (cmd->ir_scan) {
134                 free(last_ir_buf);
135                 last_ir_buf = (uint8_t *)malloc(bytes * sizeof(uint8_t));
136                 if (last_ir_buf == NULL) {
137                         LOG_ERROR("%s: malloc fail, file %s, line %d",
138                                 __func__, __FILE__, __LINE__);
139                         ret = ERROR_FAIL;
140                         goto out;
141                 }
142                 memcpy(last_ir_buf, data_buf, bytes);
143                 last_ir_num_bits = num_bits;
144         }
145         snprintf(buf, sizeof(buf), "%s %d\n", cmd->ir_scan ? "ib" : "db", num_bits);
146         ret = write_sock(buf, strlen(buf));
147         if (ret != ERROR_OK) {
148                 LOG_ERROR("write_sock() fail, file %s, line %d",
149                         __FILE__, __LINE__);
150                 goto out;
151         }
152         ret = write_sock((char *)data_buf, bytes);
153         if (ret != ERROR_OK) {
154                 LOG_ERROR("write_sock() fail, file %s, line %d",
155                         __FILE__, __LINE__);
156                 goto out;
157         }
158         ret = read_sock((char *)data_buf, bytes);
159         if (ret != ERROR_OK) {
160                 LOG_ERROR("read_sock() fail, file %s, line %d",
161                         __FILE__, __LINE__);
162                 goto out;
163         }
164
165         ret = jtag_read_buffer(data_buf, cmd);
166         if (ret != ERROR_OK) {
167                 LOG_ERROR("jtag_read_buffer() fail, file %s, line %d",
168                         __FILE__, __LINE__);
169                 goto out;
170         }
171
172 out:
173         free(data_buf);
174         return ret;
175 }
176
177 static int jtag_dpi_runtest(int cycles)
178 {
179         char buf[20];
180         uint8_t *data_buf = last_ir_buf, *read_scan;
181         int num_bits = last_ir_num_bits, bytes;
182         int ret = ERROR_OK;
183
184         if (data_buf == NULL) {
185                 LOG_ERROR("%s: NULL 'data_buf' argument, file %s, line %d",
186                         __func__, __FILE__, __LINE__);
187                 return ERROR_FAIL;
188         }
189         if (num_bits <= 0) {
190                 LOG_ERROR("%s: 'num_bits' invalid value, file %s, line %d",
191                         __func__, __FILE__, __LINE__);
192                 return ERROR_FAIL;
193         }
194
195         bytes = DIV_ROUND_UP(num_bits, 8);
196         read_scan = (uint8_t *)malloc(bytes * sizeof(uint8_t));
197         if (read_scan == NULL) {
198                 LOG_ERROR("%s: malloc fail, file %s, line %d",
199                         __func__, __FILE__, __LINE__);
200                 return ERROR_FAIL;
201         }
202         snprintf(buf, sizeof(buf), "ib %d\n", num_bits);
203         while (cycles > 0) {
204                 ret = write_sock(buf, strlen(buf));
205                 if (ret != ERROR_OK) {
206                         LOG_ERROR("write_sock() fail, file %s, line %d",
207                                 __FILE__, __LINE__);
208                         goto out;
209                 }
210                 ret = write_sock((char *)data_buf, bytes);
211                 if (ret != ERROR_OK) {
212                         LOG_ERROR("write_sock() fail, file %s, line %d",
213                                 __FILE__, __LINE__);
214                         goto out;
215                 }
216                 ret = read_sock((char *)read_scan, bytes);
217                 if (ret != ERROR_OK) {
218                         LOG_ERROR("read_sock() fail, file %s, line %d",
219                                 __FILE__, __LINE__);
220                         goto out;
221                 }
222
223                 cycles -= num_bits + 6;
224         }
225
226 out:
227         free(read_scan);
228         return ret;
229 }
230
231 static int jtag_dpi_stableclocks(int cycles)
232 {
233         return jtag_dpi_runtest(cycles);
234 }
235
236 static int jtag_dpi_execute_queue(void)
237 {
238         struct jtag_command *cmd;
239         int ret = ERROR_OK;
240
241         for (cmd = jtag_command_queue; ret == ERROR_OK && cmd != NULL;
242              cmd = cmd->next) {
243                 switch (cmd->type) {
244                 case JTAG_RUNTEST:
245                         ret = jtag_dpi_runtest(cmd->cmd.runtest->num_cycles);
246                         break;
247                 case JTAG_STABLECLOCKS:
248                         ret = jtag_dpi_stableclocks(cmd->cmd.stableclocks->num_cycles);
249                         break;
250                 case JTAG_TLR_RESET:
251                         /* Enter Test-Logic-Reset state by asserting TRST */
252                         if (cmd->cmd.statemove->end_state == TAP_RESET)
253                                 jtag_dpi_reset(1, 0);
254                         break;
255                 case JTAG_PATHMOVE:
256                         /* unsupported */
257                         break;
258                 case JTAG_TMS:
259                         /* unsupported */
260                         break;
261                 case JTAG_SLEEP:
262                         jtag_sleep(cmd->cmd.sleep->us);
263                         break;
264                 case JTAG_SCAN:
265                         ret = jtag_dpi_scan(cmd->cmd.scan);
266                         break;
267                 default:
268                         LOG_ERROR("BUG: unknown JTAG command type 0x%X",
269                                   cmd->type);
270                         ret = ERROR_FAIL;
271                         break;
272                 }
273         }
274
275         return ret;
276 }
277
278 static int jtag_dpi_init(void)
279 {
280         sockfd = socket(AF_INET, SOCK_STREAM, 0);
281         if (sockfd < 0) {
282                 LOG_ERROR("socket: %s, function %s, file %s, line %d",
283                         strerror(errno), __func__, __FILE__, __LINE__);
284                 return ERROR_FAIL;
285         }
286
287         memset(&serv_addr, 0, sizeof(serv_addr));
288
289         serv_addr.sin_family = AF_INET;
290         serv_addr.sin_port = htons(server_port);
291
292         if (server_address == NULL) {
293                 server_address = strdup(SERVER_ADDRESS);
294                 if (server_address == NULL) {
295                         LOG_ERROR("%s: strdup fail, file %s, line %d",
296                                 __func__, __FILE__, __LINE__);
297                         return ERROR_FAIL;
298                 }
299         }
300
301         serv_addr.sin_addr.s_addr = inet_addr(server_address);
302
303         if (serv_addr.sin_addr.s_addr == INADDR_NONE) {
304                 LOG_ERROR("inet_addr error occurred");
305                 return ERROR_FAIL;
306         }
307
308         if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
309                 close(sockfd);
310                 LOG_ERROR("Can't connect to %s : %" PRIu16, server_address, server_port);
311                 return ERROR_FAIL;
312         }
313         if (serv_addr.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {
314                 /* This increases performance dramatically for local
315                 * connections, which is the most likely arrangement
316                 * for a DPI connection. */
317                 int flag = 1;
318                 setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
319         }
320
321         LOG_INFO("Connection to %s : %" PRIu16 " succeed", server_address, server_port);
322
323         return ERROR_OK;
324 }
325
326 static int jtag_dpi_quit(void)
327 {
328         free(server_address);
329         server_address = NULL;
330
331         return close(sockfd);
332 }
333
334 COMMAND_HANDLER(jtag_dpi_set_port)
335 {
336         if (CMD_ARGC > 1)
337                 return ERROR_COMMAND_SYNTAX_ERROR;
338         else if (CMD_ARGC == 0)
339                 LOG_INFO("Using server port %" PRIu16, server_port);
340         else {
341                 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], server_port);
342                 LOG_INFO("Set server port to %" PRIu16, server_port);
343         }
344
345         return ERROR_OK;
346 }
347
348 COMMAND_HANDLER(jtag_dpi_set_address)
349 {
350         if (CMD_ARGC > 1)
351                 return ERROR_COMMAND_SYNTAX_ERROR;
352         else if (CMD_ARGC == 0) {
353                 if (server_address == NULL) {
354                         server_address = strdup(SERVER_ADDRESS);
355                         if (server_address == NULL) {
356                                 LOG_ERROR("%s: strdup fail, file %s, line %d",
357                                         __func__, __FILE__, __LINE__);
358                                 return ERROR_FAIL;
359                         }
360                 }
361                 LOG_INFO("Using server address %s", server_address);
362         } else {
363                 free(server_address);
364                 server_address = strdup(CMD_ARGV[0]);
365                 if (server_address == NULL) {
366                         LOG_ERROR("%s: strdup fail, file %s, line %d",
367                                 __func__, __FILE__, __LINE__);
368                         return ERROR_FAIL;
369                 }
370                 LOG_INFO("Set server address to %s", server_address);
371         }
372
373         return ERROR_OK;
374 }
375
376 static const struct command_registration jtag_dpi_command_handlers[] = {
377         {
378                 .name = "jtag_dpi_set_port",
379                 .handler = &jtag_dpi_set_port,
380                 .mode = COMMAND_CONFIG,
381                 .help = "set the port of the DPI server",
382                 .usage = "[port]",
383         },
384         {
385                 .name = "jtag_dpi_set_address",
386                 .handler = &jtag_dpi_set_address,
387                 .mode = COMMAND_CONFIG,
388                 .help = "set the address of the DPI server",
389                 .usage = "[address]",
390         },
391         COMMAND_REGISTRATION_DONE
392 };
393
394 static struct jtag_interface jtag_dpi_interface = {
395         .supported = DEBUG_CAP_TMS_SEQ,
396         .execute_queue = jtag_dpi_execute_queue,
397 };
398
399 struct adapter_driver jtag_dpi_adapter_driver = {
400         .name = "jtag_dpi",
401         .transports = jtag_only,
402         .commands = jtag_dpi_command_handlers,
403         .init = jtag_dpi_init,
404         .quit = jtag_dpi_quit,
405         .reset = jtag_dpi_reset,
406         .jtag_ops = &jtag_dpi_interface,
407 };