src/helper/configuration.h
authoroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Sun, 6 Jul 2008 19:17:43 +0000 (19:17 +0000)
committeroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Sun, 6 Jul 2008 19:17:43 +0000 (19:17 +0000)
- Log output handlers now get a "const char *line"
- Added "const" to parameter.

src/helper/command.c
src/helper/command.h
- New function:  'command_output_text()'
- Log output handlers now get a "const char *line"

src/helper/options.c
- Log output handlers now get a "const char *line"

src/server/telnet_server.c
- DO not transmit NULL bytes via TELNET.
- Log output handlers now get a "const char *line"

src/server/gdb_server.c
- Log output handlers now get a "const char *line"

*** THIS INCLUDES PORTIONS OF A PATCH FROM Oyvind sent
previously to the mailing list for TCL users try

src/target/target.c
*** THIS INCLUDES PORTIONS OF A PATCH FROM Oyvind sent
previously to the mailing list for TCL users try

src/target/target.h
*** THIS INCLUDES PORTIONS OF A PATCH FROM Oyvind sent
previously to the mailing list for TCL users try

src/openocd.c
    - **MAJOR** Work: New TCL/Jim function: mem2array
- **MAJOR** Work: Redirect Tcl/Jim stdio output to remote users.
- Previously: TCL output did not go to GDB.
- Previously: TCL output did not go to TELNET
- Previously: TCL output only goes to control console.
- This fixes that problem.
+ Created callbacks:
+openocd_jim_fwrite()
+openocd_jim_fread()
+openocd_jim_vfprintf()
+openocd_jim_fflush()
+openocd_jim_fgets()

src/Makefile.am
- New TCL files.
- Future note: This should be more automated.  As the list of
  'tcl' files grows maintaning this list will suck.

src/Jim.c
- ** THIS INCLUDES A PREVIOUS PATCH I SENT EARLIER **
- that impliments many [format] specifies JIM did not support.
- Jim_FormatString() - **MAJOR** work.
- Previously only supported "%s" "%d" and "%c"
- And what support existed had bugs.
- NEW: *MANY* formating parameters are now supported.
- TODO: The "precision" specifier is not supported.

** NEW ** This patch.

- Jim_StringToWide() test if no conversion occured.
- Jim_StringToIndex() test if no conversion occured.
- Jim_StringToDouble() test if no conversion occured.

** NEW ** This Patch. Major Work.
- Previously output from JIM did not get sent to GDB
- Ditto: Output to Telnet session.
- Above items are now fixed - By introducing callbacks
  new function pointers in the "interp" structure.

- Helpers that call the callbacks.

- New function: Jim_fprintf()
- New function: Jim_vfprintf()
- New function: Jim_fwrite()
- New function: Jim_fread()
- New function: Jim_fflush()
- New function: Jim_fgets()

By default: the output is to STDIO as previous.
The "openocd.c" - redirects the output as needed.

- Jim_Panic() - Send panic to both STDERR and the interps
specified STDERR output as a 2nd choice.

- Now JIM's "stdin/stdout/stderr" paramters are "void *"
and are no longer "FILE *".

src/Jim.h
- **MAJOR**
-  New JIM STDIO callbacks in the "interp" structure.
-  change: "stdin/stdout/stderr" are now "void *" cookies.
-  New JIM stdio helper functions.

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

27 files changed:
src/Makefile.am
src/helper/command.c
src/helper/command.h
src/helper/configuration.h
src/helper/options.c
src/jim.c
src/jim.h
src/openocd.c
src/server/gdb_server.c
src/server/telnet_server.c
src/target/target.c
src/target/target.h
src/tcl/README_ABOUT_TCL.txt [new file with mode: 0644]
src/tcl/bitsbytes.tcl [new file with mode: 0644]
src/tcl/chip/atmel/at91/aic.tcl [new file with mode: 0644]
src/tcl/chip/atmel/at91/at91sam7x128.tcl [new file with mode: 0644]
src/tcl/chip/atmel/at91/at91sam7x256.tcl [new file with mode: 0644]
src/tcl/chip/atmel/at91/pmc.tcl [new file with mode: 0644]
src/tcl/chip/atmel/at91/rtt.tcl [new file with mode: 0644]
src/tcl/chip/atmel/at91/usarts.tcl [new file with mode: 0644]
src/tcl/cpu/arm/arm7tdmi.tcl [new file with mode: 0644]
src/tcl/cpu/arm/arm920.tcl [new file with mode: 0644]
src/tcl/cpu/arm/arm946.tcl [new file with mode: 0644]
src/tcl/cpu/arm/arm966.tcl [new file with mode: 0644]
src/tcl/memory.tcl [new file with mode: 0644]
src/tcl/mmr_helpers.tcl [new file with mode: 0644]
src/tcl/readable.tcl [new file with mode: 0644]

index 462b5ee4d0a1d9f12ac0439ad4ff042696567846..924040e615b6fd9ea984b31310a2190990d40075 100644 (file)
@@ -81,4 +81,20 @@ openocd_LDADD = $(top_builddir)/src/xsvf/libxsvf.a \
 
        
        
-nobase_dist_pkglib_DATA = tcl/commands.tcl
+nobase_dist_pkglib_DATA = \
+       tcl/commands.tcl  \
+       tcl/bitsbytes.tcl  \
+       tcl/chip/atmel/at91/aic.tcl  \
+       tcl/chip/atmel/at91/at91sam7x128.tcl  \
+       tcl/chip/atmel/at91/at91sam7x256.tcl  \
+       tcl/chip/atmel/at91/pmc.tcl  \
+       tcl/chip/atmel/at91/rtt.tcl  \
+       tcl/chip/atmel/at91/usarts.tcl  \
+       tcl/cpu/arm/arm7tdmi.tcl  \
+       tcl/cpu/arm/arm920.tcl  \
+       tcl/cpu/arm/arm946.tcl  \
+       tcl/cpu/arm/arm966.tcl  \
+       tcl/memory.tcl  \
+       tcl/mmr_helpers.tcl  \
+       tcl/readable.tcl  
+
index ed0a82e6218946c51a6b683a1604f4be20136a42..386572ed94d7b5f989cf8d7405b02d5a717fca79 100644 (file)
@@ -621,7 +621,7 @@ int command_print_help(command_context_t* context, char* name, char** args, int
     return command_print_help_match(context, context->commands, name, args, argc);
 }
 
-void command_set_output_handler(command_context_t* context, int (*output_handler)(struct command_context_s *context, char* line), void *priv)
+void command_set_output_handler(command_context_t* context, int (*output_handler)(struct command_context_s *context, const char* line), void *priv)
 {
        context->output_handler = output_handler;
        context->output_handler_priv = priv;
@@ -720,3 +720,10 @@ int handle_time_command(struct command_context_s *cmd_ctx, char *cmd, char **arg
 
        return retval;
 }
+/*
+ * Local Variables: **
+ * tab-width: 4 **
+ * c-basic-offset: 4 **
+ * End: **
+ */
+
index 8d50d6e6bbd5c65f38a296f17737298ecef913e7..8db1675f84642eb22c1d7f4e2abf6ee7cb7f4d64 100644 (file)
@@ -48,7 +48,7 @@ typedef struct command_context_s
         * Returning ERROR_COMMAND_SYNTAX_ERROR will have the effect of
         * printing out the syntax of the command.
         */
-       int (*output_handler)(struct command_context_s *context, char* line);
+       int (*output_handler)(struct command_context_s *context, const char* line);
        void *output_handler_priv;
 } command_context_t;
 
@@ -67,7 +67,7 @@ typedef struct command_s
 extern command_t* register_command(command_context_t *context, command_t *parent, char *name, int (*handler)(struct command_context_s *context, char* name, char** args, int argc), enum command_mode mode, char *help);
 extern int unregister_command(command_context_t *context, char *name);
 extern int unregister_all_commands(command_context_t *context);
-extern void command_set_output_handler(command_context_t* context, int (*output_handler)(struct command_context_s *context, char* line), void *priv);
+extern void command_set_output_handler(command_context_t* context, int (*output_handler)(struct command_context_s *context, const char* line), void *priv);
 extern command_context_t* copy_command_context(command_context_t* context);
 extern command_context_t* command_init();
 extern int command_done(command_context_t *context);
@@ -86,3 +86,11 @@ extern int command_run_file(command_context_t *context, FILE *file, enum command
 extern int fast_and_dangerous;
 
 #endif /* COMMAND_H */
+
+/*
+ * Local Variables: **
+ * tab-width: 4 **
+ * c-basic-offset: 4 **
+ * End: **
+ */
+
index 894d874ce97a2380c92c2ab8ae82b19bd6cf3738..1d315cc2dac49bf850ea4b0ccd3b0ed90ce34241 100644 (file)
@@ -27,7 +27,7 @@ extern int parse_cmdline_args(struct command_context_s *cmd_ctx, int argc, char
 extern int parse_config_file(struct command_context_s *cmd_ctx);
 extern void add_config_command (const char *cfg);
 extern void add_script_search_dir (const char *dir);
-extern int configuration_output_handler(struct command_context_s *context, char* line);
+extern int configuration_output_handler(struct command_context_s *context, const char* line);
 extern FILE *open_file_from_path (char *file, char *mode);
 extern char *find_file(char *name);
 
index ab36a2865e1f14964d19113201c48459dadb3b5f..afff55ba4964a75e03c5fd943160e6a24b12a13c 100644 (file)
@@ -45,7 +45,7 @@ static struct option long_options[] =
        {0, 0, 0, 0}
 };
 
-int configuration_output_handler(struct command_context_s *context, char* line)
+int configuration_output_handler(struct command_context_s *context, const char* line)
 {
        LOG_INFO_N(line);
 
index a466a08bbdebeb8d3d34ad74d7553f3d07091440..4cf4f3dea6abb88dad406756cacdd0d9533d7dfa 100644 (file)
--- a/src/jim.c
+++ b/src/jim.c
@@ -363,7 +363,7 @@ int Jim_StringToWide(const char *str, jim_wide *widePtr, int base)
 #else
     *widePtr = strtol(str, &endptr, base);
 #endif
-    if (str[0] == '\0')
+    if ((str[0] == '\0') || (str == endptr) )
         return JIM_ERR;
     if (endptr[0] != '\0') {
         while(*endptr) {
@@ -380,7 +380,7 @@ int Jim_StringToIndex(const char *str, int *intPtr)
     char *endptr;
 
     *intPtr = strtol(str, &endptr, 10);
-    if (str[0] == '\0')
+    if ( (str[0] == '\0') || (str == endptr) )
         return JIM_ERR;
     if (endptr[0] != '\0') {
         while(*endptr) {
@@ -437,7 +437,7 @@ int Jim_StringToDouble(const char *str, double *doublePtr)
     char *endptr;
 
     *doublePtr = strtod(str, &endptr);
-    if (str[0] == '\0' || endptr[0] != '\0')
+    if (str[0] == '\0' || endptr[0] != '\0' || (str == endptr) )
         return JIM_ERR;
     return JIM_OK;
 }
@@ -460,13 +460,16 @@ static jim_wide JimPowWide(jim_wide b, jim_wide e)
 void Jim_Panic(Jim_Interp *interp, const char *fmt, ...)
 {
     va_list ap;
-    FILE *fp = interp ? interp->stderr_ : stderr;
 
     va_start(ap, fmt);
-    fprintf(fp, JIM_NL "JIM INTERPRETER PANIC: ");
-    vfprintf(fp, fmt, ap);
-    fprintf(fp, JIM_NL JIM_NL);
+       /* 
+        * Send it here first.. Assuming STDIO still works
+        */
+    fprintf(stderr, JIM_NL "JIM INTERPRETER PANIC: ");
+    vfprintf(stderr, fmt, ap);
+    fprintf(stderr, JIM_NL JIM_NL);
     va_end(ap);
+
 #ifdef HAVE_BACKTRACE
     {
         void *array[40];
@@ -481,6 +484,13 @@ void Jim_Panic(Jim_Interp *interp, const char *fmt, ...)
         fprintf(fp,"[backtrace] of 'nm <executable>' in the bug report." JIM_NL);
     }
 #endif
+       
+       /* This may actually crash... we do it last */
+       if( interp && interp->cookie_stderr ){
+               Jim_fprintf(  interp, interp->cookie_stderr, JIM_NL "JIM INTERPRETER PANIC: ");
+               Jim_vfprintf( interp, interp->cookie_stderr, fmt, ap );
+               Jim_fprintf(  interp, interp->cookie_stderr, JIM_NL JIM_NL );
+       }
     abort();
 }
 
@@ -2136,21 +2146,36 @@ static Jim_Obj *JimStringToUpper(Jim_Interp *interp, Jim_Obj *strObjPtr)
 }
 
 /* This is the core of the [format] command.
- * TODO: Export it, make it real... for now only %s and %%
- * specifiers supported. */
+ * TODO: Lots of things work - via a hack
+ *       However, no format item can be >= JIM_MAX_FMT 
+ */
 Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr,
         int objc, Jim_Obj *const *objv)
 {
-    const char *fmt;
+    const char *fmt, *_fmt;
     int fmtLen;
     Jim_Obj *resObjPtr;
+    
 
     fmt = Jim_GetString(fmtObjPtr, &fmtLen);
+       _fmt = fmt;
     resObjPtr = Jim_NewStringObj(interp, "", 0);
     while (fmtLen) {
         const char *p = fmt;
         char spec[2], c;
         jim_wide wideValue;
+               double doubleValue;
+               /* we cheat and use Sprintf()! */
+#define JIM_MAX_FMT 2048
+               char sprintf_buf[JIM_MAX_FMT];
+               char fmt_str[100];
+               char *cp;
+               int width;
+               int ljust;
+               int zpad;
+               int spad;
+               int altfm;
+               int forceplus;
 
         while (*fmt != '%' && fmtLen) {
             fmt++; fmtLen--;
@@ -2159,38 +2184,191 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr,
         if (fmtLen == 0)
             break;
         fmt++; fmtLen--; /* skip '%' */
-        if (*fmt != '%') {
+               zpad = 0;
+               spad = 0;
+               width = -1;
+               ljust = 0;
+               altfm = 0;
+               forceplus = 0;
+    next_fmt:
+               if( fmtLen <= 0 ){
+                       break;
+               }
+               switch( *fmt ){
+                       /* terminals */
+        case 'b': /* binary - not all printfs() do this */
+               case 's': /* string */
+               case 'i': /* integer */
+               case 'd': /* decimal */
+               case 'x': /* hex */
+               case 'X': /* CAP hex */
+               case 'c': /* char */
+               case 'o': /* octal */
+               case 'u': /* unsigned */
+               case 'f': /* float */
+                       break;
+                       
+                       /* non-terminals */
+               case '0': /* zero pad */
+                       zpad = 1;
+                       *fmt++;  fmtLen--;
+                       goto next_fmt;
+                       break;
+               case '+':
+                       forceplus = 1;
+                       *fmt++;  fmtLen--;
+                       goto next_fmt;
+                       break;
+               case ' ': /* sign space */
+                       spad = 1;
+                       *fmt++;  fmtLen--;
+                       goto next_fmt;
+                       break;
+               case '-':
+                       ljust = 1;
+                       *fmt++;  fmtLen--;
+                       goto next_fmt;
+                       break;
+               case '#':
+                       altfm = 1;
+                       *fmt++; fmtLen--;
+                       goto next_fmt;
+                       
+               case '1':
+               case '2':
+               case '3':
+               case '4':
+               case '5':
+               case '6':
+               case '7':
+               case '8':
+               case '9':
+                       width = 0;
+                       while( isdigit(*fmt) && (fmtLen > 0) ){
+                               width = (width * 10) + (*fmt - '0');
+                               fmt++;  fmtLen--;
+                       }
+                       goto next_fmt;
+               case '*':
+                       /* suck up the next item as an integer */
+                       *fmt++;  fmtLen--;
+                       objc--;
+                       if( objc <= 0 ){
+                               goto not_enough_args;
+                       }
+                       if( Jim_GetWide(interp,objv[0],&wideValue )== JIM_ERR ){
+                               Jim_FreeNewObj(interp, resObjPtr );
+                               return NULL;
+                       }
+                       width = wideValue;
+                       if( width < 0 ){
+                               ljust = 1;
+                               width = -width;
+                       }
+                       objv++;
+                       goto next_fmt;
+                       break;
+               }
+               
+               
+               if (*fmt != '%') {
             if (objc == 0) {
+                       not_enough_args:
                 Jim_FreeNewObj(interp, resObjPtr);
                 Jim_SetResultString(interp,
-                        "not enough arguments for all format specifiers", -1);
+                                                                       "not enough arguments for all format specifiers", -1);
                 return NULL;
             } else {
                 objc--;
             }
         }
+               
+               /*
+                * Create the formatter
+                * cause we cheat and use sprintf()
+                */
+               cp = fmt_str;
+               *cp++ = '%';
+               if( altfm ){
+                       *cp++ = '#';
+               }
+               if( forceplus ){
+                       *cp++ = '+';
+               } else if( spad ){
+                       /* PLUS overrides */
+                       *cp++ = ' ';
+               }
+               if( ljust ){
+                       *cp++ = '-';
+               }
+               if( zpad  ){
+                       *cp++ = '0';
+               }
+               if( width > 0 ){
+                       sprintf( cp, "%d", width );
+                       /* skip ahead */
+                       cp = strchr(cp,0);
+               }
+               *cp = 0;
+
+               /* here we do the work */
+               /* actually - we make sprintf() do it for us */
         switch(*fmt) {
         case 's':
-            Jim_AppendObj(interp, resObjPtr, objv[0]);
-            objv++;
+                       *cp++ = 's';
+                       *cp   = 0;
+                       /* BUG: we do not handled embeded NULLs */
+                       snprintf( sprintf_buf, JIM_MAX_FMT, fmt_str, Jim_GetString( objv[0], NULL ));
             break;
         case 'c':
+                       *cp++ = 'c';
+                       *cp   = 0;
             if (Jim_GetWide(interp, objv[0], &wideValue) == JIM_ERR) {
                 Jim_FreeNewObj(interp, resObjPtr);
                 return NULL;
             }
             c = (char) wideValue;
-            Jim_AppendString(interp, resObjPtr, &c, 1);
+                       snprintf( sprintf_buf, JIM_MAX_FMT, fmt_str, c );
             break;
+               case 'f':
+               case 'F':
+               case 'g':
+               case 'G':
+               case 'e':
+               case 'E':
+                       *cp++ = *fmt;
+                       *cp   = 0;
+                       if( Jim_GetDouble( interp, objv[0], &doubleValue ) == JIM_ERR ){
+                               Jim_FreeNewObj( interp, resObjPtr );
+                               return NULL;
+                       }
+                       snprintf( sprintf_buf, JIM_MAX_FMT, fmt_str, doubleValue );
+                       break;
+        case 'b':
         case 'd':
+               case 'i':
+               case 'u':
+               case 'x':
+               case 'X':
+                       /* jim widevaluse are 64bit */
+                       if( sizeof(jim_wide) == sizeof(long long) ){
+                               *cp++ = 'l'; 
+                               *cp++ = 'l';
+                       } else {
+                               *cp++ = 'l';
+                       }
+                       *cp++ = *fmt;
+                       *cp   = 0;
             if (Jim_GetWide(interp, objv[0], &wideValue) == JIM_ERR) {
                 Jim_FreeNewObj(interp, resObjPtr);
                 return NULL;
             }
-            Jim_AppendObj(interp, resObjPtr, objv[0]);
+                       snprintf(sprintf_buf, JIM_MAX_FMT, fmt_str, wideValue );
             break;
         case '%':
-            Jim_AppendString(interp, resObjPtr, "%" , 1);
+                       sprintf_buf[0] = '%';
+                       sprintf_buf[1] = 0;
+                       objv--; /* undo the objv++ below */
             break;
         default:
             spec[0] = *fmt; spec[1] = '\0';
@@ -2200,6 +2378,16 @@ Jim_Obj *Jim_FormatString(Jim_Interp *interp, Jim_Obj *fmtObjPtr,
                     "bad field specifier \"",  spec, "\"", NULL);
             return NULL;
         }
+               /* force terminate */
+#if 0
+               printf("FMT was: %s\n", fmt_str );
+               printf("RES was: |%s|\n", sprintf_buf );
+#endif
+               
+               sprintf_buf[ JIM_MAX_FMT - 1] = 0;
+               Jim_AppendString( interp, resObjPtr, sprintf_buf, strlen(sprintf_buf) );
+               /* next obj */
+               objv++;
         fmt++;
         fmtLen--;
     }
@@ -3910,7 +4098,7 @@ int Jim_Collect(Jim_Interp *interp)
                 Jim_AddHashEntry(&marks,
                     &objPtr->internalRep.refValue.id, NULL);
 #ifdef JIM_DEBUG_GC
-                fprintf(interp->stdout_,
+                Jim_fprintf(interp,interp->cookie_stdout,
                     "MARK (reference): %d refcount: %d" JIM_NL, 
                     (int) objPtr->internalRep.refValue.id,
                     objPtr->refCount);
@@ -3949,7 +4137,7 @@ int Jim_Collect(Jim_Interp *interp)
                  * was found. Mark it. */
                 Jim_AddHashEntry(&marks, &id, NULL);
 #ifdef JIM_DEBUG_GC
-                fprintf(interp->stdout_,"MARK: %d" JIM_NL, (int)id);
+                Jim_fprintf(interp,interp->cookie_stdout,"MARK: %d" JIM_NL, (int)id);
 #endif
                 p += JIM_REFERENCE_SPACE;
             }
@@ -3969,7 +4157,7 @@ int Jim_Collect(Jim_Interp *interp)
          * this reference. */
         if (Jim_FindHashEntry(&marks, refId) == NULL) {
 #ifdef JIM_DEBUG_GC
-            fprintf(interp->stdout_,"COLLECTING %d" JIM_NL, (int)*refId);
+            Jim_fprintf(interp,interp->cookie_stdout,"COLLECTING %d" JIM_NL, (int)*refId);
 #endif
             collected++;
             /* Drop the reference, but call the
@@ -4057,9 +4245,14 @@ Jim_Interp *Jim_CreateInterp(void)
     i->freeFramesList = NULL;
     i->prngState = NULL;
     i->evalRetcodeLevel = -1;
-    i->stdin_ = stdin;
-    i->stdout_ = stdout;
-    i->stderr_ = stderr;
+    i->cookie_stdin = stdin;
+    i->cookie_stdout = stdout;
+    i->cookie_stderr = stderr;
+       i->cb_fwrite   = ((size_t (*)( const void *, size_t, size_t, void *))(fwrite));
+       i->cb_fread    = ((size_t (*)(       void *, size_t, size_t, void *))(fread));
+       i->cb_vfprintf = ((int    (*)( void *, const char *fmt, va_list ))(vfprintf));
+       i->cb_fflush   = ((int    (*)( void *))(fflush));
+       i->cb_fgets    = ((char * (*)( char *, int, void *))(fgets));
 
     /* Note that we can create objects only after the
      * interpreter liveList and freeList pointers are
@@ -4128,23 +4321,23 @@ void Jim_FreeInterp(Jim_Interp *i)
     if (i->liveList != NULL) {
         Jim_Obj *objPtr = i->liveList;
     
-        fprintf(i->stdout_,JIM_NL "-------------------------------------" JIM_NL);
-        fprintf(i->stdout_,"Objects still in the free list:" JIM_NL);
+        Jim_fprintf( i, i->cookie_stdout,JIM_NL "-------------------------------------" JIM_NL);
+        Jim_fprintf( i, i->cookie_stdout,"Objects still in the free list:" JIM_NL);
         while(objPtr) {
             const char *type = objPtr->typePtr ?
                 objPtr->typePtr->name : "";
-            fprintf(i->stdout_,"%p \"%-10s\": '%.20s' (refCount: %d)" JIM_NL,
+            Jim_fprintf( i, i->cookie_stdout,"%p \"%-10s\": '%.20s' (refCount: %d)" JIM_NL,
                     objPtr, type,
                     objPtr->bytes ? objPtr->bytes
                     : "(null)", objPtr->refCount);
             if (objPtr->typePtr == &sourceObjType) {
-                fprintf(i->stdout_, "FILE %s LINE %d" JIM_NL,
+                Jim_fprintf( i, i->cookie_stdout, "FILE %s LINE %d" JIM_NL,
                 objPtr->internalRep.sourceValue.fileName,
                 objPtr->internalRep.sourceValue.lineNumber);
             }
             objPtr = objPtr->nextObjPtr;
         }
-        fprintf(stdout, "-------------------------------------" JIM_NL JIM_NL);
+        Jim_fprintf( i, i->cookie_stdout, "-------------------------------------" JIM_NL JIM_NL);
         Jim_Panic(i,"Live list non empty freeing the interpreter! Leak?");
     }
     /* Free all the freed objects. */
@@ -4330,22 +4523,22 @@ int Jim_GetExitCode(Jim_Interp *interp) {
     return interp->exitCode;
 }
 
-FILE *Jim_SetStdin(Jim_Interp *interp, FILE *fp)
+void *Jim_SetStdin(Jim_Interp *interp, void *fp)
 {
-    if (fp != NULL) interp->stdin_ = fp;
-    return interp->stdin_;
+    if (fp != NULL) interp->cookie_stdin = fp;
+    return interp->cookie_stdin;
 }
 
-FILE *Jim_SetStdout(Jim_Interp *interp, FILE *fp)
+void *Jim_SetStdout(Jim_Interp *interp, void *fp)
 {
-    if (fp != NULL) interp->stdout_ = fp;
-    return interp->stdout_;
+    if (fp != NULL) interp->cookie_stdout = fp;
+    return interp->cookie_stdout;
 }
 
-FILE *Jim_SetStderr(Jim_Interp *interp, FILE *fp)
+void *Jim_SetStderr(Jim_Interp *interp, void  *fp)
 {
-    if (fp != NULL) interp->stderr_ = fp;
-    return interp->stderr_;
+    if (fp != NULL) interp->cookie_stderr = fp;
+    return interp->cookie_stderr;
 }
 
 /* -----------------------------------------------------------------------------
@@ -8478,7 +8671,7 @@ int Jim_EvalObjBackground(Jim_Interp *interp, Jim_Obj *scriptObjPtr)
         Jim_IncrRefCount(objv[1]);
         if (Jim_EvalObjVector(interp, 2, objv) != JIM_OK) {
             /* Report the error to stderr. */
-            fprintf(interp->stderr_, "Background error:" JIM_NL);
+            Jim_fprintf( interp, interp->cookie_stderr, "Background error:" JIM_NL);
             Jim_PrintErrorMessage(interp);
         }
         Jim_DecrRefCount(interp, objv[0]);
@@ -8509,10 +8702,12 @@ int Jim_EvalFile(Jim_Interp *interp, const char *filename)
             maxlen = totread+buflen+1;
             prg = Jim_Realloc(prg, maxlen);
         }
+               /* do not use Jim_fread() - this is really a file */
         if ((nread = fread(prg+totread, 1, buflen, fp)) == 0) break;
         totread += nread;
     }
     prg[totread] = '\0';
+       /* do not use Jim_fclose() - this is really a file */
     fclose(fp);
 
     scriptObjPtr = Jim_NewStringObjNoAlloc(interp, prg, totread);
@@ -9011,8 +9206,8 @@ static int Jim_PutsCoreCommand(Jim_Interp *interp, int argc,
         }
     }
     str = Jim_GetString(argv[1], &len);
-    fwrite(str, 1, len, interp->stdout_);
-    if (!nonewline) fprintf(interp->stdout_, JIM_NL);
+    Jim_fwrite(interp, str, 1, len, interp->cookie_stdout);
+    if (!nonewline) Jim_fprintf( interp, interp->cookie_stdout, JIM_NL);
     return JIM_OK;
 }
 
@@ -11744,9 +11939,9 @@ void Jim_PrintErrorMessage(Jim_Interp *interp)
 {
     int len, i;
 
-    fprintf(interp->stderr_, "Runtime error, file \"%s\", line %d:" JIM_NL,
-            interp->errorFileName, interp->errorLine);
-    fprintf(interp->stderr_, "    %s" JIM_NL,
+    Jim_fprintf(interp, interp->cookie_stderr, "Runtime error, file \"%s\", line %d:" JIM_NL,
+                               interp->errorFileName, interp->errorLine);
+    Jim_fprintf(interp,interp->cookie_stderr, "    %s" JIM_NL,
             Jim_GetString(interp->result, NULL));
     Jim_ListLength(interp, interp->stackTrace, &len);
     for (i = 0; i < len; i+= 3) {
@@ -11761,7 +11956,7 @@ void Jim_PrintErrorMessage(Jim_Interp *interp)
         Jim_ListIndex(interp, interp->stackTrace, i+2, &objPtr,
                 JIM_NONE);
         line = Jim_GetString(objPtr, NULL);
-        fprintf(interp->stderr_,
+               Jim_fprintf( interp, interp->cookie_stderr,
                 "In procedure '%s' called at file \"%s\", line %s" JIM_NL,
                 proc, file, line);
     }
@@ -11772,7 +11967,7 @@ int Jim_InteractivePrompt(Jim_Interp *interp)
     int retcode = JIM_OK;
     Jim_Obj *scriptObjPtr;
 
-    fprintf(interp->stdout_, "Welcome to Jim version %d.%d, "
+    Jim_fprintf(interp,interp->cookie_stdout, "Welcome to Jim version %d.%d, "
            "Copyright (c) 2005-8 Salvatore Sanfilippo" JIM_NL,
            JIM_VERSION / 100, JIM_VERSION % 100);
      Jim_SetVariableStrWithStr(interp, "jim_interactive", "1");
@@ -11786,12 +11981,12 @@ int Jim_InteractivePrompt(Jim_Interp *interp)
 
         if (retcode != 0) {
             if (retcode >= 2 && retcode <= 6)
-                fprintf(interp->stdout_, "[%s] . ", retcodestr[retcode]);
+                Jim_fprintf(interp,interp->cookie_stdout, "[%s] . ", retcodestr[retcode]);
             else
-                fprintf(interp->stdout_, "[%d] . ", retcode);
+                Jim_fprintf(interp,interp->cookie_stdout, "[%d] . ", retcode);
         } else
-            fprintf(interp->stdout_, ". ");
-        fflush(interp->stdout_);
+            Jim_fprintf( interp, interp->cookie_stdout, ". ");
+        Jim_fflush( interp, interp->cookie_stdout);
         scriptObjPtr = Jim_NewStringObj(interp, "", 0);
         Jim_IncrRefCount(scriptObjPtr);
         while(1) {
@@ -11799,7 +11994,7 @@ int Jim_InteractivePrompt(Jim_Interp *interp)
             char state;
             int len;
 
-            if (fgets(buf, 1024, interp->stdin_) == NULL) {
+            if ( Jim_fgets(interp, buf, 1024, interp->cookie_stdin) == NULL) {
                 Jim_DecrRefCount(interp, scriptObjPtr);
                 goto out;
             }
@@ -11807,8 +12002,8 @@ int Jim_InteractivePrompt(Jim_Interp *interp)
             str = Jim_GetString(scriptObjPtr, &len);
             if (Jim_ScriptIsComplete(str, len, &state))
                 break;
-            fprintf(interp->stdout_, "%c> ", state);
-            fflush(stdout);
+            Jim_fprintf( interp, interp->cookie_stdout, "%c> ", state);
+            Jim_fflush( interp, interp->cookie_stdout);
         }
         retcode = Jim_EvalObj(interp, scriptObjPtr);
         Jim_DecrRefCount(interp, scriptObjPtr);
@@ -11819,11 +12014,91 @@ int Jim_InteractivePrompt(Jim_Interp *interp)
             exit(Jim_GetExitCode(interp));
         } else {
             if (reslen) {
-                fwrite(result, 1, reslen, interp->stdout_);
-                fprintf(interp->stdout_, JIM_NL);
+                               Jim_fwrite( interp, result, 1, reslen, interp->cookie_stdout);
+                               Jim_fprintf( interp,interp->cookie_stdout, JIM_NL);
             }
         }
     }
 out:
     return 0;
 }
+
+/* -----------------------------------------------------------------------------
+ * Jim's idea of STDIO..
+ * ---------------------------------------------------------------------------*/
+
+int
+Jim_fprintf( Jim_Interp *interp, void *cookie, const char *fmt, ... )
+{
+       int r;
+
+       va_list ap;
+       va_start(ap,fmt);
+       r = Jim_vfprintf( interp, cookie, fmt,ap );
+       va_end(ap);
+       return r;
+}
+       
+
+int 
+Jim_vfprintf( Jim_Interp *interp, void *cookie, const char *fmt, va_list ap )
+{
+       if( (interp == NULL) || (interp->cb_vfprintf == NULL) ){
+               errno = ENOTSUP;
+               return -1;
+       }
+       return (*(interp->cb_vfprintf))( cookie, fmt, ap );
+}
+
+size_t
+Jim_fwrite( Jim_Interp *interp, const void *ptr, size_t size, size_t n, void *cookie )
+{
+       if( (interp == NULL) || (interp->cb_fwrite == NULL) ){
+               errno = ENOTSUP;
+               return 0;
+       }
+       return (*(interp->cb_fwrite))( ptr, size, n, cookie);
+}
+
+size_t
+Jim_fread( Jim_Interp *interp, void *ptr, size_t size, size_t n, void *cookie )
+{
+       if( (interp == NULL) || (interp->cb_fread == NULL) ){
+               errno = ENOTSUP;
+               return 0;
+       }
+       return (*(interp->cb_fread))( ptr, size, n, cookie);
+}
+
+int
+Jim_fflush( Jim_Interp *interp, void *cookie )
+{
+       if( (interp == NULL) || (interp->cb_fflush == NULL) ){
+               /* pretend all is well */
+               return 0;
+       }
+       return (*(interp->cb_fflush))( cookie );
+}
+
+char *  
+Jim_fgets( Jim_Interp *interp, char *s, int size, void *cookie )
+{
+       if( (interp == NULL) || (interp->cb_fgets == NULL) ){
+               errno = ENOTSUP;
+               return NULL;
+       }
+       return (*(interp->cb_fgets))( s, size, cookie );
+}
+
+       
+
+
+
+
+/*
+ * Local Variables: **
+ * tab-width: 4 **
+ * c-basic-offset: 4 **
+ * End: **
+ */
+
index cbd0d8fc246b0394d000f0d4aab98bfcfed9aec1..b08c11f2a7a5337da209977b8b08c9d267d12f85 100644 (file)
--- a/src/jim.h
+++ b/src/jim.h
@@ -497,9 +497,14 @@ typedef struct Jim_Interp {
     struct Jim_HashTable assocData; /* per-interp storage for use by packages */
     Jim_PrngState *prngState; /* per interpreter Random Number Gen. state. */
     struct Jim_HashTable packages; /* Provided packages hash table */
-    FILE *stdin_; /* input file pointer, 'stdin' by default */
-    FILE *stdout_; /* output file pointer, 'stdout' by default */
-    FILE *stderr_; /* errors file pointer, 'stderr' by default */
+    void *cookie_stdin; /* input file pointer, 'stdin' by default */
+    void *cookie_stdout; /* output file pointer, 'stdout' by default */
+    void *cookie_stderr; /* errors file pointer, 'stderr' by default */
+    size_t (*cb_fwrite  )( const void *ptr, size_t size, size_t n, void *cookie );
+       size_t (*cb_fread   )( void *ptr, size_t size, size_t n, void *cookie );
+       int    (*cb_vfprintf)( void *cookie, const char *fmt, va_list ap );
+       int    (*cb_fflush  )( void *cookie );
+       char  *(*cb_fgets   )( char *s, int size, void *cookie );
 } Jim_Interp;
 
 /* Currently provided as macro that performs the increment.
@@ -662,9 +667,9 @@ JIM_STATIC int JIM_API(Jim_GetFinalizer) (Jim_Interp *interp, Jim_Obj *objPtr, J
 JIM_STATIC Jim_Interp * JIM_API(Jim_CreateInterp) (void);
 JIM_STATIC void JIM_API(Jim_FreeInterp) (Jim_Interp *i);
 JIM_STATIC int JIM_API(Jim_GetExitCode) (Jim_Interp *interp);
-JIM_STATIC FILE * JIM_API(Jim_SetStdin) (Jim_Interp *interp, FILE *fp);
-JIM_STATIC FILE * JIM_API(Jim_SetStdout) (Jim_Interp *interp, FILE *fp);
-JIM_STATIC FILE * JIM_API(Jim_SetStderr) (Jim_Interp *interp, FILE *fp);
+JIM_STATIC void * JIM_API(Jim_SetStdin) (Jim_Interp *interp, void *fp);
+JIM_STATIC void * JIM_API(Jim_SetStdout) (Jim_Interp *interp, void *fp);
+JIM_STATIC void * JIM_API(Jim_SetStderr) (Jim_Interp *interp, void *fp);
 
 /* commands */
 JIM_STATIC void JIM_API(Jim_RegisterCoreCommands) (Jim_Interp *interp);
@@ -815,6 +820,15 @@ JIM_STATIC int JIM_API(Jim_InteractivePrompt) (Jim_Interp *interp);
 /* Misc */
 JIM_STATIC void JIM_API(Jim_Panic) (Jim_Interp *interp, const char *fmt, ...);
 
+/* Jim's STDIO */
+JIM_STATIC int     JIM_API( Jim_fprintf  )( Jim_Interp *interp, void *cookie, const char *fmt, ... );
+JIM_STATIC int     JIM_API( Jim_vfprintf )( Jim_Interp *interp, void *cookie, const char *fmt, va_list ap );
+JIM_STATIC size_t  JIM_API( Jim_fwrite   )( Jim_Interp *interp, const void *ptr, size_t size, size_t nmeb, void *cookie );
+JIM_STATIC size_t  JIM_API( Jim_fread    )( Jim_Interp *interp, void *ptr, size_t size, size_t nmeb, void *cookie );
+JIM_STATIC int     JIM_API( Jim_fflush   )( Jim_Interp *interp, void *cookie );
+JIM_STATIC char *  JIM_API( Jim_fgets    )( Jim_Interp *interp, char *s, int size, void *cookie );
+
+
 #undef JIM_STATIC
 #undef JIM_API
 
@@ -942,6 +956,13 @@ static void Jim_InitExtension(Jim_Interp *interp)
   JIM_GET_API(StackPop);
   JIM_GET_API(StackPeek);
   JIM_GET_API(FreeStackElements);
+  JIM_GET_API(fprintf  );
+  JIM_GET_API(vfprintf );
+  JIM_GET_API(fwrite   );
+  JIM_GET_API(fread    );
+  JIM_GET_API(fflush   );
+  JIM_GET_API(fgets    );
+  
 }
 #endif /* defined JIM_EXTENSION || defined JIM_EMBEDDED */
 
@@ -962,3 +983,11 @@ static void Jim_InitEmbedded(void) {
 #endif
 
 #endif /* __JIM__H */
+
+/*
+ * Local Variables: **
+ * tab-width: 4 **
+ * c-basic-offset: 4 **
+ * End: **
+ */
+
index 99ee6527ed352e5edac3ff73cdc9e9cf1d507f94..b6b217df3cef91cd3b75a1bb7a6641ed8f394069 100644 (file)
@@ -165,6 +165,191 @@ void unlockBigLock()
 Jim_Interp *interp;
 command_context_t *active_cmd_ctx;
 
+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 = alloca( strlen(varname) + 30 );
+       sprintf( namebuf, "%s(%d)", varname, idx );
+
+
+    nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
+    valObjPtr = Jim_NewIntObj(interp, val );
+    Jim_IncrRefCount(nameObjPtr);
+    Jim_IncrRefCount(valObjPtr);
+    result = Jim_SetVariable(interp, nameObjPtr, valObjPtr);
+    Jim_DecrRefCount(interp, nameObjPtr);
+    Jim_DecrRefCount(interp, valObjPtr);
+       // printf( "%s = 0%08x\n", namebuf, val );
+    return result;
+}
+
+static int
+Jim_Command_mem2array( Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+       target_t *target;
+       long l;
+       u32 width;
+       u32 endian;
+       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 receive the data
+        * argv[2] = desired width
+        * argv[3] = memory address 
+        * argv[4] = length in bytes 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;
+       }
+
+       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);
+               }
+               
+               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 void tcl_output(void *privData, const char *file, int line, 
                const char *function, const char *string)
 {              
@@ -323,6 +508,97 @@ Jim_Command_echo(Jim_Interp *interp,
        return JIM_OK;
 }
 
+static size_t
+openocd_jim_fwrite( const void *_ptr, size_t size, size_t n, void *cookie )
+{
+       size_t nbytes;
+       const char *ptr;
+
+       /* make it a char easier to read code */
+       ptr = _ptr;
+
+       nbytes = size * n;
+       if( nbytes == 0 ){
+               return 0;
+       }
+
+       if( !active_cmd_ctx ){
+               /* FIXME: Where should this go? */              
+               return n;
+       }
+
+       
+       /* do we have to chunk it? */
+       if( ptr[ nbytes ] == 0 ){
+               /* no it is a C style string */
+               command_output_text( active_cmd_ctx, ptr );
+               return;
+       }
+       /* GRR we must chunk - not null terminated */
+       while( nbytes ){
+               char chunk[128+1];
+               int x;
+
+               x = nbytes;
+               if( x > 128 ){
+                       x = 128;
+               }
+               /* copy it */
+               memcpy( chunk, ptr, x );
+               /* terminate it */
+               chunk[n] = 0;
+               /* output it */
+               command_output_text( active_cmd_ctx, chunk );
+               ptr += x;
+               nbytes -= x;
+       }
+       
+       return n;
+}
+
+static size_t
+openocd_jim_fread(void *ptr, size_t size, size_t n, void *cookie )
+{
+       /* TCL wants to read... tell him no */
+       return 0;
+}
+
+
+static int
+openocd_jim_vfprintf( void *cookie, const char *fmt, va_list ap )
+{
+       char *cp;
+       int n;
+       
+       n = -1;
+       if( active_cmd_ctx ){
+               cp = alloc_vprintf( fmt, ap );
+               if( cp ){
+                       command_output_text( active_cmd_ctx, cp );
+                       n = strlen(cp);
+                       free(cp);
+               }
+       }
+       return n;
+}
+
+static int
+openocd_jim_fflush( void *cookie )
+{
+       /* nothing to flush */
+       return 0;
+}
+
+static char  *
+openocd_jim_fgets( char *s, int size, void *cookie )
+{
+       /* not supported */
+       errno = ENOTSUP;
+       return NULL;
+}
+
+
+
 void initJim(void)
 {
     Jim_InitEmbedded();
@@ -335,6 +611,17 @@ void initJim(void)
     Jim_CreateCommand(interp, "openocd_throw", Jim_Command_openocd_throw, NULL, NULL);
     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 );
+
+       /* Set Jim's STDIO */
+       interp->cookie_stdin  = NULL;
+       interp->cookie_stdout = NULL;
+       interp->cookie_stderr = NULL;
+       interp->cb_fwrite     = openocd_jim_fwrite;
+       interp->cb_fread      = openocd_jim_fread ;
+       interp->cb_vfprintf   = openocd_jim_vfprintf;
+       interp->cb_fflush     = openocd_jim_fflush;
+       interp->cb_fgets      = openocd_jim_fgets;
 }
 
 int main(int argc, char *argv[])
@@ -422,3 +709,11 @@ int main(int argc, char *argv[])
        return EXIT_SUCCESS;
 }
 
+
+/*
+ * Local Variables: **
+ * tab-width: 4 **
+ * c-basic-offset: 4 **
+ * End: **
+ */
+
index c2c18baf208d7bf69824d32d397b606751f33ac0..3ea1dde0f5a54f8fc30f53464a3785ef4fbcd144 100644 (file)
@@ -568,7 +568,7 @@ int gdb_output_con(connection_t *connection, const char* line)
        return ERROR_OK;
 }
 
-int gdb_output(struct command_context_s *context, char* line)
+int gdb_output(struct command_context_s *context, const char* line)
 {
        /* this will be dumped to the log and also sent as an O packet if possible */
        LOG_USER_N("%s", line);
@@ -577,24 +577,10 @@ int gdb_output(struct command_context_s *context, char* line)
 
 int gdb_program_handler(struct target_s *target, enum target_event event, void *priv)
 {
-       FILE *script;
        struct command_context_s *cmd_ctx = priv;
 
-       if (target->gdb_program_script)
-       {
-               script = open_file_from_path(target->gdb_program_script, "r");
-               if (!script)
-               {
-                       LOG_ERROR("couldn't open script file %s", target->gdb_program_script);
-                               return ERROR_OK;
-               }
-
-               LOG_INFO("executing gdb_program script '%s'", target->gdb_program_script);
-               command_run_file(cmd_ctx, script, COMMAND_EXEC);
-               fclose(script);
-
-               jtag_execute_queue();
-       }
+       target_invoke_script(cmd_ctx, target, "gdb_program");
+       jtag_execute_queue();
 
        return ERROR_OK;
 }
index fc3f2116a46d162a3390ac819eca3611e1f26b8f..fc39c729ab0c447daf08317937949946c1e3f4ef 100644 (file)
@@ -92,7 +92,7 @@ int telnet_outputline(connection_t *connection, const char *line)
                telnet_write(connection, line, len);
                if (line_end)
                {
-                       telnet_write(connection, "\r\n\0", 3);
+                       telnet_write(connection, "\r\n", 2);
                        line += len+1;
                }
                else
@@ -104,7 +104,7 @@ int telnet_outputline(connection_t *connection, const char *line)
        return ERROR_OK;
 }
 
-int telnet_output(struct command_context_s *cmd_ctx, char* line)
+int telnet_output(struct command_context_s *cmd_ctx, const char* line)
 {
        connection_t *connection = cmd_ctx->output_handler_priv;
 
@@ -181,7 +181,7 @@ int telnet_new_connection(connection_t *connection)
        if (telnet_service->banner)
        {
                telnet_write(connection, telnet_service->banner, strlen(telnet_service->banner));
-               telnet_write(connection, "\r\n\0", 3);
+               telnet_write(connection, "\r\n", 2);
        }
 
        telnet_prompt(connection);
@@ -658,3 +658,11 @@ int handle_exit_command(struct command_context_s *cmd_ctx, char *cmd, char **arg
 {
        return ERROR_COMMAND_CLOSE_CONNECTION;
 }
+
+/*
+ * Local Variables: **
+ * tab-width: 4 **
+ * c-basic-offset: 4 **
+ * End: **
+ */
+
index 0237fd669b4d6181c223ff3daf983ab5a619049c..86b42db26a1b9914378895d6c5804f33674b3b7f 100644 (file)
@@ -215,23 +215,6 @@ target_t* get_current_target(command_context_t *cmd_ctx)
        return target;
 }
 
-static void execute_script(struct command_context_s *cmd_ctx, char *reset_script)
-{
-       if (reset_script==NULL)
-               return;
-       FILE *script;
-       script = open_file_from_path(reset_script, "r");
-       if (!script)
-       {
-               LOG_ERROR("couldn't open script file %s", reset_script);
-               return;
-       }
-       
-       LOG_INFO("executing script '%s'", reset_script);
-       command_run_file(cmd_ctx, script, COMMAND_EXEC);
-       fclose(script);
-}
-
 /* Process target initialization, when target entered debug out of reset
  * the handler is unregistered at the end of this function, so it's only called once
  */
@@ -243,7 +226,7 @@ int target_init_handler(struct target_s *target, enum target_event event, void *
        {
                target_unregister_event_callback(target_init_handler, priv);
 
-               execute_script(cmd_ctx, target->reset_script);
+               target_invoke_script(cmd_ctx, target, "reset");
 
                jtag_execute_queue();
        }
@@ -305,7 +288,7 @@ int target_process_reset(struct command_context_s *cmd_ctx)
        target = targets;
        while (target)
        {
-               execute_script(cmd_ctx, target->pre_reset_script);
+               target_invoke_script(cmd_ctx, target, "pre_reset");
                target = target->next;
        }
        
@@ -950,7 +933,8 @@ int target_register_commands(struct command_context_s *cmd_ctx)
 {
        register_command(cmd_ctx, NULL, "target", handle_target_command, COMMAND_CONFIG, "target <cpu> [reset_init default - DEPRECATED] <chainpos> <endianness> <variant> [cpu type specifc args]");
        register_command(cmd_ctx, NULL, "targets", handle_targets_command, COMMAND_EXEC, NULL);
-       register_command(cmd_ctx, NULL, "target_script", handle_target_script_command, COMMAND_CONFIG, NULL);
+       register_command(cmd_ctx, NULL, "target_script", handle_target_script_command, COMMAND_CONFIG, 
+       "target_script <target#> <event=reset/pre_reset/post_halt/pre_resume/gdb_program_config> <script_file>");
        register_command(cmd_ctx, NULL, "run_and_halt_time", handle_run_and_halt_time_command, COMMAND_CONFIG, "<target> <run time ms>");
        register_command(cmd_ctx, NULL, "working_area", handle_working_area_command, COMMAND_ANY, "working_area <target#> <address> <size> <'backup'|'nobackup'> [virtual address]");
        register_command(cmd_ctx, NULL, "virt2phys", handle_virt2phys_command, COMMAND_ANY, "virt2phys <virtual address>");
@@ -1437,12 +1421,6 @@ int handle_target_command(struct command_context_s *cmd_ctx, char *cmd, char **a
                                }
                                (*last_target_p)->run_and_halt_time = 1000; /* default 1s */
                                
-                               (*last_target_p)->reset_script = NULL;
-                               (*last_target_p)->pre_reset_script = NULL;
-                               (*last_target_p)->post_halt_script = NULL;
-                               (*last_target_p)->pre_resume_script = NULL;
-                               (*last_target_p)->gdb_program_script = NULL;
-                               
                                (*last_target_p)->working_area = 0x0;
                                (*last_target_p)->working_area_size = 0x0;
                                (*last_target_p)->working_areas = NULL;
@@ -1487,7 +1465,14 @@ int handle_target_command(struct command_context_s *cmd_ctx, char *cmd, char **a
        return ERROR_OK;
 }
 
-/* usage: target_script <target#> <event> <script_file> */
+int target_invoke_script(struct command_context_s *cmd_ctx, target_t *target, char *name)
+{
+       return command_run_linef(cmd_ctx, " if {[catch {info body target_%s_%d} t]==0} {target_%s_%d}", 
+       name, get_num_by_target(target),
+       name, get_num_by_target(target));
+}
+
+
 int handle_target_script_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
        target_t *target = NULL;
@@ -1505,41 +1490,14 @@ int handle_target_script_command(struct command_context_s *cmd_ctx, char *cmd, c
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
        
-       if ((strcmp(args[1], "reset") == 0)||(strcmp(args[1], "post_reset") == 0))
-       {
-               if (target->reset_script)
-                       free(target->reset_script);
-               target->reset_script = strdup(args[2]);
-       }
-       else if (strcmp(args[1], "pre_reset") == 0)
-       {
-               if (target->pre_reset_script)
-                       free(target->pre_reset_script);
-               target->pre_reset_script = strdup(args[2]);
-       }
-       else if (strcmp(args[1], "post_halt") == 0)
-       {
-               if (target->post_halt_script)
-                       free(target->post_halt_script);
-               target->post_halt_script = strdup(args[2]);
-       }
-       else if (strcmp(args[1], "pre_resume") == 0)
-       {
-               if (target->pre_resume_script)
-                       free(target->pre_resume_script);
-               target->pre_resume_script = strdup(args[2]);
-       }
-       else if (strcmp(args[1], "gdb_program_config") == 0)
-       {
-               if (target->gdb_program_script)
-                       free(target->gdb_program_script);
-               target->gdb_program_script = strdup(args[2]);
-       }
-       else
-       {
-               LOG_ERROR("unknown event type: '%s", args[1]);
-               return ERROR_COMMAND_SYNTAX_ERROR;
-       }
+       /* Define a tcl procedure which we'll invoke upon some event */
+       command_run_linef(cmd_ctx, 
+       "proc target_%s_%d {} {"
+       "openocd {script %s}" 
+       "}",
+       args[1],
+       get_num_by_target(target),
+       args[2]);
        
        return ERROR_OK;
 }
@@ -2021,14 +1979,11 @@ int handle_md_command(struct command_context_s *cmd_ctx, char *cmd, char **args,
                                output_len = 0;
                        }
                }
-       } else
-       {
-               LOG_ERROR("Failure examining memory");
        }
 
        free(buffer);
        
-       return ERROR_OK;
+       return retval;
 }
 
 int handle_mw_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
index c12dff5e97673481e6a5616d37ed086fe555d90c..05ea584f89ab33c22ba545a6617d78227c9d8a91 100644 (file)
@@ -200,11 +200,6 @@ typedef struct target_s
        target_type_t *type;                            /* target type definition (name, access functions) */
        enum target_reset_mode reset_mode;      /* what to do after a reset */
        int run_and_halt_time;                          /* how long the target should run after a run_and_halt reset */
-       char *pre_reset_script;                                 /* script file to initialize the target before a reset */
-       char *reset_script;                                     /* script file to initialize the target after a reset */
-       char *post_halt_script;                         /* script file to execute after the target halted */
-       char *pre_resume_script;                        /* script file to execute before the target resumed */
-       char *gdb_program_script;                       /* script file to execute before programming vis gdb */
        u32 working_area;                                       /* working area (initialized RAM). Evaluated 
                                                                                   upon first allocation from virtual/physical address.
                                                                                  */
@@ -325,6 +320,9 @@ int target_write_u8(struct target_s *target, u32 address, u8 value);
 /* Issues USER() statements with target state information */
 int target_arch_state(struct target_s *target);
 
+int target_invoke_script(struct command_context_s *cmd_ctx, target_t *target, char *name);
+
+
 #define ERROR_TARGET_INVALID   (-300)
 #define ERROR_TARGET_INIT_FAILED (-301)
 #define ERROR_TARGET_TIMEOUT   (-302)
diff --git a/src/tcl/README_ABOUT_TCL.txt b/src/tcl/README_ABOUT_TCL.txt
new file mode 100644 (file)
index 0000000..47131fe
--- /dev/null
@@ -0,0 +1,430 @@
+****************************************
+****************************************
+
+This is a short introduction to 'un-scare' you about the language
+known as TCL. It is structured as a guided tour through the files
+written by me [Duane Ellis] - in early July 2008 for OpenOCD.
+
+Which uses the "JIM" embedded Tcl clone-ish language.
+
+Thing described here are *totally* TCL generic... not Jim specific.
+
+The goal of this document is to encourage you to add your own set of
+chips to the TCL package - and most importantly you should know where
+you should put them - so they end up in an orginized way.
+
+--Duane Ellis.
+       duane@duaneellis.com
+
+****************************************
+****************************************
+
+Adding "chip" support - Duane Ellis July 5 - 2008.
+
+The concept is this:
+  In your "openocd.cfg" file add something like this:
+
+     source [find tcl/chip/VENDOR/FAMILY/NAME.tcl]
+
+  For example...
+     source [find tcl/chip/atmel/at91/at91sam7x256.tcl]
+
+  You'll notice that it makes use of:
+
+       tcl/cpu/arm/<NAME>.tcl.
+
+  Yes, that is where you should put "core" specific things.
+  Be carefull and learn the difference:
+
+  THE "CORE" - is not the entire chip!
+
+Definition:
+   That "file" listed above is called a "CHIP FILE".
+
+   It may be standalone, or may need to "source" other "helper" files.
+
+   The reference [7/5/2008] is the at91sam7x256.tcl file.
+
+****************************************
+****************************************
+=== TCL TOUR ===
+Open:  at91sam7x256.tcl
+=== TCL TOUR ===
+
+A walk through --- For those who are new to TCL.
+
+Examine the file: at91sam7x256.tcl
+
+It starts with:
+       source [find path/filename.tcl]
+
+In TCL - this is very important.
+
+       Rule #1 Everything is a string.
+       Rule #2 If you think other wise See #1.
+Reminds you of:
+       Rule #1: The wife is correct.
+       Rule #2: If you think otherwise, See #1
+
+Any text contained inside of [square-brackets]
+is just like `back-ticks` in BASH.
+
+Hence, the [find FILENAME] executes the command find with a single
+parameter the filename.
+
+========================================
+
+Next you see a series of:
+
+set  NAME    VALUE
+
+It is mostly "obious" what is going on.
+
+Execption: The arrays.
+
+  You would *THINK* Tcl supports arrays.
+  In fact, multi-dim arrays. That is false.
+
+  For the index for"FLASH(0,CHIPSELECT)" is actually the string
+  "0,CHIPSELECT".  This is problematic. In the normal world, you think
+  of array indexes as integers.
+
+  For example these are different:
+
+       set foo(0x0c)  123
+       set foo(12)    444
+
+  Why? Because 0x0c {lowercase} is a string.
+  Don't forget UPPER CASE.
+
+  You must be careful - always... always...  use simple decimal
+  numbers. When in doubt use 'expr' the evaluator. These are all the
+  same.
+
+       set x 0x0c
+       set foo([expr $x])  "twelve"
+
+       set x 12
+       set foo([expr $x])  "twelve"
+
+       set x "2 * 6"
+       set foo([expr $x])  "twelve"
+       
+**************************************************
+***************************************************
+=== TCL TOUR ===
+Open the file: "bitsbytes.tcl"
+
+There is some tricky things going on.
+===============
+
+First, there is a "for" loop - at level 0
+{level 0 means: out side of a proc/function}
+
+This means it is evaluated when the file is parsed.
+
+== SIDEBAR: About The FOR command ==
+In TCL, "FOR" is a funny thing, it is not what you think it is.
+
+Syntatically - FOR is a just a command, it is not language
+construct like for(;;) in C... 
+
+The "for" command takes 4 parameters.
+   (1) The "initial command" to execute.
+   (2) the test "expression"
+   (3) the "next command"
+   (4) the "body command" of the FOR loop.
+
+Notice I used the words "command" and "expresion" above.
+
+The FOR command:
+1)  executes the "initial command"
+2)  evaluates the expression if 0 it stops.
+3)  executes the "body command"
+4)  executes the "next command"
+5)  Goto Step 2.
+
+As show, each of these items are in {curly-braces}.  This means they
+are passed as they are - KEY-POINT: un evaluated to the FOR
+command. Think of it like escaping the backticks in Bash so that the
+"under-lying" command can evaluate the contents. In this case, the FOR
+COMMAND.
+
+== END: SIDEBAR: About The FOR command ==
+
+You'll see two lines:
+
+LINE1:
+       set vn [format "BIT%d" $x]
+
+Format is like "sprintf". Because of the [brackets], it becomes what
+you think.  But here's how:
+
+First - the line is parsed - for {braces}.  In this case, there are
+none.  The, the parser looks for [brackets] and finds them.  The,
+parser then evaluates the contents of the [brackets], and replaces
+them. It is alot this bash statement.
+
+       EXPORT vn=`date`
+
+LINE 2 & 3
+       set $vn [expr (1024 * $x)]
+       global $vn
+
+In line 1, we dynamically created a variable name.  Here, we are
+assigning it a value. Lastly Line 3 we force the variable to be
+global, not "local" the the "for command body"
+
+===============
+The PROCS
+
+proc create_mask { MSB LSB } {
+     ... body ....
+}
+
+Like "for" - PROC is really just a command that takes 3 parameters.
+The (1) NAME of the function, a (2) LIST of parameters, and a (3) BODY
+
+Again, this is at "level 0" so it is a global function.  (Yes, TCL
+supports local functions, you put them inside of a function}
+
+You'll see in some cases, I nest [brackets] alot and in others I'm
+lazy or wanted it to be more clear... it is a matter of choice.
+===============
+
+
+**************************************************
+***************************************************
+=== TCL TOUR ===
+Open the file: "memory.tcl"
+===============
+
+Here is where I setup some 'memory definitions' that various targets can use.
+
+For example - there is an "unknown" memory region.
+
+All memory regions must have 2 things:
+
+ (1)  N_<name>
+ (2)  NAME( array )
+      And the array must have some specific names:
+          ( <idx>, THING )
+           Where: THING is one of: 
+                  CHIPSELECT
+                  BASE
+                  LEN
+                  HUMAN
+                  TYPE
+                  RWX - the access ablity.
+                  WIDTH - the accessable width.
+
+        ie: Some regions of memory are not 'word' 
+       accessable.
+
+The function "address_info" - given an address should
+tell you about the address.
+
+     [as of this writing: 7/5/2008 I have done
+     only a little bit with this -Duane]
+
+===
+MAJOR FUNCTION:
+==
+
+proc memread32 { ADDR } 
+proc memread16 { ADDR } 
+proc memread8 { ADDR } 
+
+All read memory - and return the contents.
+
+[ fixme: 7/5/2008 - I need to create "memwrite" functions]
+                
+**************************************************
+***************************************************
+=== TCL TOUR ===
+Open the file: "mmr_helpers.tcl"
+===============
+
+This file is used to display and work with "memory mapped registers"
+
+For example - 'show_mmr32_reg' is given the NAME of the register to
+display. The assumption is - the NAME is a global variable holding the
+address of that MMR.
+
+The code does some tricks. The [set [set NAME]] is the TCL way
+of doing double variable interpolation - like makefiles...
+
+In a makefile or shell script you may have seen this:
+
+     FOO_linux = "Penguins rule"
+     FOO_winXP = "Broken Glass"
+     FOO_mac   = "I like cat names"
+     
+     # Pick one
+     BUILD  = linux
+     #BUILD = winXP
+     #BUILD = mac
+     FOO = ${FOO_${BUILD}}
+                               
+The "double [set] square bracket" thing is the TCL way, nothing more.
+
+----
+
+The IF statement - and "CATCH" .
+
+Notice this IF COMMAND - (not statement) is like this:
+[7/5/2008 it is this way]
+
+       if ![catch { command } msg ] {
+         ...something...
+       } else {
+          error [format string...]
+       }
+
+The "IF" command expects either 2 params, or 4 params.
+
+ === Sidebar: About "commands" ===
+  
+     Take a look at the internals of "jim.c"
+     Look for the function: Jim_IfCoreCommand()
+     And all those other "CoreCommands"
+
+     You'll notice - they all have "argc" and "argv"
+
+     Yea, the entire thing is done that way.
+     
+     IF is a command. SO is "FOR" and "WHILE" and "DO" and the
+     others. That is why I keep using the prhase it is a "command"
+     
+ === END: Sidebar: About "commands" ===
+
+Paramter 1 to the IF command is expected to be an expression.
+
+As such, I do not need to wrap it in {braces}.
+
+In this case, the "expression" is the resul of the "CATCH" command.
+
+CATCH - is an error catcher.
+
+You give CATCH 1 or 2 parameters.
+    The first 1st parameter is the "code to execute"
+    The 2nd (optional) is where to put the error message.
+    
+    CATCH returns 0 on success, 1 for failure.
+    The "![catch command]" is self explaintory.
+
+
+The 3rd parameter to IF must be exacty "else" or "elseif" [I lied
+above, the IF command can take many parameters they just have to
+be joined by exactly the words "else" or "elseif".
+
+The 4th parameter contains:
+    
+    "error [format STRING....]"
+
+This lets me modify the previous lower level error by tacking more
+text onto the end of it. In this case, i want to add the MMR register
+name to make my error message look better.
+
+---------
+Back to something inside show_mmr32_reg{}.
+
+You'll see something 'set fn show_${NAME}_helper' Here I am
+constructing a 'function name' Then - I look it up to see if it
+exists.  {the function: "proc_exists" does this}
+
+And - if it does - I call the function.
+
+In "C" it is alot like using: 'sprintf()' to construct a function name
+string, then using "dlopen()" and "dlsym()" to look it up - and get a
+function pointer - and calling the function pointer.
+
+In this case - I execute a dynamic command. You can do some cool
+tricks with interpretors. 
+
+----------
+
+Function:   show_mmr32_bits()
+
+In this case, we use the special TCL command "upvar" which tcl's way
+of passing things by reference. In this case, we want to reach up into
+the callers lexical scope and find the array named "NAMES"
+
+The rest of the function is pretty straight forward.
+
+First - we figure out the longest name.
+Then print 4 rows of 8bits - with names.
+
+
+**************************************************
+***************************************************
+=== TCL TOUR ===
+Open the file: "chips/atmel/at91/usarts.tcl"
+===============
+
+First - about the AT91SAM series - all of the usarts
+are basically identical...
+
+Second - there can be many of them.
+
+In this case - I do some more TCL tricks to dynamically
+create functions out of thin air.
+
+Some assumptions:
+
+The "CHIP" file has defined some variables in a proper form.
+
+ie:   AT91C_BASE_US0 - for usart0, 
+      AT91C_BASE_US1 - for usart1
+      ... And so on ...
+
+Near the end of the file - look for a large "foreach" loop that
+looks like this:
+
+      foreach WHO { US0 US1 US2 US3 US4 .... } {
+
+      }
+
+In this case, I'm trying to figure out what USARTs exist.
+
+Step 1 - is to determine if the NAME has been defined.
+ie: Does AT91C_BASE_USx - where X is some number exist?
+
+The "info exists VARNAME" tells you if the variable exists.  Then -
+inside the IF statement... There is another loop. This loop is the
+name of various "sub-registers" within the USART.
+
+Some more trick are played with the [set VAR] backtick evaluation stuff.
+And we create two variables
+
+We calculate and create the global variable name for every subregister in the USART.
+And - declare that variable as GLOBAL so the world can find it.
+
+Then - we dynamically create a function - based on the register name.
+
+Look carefully at how that is done. You'll notice the FUNCTION BODY is
+a string - not something in {braces}. Why? This is because we need TCL
+to evaluate the contents of that string "*NOW*" - when $vn exists not
+later, when the function "show_FOO" is invoked.
+
+Lastly - we build a "str" of commands - and create a single function -
+with the generated list of commands for the entire USART.
+
+With that little bit of code - I now have a bunch of functions like:
+
+   show_US0, show_US1, show_US2, .... etc ...
+   
+   And show_US0_MR, show_US0_IMR ... etc...
+  
+And - I have this for every USART... without having to create tons of
+boiler plate yucky code.
+
+****************************************
+****************************************
+END of the Tcl Intro and Walk Through
+****************************************
+****************************************
+
+FUTURE PLANS
+
+       Some "GPIO" functions...
diff --git a/src/tcl/bitsbytes.tcl b/src/tcl/bitsbytes.tcl
new file mode 100644 (file)
index 0000000..b1771b4
--- /dev/null
@@ -0,0 +1,63 @@
+#----------------------------------------
+# Purpose - Create some $BIT variables
+#           Create $K and $M variables
+#          and some bit field extraction variables.
+# Creat helper variables ...
+#    BIT0.. BIT31
+
+for { set x 0  } { $x < 32 } { set x [expr $x + 1]} {
+    set vn [format "BIT%d" $x]
+    set $vn   [expr (1 << $x)]
+    global $vn
+
+}
+
+# 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
+}
+
+# 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
+}
+
+proc create_mask { MSB LSB } {
+    return [expr (((1 << ($MSB - $LSB + 1))-1) << $LSB)]
+
+}
+
+# Cut Bits $MSB to $LSB out of this value.
+# Example: % format "0x%08x" [extract_bitfield 0x12345678 27 16]
+# Result:  0x02340000
+
+proc extract_bitfield { VALUE MSB LSB } {
+    return [expr [create_mask $MSB $LSB] & $VALUE]
+}
+
+
+# Cut bits $MSB to $LSB out of this value
+# and shift (normalize) them down to bit 0.
+#
+# Example: % format "0x%08x" [normalize_bitfield 0x12345678 27 16]
+# Result:  0x00000234
+#
+proc normalize_bitfield { VALUE MSB LSB } {
+    return [expr [extract_bitfield $VALUE $MSB $LSB ] >> $LSB]
+}
+
+proc show_normalize_bitfield { VALUE MSB LSB } {
+    set m [create_mask $MSB $LSB]
+    set mr [expr $VALUE & $m]
+    set sr [expr $mr >> $LSB]
+    puts [format "((0x%08x & 0x%08x) -> 0x%08x) >> %2d => (0x%x) %5d " $VALUE $m $mr $LSB $sr $sr]
+   return $sr
+}
+
+
diff --git a/src/tcl/chip/atmel/at91/aic.tcl b/src/tcl/chip/atmel/at91/aic.tcl
new file mode 100644 (file)
index 0000000..245224a
--- /dev/null
@@ -0,0 +1,101 @@
+set AIC_SMR            [expr $AT91C_BASE_AIC + 0x00000000 ]
+global AIC_SMR
+set AIC_SVR            [expr $AT91C_BASE_AIC + 0x00000080 ]
+global AIC_SVR
+set AIC_IVR            [expr $AT91C_BASE_AIC + 0x00000100 ]
+global AIC_IVR
+set AIC_FVR            [expr $AT91C_BASE_AIC + 0x00000104 ]
+global AIC_FVR
+set AIC_ISR            [expr $AT91C_BASE_AIC + 0x00000108 ]
+global AIC_ISR
+set AIC_IPR            [expr $AT91C_BASE_AIC + 0x0000010C ]
+global AIC_IPR
+set AIC_IMR            [expr $AT91C_BASE_AIC + 0x00000110 ]
+global AIC_IMR
+set AIC_CISR           [expr $AT91C_BASE_AIC + 0x00000114 ]
+global AIC_CISR
+set AIC_IECR           [expr $AT91C_BASE_AIC + 0x00000120 ]
+global AIC_IECR
+set AIC_IDCR           [expr $AT91C_BASE_AIC + 0x00000124 ]
+global AIC_IDCR
+set AIC_ICCR           [expr $AT91C_BASE_AIC + 0x00000128 ]
+global AIC_ICCR
+set AIC_ISCR           [expr $AT91C_BASE_AIC + 0x0000012C ]
+global AIC_ISCR
+set AIC_EOICR          [expr $AT91C_BASE_AIC + 0x00000130 ]
+global AIC_EOICR
+set AIC_SPU            [expr $AT91C_BASE_AIC + 0x00000134 ]
+global AIC_SPU
+set AIC_DCR            [expr $AT91C_BASE_AIC + 0x00000138 ]
+global AIC_DCR
+set AIC_FFER           [expr $AT91C_BASE_AIC + 0x00000140 ]
+global AIC_FFER
+set AIC_FFDR           [expr $AT91C_BASE_AIC + 0x00000144 ]
+global AIC_FFDR
+set AIC_FFSR           [expr $AT91C_BASE_AIC + 0x00000148 ]
+global AIC_FFSR
+
+
+proc aic_enable_disable_list { VAL ENAME DNAME } {
+    global AT91C_ID
+
+    show_mmr32_bits AT91C_ID $VAL
+
+}
+
+proc show_AIC_IPR_helper { NAME ADDR VAL } {
+    aic_enable_disable_list  $VAL "IRQ PENDING" "irq not-pending"
+}
+
+proc show_AIC_IMR_helper { NAME ADDR VAL } {
+    aic_enable_disable_list  $VAL "IRQ ENABLED" "irq disabled"
+}
+
+
+proc show_AIC { } {
+    global AIC_SMR
+    if [catch { mem2array aaa 32 $AIC_SMR [expr 32 * 4] } msg ] {
+       error [format "%s (%s)" $msg AIC_SMR]
+    }
+    puts "AIC_SMR: Mode & Type"
+    global AT91C_ID
+    for { set x 0 } { $x < 32 } {  } {
+       puts -nonewline "   "
+       puts -nonewline [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) $aaa($x)]
+       incr x
+       puts -nonewline [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) $aaa($x)]
+       incr x
+       puts -nonewline [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) $aaa($x)]
+       incr x
+       puts  [format "%2d: %5s 0x%08x"  $x $AT91C_ID($x) $aaa($x)]
+       incr x
+    }
+    global AIC_SVR
+    if [catch { mem2array aaa 32 $AIC_SVR [expr 32 * 4] } msg ] {
+       error [format "%s (%s)" $msg AIC_SVR]
+    }
+    puts "AIC_SVR: Vectors"
+    for { set x 0 } { $x < 32 } {  } {
+       puts -nonewline "   "
+       puts -nonewline [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) $aaa($x)]
+       incr x
+       puts -nonewline [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) $aaa($x)]
+       incr x
+       puts -nonewline [format "%2d: %5s 0x%08x | " $x $AT91C_ID($x) $aaa($x)]
+       incr x
+       puts [format "%2d: %5s 0x%08x" $x $AT91C_ID($x) $aaa($x)]
+       incr x
+    } 
+
+    foreach REG {
+       AIC_IVR   AIC_FVR  AIC_ISR 
+       AIC_IPR  AIC_IMR  AIC_CISR  AIC_IECR AIC_IDCR
+       AIC_ICCR AIC_ISCR AIC_EOICR AIC_SPU  AIC_DCR     
+       AIC_FFER AIC_FFDR AIC_FFSR } {
+       if [catch { show_mmr32_reg $REG } msg ] {
+           error $msg
+           break
+       }
+    }
+}
+
diff --git a/src/tcl/chip/atmel/at91/at91sam7x128.tcl b/src/tcl/chip/atmel/at91/at91sam7x128.tcl
new file mode 100644 (file)
index 0000000..1cf7c1c
--- /dev/null
@@ -0,0 +1,128 @@
+source [find tcl/bitsbytes.tcl]
+source [find tcl/cpu/arm/arm7tdmi.tcl]
+source [find tcl/memory.tcl]
+source [find tcl/mmr_helpers.tcl]
+
+set CHIP_MAKER  atmel
+set CHIP_FAMILY at91sam7
+set CHIP_NAME   at91sam7x128
+# how many flash regions.
+set N_FLASH                1
+set FLASH(0,CHIPSELECT)    -1
+set FLASH(0,BASE)          0x00100000
+set FLASH(0,LEN)           $__128K
+set FLASH(0,HUMAN)         "internal flash"
+set FLASH(0,TYPE)          "flash"
+set FLASH(0,RWX)           $RWX_R_X
+set FLASH(0,ACCESS_WIDTH)  $ACCESS_WIDTH_ANY
+# how many ram regions.
+set N_RAM                  1
+set RAM(0,CHIPSELECT)      -1
+set RAM(0,BASE)            0x00200000
+set RAM(0,LEN)             $__32K
+set RAM(0,HUMAN)           "internal ram"
+set RAM(0,TYPE)            "ram"
+set RAM(0,RWX)             $RWX_RWX
+set RAM(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY
+
+# I AM LAZY... I create 1 region for all MMRs.
+set N_MMREGS    1
+set MMREGS(0,CHIPSELECT)      -1
+set MMREGS(0,BASE)            0xfff00000
+set MMREGS(0,LEN)             0x000fffff
+set MMREGS(0,HUMAN)           "mm-regs"
+set MMREGS(0,TYPE)            "mmr"
+set MMREGS(0,RWX)             $RWX_RW
+set MMREGS(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY
+
+# no external memory
+set N_XMEM 0
+
+
+
+
+set AT91C_BASE_SYS       0xFFFFF000
+set AT91C_BASE_AIC       0xFFFFF000
+set AT91C_BASE_PDC_DBGU  0xFFFFF300
+set AT91C_BASE_DBGU      0xFFFFF200
+set AT91C_BASE_PIOA      0xFFFFF400
+set AT91C_BASE_PIOB      0xFFFFF600
+set AT91C_BASE_CKGR      0xFFFFFC20
+set AT91C_BASE_PMC       0xFFFFFC00
+set AT91C_BASE_RSTC      0xFFFFFD00
+set AT91C_BASE_RTTC      0xFFFFFD20
+set AT91C_BASE_PITC      0xFFFFFD30
+set AT91C_BASE_WDTC      0xFFFFFD40
+set AT91C_BASE_VREG      0xFFFFFD60
+set AT91C_BASE_MC        0xFFFFFF00
+set AT91C_BASE_PDC_SPI1  0xFFFE4100
+set AT91C_BASE_SPI1      0xFFFE4000
+set AT91C_BASE_PDC_SPI0  0xFFFE0100
+set AT91C_BASE_SPI0      0xFFFE0000
+set AT91C_BASE_PDC_US1   0xFFFC4100
+set AT91C_BASE_US1       0xFFFC4000
+set AT91C_BASE_PDC_US0   0xFFFC0100
+set AT91C_BASE_US0       0xFFFC0000
+set AT91C_BASE_PDC_SSC   0xFFFD4100
+set AT91C_BASE_SSC       0xFFFD4000
+set AT91C_BASE_TWI       0xFFFB8000
+set AT91C_BASE_PWMC_CH3  0xFFFCC260
+set AT91C_BASE_PWMC_CH2  0xFFFCC240
+set AT91C_BASE_PWMC_CH1  0xFFFCC220
+set AT91C_BASE_PWMC_CH0  0xFFFCC200
+set AT91C_BASE_PWMC      0xFFFCC000
+set AT91C_BASE_UDP       0xFFFB0000
+set AT91C_BASE_TC0       0xFFFA0000
+set AT91C_BASE_TC1       0xFFFA0040
+set AT91C_BASE_TC2       0xFFFA0080
+set AT91C_BASE_TCB       0xFFFA0000
+set AT91C_BASE_CAN_MB0   0xFFFD0200
+set AT91C_BASE_CAN_MB1   0xFFFD0220
+set AT91C_BASE_CAN_MB2   0xFFFD0240
+set AT91C_BASE_CAN_MB3   0xFFFD0260
+set AT91C_BASE_CAN_MB4   0xFFFD0280
+set AT91C_BASE_CAN_MB5   0xFFFD02A0
+set AT91C_BASE_CAN_MB6   0xFFFD02C0
+set AT91C_BASE_CAN_MB7   0xFFFD02E0
+set AT91C_BASE_CAN       0xFFFD0000
+set AT91C_BASE_EMAC      0xFFFDC000
+set AT91C_BASE_PDC_ADC   0xFFFD8100
+set AT91C_BASE_ADC       0xFFFD8000
+
+set AT91C_ID(0) FIQ
+set AT91C_ID(1) SYS
+set AT91C_ID(2) PIOA
+set AT91C_ID(3) PIOB
+set AT91C_ID(4) SPI0
+set AT91C_ID(5) SPI1
+set AT91C_ID(6) US0
+set AT91C_ID(7) US1
+set AT91C_ID(8) SSC
+set AT91C_ID(9) TWI
+set AT91C_ID(10) PWMC
+set AT91C_ID(11) UDP
+set AT91C_ID(12) TC0
+set AT91C_ID(13) TC1
+set AT91C_ID(14) TC2
+set AT91C_ID(15) CAN
+set AT91C_ID(16) EMAC
+set AT91C_ID(17) ADC
+set AT91C_ID(18) ""
+set AT91C_ID(19) ""
+set AT91C_ID(20) ""
+set AT91C_ID(21) ""
+set AT91C_ID(22) ""
+set AT91C_ID(23) ""
+set AT91C_ID(24) ""
+set AT91C_ID(25) ""
+set AT91C_ID(26) ""
+set AT91C_ID(27) ""
+set AT91C_ID(28) ""
+set AT91C_ID(29) ""
+set AT91C_ID(30) IRQ0
+set AT91C_ID(31) IRQ1
+
+source [find tcl/chip/atmel/at91/aic.tcl]
+source [find tcl/chip/atmel/at91/usarts.tcl]
+source [find tcl/chip/atmel/at91/pmc.tcl]
+source [find tcl/chip/atmel/at91/rtt.tcl]
diff --git a/src/tcl/chip/atmel/at91/at91sam7x256.tcl b/src/tcl/chip/atmel/at91/at91sam7x256.tcl
new file mode 100644 (file)
index 0000000..1cba485
--- /dev/null
@@ -0,0 +1,126 @@
+source [find tcl/bitsbytes.tcl]
+source [find tcl/cpu/arm/arm7tdmi.tcl]
+source [find tcl/memory.tcl]
+source [find tcl/mmr_helpers.tcl]
+
+set CHIP_MAKER  atmel
+set CHIP_FAMILY at91sam7
+set CHIP_NAME   at91sam7x256
+# how many flash regions.
+set N_FLASH                1
+set FLASH(0,CHIPSELECT)    -1
+set FLASH(0,BASE)          0x00100000
+set FLASH(0,LEN)           $__256K
+set FLASH(0,HUMAN)         "internal flash"
+set FLASH(0,TYPE)          "flash"
+set FLASH(0,RWX)           $RWX_R_X
+set FLASH(0,ACCESS_WIDTH)  $ACCESS_WIDTH_ANY
+# how many ram regions.
+set N_RAM                  1
+set RAM(0,CHIPSELECT)      -1
+set RAM(0,BASE)            0x00200000
+set RAM(0,LEN)             $__64K
+set RAM(0,HUMAN)           "internal ram"
+set RAM(0,TYPE)            "ram"
+set RAM(0,RWX)             $RWX_RWX
+set RAM(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY
+
+# I AM LAZY... I create 1 region for all MMRs.
+set N_MMREGS    1
+set MMREGS(0,CHIPSELECT)      -1
+set MMREGS(0,BASE)            0xfff00000
+set MMREGS(0,LEN)             0x000fffff
+set MMREGS(0,HUMAN)           "mm-regs"
+set MMREGS(0,TYPE)            "mmr"
+set MMREGS(0,RWX)             $RWX_RW
+set MMREGS(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY
+
+# no external memory
+set N_XMEM 0
+
+set  AT91C_BASE_SYS              0xFFFFF000
+set  AT91C_BASE_AIC              0xFFFFF000
+set  AT91C_BASE_PDC_DBGU         0xFFFFF300
+set  AT91C_BASE_DBGU             0xFFFFF200
+set  AT91C_BASE_PIOA             0xFFFFF400
+set  AT91C_BASE_PIOB             0xFFFFF600
+set  AT91C_BASE_CKGR             0xFFFFFC20
+set  AT91C_BASE_PMC              0xFFFFFC00
+set  AT91C_BASE_RSTC             0xFFFFFD00
+set  AT91C_BASE_RTTC             0xFFFFFD20
+set  AT91C_BASE_PITC             0xFFFFFD30
+set  AT91C_BASE_WDTC             0xFFFFFD40
+set  AT91C_BASE_VREG             0xFFFFFD60
+set  AT91C_BASE_MC          0xFFFFFF00
+set  AT91C_BASE_PDC_SPI1      0xFFFE4100
+set  AT91C_BASE_SPI1          0xFFFE4000
+set  AT91C_BASE_PDC_SPI0      0xFFFE0100
+set  AT91C_BASE_SPI0          0xFFFE0000
+set  AT91C_BASE_PDC_US1       0xFFFC4100
+set  AT91C_BASE_US1           0xFFFC4000
+set  AT91C_BASE_PDC_US0       0xFFFC0100
+set  AT91C_BASE_US0           0xFFFC0000
+set  AT91C_BASE_PDC_SSC       0xFFFD4100
+set  AT91C_BASE_SSC           0xFFFD4000
+set  AT91C_BASE_TWI           0xFFFB8000
+set  AT91C_BASE_PWMC_CH3      0xFFFCC260
+set  AT91C_BASE_PWMC_CH2      0xFFFCC240
+set  AT91C_BASE_PWMC_CH1      0xFFFCC220
+set  AT91C_BASE_PWMC_CH0      0xFFFCC200
+set  AT91C_BASE_PWMC          0xFFFCC000
+set  AT91C_BASE_UDP           0xFFFB0000
+set  AT91C_BASE_TC0         0xFFFA0000
+set  AT91C_BASE_TC1         0xFFFA0040
+set  AT91C_BASE_TC2         0xFFFA0080
+set  AT91C_BASE_TCB             0xFFFA0000
+set  AT91C_BASE_CAN_MB0         0xFFFD0200
+set  AT91C_BASE_CAN_MB1         0xFFFD0220
+set  AT91C_BASE_CAN_MB2         0xFFFD0240
+set  AT91C_BASE_CAN_MB3         0xFFFD0260
+set  AT91C_BASE_CAN_MB4         0xFFFD0280
+set  AT91C_BASE_CAN_MB5         0xFFFD02A0
+set  AT91C_BASE_CAN_MB6         0xFFFD02C0
+set  AT91C_BASE_CAN_MB7         0xFFFD02E0
+set  AT91C_BASE_CAN             0xFFFD0000
+set  AT91C_BASE_EMAC            0xFFFDC000
+set  AT91C_BASE_PDC_ADC         0xFFFD8100
+set  AT91C_BASE_ADC             0xFFFD8000
+
+set AT91C_ID(0)   "FIQ"
+set AT91C_ID(1)   "SYS"
+set AT91C_ID(2)   "PIOA"
+set AT91C_ID(3)   "PIOB"
+set AT91C_ID(4)   "SPI0"
+set AT91C_ID(5)   "SPI1"
+set AT91C_ID(6)   "US0"
+set AT91C_ID(7)   "US1"
+set AT91C_ID(8)   "SSC"
+set AT91C_ID(9)   "TWI"
+set AT91C_ID(10)   "PWMC"
+set AT91C_ID(11)   "UDP"
+set AT91C_ID(12)   "TC0"
+set AT91C_ID(13)   "TC1"
+set AT91C_ID(14)   "TC2"
+set AT91C_ID(15)   "CAN"
+set AT91C_ID(16)   "EMAC"
+set AT91C_ID(17)   "ADC"
+set AT91C_ID(18)   ""
+set AT91C_ID(19)   ""
+set AT91C_ID(20)   ""
+set AT91C_ID(21)   ""
+set AT91C_ID(22)   ""
+set AT91C_ID(23)   ""
+set AT91C_ID(24)   ""
+set AT91C_ID(25)   ""
+set AT91C_ID(26)   ""
+set AT91C_ID(27)   ""
+set AT91C_ID(28)   ""
+set AT91C_ID(29)   ""
+set AT91C_ID(30)   "IRQ0"
+set AT91C_ID(31)   "IRQ1"
+
+
+source [find tcl/chip/atmel/at91/aic.tcl]
+source [find tcl/chip/atmel/at91/usarts.tcl]
+source [find tcl/chip/atmel/at91/pmc.tcl]
+source [find tcl/chip/atmel/at91/rtt.tcl]
diff --git a/src/tcl/chip/atmel/at91/pmc.tcl b/src/tcl/chip/atmel/at91/pmc.tcl
new file mode 100644 (file)
index 0000000..584acb8
--- /dev/null
@@ -0,0 +1,17 @@
+
+if [info exists AT91C_MAINOSC_FREQ] {
+    # user set this... let it be.
+} {
+    # 18.432mhz is a common thing...
+    set AT91C_MAINOSC_FREQ 18432000
+}
+global AT91C_MAINOSC_FREQ
+
+if [info exists AT91C_SLOWOSC_FREQ] {
+    # user set this... let it be.
+} {
+    # 32khz is the norm
+    set AT91C_SLOWOSC_FREQ 32768
+}
+global AT91C_SLOWOSC_FREQ
+
diff --git a/src/tcl/chip/atmel/at91/rtt.tcl b/src/tcl/chip/atmel/at91/rtt.tcl
new file mode 100644 (file)
index 0000000..56abb29
--- /dev/null
@@ -0,0 +1,54 @@
+
+set RTTC_RTMR [expr $AT91C_BASE_RTTC + 0x00]
+set RTTC_RTAR [expr $AT91C_BASE_RTTC + 0x04]
+set RTTC_RTVR [expr $AT91C_BASE_RTTC + 0x08]
+set RTTC_RTSR [expr $AT91C_BASE_RTTC + 0x0c]
+global RTTC_RTMR
+global RTTC_RTAR
+global RTTC_RTVR
+global RTTC_RTSR
+
+proc show_RTTC_RTMR_helper { NAME ADDR VAL } {
+    set rtpres [expr $VAL & 0x0ffff]
+    global BIT16 BIT17
+    if { $rtpres == 0 } {
+       set rtpres 65536;
+    } 
+    global AT91C_SLOWOSC_FREQ
+    set f [expr double($AT91C_SLOWOSC_FREQ) / double($rtpres)]
+    puts [format "\tPrescale value: 0x%04x (%5d) => %f Hz" $rtpres $rtpres $f]
+    if { $VAL & $BIT16 } {
+       puts "\tBit16 -> Alarm IRQ Enabled"
+    } else {
+       puts "\tBit16 -> Alarm IRQ Disabled"
+    }
+    if { $VAL & $BIT17 } {
+       puts "\tBit17 -> RTC Inc IRQ Enabled"
+    } else {
+       puts "\tBit17 -> RTC Inc IRQ Disabled"
+    }
+    # Bit 18 is write only.
+}
+
+proc show_RTTC_RTSR_helper { NAME ADDR VAL } {
+    global BIT0 BIT1
+    if { $VAL & $BIT0 } {
+       puts "\tBit0 -> ALARM PENDING"
+    } else {
+       puts "\tBit0 -> alarm not pending"
+    }
+    if { $VAL & $BIT1 } {
+       puts "\tBit0 -> RTINC PENDING"
+    } else {
+       puts "\tBit0 -> rtinc not pending"
+    }
+}
+
+proc show_RTTC { } {
+    
+    show_mmr32_reg RTTC_RTMR
+    show_mmr32_reg RTTC_RTAR
+    show_mmr32_reg RTTC_RTVR
+    show_mmr32_reg RTTC_RTSR
+}
+
diff --git a/src/tcl/chip/atmel/at91/usarts.tcl b/src/tcl/chip/atmel/at91/usarts.tcl
new file mode 100644 (file)
index 0000000..19f4ed4
--- /dev/null
@@ -0,0 +1,135 @@
+# the DBGU and USARTs are 'almost' indentical'
+set DBGU_CR         [expr $AT91C_BASE_DBGU + 0x00000000]
+set DBGU_MR         [expr $AT91C_BASE_DBGU + 0x00000004]
+set DBGU_IER        [expr $AT91C_BASE_DBGU + 0x00000008]
+set DBGU_IDR        [expr $AT91C_BASE_DBGU + 0x0000000C]
+set DBGU_IMR        [expr $AT91C_BASE_DBGU + 0x00000010]
+set DBGU_CSR        [expr $AT91C_BASE_DBGU + 0x00000014]
+set DBGU_RHR        [expr $AT91C_BASE_DBGU + 0x00000018]
+set DBGU_THR        [expr $AT91C_BASE_DBGU + 0x0000001C]
+set DBGU_BRGR       [expr $AT91C_BASE_DBGU + 0x00000020]
+# no RTOR
+# no TTGR
+# no FIDI
+# no NER
+set DBGU_CIDR       [expr $AT91C_BASE_DBGU + 0x00000040]
+set DBGU_EXID       [expr $AT91C_BASE_DBGU + 0x00000044]
+set DBGU_FNTR       [expr $AT91C_BASE_DBGU + 0x00000048]
+
+
+set USx_CR           0x00000000
+set USx_MR           0x00000004
+set USx_IER          0x00000008
+set USx_IDR          0x0000000C
+set USx_IMR          0x00000010
+set USx_CSR          0x00000014
+set USx_RHR          0x00000018
+set USx_THR          0x0000001C
+set USx_BRGR         0x00000020
+set USx_RTOR         0x00000024
+set USx_TTGR         0x00000028
+set USx_FIDI         0x00000040
+set USx_NER          0x00000044
+set USx_IF           0x0000004C
+
+# Create all the uarts that exist..
+# we blow up if there are >9
+
+
+proc show_mmr_USx_MR_helper { NAME ADDR VAL } {
+    # First - just print it
+
+    set x [show_normalize_bitfield $VAL 3 0]
+    if { $x == 0 } {
+       puts "\tNormal operation"
+    } else {
+       puts [format "\tNon Normal operation mode: 0x%02x" $x]
+    }
+
+    set x [show_normalize_bitfield $VAL 11 9]
+    set s "unknown"
+    switch -exact $x { 
+       0 { set s "Even" }
+       1 { set s "Odd" }
+       2 { set s "Force=0" }
+       3 { set s "Force=1" }
+       * {
+           set $x [expr $x & 6]
+           switch -exact $x {
+               4 { set s "None" }
+               6 { set s "Multidrop Mode" }
+           }
+       }
+    }
+    puts [format "\tParity: %s " $s]
+    
+    set x [expr 5 + [show_normalize_bitfield $VAL 7 6]]
+    puts [format "\tDatabits: %d" $x]
+
+    set x [show_normalize_bitfield $VAL 13 12]
+    switch -exact $x {
+       0 { puts "\tStop bits: 1" }
+       1 { puts "\tStop bits: 1.5" }
+       2 { puts "\tStop bits: 2" }
+       3 { puts "\tStop bits: Illegal/Reserved" }
+    }
+}
+
+# For every possbile usart...
+foreach WHO { US0 US1 US2 US3 US4 US5 US6 US7 US8 US9 } {
+    set n AT91C_BASE_[set WHO]
+    set str ""
+
+    # Only if it exists on the chip 
+    if [ info exists $n ] {
+       # Hence: $n - is like AT91C_BASE_USx
+       # For every sub-register
+       foreach REG {CR MR IER IDR IMR CSR RHR THR BRGR RTOR TTGR FIDI NER IF}  {
+           # vn = variable name
+           set vn [set WHO]_[set REG]
+           # vn = USx_IER
+           # vv = variable value
+           set vv [expr $$n + [set USx_[set REG]]]
+           # And VV is the address in memory of that register
+
+
+           # make that VN a GLOBAL so others can find it
+           global $vn
+           set $vn $vv
+
+           # Create a command for this specific register.
+           proc show_$vn { } "show_mmr32_reg $vn"
+
+           # Add this command to the Device(as a whole) command
+           set str "$str\nshow_$vn"
+       }
+       # Now - create the DEVICE(as a whole) command
+       set fn show_$WHO
+       proc $fn { } $str
+    }
+}
+
+# The Debug Uart is special..
+set str ""
+
+
+# For every sub-register
+foreach REG {DBGU_CR DBGU_MR DBGU_IER DBGU_IDR DBGU_IMR 
+    DBGU_CSR DBGU_RHR DBGU_THR DBGU_BRGR DBGU_CIDR DBGU_EXID DBGU_FNTR} {
+
+    # Create a command for this specific register.
+    proc show_$REG { } "show_mmr32_reg $REG"
+    
+    # Add this command to the Device(as a whole) command
+    set str "$str\nshow_$REG"
+}
+
+# Now - create the DEVICE(as a whole) command
+proc show_DBGU { } $str
+
+unset str
+
+proc show_DBGU_MR_helper { NAME ADDR VAL } { show_mmr_USx_MR_helper $NAME $ADDR $VAL }
+
+
+
diff --git a/src/tcl/cpu/arm/arm7tdmi.tcl b/src/tcl/cpu/arm/arm7tdmi.tcl
new file mode 100644 (file)
index 0000000..37db266
--- /dev/null
@@ -0,0 +1,6 @@
+set CPU_TYPE   arm
+set CPU_NAME   arm7tdmi
+set CPU_ARCH   armv4t
+set CPU_MAX_ADDRESS 0xFFFFFFFF
+set CPU_NBITS  32
+
diff --git a/src/tcl/cpu/arm/arm920.tcl b/src/tcl/cpu/arm/arm920.tcl
new file mode 100644 (file)
index 0000000..f19b20b
--- /dev/null
@@ -0,0 +1,6 @@
+set CPU_TYPE   arm
+set CPU_NAME   arm920
+set CPU_ARCH   armv4t
+set CPU_MAX_ADDRESS 0xFFFFFFFF
+set CPU_NBITS  32
+
diff --git a/src/tcl/cpu/arm/arm946.tcl b/src/tcl/cpu/arm/arm946.tcl
new file mode 100644 (file)
index 0000000..5204101
--- /dev/null
@@ -0,0 +1,6 @@
+set CPU_TYPE   arm
+set CPU_NAME   arm946
+set CPU_ARCH   armv5te
+set CPU_MAX_ADDRESS 0xFFFFFFFF
+set CPU_NBITS  32
+
diff --git a/src/tcl/cpu/arm/arm966.tcl b/src/tcl/cpu/arm/arm966.tcl
new file mode 100644 (file)
index 0000000..83ce0f6
--- /dev/null
@@ -0,0 +1,6 @@
+set CPU_TYPE   arm
+set CPU_NAME   arm966
+set CPU_ARCH   armv5te
+set CPU_MAX_ADDRESS 0xFFFFFFFF
+set CPU_NBITS  32
+
diff --git a/src/tcl/memory.tcl b/src/tcl/memory.tcl
new file mode 100644 (file)
index 0000000..1f90ef2
--- /dev/null
@@ -0,0 +1,108 @@
+# MEMORY 
+#
+# All Memory regions have two components.
+#    (1) A count of regions, in the form N_NAME
+#    (2) An array within info about each region.
+#
+# The ARRAY
+#
+#       <NAME>(  RegionNumber ,  ATTRIBUTE )
+#
+# Where <NAME> is one of:
+#
+#     N_FLASH  & FLASH   (internal memory)
+#     N_RAM    & RAM     (internal memory)
+#     N_MMREGS & MMREGS  (for memory mapped registers)
+#     N_XMEM   & XMEM    (off chip memory, ie: flash on cs0, sdram on cs2)
+# or  N_UNKNOWN & UNKNOWN for things that do not exist.
+#
+# We have 1 unknown region.
+set N_UNKNOWN 1
+# All MEMORY regions must have these attributes
+#     CS          - chip select (if internal, use -1)
+set UNKNOWN(0,CHIPSELECT) -1
+#     BASE        - base address in memory
+set UNKNOWN(0,BASE)       0
+#     LEN         - length in bytes
+set UNKNOWN(0,LEN)        $CPU_MAX_ADDRESS
+#     HUMAN       - human name of the region
+set UNKNOWN(0,HUMAN) "unknown"
+#     TYPE        - one of:
+#                       flash, ram, mmr, unknown
+#                    For harvard arch:
+#                       iflash, dflash, iram, dram
+set UNKNOWN(0,TYPE)       "unknown"
+#     RWX         - access ablity
+#                       unix style chmod bits
+#                           0 - no access
+#                           1 - execute
+#                           2 - write
+#                           4 - read
+#                       hence: 7 - readwrite execute
+set RWX_NO_ACCESS     0
+set RWX_X_ONLY        $BIT0
+set RWX_W_ONLY        $BIT1
+set RWX_R_ONLY        $BIT2
+set RWX_RW            [expr $RWX_R_ONLY + $RWX_W_ONLY]
+set RWX_R_X           [expr $RWX_R_ONLY + $RWX_X_ONLY]
+set RWX_RWX           [expr $RWX_R_ONLY + $RWX_W_ONLY + $RWX_X_ONLY]
+set UNKNOWN(0,RWX)     $RWX_NO_ACCESS
+
+#     WIDTH       - access width
+#                      8,16,32 [0 means ANY]
+set ACCESS_WIDTH_NONE 0
+set ACCESS_WIDTH_8    $BIT0
+set ACCESS_WIDTH_16   $BIT1
+set ACCESS_WIDTH_32   $BIT2
+set ACCESS_WIDTH_ANY  [expr $ACCESS_WIDTH_8 + $ACCESS_WIDTH_16 + $ACCESS_WIDTH_32]
+set UNKNOWN(0,ACCESS_WIDTH) $ACCESS_WIDTH_NONE
+
+proc iswithin { ADDRESS BASE LEN } {
+    return [expr ((($ADDRESS - $BASE) > 0) && (($ADDRESS - $BASE + $LEN) > 0))]
+}
+
+proc address_info { ADDRESS } {
+    
+    foreach WHERE { FLASH RAM MMREGS XMEM UNKNOWN } {
+       if { info exists $WHERE } {
+           set lmt [set N_[set WHERE]]
+           for { set region 0 } { $region < $lmt } { incr region } {
+               if { iswithin $ADDRESS $WHERE($region,BASE) $WHERE($region,LEN) } {
+                   return  "$WHERE $region";
+               }
+           }
+       }
+    }
+
+    # Return the 'unknown'
+    return "UNKNOWN 0"
+}
+
+proc memread32 {ADDR } {
+    set foo(0) 0
+    if ![ catch { mem2array foo 32 $ADDR 1  } msg ] {
+       return $foo(0)
+    } else {
+       error "memead32: $msg"
+    }
+}    
+
+proc memread16 {ADDR } {
+    set foo(0) 0
+    if ![ catch { mem2array foo 16 $ADDR 1  } msg ] {
+       return $foo(0)
+    } else {
+       error "memead16: $msg"
+    }
+}    
+
+proc memread82 {ADDR } {
+    set foo(0) 0
+    if ![ catch { mem2array foo 8 $ADDR 1  } msg ] {
+       return $foo(0)
+    } else {
+       error "memead8: $msg"
+    }
+}    
+
+
diff --git a/src/tcl/mmr_helpers.tcl b/src/tcl/mmr_helpers.tcl
new file mode 100644 (file)
index 0000000..5dac48a
--- /dev/null
@@ -0,0 +1,59 @@
+
+proc proc_exists { NAME } {
+    set n [info commands $NAME]
+    set l [string length $n]
+    return [expr $l != 0]
+}
+
+# Give: REGISTER name - must be a global variable.
+proc show_mmr32_reg { NAME } {
+    
+    global $NAME
+    # we want $($NAME)
+    set a [set [set NAME]]
+
+    if ![catch { set v [memread32 $a] } msg ] {
+       puts [format "%10s: (0x%08x): 0x%08x" $NAME $a $v]
+
+       # Was a helper defined?
+       set fn show_${NAME}_helper
+       if [ proc_exists $fn ] {
+           # Then call it
+           $fn $NAME $a $v
+       }
+       return $v;
+    } else {
+       error [format "%s (%s)" $msg $NAME ]
+    }
+}
+
+
+# Give: NAMES - an array of names accessable
+#               in the callers symbol-scope.
+#       VAL - the bits to display.
+
+proc show_mmr32_bits { NAMES VAL } {
+
+    upvar $NAMES MYNAMES
+
+    set w 0
+    foreach {IDX N} $MYNAMES {
+       set l [string length $N]
+       if { $l > $w } { set w $l }
+    }
+    
+    for { set x 24 } { $x >= 0 } { incr x -8 } {
+       puts -nonewline "  "
+       for { set y 7 } { $y >= 0 } { incr y -1 } {
+           set s $MYNAMES([expr $x + $y])
+           puts -nonewline [format "%2d: %-*s | " [expr $x + $y] $w $s ]
+       }
+       puts ""
+
+       puts -nonewline "  "
+       for { set y 7 } { $y >= 0 } { incr y -1 } {
+           puts -nonewline [format "    %d%*s | " [expr !!($VAL & (1 << ($x + $y)))] [expr $w -1] ""]
+       }
+       puts ""
+    }
+}
diff --git a/src/tcl/readable.tcl b/src/tcl/readable.tcl
new file mode 100644 (file)
index 0000000..39f43ca
--- /dev/null
@@ -0,0 +1,25 @@
+proc iswithin { ADDRESS BASE LEN } {
+    return [expr ((($ADDRESS - $BASE) > 0) && (($ADDRESS - $BASE + $LEN) > 0))]
+}
+
+proc memorytype { ADDRESS } {
+    for { set chip 0 } { $chip < $N_CHIP } { incr chip } {
+       if { iswithin $ADDRESS $FLASH($chip,BASE) $FLASH($chip,LEN) } {
+           return "flash"
+       }
+    }
+
+    for { set chip 0 } { $chip < $N_RAM } { incr chip } {
+       if { iswithin $ADDRESS $RAM($chip,BASE) $RAM($chip,LEN) } {
+           return "ram"
+       }
+    }
+}
+
+# default to 32bit reads.
+proc isreadable { ADDRESS } {
+     return isreadable32 $ADDRESS
+}
+
+proc isreadable32 { ADDRESS } {
+    
\ No newline at end of file

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)