You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

408 lines
9.6 KiB

  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. #ifdef HAVE_CONFIG_H
  25. #include "config.h"
  26. #endif
  27. #include <jtag/interface.h>
  28. #ifdef HAVE_ARPA_INET_H
  29. #include <arpa/inet.h>
  30. #endif
  31. #ifndef _WIN32
  32. #include <netinet/tcp.h>
  33. #endif
  34. #define SERVER_ADDRESS "127.0.0.1"
  35. #define SERVER_PORT 5555
  36. static uint16_t server_port = SERVER_PORT;
  37. static char *server_address;
  38. static int sockfd;
  39. static struct sockaddr_in serv_addr;
  40. static uint8_t *last_ir_buf;
  41. static int last_ir_num_bits;
  42. static int write_sock(char *buf, size_t len)
  43. {
  44. if (!buf) {
  45. LOG_ERROR("%s: NULL 'buf' argument, file %s, line %d",
  46. __func__, __FILE__, __LINE__);
  47. return ERROR_FAIL;
  48. }
  49. if (write(sockfd, buf, len) != (ssize_t)len) {
  50. LOG_ERROR("%s: %s, file %s, line %d", __func__,
  51. strerror(errno), __FILE__, __LINE__);
  52. return ERROR_FAIL;
  53. }
  54. return ERROR_OK;
  55. }
  56. static int read_sock(char *buf, size_t len)
  57. {
  58. if (!buf) {
  59. LOG_ERROR("%s: NULL 'buf' argument, file %s, line %d",
  60. __func__, __FILE__, __LINE__);
  61. return ERROR_FAIL;
  62. }
  63. if (read(sockfd, buf, len) != (ssize_t)len) {
  64. LOG_ERROR("%s: %s, file %s, line %d", __func__,
  65. strerror(errno), __FILE__, __LINE__);
  66. return ERROR_FAIL;
  67. }
  68. return ERROR_OK;
  69. }
  70. /**
  71. * jtag_dpi_reset - ask to reset the JTAG device
  72. * @param trst 1 if TRST is to be asserted
  73. * @param srst 1 if SRST is to be asserted
  74. */
  75. static int jtag_dpi_reset(int trst, int srst)
  76. {
  77. char *buf = "reset\n";
  78. int ret = ERROR_OK;
  79. LOG_DEBUG_IO("JTAG DRIVER DEBUG: reset trst: %i srst %i", trst, srst);
  80. if (trst == 1) {
  81. /* reset the JTAG TAP controller */
  82. ret = write_sock(buf, strlen(buf));
  83. if (ret != ERROR_OK) {
  84. LOG_ERROR("write_sock() fail, file %s, line %d",
  85. __FILE__, __LINE__);
  86. }
  87. }
  88. if (srst == 1) {
  89. /* System target reset not supported */
  90. LOG_ERROR("DPI SRST not supported");
  91. ret = ERROR_FAIL;
  92. }
  93. return ret;
  94. }
  95. /**
  96. * jtag_dpi_scan - launches a DR-scan or IR-scan
  97. * @param cmd the command to launch
  98. *
  99. * Launch a JTAG IR-scan or DR-scan
  100. *
  101. * Returns ERROR_OK if OK, ERROR_xxx if a read/write error occurred.
  102. */
  103. static int jtag_dpi_scan(struct scan_command *cmd)
  104. {
  105. char buf[20];
  106. uint8_t *data_buf;
  107. int num_bits, bytes;
  108. int ret = ERROR_OK;
  109. num_bits = jtag_build_buffer(cmd, &data_buf);
  110. if (!data_buf) {
  111. LOG_ERROR("jtag_build_buffer call failed, data_buf == NULL, "
  112. "file %s, line %d", __FILE__, __LINE__);
  113. return ERROR_FAIL;
  114. }
  115. bytes = DIV_ROUND_UP(num_bits, 8);
  116. if (cmd->ir_scan) {
  117. free(last_ir_buf);
  118. last_ir_buf = (uint8_t *)malloc(bytes * sizeof(uint8_t));
  119. if (!last_ir_buf) {
  120. LOG_ERROR("%s: malloc fail, file %s, line %d",
  121. __func__, __FILE__, __LINE__);
  122. ret = ERROR_FAIL;
  123. goto out;
  124. }
  125. memcpy(last_ir_buf, data_buf, bytes);
  126. last_ir_num_bits = num_bits;
  127. }
  128. snprintf(buf, sizeof(buf), "%s %d\n", cmd->ir_scan ? "ib" : "db", num_bits);
  129. ret = write_sock(buf, strlen(buf));
  130. if (ret != ERROR_OK) {
  131. LOG_ERROR("write_sock() fail, file %s, line %d",
  132. __FILE__, __LINE__);
  133. goto out;
  134. }
  135. ret = write_sock((char *)data_buf, bytes);
  136. if (ret != ERROR_OK) {
  137. LOG_ERROR("write_sock() fail, file %s, line %d",
  138. __FILE__, __LINE__);
  139. goto out;
  140. }
  141. ret = read_sock((char *)data_buf, bytes);
  142. if (ret != ERROR_OK) {
  143. LOG_ERROR("read_sock() fail, file %s, line %d",
  144. __FILE__, __LINE__);
  145. goto out;
  146. }
  147. ret = jtag_read_buffer(data_buf, cmd);
  148. if (ret != ERROR_OK) {
  149. LOG_ERROR("jtag_read_buffer() fail, file %s, line %d",
  150. __FILE__, __LINE__);
  151. goto out;
  152. }
  153. out:
  154. free(data_buf);
  155. return ret;
  156. }
  157. static int jtag_dpi_runtest(int cycles)
  158. {
  159. char buf[20];
  160. uint8_t *data_buf = last_ir_buf, *read_scan;
  161. int num_bits = last_ir_num_bits, bytes;
  162. int ret = ERROR_OK;
  163. if (!data_buf) {
  164. LOG_ERROR("%s: NULL 'data_buf' argument, file %s, line %d",
  165. __func__, __FILE__, __LINE__);
  166. return ERROR_FAIL;
  167. }
  168. if (num_bits <= 0) {
  169. LOG_ERROR("%s: 'num_bits' invalid value, file %s, line %d",
  170. __func__, __FILE__, __LINE__);
  171. return ERROR_FAIL;
  172. }
  173. bytes = DIV_ROUND_UP(num_bits, 8);
  174. read_scan = (uint8_t *)malloc(bytes * sizeof(uint8_t));
  175. if (!read_scan) {
  176. LOG_ERROR("%s: malloc fail, file %s, line %d",
  177. __func__, __FILE__, __LINE__);
  178. return ERROR_FAIL;
  179. }
  180. snprintf(buf, sizeof(buf), "ib %d\n", num_bits);
  181. while (cycles > 0) {
  182. ret = write_sock(buf, strlen(buf));
  183. if (ret != ERROR_OK) {
  184. LOG_ERROR("write_sock() fail, file %s, line %d",
  185. __FILE__, __LINE__);
  186. goto out;
  187. }
  188. ret = write_sock((char *)data_buf, bytes);
  189. if (ret != ERROR_OK) {
  190. LOG_ERROR("write_sock() fail, file %s, line %d",
  191. __FILE__, __LINE__);
  192. goto out;
  193. }
  194. ret = read_sock((char *)read_scan, bytes);
  195. if (ret != ERROR_OK) {
  196. LOG_ERROR("read_sock() fail, file %s, line %d",
  197. __FILE__, __LINE__);
  198. goto out;
  199. }
  200. cycles -= num_bits + 6;
  201. }
  202. out:
  203. free(read_scan);
  204. return ret;
  205. }
  206. static int jtag_dpi_stableclocks(int cycles)
  207. {
  208. return jtag_dpi_runtest(cycles);
  209. }
  210. static int jtag_dpi_execute_queue(void)
  211. {
  212. struct jtag_command *cmd;
  213. int ret = ERROR_OK;
  214. for (cmd = jtag_command_queue; ret == ERROR_OK && cmd;
  215. cmd = cmd->next) {
  216. switch (cmd->type) {
  217. case JTAG_RUNTEST:
  218. ret = jtag_dpi_runtest(cmd->cmd.runtest->num_cycles);
  219. break;
  220. case JTAG_STABLECLOCKS:
  221. ret = jtag_dpi_stableclocks(cmd->cmd.stableclocks->num_cycles);
  222. break;
  223. case JTAG_TLR_RESET:
  224. /* Enter Test-Logic-Reset state by asserting TRST */
  225. if (cmd->cmd.statemove->end_state == TAP_RESET)
  226. jtag_dpi_reset(1, 0);
  227. break;
  228. case JTAG_PATHMOVE:
  229. /* unsupported */
  230. break;
  231. case JTAG_TMS:
  232. /* unsupported */
  233. break;
  234. case JTAG_SLEEP:
  235. jtag_sleep(cmd->cmd.sleep->us);
  236. break;
  237. case JTAG_SCAN:
  238. ret = jtag_dpi_scan(cmd->cmd.scan);
  239. break;
  240. default:
  241. LOG_ERROR("BUG: unknown JTAG command type 0x%X",
  242. cmd->type);
  243. ret = ERROR_FAIL;
  244. break;
  245. }
  246. }
  247. return ret;
  248. }
  249. static int jtag_dpi_init(void)
  250. {
  251. sockfd = socket(AF_INET, SOCK_STREAM, 0);
  252. if (sockfd < 0) {
  253. LOG_ERROR("socket: %s, function %s, file %s, line %d",
  254. strerror(errno), __func__, __FILE__, __LINE__);
  255. return ERROR_FAIL;
  256. }
  257. memset(&serv_addr, 0, sizeof(serv_addr));
  258. serv_addr.sin_family = AF_INET;
  259. serv_addr.sin_port = htons(server_port);
  260. if (!server_address) {
  261. server_address = strdup(SERVER_ADDRESS);
  262. if (!server_address) {
  263. LOG_ERROR("%s: strdup fail, file %s, line %d",
  264. __func__, __FILE__, __LINE__);
  265. return ERROR_FAIL;
  266. }
  267. }
  268. serv_addr.sin_addr.s_addr = inet_addr(server_address);
  269. if (serv_addr.sin_addr.s_addr == INADDR_NONE) {
  270. LOG_ERROR("inet_addr error occurred");
  271. return ERROR_FAIL;
  272. }
  273. if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
  274. close(sockfd);
  275. LOG_ERROR("Can't connect to %s : %" PRIu16, server_address, server_port);
  276. return ERROR_FAIL;
  277. }
  278. if (serv_addr.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {
  279. /* This increases performance dramatically for local
  280. * connections, which is the most likely arrangement
  281. * for a DPI connection. */
  282. int flag = 1;
  283. setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
  284. }
  285. LOG_INFO("Connection to %s : %" PRIu16 " succeed", server_address, server_port);
  286. return ERROR_OK;
  287. }
  288. static int jtag_dpi_quit(void)
  289. {
  290. free(server_address);
  291. server_address = NULL;
  292. return close(sockfd);
  293. }
  294. COMMAND_HANDLER(jtag_dpi_set_port)
  295. {
  296. if (CMD_ARGC > 1)
  297. return ERROR_COMMAND_SYNTAX_ERROR;
  298. else if (CMD_ARGC == 0)
  299. LOG_INFO("Using server port %" PRIu16, server_port);
  300. else {
  301. COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], server_port);
  302. LOG_INFO("Set server port to %" PRIu16, server_port);
  303. }
  304. return ERROR_OK;
  305. }
  306. COMMAND_HANDLER(jtag_dpi_set_address)
  307. {
  308. if (CMD_ARGC > 1)
  309. return ERROR_COMMAND_SYNTAX_ERROR;
  310. else if (CMD_ARGC == 0) {
  311. if (!server_address) {
  312. server_address = strdup(SERVER_ADDRESS);
  313. if (!server_address) {
  314. LOG_ERROR("%s: strdup fail, file %s, line %d",
  315. __func__, __FILE__, __LINE__);
  316. return ERROR_FAIL;
  317. }
  318. }
  319. LOG_INFO("Using server address %s", server_address);
  320. } else {
  321. free(server_address);
  322. server_address = strdup(CMD_ARGV[0]);
  323. if (!server_address) {
  324. LOG_ERROR("%s: strdup fail, file %s, line %d",
  325. __func__, __FILE__, __LINE__);
  326. return ERROR_FAIL;
  327. }
  328. LOG_INFO("Set server address to %s", server_address);
  329. }
  330. return ERROR_OK;
  331. }
  332. static const struct command_registration jtag_dpi_command_handlers[] = {
  333. {
  334. .name = "jtag_dpi_set_port",
  335. .handler = &jtag_dpi_set_port,
  336. .mode = COMMAND_CONFIG,
  337. .help = "set the port of the DPI server",
  338. .usage = "[port]",
  339. },
  340. {
  341. .name = "jtag_dpi_set_address",
  342. .handler = &jtag_dpi_set_address,
  343. .mode = COMMAND_CONFIG,
  344. .help = "set the address of the DPI server",
  345. .usage = "[address]",
  346. },
  347. COMMAND_REGISTRATION_DONE
  348. };
  349. static struct jtag_interface jtag_dpi_interface = {
  350. .supported = DEBUG_CAP_TMS_SEQ,
  351. .execute_queue = jtag_dpi_execute_queue,
  352. };
  353. struct adapter_driver jtag_dpi_adapter_driver = {
  354. .name = "jtag_dpi",
  355. .transports = jtag_only,
  356. .commands = jtag_dpi_command_handlers,
  357. .init = jtag_dpi_init,
  358. .quit = jtag_dpi_quit,
  359. .reset = jtag_dpi_reset,
  360. .jtag_ops = &jtag_dpi_interface,
  361. };