Extend configure script to check for environ declaration in stdlib.h.
[openocd.git] / src / helper / tclapi.c
index 1839ae50bac813653a336eb0c397cd8517c44197..d8723a0518749881c133b82c90b540642bb2918b 100644 (file)
-/***************************************************************************\r
- *   Copyright (C) 2007,2008 Ã˜yvind Harboe                                 *\r
- *   Copyright (C) 2008 Duane Ellis                                        *\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
-#include "target.h"\r
-#include "target_request.h"\r
-\r
-#include "log.h"\r
-#include "configuration.h"\r
-#include "binarybuffer.h"\r
-#include "jtag.h"\r
-#include "flash.h"\r
-\r
-#include <string.h>\r
-#include <stdlib.h>\r
-#include <inttypes.h>\r
-\r
-#include <sys/types.h>\r
-#include <sys/stat.h>\r
-#include <unistd.h>\r
-#include <errno.h>\r
-\r
-#include <sys/time.h>\r
-#include <time.h>\r
-\r
-#include <time_support.h>\r
-\r
-#include <fileio.h>\r
-#include <image.h>\r
-\r
-static int new_int_array_element(Jim_Interp * interp, const char *varname, int idx, u32 val)\r
-{\r
-       char *namebuf;\r
-       Jim_Obj *nameObjPtr, *valObjPtr;\r
-       int result;\r
-\r
-       namebuf = alloc_printf("%s(%d)", varname, idx);\r
-       if (!namebuf)\r
-               return JIM_ERR;\r
-\r
-       nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);\r
-       valObjPtr = Jim_NewIntObj(interp, val);\r
-       if (!nameObjPtr || !valObjPtr)\r
-       {\r
-               free(namebuf);\r
-               return JIM_ERR;\r
-       }\r
-\r
-       Jim_IncrRefCount(nameObjPtr);\r
-       Jim_IncrRefCount(valObjPtr);\r
-       result = Jim_SetVariable(interp, nameObjPtr, valObjPtr);\r
-       Jim_DecrRefCount(interp, nameObjPtr);\r
-       Jim_DecrRefCount(interp, valObjPtr);\r
-       free(namebuf);\r
-       /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */\r
-       return result;\r
-}\r
-\r
-static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv)\r
-{\r
-       target_t *target;\r
-       command_context_t *context;\r
-       long l;\r
-       u32 width;\r
-       u32 len;\r
-       u32 addr;\r
-       u32 count;\r
-       u32 v;\r
-       const char *varname;\r
-       u8 buffer[4096];\r
-       int  i, n, e, retval;\r
-\r
-       /* argv[1] = name of array to receive the data\r
-        * argv[2] = desired width\r
-        * argv[3] = memory address\r
-        * argv[4] = count of times to read\r
-        */\r
-       if (argc != 5) {\r
-               Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");\r
-               return JIM_ERR;\r
-       }\r
-       varname = Jim_GetString(argv[1], &len);\r
-       /* given "foo" get space for worse case "foo(%d)" .. add 20 */\r
-\r
-       e = Jim_GetLong(interp, argv[2], &l);\r
-       width = l;\r
-       if (e != JIM_OK) {\r
-               return e;\r
-       }\r
-\r
-       e = Jim_GetLong(interp, argv[3], &l);\r
-       addr = l;\r
-       if (e != JIM_OK) {\r
-               return e;\r
-       }\r
-       e = Jim_GetLong(interp, argv[4], &l);\r
-       len = l;\r
-       if (e != JIM_OK) {\r
-               return e;\r
-       }\r
-       switch (width) {\r
-               case 8:\r
-                       width = 1;\r
-                       break;\r
-               case 16:\r
-                       width = 2;\r
-                       break;\r
-               case 32:\r
-                       width = 4;\r
-                       break;\r
-               default:\r
-                       Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));\r
-                       Jim_AppendStrings( interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL );\r
-                       return JIM_ERR;\r
-       }\r
-       if (len == 0) {\r
-               Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));\r
-               Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: zero width read?", NULL);\r
-               return JIM_ERR;\r
-       }\r
-       if ((addr + (len * width)) < addr) {\r
-               Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));\r
-               Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: addr + len - wraps to zero?", NULL);\r
-               return JIM_ERR;\r
-       }\r
-       /* absurd transfer size? */\r
-       if (len > 65536) {\r
-               Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));\r
-               Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: absurd > 64K item request", NULL);\r
-               return JIM_ERR;\r
-       }\r
-\r
-       if ((width == 1) ||\r
-               ((width == 2) && ((addr & 1) == 0)) ||\r
-               ((width == 4) && ((addr & 3) == 0))) {\r
-               /* all is well */\r
-       } else {\r
-               char buf[100];\r
-               Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));\r
-               sprintf(buf, "mem2array address: 0x%08x is not aligned for %d byte reads", addr, width);\r
-               Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);\r
-               return JIM_ERR;\r
-       }\r
-\r
-       context = Jim_GetAssocData(interp, "context");\r
-       if (context == NULL)\r
-       {\r
-               LOG_ERROR("mem2array: no command context");\r
-               return JIM_ERR;\r
-       }\r
-       target = get_current_target(context);\r
-       if (target == NULL)\r
-       {\r
-               LOG_ERROR("mem2array: no current target");\r
-               return JIM_ERR;\r
-       }\r
-\r
-       /* Transfer loop */\r
-\r
-       /* index counter */\r
-       n = 0;\r
-       /* assume ok */\r
-       e = JIM_OK;\r
-       while (len) {\r
-               /* Slurp... in buffer size chunks */\r
-\r
-               count = len; /* in objects.. */\r
-               if (count > (sizeof(buffer)/width)) {\r
-                       count = (sizeof(buffer)/width);\r
-               }\r
-\r
-               retval = target->type->read_memory( target, addr, width, count, buffer );\r
-               if (retval != ERROR_OK) {\r
-                       /* BOO !*/\r
-                       LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count);\r
-                       Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));\r
-                       Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL);\r
-                       e = JIM_ERR;\r
-                       len = 0;\r
-               } else {\r
-                       v = 0; /* shut up gcc */\r
-                       for (i = 0 ;i < count ;i++, n++) {\r
-                               switch (width) {\r
-                                       case 4:\r
-                                               v = target_buffer_get_u32(target, &buffer[i*width]);\r
-                                               break;\r
-                                       case 2:\r
-                                               v = target_buffer_get_u16(target, &buffer[i*width]);\r
-                                               break;\r
-                                       case 1:\r
-                                               v = buffer[i] & 0x0ff;\r
-                                               break;\r
-                               }\r
-                               new_int_array_element(interp, varname, n, v);\r
-                       }\r
-                       len -= count;\r
-               }\r
-       }\r
-\r
-       Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));\r
-\r
-       return JIM_OK;\r
-}\r
-\r
-static int get_int_array_element(Jim_Interp * interp, const char *varname, int idx, u32 *val)\r
-{\r
-       char *namebuf;\r
-       Jim_Obj *nameObjPtr, *valObjPtr;\r
-       int result;\r
-       long l;\r
-\r
-       namebuf = alloc_printf("%s(%d)", varname, idx);\r
-       if (!namebuf)\r
-               return JIM_ERR;\r
-\r
-       nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);\r
-       if (!nameObjPtr)\r
-       {\r
-               free(namebuf);\r
-               return JIM_ERR;\r
-       }\r
-\r
-       Jim_IncrRefCount(nameObjPtr);\r
-       valObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_ERRMSG);\r
-       Jim_DecrRefCount(interp, nameObjPtr);\r
-       free(namebuf);\r
-       if (valObjPtr == NULL)\r
-               return JIM_ERR;\r
-\r
-       result = Jim_GetLong(interp, valObjPtr, &l);\r
-       /* printf("%s(%d) => 0%08x\n", varname, idx, val); */\r
-       *val = l;\r
-       return result;\r
-}\r
-\r
-static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv)\r
-{\r
-       target_t *target;\r
-       command_context_t *context;\r
-       long l;\r
-       u32 width;\r
-       u32 len;\r
-       u32 addr;\r
-       u32 count;\r
-       u32 v;\r
-       const char *varname;\r
-       u8 buffer[4096];\r
-       int  i, n, e, retval;\r
-\r
-       /* argv[1] = name of array to get the data\r
-        * argv[2] = desired width\r
-        * argv[3] = memory address\r
-        * argv[4] = count to write\r
-        */\r
-       if (argc != 5) {\r
-               Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");\r
-               return JIM_ERR;\r
-       }\r
-       varname = Jim_GetString(argv[1], &len);\r
-       /* given "foo" get space for worse case "foo(%d)" .. add 20 */\r
-\r
-       e = Jim_GetLong(interp, argv[2], &l);\r
-       width = l;\r
-       if (e != JIM_OK) {\r
-               return e;\r
-       }\r
-\r
-       e = Jim_GetLong(interp, argv[3], &l);\r
-       addr = l;\r
-       if (e != JIM_OK) {\r
-               return e;\r
-       }\r
-       e = Jim_GetLong(interp, argv[4], &l);\r
-       len = l;\r
-       if (e != JIM_OK) {\r
-               return e;\r
-       }\r
-       switch (width) {\r
-               case 8:\r
-                       width = 1;\r
-                       break;\r
-               case 16:\r
-                       width = 2;\r
-                       break;\r
-               case 32:\r
-                       width = 4;\r
-                       break;\r
-               default:\r
-                       Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));\r
-                       Jim_AppendStrings( interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL );\r
-                       return JIM_ERR;\r
-       }\r
-       if (len == 0) {\r
-               Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));\r
-               Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: zero width read?", NULL);\r
-               return JIM_ERR;\r
-       }\r
-       if ((addr + (len * width)) < addr) {\r
-               Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));\r
-               Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: addr + len - wraps to zero?", NULL);\r
-               return JIM_ERR;\r
-       }\r
-       /* absurd transfer size? */\r
-       if (len > 65536) {\r
-               Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));\r
-               Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: absurd > 64K item request", NULL);\r
-               return JIM_ERR;\r
-       }\r
-\r
-       if ((width == 1) ||\r
-               ((width == 2) && ((addr & 1) == 0)) ||\r
-               ((width == 4) && ((addr & 3) == 0))) {\r
-               /* all is well */\r
-       } else {\r
-               char buf[100];\r
-               Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));\r
-               sprintf(buf, "array2mem address: 0x%08x is not aligned for %d byte reads", addr, width);\r
-               Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);\r
-               return JIM_ERR;\r
-       }\r
-\r
-       context = Jim_GetAssocData(interp, "context");\r
-       if (context == NULL)\r
-       {\r
-               LOG_ERROR("array2mem: no command context");\r
-               return JIM_ERR;\r
-       }\r
-       target = get_current_target(context);\r
-       if (target == NULL)\r
-       {\r
-               LOG_ERROR("array2mem: no current target");\r
-               return JIM_ERR;\r
-       }\r
-\r
-       /* Transfer loop */\r
-\r
-       /* index counter */\r
-       n = 0;\r
-       /* assume ok */\r
-       e = JIM_OK;\r
-       while (len) {\r
-               /* Slurp... in buffer size chunks */\r
-\r
-               count = len; /* in objects.. */\r
-               if (count > (sizeof(buffer)/width)) {\r
-                       count = (sizeof(buffer)/width);\r
-               }\r
-\r
-               v = 0; /* shut up gcc */\r
-               for (i = 0 ;i < count ;i++, n++) {\r
-                       get_int_array_element(interp, varname, n, &v);\r
-                       switch (width) {\r
-                       case 4:\r
-                               target_buffer_set_u32(target, &buffer[i*width], v);\r
-                               break;\r
-                       case 2:\r
-                               target_buffer_set_u16(target, &buffer[i*width], v);\r
-                               break;\r
-                       case 1:\r
-                               buffer[i] = v & 0x0ff;\r
-                               break;\r
-                       }\r
-               }\r
-               len -= count;\r
-\r
-               retval = target->type->write_memory(target, addr, width, count, buffer);\r
-               if (retval != ERROR_OK) {\r
-                       /* BOO !*/\r
-                       LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count);\r
-                       Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));\r
-                       Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL);\r
-                       e = JIM_ERR;\r
-                       len = 0;\r
-               }\r
-       }\r
-\r
-       Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));\r
-\r
-       return JIM_OK;\r
-}\r
-\r
-int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args)\r
-{\r
-       int retval;\r
-       scan_field_t *fields;\r
-       int num_fields;\r
-       int field_count = 0;\r
-       int i, e;\r
-       long device;\r
-\r
-       /* args[1] = device\r
-        * args[2] = num_bits\r
-        * args[3] = hex string\r
-        * ... repeat num bits and hex string ...\r
-        */\r
-       if ((argc < 4) || ((argc % 2)!=0))\r
-       {\r
-               Jim_WrongNumArgs(interp, 1, args, "wrong arguments");\r
-               return JIM_ERR;\r
-       }\r
-\r
-       for (i = 2; i < argc; i+=2)\r
-       {\r
-               long bits;\r
-\r
-               e = Jim_GetLong(interp, args[i], &bits);\r
-               if (e != JIM_OK)\r
-                       return e;\r
-       }\r
-\r
-       e = Jim_GetLong(interp, args[1], &device);\r
-       if (e != JIM_OK)\r
-               return e;\r
-\r
-       num_fields=(argc-2)/2;\r
-       fields = malloc(sizeof(scan_field_t) * num_fields);\r
-       for (i = 2; i < argc; i+=2)\r
-       {\r
-               long bits;\r
-               int len;\r
-               const char *str;\r
-\r
-               Jim_GetLong(interp, args[i], &bits);\r
-               str = Jim_GetString(args[i+1], &len);\r
-\r
-               fields[field_count].device = device;\r
-               fields[field_count].num_bits = bits;\r
-               fields[field_count].out_value = malloc(CEIL(bits, 8));\r
-               str_to_buf(str, len, fields[field_count].out_value, bits, 0);\r
-               fields[field_count].out_mask = NULL;\r
-               fields[field_count].in_value = fields[field_count].out_value;\r
-               fields[field_count].in_check_mask = NULL;\r
-               fields[field_count].in_check_value = NULL;\r
-               fields[field_count].in_handler = NULL;\r
-               fields[field_count++].in_handler_priv = NULL;\r
-       }\r
-\r
-       jtag_add_dr_scan(num_fields, fields, -1);\r
-       retval = jtag_execute_queue();\r
-       if (retval != ERROR_OK)\r
-       {\r
-               Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));\r
-               Jim_AppendStrings(interp, Jim_GetResult(interp), "drscan: jtag execute failed", NULL);\r
-               return JIM_ERR;\r
-       }\r
-\r
-       field_count=0;\r
-       Jim_Obj *list = Jim_NewListObj(interp, NULL, 0);\r
-       for (i = 2; i < argc; i+=2)\r
-       {\r
-               long bits;\r
-               char *str;\r
-\r
-               Jim_GetLong(interp, args[i], &bits);\r
-               str = buf_to_str(fields[field_count].in_value, bits, 16);\r
-               free(fields[field_count].out_value);\r
-\r
-               Jim_ListAppendElement(interp, list, Jim_NewStringObj(interp, str, strlen(str)));\r
-               free(str);\r
-               field_count++;\r
-       }\r
-\r
-       Jim_SetResult(interp, list);\r
-\r
-       free(fields);\r
-\r
-       return JIM_OK;\r
-}\r
-\r
-static int jim_flash_banks(Jim_Interp *interp, int argc, Jim_Obj *const *argv)\r
-{\r
-       flash_bank_t *p;\r
-\r
-       if (argc != 1) {\r
-               Jim_WrongNumArgs(interp, 1, argv, "no arguments to flash_banks command");\r
-               return JIM_ERR;\r
-       }\r
-\r
-       if (!flash_banks)\r
-       {\r
-               return JIM_ERR;\r
-       }\r
-\r
-       Jim_Obj *list=Jim_NewListObj(interp, NULL, 0);\r
-       for (p = flash_banks; p; p = p->next)\r
-       {\r
-               Jim_Obj *elem=Jim_NewListObj(interp, NULL, 0);\r
-\r
-               Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "name", -1));\r
-               Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, p->driver->name, -1));\r
-               Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "base", -1));\r
-               Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->base));\r
-               Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "size", -1));\r
-               Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->size));\r
-               Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "bus_width", -1));\r
-               Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->bus_width));\r
-               Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "chip_width", -1));\r
-               Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->chip_width));\r
-\r
-               Jim_ListAppendElement(interp, list, elem);\r
-       }\r
-\r
-       Jim_SetResult(interp, list);\r
-\r
-       return JIM_OK;\r
-}\r
-\r
-\r
-int tclapi_register_commands()\r
-{\r
-       register_jim("ocd_mem2array", jim_mem2array, "read memory and return as a TCL array for script processing");\r
-       register_jim("ocd_array2mem", jim_array2mem, "convert a TCL array to memory locations and write the values");\r
-       register_jim("drscan", Jim_Command_drscan, "execute DR scan <device> <num_bits> <value> <num_bits1> <value2> ...");\r
-       register_jim("ocd_flash_banks", jim_flash_banks, "return information about the flash banks");\r
-\r
-}\r
+/***************************************************************************
+ *   Copyright (C) 2007,2008 Ã˜yvind Harboe                                 *
+ *   Copyright (C) 2008 Duane Ellis                                        *
+ *                                                                         *
+ *   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 "tclapi.h"
+#include "../target/target.h"
+#include "../jtag/jtag.h"
+#include "../flash/flash.h"
+
+#include <string.h>
+
+
+static int new_int_array_element(Jim_Interp * interp, const char *varname, int idx, u32 val)
+{
+       char *namebuf;
+       Jim_Obj *nameObjPtr, *valObjPtr;
+       int result;
+
+       namebuf = alloc_printf("%s(%d)", varname, idx);
+       if (!namebuf)
+               return JIM_ERR;
+
+       nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
+       valObjPtr = Jim_NewIntObj(interp, val);
+       if (!nameObjPtr || !valObjPtr)
+       {
+               free(namebuf);
+               return JIM_ERR;
+       }
+
+       Jim_IncrRefCount(nameObjPtr);
+       Jim_IncrRefCount(valObjPtr);
+       result = Jim_SetVariable(interp, nameObjPtr, valObjPtr);
+       Jim_DecrRefCount(interp, nameObjPtr);
+       Jim_DecrRefCount(interp, valObjPtr);
+       free(namebuf);
+       /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */
+       return result;
+}
+
+static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+       target_t *target;
+       command_context_t *context;
+       long l;
+       u32 width;
+       int len;
+       u32 addr;
+       unsigned count;
+       u32 v;
+       const char *varname;
+       u8 buffer[4096];
+       unsigned i, n;
+       int e, retval;
+
+       /* argv[1] = name of array to receive the data
+        * argv[2] = desired width
+        * argv[3] = memory address
+        * argv[4] = count of times to read
+        */
+       if (argc != 5) {
+               Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
+               return JIM_ERR;
+       }
+       varname = Jim_GetString(argv[1], &len);
+       /* given "foo" get space for worse case "foo(%d)" .. add 20 */
+
+       e = Jim_GetLong(interp, argv[2], &l);
+       width = l;
+       if (e != JIM_OK) {
+               return e;
+       }
+
+       e = Jim_GetLong(interp, argv[3], &l);
+       addr = l;
+       if (e != JIM_OK) {
+               return e;
+       }
+       e = Jim_GetLong(interp, argv[4], &l);
+       len = l;
+       if (e != JIM_OK) {
+               return e;
+       }
+       switch (width) {
+               case 8:
+                       width = 1;
+                       break;
+               case 16:
+                       width = 2;
+                       break;
+               case 32:
+                       width = 4;
+                       break;
+               default:
+                       Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+                       Jim_AppendStrings( interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL );
+                       return JIM_ERR;
+       }
+       if (len == 0) {
+               Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+               Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: zero width read?", NULL);
+               return JIM_ERR;
+       }
+       if ((addr + (len * width)) < addr) {
+               Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+               Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: addr + len - wraps to zero?", NULL);
+               return JIM_ERR;
+       }
+       /* absurd transfer size? */
+       if (len > 65536) {
+               Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+               Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: absurd > 64K item request", NULL);
+               return JIM_ERR;
+       }
+
+       if ((width == 1) ||
+               ((width == 2) && ((addr & 1) == 0)) ||
+               ((width == 4) && ((addr & 3) == 0))) {
+               /* all is well */
+       } else {
+               char buf[100];
+               Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+               sprintf(buf, "mem2array address: 0x%08x is not aligned for %d byte reads", addr, width);
+               Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
+               return JIM_ERR;
+       }
+
+       context = Jim_GetAssocData(interp, "context");
+       if (context == NULL)
+       {
+               LOG_ERROR("mem2array: no command context");
+               return JIM_ERR;
+       }
+       target = get_current_target(context);
+       if (target == NULL)
+       {
+               LOG_ERROR("mem2array: no current target");
+               return JIM_ERR;
+       }
+
+       /* Transfer loop */
+
+       /* index counter */
+       n = 0;
+       /* assume ok */
+       e = JIM_OK;
+       while (len) {
+               /* Slurp... in buffer size chunks */
+
+               count = len; /* in objects.. */
+               if (count > (sizeof(buffer)/width)) {
+                       count = (sizeof(buffer)/width);
+               }
+
+               retval = target->type->read_memory( target, addr, width, count, buffer );
+               if (retval != ERROR_OK) {
+                       /* BOO !*/
+                       LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count);
+                       Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+                       Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL);
+                       e = JIM_ERR;
+                       len = 0;
+               } else {
+                       v = 0; /* shut up gcc */
+                       for (i = 0 ;i < count ;i++, n++) {
+                               switch (width) {
+                                       case 4:
+                                               v = target_buffer_get_u32(target, &buffer[i*width]);
+                                               break;
+                                       case 2:
+                                               v = target_buffer_get_u16(target, &buffer[i*width]);
+                                               break;
+                                       case 1:
+                                               v = buffer[i] & 0x0ff;
+                                               break;
+                               }
+                               new_int_array_element(interp, varname, n, v);
+                       }
+                       len -= count;
+               }
+       }
+
+       Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+
+       return JIM_OK;
+}
+
+static int get_int_array_element(Jim_Interp * interp, const char *varname, int idx, u32 *val)
+{
+       char *namebuf;
+       Jim_Obj *nameObjPtr, *valObjPtr;
+       int result;
+       long l;
+
+       namebuf = alloc_printf("%s(%d)", varname, idx);
+       if (!namebuf)
+               return JIM_ERR;
+
+       nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
+       if (!nameObjPtr)
+       {
+               free(namebuf);
+               return JIM_ERR;
+       }
+
+       Jim_IncrRefCount(nameObjPtr);
+       valObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_ERRMSG);
+       Jim_DecrRefCount(interp, nameObjPtr);
+       free(namebuf);
+       if (valObjPtr == NULL)
+               return JIM_ERR;
+
+       result = Jim_GetLong(interp, valObjPtr, &l);
+       /* printf("%s(%d) => 0%08x\n", varname, idx, val); */
+       *val = l;
+       return result;
+}
+
+static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+       target_t *target;
+       command_context_t *context;
+       long l;
+       u32 width;
+       int len;
+       u32 addr;
+       u32 count;
+       u32 v;
+       const char *varname;
+       u8 buffer[4096];
+       int  n, e, retval;
+
+       /* argv[1] = name of array to get the data
+        * argv[2] = desired width
+        * argv[3] = memory address
+        * argv[4] = count to write
+        */
+       if (argc != 5) {
+               Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
+               return JIM_ERR;
+       }
+       varname = Jim_GetString(argv[1], &len);
+       /* given "foo" get space for worse case "foo(%d)" .. add 20 */
+
+       e = Jim_GetLong(interp, argv[2], &l);
+       width = l;
+       if (e != JIM_OK) {
+               return e;
+       }
+
+       e = Jim_GetLong(interp, argv[3], &l);
+       addr = l;
+       if (e != JIM_OK) {
+               return e;
+       }
+       e = Jim_GetLong(interp, argv[4], &l);
+       len = l;
+       if (e != JIM_OK) {
+               return e;
+       }
+       switch (width) {
+               case 8:
+                       width = 1;
+                       break;
+               case 16:
+                       width = 2;
+                       break;
+               case 32:
+                       width = 4;
+                       break;
+               default:
+                       Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+                       Jim_AppendStrings( interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL );
+                       return JIM_ERR;
+       }
+       if (len == 0) {
+               Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+               Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: zero width read?", NULL);
+               return JIM_ERR;
+       }
+       if ((addr + (len * width)) < addr) {
+               Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+               Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: addr + len - wraps to zero?", NULL);
+               return JIM_ERR;
+       }
+       /* absurd transfer size? */
+       if (len > 65536) {
+               Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+               Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: absurd > 64K item request", NULL);
+               return JIM_ERR;
+       }
+
+       if ((width == 1) ||
+               ((width == 2) && ((addr & 1) == 0)) ||
+               ((width == 4) && ((addr & 3) == 0))) {
+               /* all is well */
+       } else {
+               char buf[100];
+               Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+               sprintf(buf, "array2mem address: 0x%08x is not aligned for %d byte reads", addr, width);
+               Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
+               return JIM_ERR;
+       }
+
+       context = Jim_GetAssocData(interp, "context");
+       if (context == NULL)
+       {
+               LOG_ERROR("array2mem: no command context");
+               return JIM_ERR;
+       }
+       target = get_current_target(context);
+       if (target == NULL)
+       {
+               LOG_ERROR("array2mem: no current target");
+               return JIM_ERR;
+       }
+
+       /* Transfer loop */
+
+       /* index counter */
+       n = 0;
+       /* assume ok */
+       e = JIM_OK;
+       while (len) {
+               /* Slurp... in buffer size chunks */
+
+               count = len; /* in objects.. */
+               if (count > (sizeof(buffer)/width)) {
+                       count = (sizeof(buffer)/width);
+               }
+
+               v = 0; /* shut up gcc */
+               for (unsigned i = 0 ;i < count ;i++, n++) {
+                       get_int_array_element(interp, varname, n, &v);
+                       switch (width) {
+                       case 4:
+                               target_buffer_set_u32(target, &buffer[i*width], v);
+                               break;
+                       case 2:
+                               target_buffer_set_u16(target, &buffer[i*width], v);
+                               break;
+                       case 1:
+                               buffer[i] = v & 0x0ff;
+                               break;
+                       }
+               }
+               len -= count;
+
+               retval = target->type->write_memory(target, addr, width, count, buffer);
+               if (retval != ERROR_OK) {
+                       /* BOO !*/
+                       LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count);
+                       Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+                       Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL);
+                       e = JIM_ERR;
+                       len = 0;
+               }
+       }
+
+       Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+
+       return JIM_OK;
+}
+
+int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args)
+{
+       int retval;
+       scan_field_t *fields;
+       int num_fields;
+       int field_count = 0;
+       int i, e;
+       long device;
+
+       /* args[1] = device
+        * args[2] = num_bits
+        * args[3] = hex string
+        * ... repeat num bits and hex string ...
+        */
+       if ((argc < 4) || ((argc % 2)!=0))
+       {
+               Jim_WrongNumArgs(interp, 1, args, "<device> <num_bits1> <value1> <num_bits2> <value2> ...");
+               return JIM_ERR;
+       }
+
+       for (i = 2; i < argc; i+=2)
+       {
+               long bits;
+
+               e = Jim_GetLong(interp, args[i], &bits);
+               if (e != JIM_OK)
+                       return e;
+       }
+
+       e = Jim_GetLong(interp, args[1], &device);
+       if (e != JIM_OK)
+               return e;
+
+       num_fields=(argc-2)/2;
+       fields = malloc(sizeof(scan_field_t) * num_fields);
+       for (i = 2; i < argc; i+=2)
+       {
+               long bits;
+               int len;
+               const char *str;
+
+               Jim_GetLong(interp, args[i], &bits);
+               str = Jim_GetString(args[i+1], &len);
+
+               fields[field_count].num_bits = bits;
+               fields[field_count].out_value = malloc(CEIL(bits, 8));
+               str_to_buf(str, len, fields[field_count].out_value, bits, 0);
+               fields[field_count].in_value = fields[field_count].out_value;
+       }
+
+       jtag_add_dr_scan(num_fields, fields, TAP_INVALID);
+       retval = jtag_execute_queue();
+       if (retval != ERROR_OK)
+       {
+               Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+               Jim_AppendStrings(interp, Jim_GetResult(interp), "drscan: jtag execute failed", NULL);
+               return JIM_ERR;
+       }
+
+       field_count=0;
+       Jim_Obj *list = Jim_NewListObj(interp, NULL, 0);
+       for (i = 2; i < argc; i+=2)
+       {
+               long bits;
+               char *str;
+
+               Jim_GetLong(interp, args[i], &bits);
+               str = buf_to_str(fields[field_count].in_value, bits, 16);
+               free(fields[field_count].out_value);
+
+               Jim_ListAppendElement(interp, list, Jim_NewStringObj(interp, str, strlen(str)));
+               free(str);
+               field_count++;
+       }
+
+       Jim_SetResult(interp, list);
+
+       free(fields);
+
+       return JIM_OK;
+}
+
+static int jim_flash_banks(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+
+       if (argc != 1) {
+               Jim_WrongNumArgs(interp, 1, argv, "no arguments to flash_banks command");
+               return JIM_ERR;
+       }
+
+       unsigned flash_banks = flash_get_bank_count();
+       if (!flash_banks)
+       {
+               return JIM_ERR;
+       }
+
+       Jim_Obj *list=Jim_NewListObj(interp, NULL, 0);
+       for (unsigned i = 0; i < flash_banks; i++)
+       {
+               flash_bank_t *p = get_flash_bank_by_num(i);
+               Jim_Obj *elem=Jim_NewListObj(interp, NULL, 0);
+
+               Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "name", -1));
+               Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, p->driver->name, -1));
+               Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "base", -1));
+               Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->base));
+               Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "size", -1));
+               Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->size));
+               Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "bus_width", -1));
+               Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->bus_width));
+               Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "chip_width", -1));
+               Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->chip_width));
+
+               Jim_ListAppendElement(interp, list, elem);
+       }
+
+       Jim_SetResult(interp, list);
+
+       return JIM_OK;
+}
+
+int tclapi_register_commands(struct command_context_s *cmd_ctx)
+{
+       register_jim(cmd_ctx, "ocd_mem2array", &jim_mem2array,
+               "read memory and return as a TCL array for script processing");
+       register_jim(cmd_ctx, "ocd_array2mem", &jim_array2mem,
+               "convert a TCL array to memory locations and write the values");
+       register_jim(cmd_ctx, "drscan", &Jim_Command_drscan,
+               "execute DR scan <device> <num_bits> <value> <num_bits1> <value2> ...");
+       register_jim(cmd_ctx, "ocd_flash_banks", &jim_flash_banks,
+               "return information about the flash banks");
+       return ERROR_OK;
+}

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)