]> git.sur5r.net Git - openocd/commitdiff
Charles Hardin <ckhardin@gmail.com>
authoroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Thu, 10 Jul 2008 18:47:50 +0000 (18:47 +0000)
committeroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Thu, 10 Jul 2008 18:47:50 +0000 (18:47 +0000)
Add semantics to support memwrite(32,16,8) with an array2mem command
Move the global up in bits2bytes.tcl so the set puts the value in the global
context.
Add memwrite procs to memory.tcl

git-svn-id: svn://svn.berlios.de/openocd/trunk@786 b42882b7-edfa-0310-969c-e2dbd0fdcd60

src/openocd.c
src/tcl/bitsbytes.tcl
src/tcl/memory.tcl

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;
index b1771b4bc6bd5b30dfb28253b19bf8aacae7e58e..9129ae0ad6036802cb6c5856809bbb6f87c25152 100644 (file)
@@ -7,30 +7,28 @@
 
 for { set x 0  } { $x < 32 } { set x [expr $x + 1]} {
     set vn [format "BIT%d" $x]
-    set $vn   [expr (1 << $x)]
     global $vn
-
+    set $vn   [expr (1 << $x)]
 }
 
 # Create K bytes values
 #    __1K ... to __2048K
 for { set x 1  } { $x < 2048 } { set x [expr $x * 2]} {
     set vn [format "__%dK" $x]
-    set $vn   [expr (1024 * $x)]
     global $vn
+    set $vn   [expr (1024 * $x)]
 }
 
 # Create M bytes values
 #    __1M ... to __2048K
 for { set x 1  } { $x < 2048 } { set x [expr $x * 2]} {
     set vn [format "__%dM" $x] 
-    set $vn [expr (1024 * 1024 * $x)]
     global $vn
+    set $vn [expr (1024 * 1024 * $x)]
 }
 
 proc create_mask { MSB LSB } {
     return [expr (((1 << ($MSB - $LSB + 1))-1) << $LSB)]
-
 }
 
 # Cut Bits $MSB to $LSB out of this value.
index 5ac3c4bd87522c373179a0ed6f43289e977176f5..42cd06276bdae6b2f58a947cb937f31baf6e59f7 100644 (file)
@@ -78,31 +78,56 @@ proc address_info { ADDRESS } {
     return "UNKNOWN 0"
 }
 
-proc memread32 {ADDR } {
+proc memread32 {ADDR} {
     set foo(0) 0
     if ![ catch { mem2array foo 32 $ADDR 1  } msg ] {
        return $foo(0)
     } else {
-       error "memead32: $msg"
+       error "memread32: $msg"
     }
 }    
 
-proc memread16 {ADDR } {
+proc memread16 {ADDR} {
     set foo(0) 0
     if ![ catch { mem2array foo 16 $ADDR 1  } msg ] {
        return $foo(0)
     } else {
-       error "memead16: $msg"
+       error "memread16: $msg"
     }
 }    
 
-proc memread8 {ADDR } {
+proc memread8 {ADDR} {
     set foo(0) 0
     if ![ catch { mem2array foo 8 $ADDR 1  } msg ] {
        return $foo(0)
     } else {
-       error "memead8: $msg"
+       error "memread8: $msg"
     }
 }    
 
+proc memwrite32 {ADDR DATA} {
+    set foo(0) $DATA
+    if ![ catch { array2mem foo 32 $ADDR 1  } msg ] {
+       return $foo(0)
+    } else {
+       error "memwrite32: $msg"
+    }
+}    
 
+proc memwrite16 {ADDR DATA} {
+    set foo(0) $DATA
+    if ![ catch { array2mem foo 16 $ADDR 1  } msg ] {
+       return $foo(0)
+    } else {
+       error "memwrite16: $msg"
+    }
+}    
+
+proc memwrite8 {ADDR DATA} {
+    set foo(0) $DATA
+    if ![ catch { array2mem foo 8 $ADDR 1  } msg ] {
+       return $foo(0)
+    } else {
+       error "memwrite8: $msg"
+    }
+}