jtag_command_t -> struct jtag_command
[openocd.git] / src / jtag / amt_jtagaccel.c
index dc40226d311bfc2fd3e0860cea02684a6262f73d..87d9cd3c2fca310a62be72de272dab124f09e88a 100644 (file)
-/***************************************************************************\r
- *   Copyright (C) 2005 by Dominic Rath                                    *\r
- *   Dominic.Rath@gmx.de                                                   *\r
- *                                                                         *\r
- *   This program is free software; you can redistribute it and/or modify  *\r
- *   it under the terms of the GNU General Public License as published by  *\r
- *   the Free Software Foundation; either version 2 of the License, or     *\r
- *   (at your option) any later version.                                   *\r
- *                                                                         *\r
- *   This program is distributed in the hope that it will be useful,       *\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
- *   GNU General Public License for more details.                          *\r
- *                                                                         *\r
- *   You should have received a copy of the GNU General Public License     *\r
- *   along with this program; if not, write to the                         *\r
- *   Free Software Foundation, Inc.,                                       *\r
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
- ***************************************************************************/\r
-#ifdef HAVE_CONFIG_H\r
-#include "config.h"\r
-#endif\r
-\r
-#include "replacements.h"\r
-\r
-#include "jtag.h"\r
-\r
-/* system includes */\r
-\r
-#ifdef _WIN32\r
-#include "errno.h"\r
-#endif /* _WIN32 */\r
-\r
-#include <string.h>\r
-#include <stdlib.h>\r
-\r
-#include <sys/time.h>\r
-#include <time.h>\r
-\r
-#if PARPORT_USE_PPDEV == 1\r
-#include <linux/parport.h>\r
-#include <linux/ppdev.h>\r
-#include <fcntl.h>\r
-#include <sys/ioctl.h>\r
-#include <unistd.h>\r
-#else /* not PARPORT_USE_PPDEV */\r
-#ifndef _WIN32\r
-#include <sys/io.h>\r
-#endif\r
-#endif\r
-\r
-#if PARPORT_USE_GIVEIO == 1\r
-#if IS_CYGWIN == 1\r
-#include <windows.h>\r
-#include <errno.h>\r
-#undef ERROR\r
-#endif\r
-#endif\r
-\r
-#include "log.h"\r
-\r
-/* configuration */\r
-u16 amt_jtagaccel_port;\r
-\r
-/* interface variables\r
- */\r
-static u8 aw_control_rst = 0x00;\r
-static u8 aw_control_fsm = 0x10;\r
-static u8 aw_control_baudrate = 0x20;\r
-\r
-static int rtck_enabled = 0;\r
-\r
-#if PARPORT_USE_PPDEV == 1\r
-static int device_handle;\r
-int addr_mode = IEEE1284_MODE_EPP | IEEE1284_ADDR ;\r
-int data_mode = IEEE1284_MODE_EPP | IEEE1284_DATA ;\r
-#define AMT_AW(val)    do { ioctl(device_handle, PPSETMODE, &addr_mode); write(device_handle, &val, 1); } while (0)\r
-#define AMT_AR(val)    do { ioctl(device_handle, PPSETMODE, &addr_mode); read(device_handle, &val, 1); } while (0)\r
-#define AMT_DW(val)    do { ioctl(device_handle, PPSETMODE, &data_mode); write(device_handle, &val, 1); } while (0)\r
-#define AMT_DR(val)    do { ioctl(device_handle, PPSETMODE, &data_mode); read(device_handle, &val, 1); } while (0)\r
-#else\r
-#define AMT_AW(val)    do { outb(val, amt_jtagaccel_port + 3); } while (0)\r
-#define AMT_AR(val)    do { val = inb(amt_jtagaccel_port + 3); } while (0)\r
-#define AMT_DW(val)    do { outb(val, amt_jtagaccel_port + 4); } while (0)\r
-#define AMT_DR(val)    do { val = inb(amt_jtagaccel_port + 4); } while (0)\r
-#endif\r
-\r
-int amt_jtagaccel_execute_queue(void);\r
-int amt_jtagaccel_register_commands(struct command_context_s *cmd_ctx);\r
-int amt_jtagaccel_speed(int speed);\r
-int amt_jtagaccel_init(void);\r
-int amt_jtagaccel_quit(void);\r
-\r
-int amt_jtagaccel_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
-int amt_jtagaccel_handle_rtck_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
-\r
-/* tap_move[i][j]: tap movement command to go from state i to state j\r
- * 0: Test-Logic-Reset\r
- * 1: Run-Test/Idle\r
- * 2: Shift-DR\r
- * 3: Pause-DR\r
- * 4: Shift-IR\r
- * 5: Pause-IR\r
- */\r
-u8 amt_jtagaccel_tap_move[6][6][2] =\r
-{\r
-       /*         TLR           RTI              SD            PD            SI            PI             */\r
-       {{0x1f, 0x00}, {0x0f, 0x00}, {0x8a, 0x04}, {0x0a, 0x00}, {0x06, 0x00}, {0x96, 0x00}},   /* TLR */\r
-       {{0x1f, 0x00}, {0x00, 0x00}, {0x85, 0x08}, {0x05, 0x00}, {0x8b, 0x08}, {0x0b, 0x00}},   /* RTI */\r
-       {{0x1f, 0x00}, {0x0d, 0x00}, {0x00, 0x00}, {0x01, 0x00}, {0x8f, 0x09}, {0x8f, 0x01}},   /* SD  */\r
-       {{0x1f, 0x00}, {0x0c, 0x00}, {0x08, 0x00}, {0x00, 0x00}, {0x8f, 0x09}, {0x8f, 0x01}},   /* PD  */\r
-       {{0x1f, 0x00}, {0x0d, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x00, 0x00}, {0x01, 0x00}},   /* SI  */\r
-       {{0x1f, 0x00}, {0x0c, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x08, 0x00}, {0x00, 0x00}},   /* PI  */\r
-};\r
-\r
-jtag_interface_t amt_jtagaccel_interface = \r
-{\r
-       .name = "amt_jtagaccel",\r
-       \r
-       .execute_queue = amt_jtagaccel_execute_queue,\r
-\r
-       .speed = amt_jtagaccel_speed,   \r
-       .register_commands = amt_jtagaccel_register_commands,\r
-       .init = amt_jtagaccel_init,\r
-       .quit = amt_jtagaccel_quit,\r
-};\r
-\r
-int amt_jtagaccel_register_commands(struct command_context_s *cmd_ctx)\r
-{\r
-       register_command(cmd_ctx, NULL, "parport_port", amt_jtagaccel_handle_parport_port_command,\r
-                                        COMMAND_CONFIG, NULL);\r
-       register_command(cmd_ctx, NULL, "rtck", amt_jtagaccel_handle_rtck_command,\r
-                                        COMMAND_CONFIG, NULL);\r
-       \r
-       return ERROR_OK;\r
-}\r
-\r
-void amt_jtagaccel_reset(int trst, int srst)\r
-{\r
-       if (trst == 1)\r
-               aw_control_rst |= 0x4;\r
-       else if (trst == 0)\r
-               aw_control_rst &= ~0x4;\r
-\r
-       if (srst == 1)\r
-               aw_control_rst |= 0x1;\r
-       else if (srst == 0)\r
-               aw_control_rst &= ~0x1;\r
-       \r
-       AMT_AW(aw_control_rst);\r
-}\r
-\r
-int amt_jtagaccel_speed(int speed)\r
-{\r
-       aw_control_baudrate &= 0xf0;\r
-       aw_control_baudrate |= speed & 0x0f;\r
-       AMT_AW(aw_control_baudrate);\r
-       \r
-       return ERROR_OK;\r
-}\r
-\r
-void amt_jtagaccel_end_state(state)\r
-{\r
-       if (tap_move_map[state] != -1)\r
-               end_state = state;\r
-       else\r
-       {\r
-               ERROR("BUG: %i is not a valid end state", state);\r
-               exit(-1);\r
-       }\r
-}\r
-\r
-void amt_wait_scan_busy()\r
-{\r
-       int timeout = 4096;\r
-       u8 ar_status;\r
-       \r
-       AMT_AR(ar_status);\r
-       while (((ar_status) & 0x80) && (timeout-- > 0))\r
-               AMT_AR(ar_status);\r
-       \r
-       if (ar_status & 0x80)\r
-       {\r
-               ERROR("amt_jtagaccel timed out while waiting for end of scan, rtck was %s, last AR_STATUS: 0x%2.2x", (rtck_enabled) ? "enabled" : "disabled", ar_status);\r
-               exit(-1);\r
-       }\r
-}\r
-\r
-void amt_jtagaccel_state_move(void)\r
-{\r
-       u8 aw_scan_tms_5;\r
-       u8 tms_scan[2];\r
-        \r
-       tms_scan[0] = amt_jtagaccel_tap_move[tap_move_map[cur_state]][tap_move_map[end_state]][0];\r
-       tms_scan[1] = amt_jtagaccel_tap_move[tap_move_map[cur_state]][tap_move_map[end_state]][1];\r
-       \r
-       aw_scan_tms_5 = 0x40 | (tms_scan[0] & 0x1f);\r
-       AMT_AW(aw_scan_tms_5);\r
-       if (jtag_speed > 3 || rtck_enabled)\r
-               amt_wait_scan_busy();\r
-               \r
-       if (tms_scan[0] & 0x80)\r
-       {\r
-               aw_scan_tms_5 = 0x40 | (tms_scan[1] & 0x1f);\r
-               AMT_AW(aw_scan_tms_5);\r
-               if (jtag_speed > 3 || rtck_enabled)\r
-                       amt_wait_scan_busy();\r
-       }\r
-       \r
-       cur_state = end_state;\r
-}\r
-\r
-void amt_jtagaccel_runtest(int num_cycles)\r
-{\r
-       int i = 0;\r
-       u8 aw_scan_tms_5;\r
-       u8 aw_scan_tms_1to4;\r
-\r
-       enum tap_state saved_end_state = end_state;\r
-       \r
-       /* only do a state_move when we're not already in RTI */\r
-       if (cur_state != TAP_RTI)\r
-       {\r
-               amt_jtagaccel_end_state(TAP_RTI);\r
-               amt_jtagaccel_state_move();\r
-       }\r
-       \r
-       while (num_cycles - i >= 5)\r
-       {\r
-               aw_scan_tms_5 = 0x40;\r
-               AMT_AW(aw_scan_tms_5);\r
-               i += 5;\r
-       }\r
-       \r
-       if (num_cycles - i > 0)\r
-       {\r
-               aw_scan_tms_1to4 = 0x80 | ((num_cycles - i - 1) & 0x3) << 4;\r
-               AMT_AW(aw_scan_tms_1to4);\r
-       }\r
-       \r
-       amt_jtagaccel_end_state(saved_end_state);\r
-       if (cur_state != end_state)\r
-               amt_jtagaccel_state_move();\r
-}\r
-\r
-void amt_jtagaccel_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size)\r
-{\r
-       int bits_left = scan_size;\r
-       int bit_count = 0;\r
-       enum tap_state saved_end_state = end_state;\r
-       u8 aw_tdi_option;\r
-       u8 dw_tdi_scan;\r
-       u8 dr_tdo;\r
-       u8 aw_tms_scan;\r
-       u8 tms_scan[2];\r
-\r
-       if (ir_scan)\r
-               amt_jtagaccel_end_state(TAP_SI);\r
-       else\r
-               amt_jtagaccel_end_state(TAP_SD);\r
-\r
-       amt_jtagaccel_state_move();\r
-       amt_jtagaccel_end_state(saved_end_state);\r
-\r
-       /* handle unaligned bits at the beginning */\r
-       if ((scan_size - 1) % 8)\r
-       {\r
-               aw_tdi_option = 0x30 | (((scan_size - 1) % 8) - 1);\r
-               AMT_AW(aw_tdi_option);\r
-               \r
-               dw_tdi_scan = buf_get_u32(buffer, bit_count, (scan_size - 1) % 8) & 0xff;\r
-               AMT_DW(dw_tdi_scan);\r
-               if (jtag_speed > 3 || rtck_enabled)\r
-                       amt_wait_scan_busy();\r
-\r
-               if ((type == SCAN_IN) || (type == SCAN_IO))\r
-               {\r
-                       AMT_DR(dr_tdo);\r
-                       dr_tdo = dr_tdo >> (8 - ((scan_size - 1) % 8));\r
-                       buf_set_u32(buffer, bit_count, (scan_size - 1) % 8, dr_tdo);\r
-               }\r
-               \r
-               bit_count += (scan_size - 1) % 8;\r
-               bits_left -= (scan_size - 1) % 8;\r
-       }\r
-       \r
-       while (bits_left - 1 >= 8)\r
-       {\r
-               dw_tdi_scan = buf_get_u32(buffer, bit_count, 8) & 0xff;\r
-               AMT_DW(dw_tdi_scan);\r
-               if (jtag_speed > 3 || rtck_enabled)\r
-                       amt_wait_scan_busy();\r
-\r
-               if ((type == SCAN_IN) || (type == SCAN_IO))\r
-               {\r
-                       AMT_DR(dr_tdo);\r
-                       buf_set_u32(buffer, bit_count, 8, dr_tdo);\r
-               }\r
-                               \r
-               bit_count += 8;\r
-               bits_left -= 8;\r
-       }\r
-               \r
-       tms_scan[0] = amt_jtagaccel_tap_move[tap_move_map[cur_state]][tap_move_map[end_state]][0];\r
-       tms_scan[1] = amt_jtagaccel_tap_move[tap_move_map[cur_state]][tap_move_map[end_state]][1];\r
-       aw_tms_scan = 0x40 | (tms_scan[0] & 0x1f) | (buf_get_u32(buffer, bit_count, 1) << 5);\r
-       AMT_AW(aw_tms_scan);\r
-       if (jtag_speed > 3 || rtck_enabled)\r
-               amt_wait_scan_busy();\r
-\r
-       if ((type == SCAN_IN) || (type == SCAN_IO))\r
-       {\r
-               AMT_DR(dr_tdo);\r
-               dr_tdo = dr_tdo >> 7;\r
-               buf_set_u32(buffer, bit_count, 1, dr_tdo);\r
-       }\r
-       \r
-       if (tms_scan[0] & 0x80)\r
-       {\r
-               aw_tms_scan = 0x40 | (tms_scan[1] & 0x1f);\r
-               AMT_AW(aw_tms_scan);\r
-               if (jtag_speed > 3 || rtck_enabled)\r
-                       amt_wait_scan_busy();\r
-       }\r
-       cur_state = end_state;\r
-}\r
-\r
-int amt_jtagaccel_execute_queue(void)\r
-{\r
-       jtag_command_t *cmd = jtag_command_queue; /* currently processed command */\r
-       int scan_size;\r
-       enum scan_type type;\r
-       u8 *buffer;\r
-       int retval;\r
-       \r
-       /* return ERROR_OK, unless a jtag_read_buffer returns a failed check\r
-        * that wasn't handled by a caller-provided error handler\r
-        */ \r
-       retval = ERROR_OK;\r
-               \r
-       while (cmd)\r
-       {\r
-               switch (cmd->type)\r
-               {\r
-                       case JTAG_END_STATE:\r
-#ifdef _DEBUG_JTAG_IO_\r
-                               DEBUG("end_state: %i", cmd->cmd.end_state->end_state);\r
-#endif\r
-                               if (cmd->cmd.end_state->end_state != -1)\r
-                                       amt_jtagaccel_end_state(cmd->cmd.end_state->end_state);\r
-                               break;\r
-                       case JTAG_RESET:\r
-#ifdef _DEBUG_JTAG_IO_\r
-                               DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);\r
-#endif\r
-                               if (cmd->cmd.reset->trst == 1)\r
-                               {\r
-                                       cur_state = TAP_TLR;\r
-                               }\r
-                               amt_jtagaccel_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);\r
-                               break;\r
-                       case JTAG_RUNTEST:\r
-#ifdef _DEBUG_JTAG_IO_\r
-                               DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);\r
-#endif\r
-                               if (cmd->cmd.runtest->end_state != -1)\r
-                                       amt_jtagaccel_end_state(cmd->cmd.runtest->end_state);\r
-                               amt_jtagaccel_runtest(cmd->cmd.runtest->num_cycles);\r
-                               break;\r
-                       case JTAG_STATEMOVE:\r
-#ifdef _DEBUG_JTAG_IO_\r
-                               DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);\r
-#endif\r
-                               if (cmd->cmd.statemove->end_state != -1)\r
-                                       amt_jtagaccel_end_state(cmd->cmd.statemove->end_state);\r
-                               amt_jtagaccel_state_move();\r
-                               break;\r
-                       case JTAG_SCAN:\r
-#ifdef _DEBUG_JTAG_IO_\r
-                               DEBUG("scan end in %i", cmd->cmd.scan->end_state);\r
-#endif\r
-                               if (cmd->cmd.scan->end_state != -1)\r
-                                       amt_jtagaccel_end_state(cmd->cmd.scan->end_state);\r
-                               scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);\r
-                               type = jtag_scan_type(cmd->cmd.scan);\r
-                               amt_jtagaccel_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);\r
-                               if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)\r
-                                       retval = ERROR_JTAG_QUEUE_FAILED;\r
-                               if (buffer)\r
-                                       free(buffer);\r
-                               break;\r
-                       case JTAG_SLEEP:\r
-#ifdef _DEBUG_JTAG_IO_\r
-                               DEBUG("sleep %i", cmd->cmd.sleep->us);\r
-#endif\r
-                               jtag_sleep(cmd->cmd.sleep->us);\r
-                               break;\r
-                       default:\r
-                               ERROR("BUG: unknown JTAG command type encountered");\r
-                               exit(-1);\r
-               }\r
-               cmd = cmd->next;\r
-       }\r
-       \r
-       return retval;\r
-}\r
-\r
-#if PARPORT_USE_GIVEIO == 1\r
-int amt_jtagaccel_get_giveio_access()\r
-{\r
-    HANDLE h;\r
-    OSVERSIONINFO version;\r
-\r
-    version.dwOSVersionInfoSize = sizeof version;\r
-    if (!GetVersionEx( &version )) {\r
-        errno = EINVAL;\r
-        return -1;\r
-    }\r
-    if (version.dwPlatformId != VER_PLATFORM_WIN32_NT)\r
-        return 0;\r
-\r
-    h = CreateFile( "\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );\r
-    if (h == INVALID_HANDLE_VALUE) {\r
-        errno = ENODEV;\r
-        return -1;\r
-    }\r
-\r
-    CloseHandle( h );\r
-\r
-    return 0;\r
-}\r
-#endif\r
-\r
-int amt_jtagaccel_init(void)\r
-{\r
-#if PARPORT_USE_PPDEV == 1\r
-       char buffer[256];\r
-       int i = 0;\r
-       u8 control_port;\r
-#else\r
-       u8 status_port;\r
-#endif\r
-       u8 ar_status;\r
-       \r
-#if PARPORT_USE_PPDEV == 1\r
-       if (device_handle > 0)\r
-       {\r
-               ERROR("device is already opened");\r
-               return ERROR_JTAG_INIT_FAILED;\r
-       }\r
-\r
-       snprintf(buffer, 256, "/dev/parport%d", amt_jtagaccel_port);\r
-       device_handle = open(buffer, O_RDWR);\r
-       \r
-       if (device_handle < 0)\r
-       {\r
-               ERROR("cannot open device. check it exists and that user read and write rights are set");\r
-               return ERROR_JTAG_INIT_FAILED;\r
-       }\r
-\r
-       i = ioctl(device_handle, PPCLAIM);\r
-       if (i < 0)\r
-       {\r
-               ERROR("cannot claim device");\r
-               return ERROR_JTAG_INIT_FAILED;\r
-       }\r
-\r
-       i = IEEE1284_MODE_EPP;\r
-       i = ioctl(device_handle, PPSETMODE, & i);\r
-       if (i < 0)\r
-       {\r
-               ERROR(" cannot set compatible mode to device");\r
-               return ERROR_JTAG_INIT_FAILED;\r
-       }\r
-       \r
-       control_port = 0x00;\r
-       i = ioctl(device_handle, PPWCONTROL, &control_port);\r
-\r
-       control_port = 0x04;\r
-       i = ioctl(device_handle, PPWCONTROL, &control_port);\r
-\r
-#else\r
-       if (amt_jtagaccel_port == 0)\r
-       {\r
-               amt_jtagaccel_port = 0x378;\r
-               WARNING("No parport port specified, using default '0x378' (LPT1)");\r
-       }\r
-\r
-#if PARPORT_USE_GIVEIO == 1\r
-       if (amt_jtagaccel_get_giveio_access() != 0) {\r
-#else /* PARPORT_USE_GIVEIO */ \r
-       if (ioperm(amt_jtagaccel_port, 5, 1) != 0) {\r
-#endif /* PARPORT_USE_GIVEIO */\r
-               ERROR("missing privileges for direct i/o");\r
-               return ERROR_JTAG_INIT_FAILED;\r
-       }\r
-       \r
-       /* prepare epp port */\r
-       /* clear timeout */\r
-       status_port = inb(amt_jtagaccel_port + 1);\r
-       outb(status_port | 0x1, amt_jtagaccel_port + 1);\r
-       \r
-       /* reset epp port */\r
-       outb(0x00, amt_jtagaccel_port + 2);\r
-       outb(0x04, amt_jtagaccel_port + 2);\r
-#endif\r
-       \r
-       if (rtck_enabled)\r
-       {       \r
-               /* set RTCK enable bit */\r
-               aw_control_fsm |= 0x02;\r
-       }\r
-       \r
-       /* enable JTAG port */\r
-       aw_control_fsm |= 0x04;\r
-       AMT_AW(aw_control_fsm);\r
-       \r
-       amt_jtagaccel_speed(jtag_speed);\r
-       \r
-       if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)\r
-               aw_control_rst &= ~0x8;\r
-       else\r
-               aw_control_rst |= 0x8;\r
-       \r
-       if (jtag_reset_config & RESET_SRST_PUSH_PULL)\r
-               aw_control_rst &= ~0x2;\r
-       else\r
-               aw_control_rst |= 0x2;\r
-       \r
-       amt_jtagaccel_reset(0, 0);\r
-       \r
-       /* read status register */\r
-       AMT_AR(ar_status);\r
-       DEBUG("AR_STATUS: 0x%2.2x", ar_status);\r
-       \r
-       return ERROR_OK;\r
-}\r
-\r
-int amt_jtagaccel_quit(void)\r
-{\r
-       \r
-       return ERROR_OK;\r
-}\r
-\r
-int amt_jtagaccel_handle_parport_port_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
-{\r
-       if (argc == 0)\r
-               return ERROR_OK;\r
-\r
-       /* only if the port wasn't overwritten by cmdline */\r
-       if (amt_jtagaccel_port == 0)\r
-               amt_jtagaccel_port = strtoul(args[0], NULL, 0);\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-int amt_jtagaccel_handle_rtck_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
-{\r
-       if (argc == 0)\r
-       {\r
-               command_print(cmd_ctx, "amt_jtagaccel RTCK feature %s", (rtck_enabled) ? "enabled" : "disabled");\r
-               return ERROR_OK;\r
-       }\r
-       else\r
-       {\r
-               if (strcmp(args[0], "enabled") == 0)\r
-               {\r
-                       rtck_enabled = 1;\r
-               }\r
-               else\r
-               {\r
-                       rtck_enabled = 0;\r
-               }\r
-       }\r
-       \r
-       return ERROR_OK;\r
-}\r
+/***************************************************************************
+ *   Copyright (C) 2005 by Dominic Rath                                    *
+ *   Dominic.Rath@gmx.de                                                   *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   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.             *
+ ***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "interface.h"
+#include "commands.h"
+
+
+#if PARPORT_USE_PPDEV == 1
+#include <linux/parport.h>
+#include <linux/ppdev.h>
+#include <sys/ioctl.h>
+#else /* not PARPORT_USE_PPDEV */
+#ifndef _WIN32
+#include <sys/io.h>
+#endif
+#endif
+
+#if PARPORT_USE_GIVEIO == 1
+#if IS_CYGWIN == 1
+#include <windows.h>
+#endif
+#endif
+
+/* configuration */
+static uint16_t amt_jtagaccel_port;
+
+/* interface variables
+ */
+static uint8_t aw_control_rst = 0x00;
+static uint8_t aw_control_fsm = 0x10;
+static uint8_t aw_control_baudrate = 0x20;
+
+static int rtck_enabled = 0;
+
+#if PARPORT_USE_PPDEV == 1
+static int device_handle;
+
+static int addr_mode = IEEE1284_MODE_EPP | IEEE1284_ADDR ;
+#define AMT_AW(val)    do { ioctl(device_handle, PPSETMODE, &addr_mode); write(device_handle, &val, 1); } while (0)
+#define AMT_AR(val)    do { ioctl(device_handle, PPSETMODE, &addr_mode); read(device_handle, &val, 1); } while (0)
+
+static int data_mode = IEEE1284_MODE_EPP | IEEE1284_DATA ;
+#define AMT_DW(val)    do { ioctl(device_handle, PPSETMODE, &data_mode); write(device_handle, &val, 1); } while (0)
+#define AMT_DR(val)    do { ioctl(device_handle, PPSETMODE, &data_mode); read(device_handle, &val, 1); } while (0)
+
+#else
+
+#define AMT_AW(val)    do { outb(val, amt_jtagaccel_port + 3); } while (0)
+#define AMT_AR(val)    do { val = inb(amt_jtagaccel_port + 3); } while (0)
+#define AMT_DW(val)    do { outb(val, amt_jtagaccel_port + 4); } while (0)
+#define AMT_DR(val)    do { val = inb(amt_jtagaccel_port + 4); } while (0)
+
+#endif // PARPORT_USE_PPDEV
+
+/* tap_move[i][j]: tap movement command to go from state i to state j
+ * 0: Test-Logic-Reset
+ * 1: Run-Test/Idle
+ * 2: Shift-DR
+ * 3: Pause-DR
+ * 4: Shift-IR
+ * 5: Pause-IR
+ */
+static uint8_t amt_jtagaccel_tap_move[6][6][2] =
+{
+       /*         RESET         IDLE        DRSHIFT       DRPAUSE       IRSHIFT       IRPAUSE             */
+       {{0x1f, 0x00}, {0x0f, 0x00}, {0x05, 0x00}, {0x0a, 0x00}, {0x06, 0x00}, {0x96, 0x00}},   /* RESET */
+       {{0x1f, 0x00}, {0x00, 0x00}, {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x0b, 0x00}},   /* IDLE */
+       {{0x1f, 0x00}, {0x0d, 0x00}, {0x00, 0x00}, {0x01, 0x00}, {0x8f, 0x09}, {0x8f, 0x01}},   /* DRSHIFT  */
+       {{0x1f, 0x00}, {0x0c, 0x00}, {0x08, 0x00}, {0x00, 0x00}, {0x8f, 0x09}, {0x8f, 0x01}},   /* DRPAUSE  */
+       {{0x1f, 0x00}, {0x0d, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x00, 0x00}, {0x01, 0x00}},   /* IRSHIFT  */
+       {{0x1f, 0x00}, {0x0c, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x08, 0x00}, {0x00, 0x00}},   /* IRPAUSE  */
+};
+
+
+static void amt_jtagaccel_reset(int trst, int srst)
+{
+       if (trst == 1)
+               aw_control_rst |= 0x4;
+       else if (trst == 0)
+               aw_control_rst &= ~0x4;
+
+       if (srst == 1)
+               aw_control_rst |= 0x1;
+       else if (srst == 0)
+               aw_control_rst &= ~0x1;
+
+       AMT_AW(aw_control_rst);
+}
+
+static int amt_jtagaccel_speed(int speed)
+{
+       aw_control_baudrate &= 0xf0;
+       aw_control_baudrate |= speed & 0x0f;
+       AMT_AW(aw_control_baudrate);
+
+       return ERROR_OK;
+}
+
+static void amt_jtagaccel_end_state(tap_state_t state)
+{
+       if (tap_is_state_stable(state))
+               tap_set_end_state(state);
+       else
+       {
+               LOG_ERROR("BUG: %i is not a valid end state", state);
+               exit(-1);
+       }
+}
+
+static void amt_wait_scan_busy(void)
+{
+       int timeout = 4096;
+       uint8_t ar_status;
+
+       AMT_AR(ar_status);
+       while (((ar_status) & 0x80) && (timeout-- > 0))
+               AMT_AR(ar_status);
+
+       if (ar_status & 0x80)
+       {
+               LOG_ERROR("amt_jtagaccel timed out while waiting for end of scan, rtck was %s, last AR_STATUS: 0x%2.2x", (rtck_enabled) ? "enabled" : "disabled", ar_status);
+               exit(-1);
+       }
+}
+
+static void amt_jtagaccel_state_move(void)
+{
+       uint8_t aw_scan_tms_5;
+       uint8_t tms_scan[2];
+
+       tap_state_t     cur_state = tap_get_state();
+       tap_state_t     end_state = tap_get_end_state();
+
+       tms_scan[0] = amt_jtagaccel_tap_move[tap_move_ndx(cur_state)][tap_move_ndx(end_state)][0];
+       tms_scan[1] = amt_jtagaccel_tap_move[tap_move_ndx(cur_state)][tap_move_ndx(end_state)][1];
+
+       aw_scan_tms_5 = 0x40 | (tms_scan[0] & 0x1f);
+       AMT_AW(aw_scan_tms_5);
+       int jtag_speed = jtag_get_speed();
+       if (jtag_speed > 3 || rtck_enabled)
+               amt_wait_scan_busy();
+
+       if (tms_scan[0] & 0x80)
+       {
+               aw_scan_tms_5 = 0x40 | (tms_scan[1] & 0x1f);
+               AMT_AW(aw_scan_tms_5);
+               if (jtag_speed > 3 || rtck_enabled)
+                       amt_wait_scan_busy();
+       }
+
+       tap_set_state(end_state);
+}
+
+static void amt_jtagaccel_runtest(int num_cycles)
+{
+       int i = 0;
+       uint8_t aw_scan_tms_5;
+       uint8_t aw_scan_tms_1to4;
+
+       tap_state_t saved_end_state = tap_get_end_state();
+
+       /* only do a state_move when we're not already in IDLE */
+       if (tap_get_state() != TAP_IDLE)
+       {
+               amt_jtagaccel_end_state(TAP_IDLE);
+               amt_jtagaccel_state_move();
+       }
+
+       while (num_cycles - i >= 5)
+       {
+               aw_scan_tms_5 = 0x40;
+               AMT_AW(aw_scan_tms_5);
+               i += 5;
+       }
+
+       if (num_cycles - i > 0)
+       {
+               aw_scan_tms_1to4 = 0x80 | ((num_cycles - i - 1) & 0x3) << 4;
+               AMT_AW(aw_scan_tms_1to4);
+       }
+
+       amt_jtagaccel_end_state(saved_end_state);
+       if (tap_get_state() != tap_get_end_state())
+               amt_jtagaccel_state_move();
+}
+
+static void amt_jtagaccel_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size)
+{
+       int bits_left = scan_size;
+       int bit_count = 0;
+       tap_state_t saved_end_state = tap_get_end_state();
+       uint8_t aw_tdi_option;
+       uint8_t dw_tdi_scan;
+       uint8_t dr_tdo;
+       uint8_t aw_tms_scan;
+       uint8_t tms_scan[2];
+       int jtag_speed = jtag_get_speed();
+
+       if (ir_scan)
+               amt_jtagaccel_end_state(TAP_IRSHIFT);
+       else
+               amt_jtagaccel_end_state(TAP_DRSHIFT);
+
+       amt_jtagaccel_state_move();
+       amt_jtagaccel_end_state(saved_end_state);
+
+       /* handle unaligned bits at the beginning */
+       if ((scan_size - 1) % 8)
+       {
+               aw_tdi_option = 0x30 | (((scan_size - 1) % 8) - 1);
+               AMT_AW(aw_tdi_option);
+
+               dw_tdi_scan = buf_get_u32(buffer, bit_count, (scan_size - 1) % 8) & 0xff;
+               AMT_DW(dw_tdi_scan);
+               if (jtag_speed > 3 || rtck_enabled)
+                       amt_wait_scan_busy();
+
+               if ((type == SCAN_IN) || (type == SCAN_IO))
+               {
+                       AMT_DR(dr_tdo);
+                       dr_tdo = dr_tdo >> (8 - ((scan_size - 1) % 8));
+                       buf_set_u32(buffer, bit_count, (scan_size - 1) % 8, dr_tdo);
+               }
+
+               bit_count += (scan_size - 1) % 8;
+               bits_left -= (scan_size - 1) % 8;
+       }
+
+       while (bits_left - 1 >= 8)
+       {
+               dw_tdi_scan = buf_get_u32(buffer, bit_count, 8) & 0xff;
+               AMT_DW(dw_tdi_scan);
+               if (jtag_speed > 3 || rtck_enabled)
+                       amt_wait_scan_busy();
+
+               if ((type == SCAN_IN) || (type == SCAN_IO))
+               {
+                       AMT_DR(dr_tdo);
+                       buf_set_u32(buffer, bit_count, 8, dr_tdo);
+               }
+
+               bit_count += 8;
+               bits_left -= 8;
+       }
+
+       tms_scan[0] = amt_jtagaccel_tap_move[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][0];
+       tms_scan[1] = amt_jtagaccel_tap_move[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][1];
+       aw_tms_scan = 0x40 | (tms_scan[0] & 0x1f) | (buf_get_u32(buffer, bit_count, 1) << 5);
+       AMT_AW(aw_tms_scan);
+       if (jtag_speed > 3 || rtck_enabled)
+               amt_wait_scan_busy();
+
+       if ((type == SCAN_IN) || (type == SCAN_IO))
+       {
+               AMT_DR(dr_tdo);
+               dr_tdo = dr_tdo >> 7;
+               buf_set_u32(buffer, bit_count, 1, dr_tdo);
+       }
+
+       if (tms_scan[0] & 0x80)
+       {
+               aw_tms_scan = 0x40 | (tms_scan[1] & 0x1f);
+               AMT_AW(aw_tms_scan);
+               if (jtag_speed > 3 || rtck_enabled)
+                       amt_wait_scan_busy();
+       }
+       tap_set_state(tap_get_end_state());
+}
+
+static int amt_jtagaccel_execute_queue(void)
+{
+       struct jtag_command *cmd = jtag_command_queue; /* currently processed command */
+       int scan_size;
+       enum scan_type type;
+       uint8_t *buffer;
+       int retval;
+
+       /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
+        * that wasn't handled by a caller-provided error handler
+        */
+       retval = ERROR_OK;
+
+       while (cmd)
+       {
+               switch (cmd->type)
+               {
+                       case JTAG_RESET:
+#ifdef _DEBUG_JTAG_IO_
+                               LOG_DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
+#endif
+                               if (cmd->cmd.reset->trst == 1)
+                               {
+                                       tap_set_state(TAP_RESET);
+                               }
+                               amt_jtagaccel_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
+                               break;
+                       case JTAG_RUNTEST:
+#ifdef _DEBUG_JTAG_IO_
+                               LOG_DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
+#endif
+                               amt_jtagaccel_end_state(cmd->cmd.runtest->end_state);
+                               amt_jtagaccel_runtest(cmd->cmd.runtest->num_cycles);
+                               break;
+                       case JTAG_STATEMOVE:
+#ifdef _DEBUG_JTAG_IO_
+                               LOG_DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);
+#endif
+                               amt_jtagaccel_end_state(cmd->cmd.statemove->end_state);
+                               amt_jtagaccel_state_move();
+                               break;
+                       case JTAG_SCAN:
+#ifdef _DEBUG_JTAG_IO_
+                               LOG_DEBUG("scan end in %i", cmd->cmd.scan->end_state);
+#endif
+                               amt_jtagaccel_end_state(cmd->cmd.scan->end_state);
+                               scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
+                               type = jtag_scan_type(cmd->cmd.scan);
+                               amt_jtagaccel_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
+                               if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
+                                       retval = ERROR_JTAG_QUEUE_FAILED;
+                               if (buffer)
+                                       free(buffer);
+                               break;
+                       case JTAG_SLEEP:
+#ifdef _DEBUG_JTAG_IO_
+                               LOG_DEBUG("sleep %" PRIi32, cmd->cmd.sleep->us);
+#endif
+                               jtag_sleep(cmd->cmd.sleep->us);
+                               break;
+                       default:
+                               LOG_ERROR("BUG: unknown JTAG command type encountered");
+                               exit(-1);
+               }
+               cmd = cmd->next;
+       }
+
+       return retval;
+}
+
+#if PARPORT_USE_GIVEIO == 1
+int amt_jtagaccel_get_giveio_access(void)
+{
+       HANDLE h;
+       OSVERSIONINFO version;
+
+       version.dwOSVersionInfoSize = sizeof version;
+       if (!GetVersionEx(&version)) {
+       errno = EINVAL;
+       return -1;
+       }
+       if (version.dwPlatformId != VER_PLATFORM_WIN32_NT)
+       return 0;
+
+       h = CreateFile("\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+       if (h == INVALID_HANDLE_VALUE) {
+       errno = ENODEV;
+       return -1;
+       }
+
+       CloseHandle(h);
+
+       return 0;
+}
+#endif
+
+static int amt_jtagaccel_init(void)
+{
+#if PARPORT_USE_PPDEV == 1
+       char buffer[256];
+       int i = 0;
+       uint8_t control_port;
+#else
+       uint8_t status_port;
+#endif
+       uint8_t ar_status;
+
+#if PARPORT_USE_PPDEV == 1
+       if (device_handle > 0)
+       {
+               LOG_ERROR("device is already opened");
+               return ERROR_JTAG_INIT_FAILED;
+       }
+
+       snprintf(buffer, 256, "/dev/parport%d", amt_jtagaccel_port);
+       device_handle = open(buffer, O_RDWR);
+
+       if (device_handle < 0)
+       {
+               LOG_ERROR("cannot open device. check it exists and that user read and write rights are set");
+               return ERROR_JTAG_INIT_FAILED;
+       }
+
+       i = ioctl(device_handle, PPCLAIM);
+       if (i < 0)
+       {
+               LOG_ERROR("cannot claim device");
+               return ERROR_JTAG_INIT_FAILED;
+       }
+
+       i = IEEE1284_MODE_EPP;
+       i = ioctl(device_handle, PPSETMODE, & i);
+       if (i < 0)
+       {
+               LOG_ERROR(" cannot set compatible mode to device");
+               return ERROR_JTAG_INIT_FAILED;
+       }
+
+       control_port = 0x00;
+       i = ioctl(device_handle, PPWCONTROL, &control_port);
+
+       control_port = 0x04;
+       i = ioctl(device_handle, PPWCONTROL, &control_port);
+
+#else
+       if (amt_jtagaccel_port == 0)
+       {
+               amt_jtagaccel_port = 0x378;
+               LOG_WARNING("No parport port specified, using default '0x378' (LPT1)");
+       }
+
+#if PARPORT_USE_GIVEIO == 1
+       if (amt_jtagaccel_get_giveio_access() != 0) {
+#else /* PARPORT_USE_GIVEIO */
+       if (ioperm(amt_jtagaccel_port, 5, 1) != 0) {
+#endif /* PARPORT_USE_GIVEIO */
+               LOG_ERROR("missing privileges for direct i/o");
+               return ERROR_JTAG_INIT_FAILED;
+       }
+
+       /* prepare epp port */
+       /* clear timeout */
+       status_port = inb(amt_jtagaccel_port + 1);
+       outb(status_port | 0x1, amt_jtagaccel_port + 1);
+
+       /* reset epp port */
+       outb(0x00, amt_jtagaccel_port + 2);
+       outb(0x04, amt_jtagaccel_port + 2);
+#endif
+
+       if (rtck_enabled)
+       {
+               /* set RTCK enable bit */
+               aw_control_fsm |= 0x02;
+       }
+
+       /* enable JTAG port */
+       aw_control_fsm |= 0x04;
+       AMT_AW(aw_control_fsm);
+
+       amt_jtagaccel_speed(jtag_get_speed());
+
+       enum reset_types jtag_reset_config = jtag_get_reset_config();
+       if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
+               aw_control_rst &= ~0x8;
+       else
+               aw_control_rst |= 0x8;
+
+       if (jtag_reset_config & RESET_SRST_PUSH_PULL)
+               aw_control_rst &= ~0x2;
+       else
+               aw_control_rst |= 0x2;
+
+       amt_jtagaccel_reset(0, 0);
+
+       /* read status register */
+       AMT_AR(ar_status);
+       LOG_DEBUG("AR_STATUS: 0x%2.2x", ar_status);
+
+       return ERROR_OK;
+}
+
+static int amt_jtagaccel_quit(void)
+{
+
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(amt_jtagaccel_handle_parport_port_command)
+{
+       if (argc == 1)
+       {
+               /* only if the port wasn't overwritten by cmdline */
+               if (amt_jtagaccel_port == 0)
+               {
+                       uint16_t port;
+                       COMMAND_PARSE_NUMBER(u16, args[0], port);
+                       amt_jtagaccel_port = port;
+               }
+               else
+               {
+                       LOG_ERROR("The parport port was already configured!");
+                       return ERROR_FAIL;
+               }
+       }
+
+       command_print(cmd_ctx, "parport port = %u", amt_jtagaccel_port);
+
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(amt_jtagaccel_handle_rtck_command)
+{
+       if (argc == 0)
+       {
+               command_print(cmd_ctx, "amt_jtagaccel RTCK feature %s", (rtck_enabled) ? "enabled" : "disabled");
+               return ERROR_OK;
+       }
+       else
+       {
+               if (strcmp(args[0], "enabled") == 0)
+               {
+                       rtck_enabled = 1;
+               }
+               else
+               {
+                       rtck_enabled = 0;
+               }
+       }
+
+       return ERROR_OK;
+}
+
+static int amt_jtagaccel_register_commands(struct command_context_s *cmd_ctx)
+{
+       register_command(cmd_ctx, NULL, "parport_port",
+                       amt_jtagaccel_handle_parport_port_command, COMMAND_CONFIG,
+                       NULL);
+       register_command(cmd_ctx, NULL, "rtck",
+                       amt_jtagaccel_handle_rtck_command, COMMAND_CONFIG,
+                       NULL);
+
+       return ERROR_OK;
+}
+
+struct jtag_interface amt_jtagaccel_interface = {
+               .name = "amt_jtagaccel",
+               .register_commands = &amt_jtagaccel_register_commands,
+               .init = &amt_jtagaccel_init,
+               .quit = &amt_jtagaccel_quit,
+               .speed = &amt_jtagaccel_speed,
+               .execute_queue = &amt_jtagaccel_execute_queue,
+       };

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)