Charles Hardin <ckhardin@gmail.com>
[openocd.git] / src / openocd.c
index c7b18eb24cf7b26b67b1e7c51bfd644f8206bc5c..64965e37a6a02c5d3678c298d44a32f2b365d32b 100644 (file)
@@ -194,16 +194,24 @@ static int new_int_array_element(Jim_Interp * interp, const char *varname, int i
        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 = 0%08x\n", namebuf, val ); */
+       /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */
        return result;
 }
 
@@ -223,7 +231,7 @@ static int Jim_Command_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *a
        /* argv[1] = name of array to receive the data
         * argv[2] = desired width
         * argv[3] = memory address 
-        * argv[4] = length in bytes to read
+        * argv[4] = count of times to read
         */
        if (argc != 5) {
                Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
@@ -309,7 +317,6 @@ static int Jim_Command_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *a
                }
                
                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);
@@ -342,6 +349,171 @@ static int Jim_Command_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *a
        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_Command_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+       target_t *target;
+       long l;
+       u32 width;
+       u32 len;
+       u32 addr;
+       u32 count;
+       u32 v;
+       const char *varname;
+       u8 buffer[4096];
+       int  i, 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;
+       }
+
+       target = get_current_target(active_cmd_ctx);
+       
+       /* 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 (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;
+}
+
 static void tcl_output(void *privData, const char *file, int line, const char *function, const char *string)
 {              
        Jim_Obj *tclOutput=(Jim_Obj *)privData;
@@ -557,7 +729,8 @@ void initJim(void)
        Jim_CreateCommand(interp, "find", Jim_Command_find, NULL, NULL);
        Jim_CreateCommand(interp, "echo", Jim_Command_echo, NULL, NULL);
        Jim_CreateCommand(interp, "mem2array", Jim_Command_mem2array, NULL, NULL );
-       
+       Jim_CreateCommand(interp, "array2mem", Jim_Command_array2mem, NULL, NULL );
+
        /* Set Jim's STDIO */
        interp->cookie_stdin = NULL;
        interp->cookie_stdout = NULL;

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)