#include <errno.h>
#include <inttypes.h>
-#include "jim.h"
-extern Jim_Interp *interp;
-
-
/* command handlers */
int handle_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_flash_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
return ERROR_OK;
}
-static int Jim_Command_flash_banks(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+static int jim_flash_banks(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
if (argc != 1) {
Jim_WrongNumArgs(interp, 1, argv, "no arguments to flash_banks command");
Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, "chip_width", -1));
Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, p->chip_width));
- Jim_ListAppendElement(interp, list, elem);
+ Jim_ListAppendElement(interp, list, elem);
}
Jim_SetResult(interp, list);
{
if (flash_banks)
{
- Jim_CreateCommand(interp, "openocd_flash_banks", Jim_Command_flash_banks, NULL, NULL );
+ register_jim(cmd_ctx, "openocd_flash_banks", jim_flash_banks, "return information about the flash banks");
register_command(cmd_ctx, flash_cmd, "info", handle_flash_info_command, COMMAND_EXEC,
"print info about flash bank <num>");
#include <stdarg.h>
#include <stdio.h>
#include <unistd.h>
-
-#include <openocd_tcl.h>
+#include <errno.h>
int fast_and_dangerous = 0;
+Jim_Interp *interp = NULL;
int handle_sleep_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_fast_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
return ERROR_OK;
}
+
+/* find full path to file */
+static int jim_find(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ if (argc != 2)
+ return JIM_ERR;
+ const char *file = Jim_GetString(argv[1], NULL);
+ char *full_path = find_file(file);
+ if (full_path == NULL)
+ return JIM_ERR;
+ Jim_Obj *result = Jim_NewStringObj(interp, full_path, strlen(full_path));
+ free(full_path);
+
+ Jim_SetResult(interp, result);
+ return JIM_OK;
+}
+
+static int jim_echo(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ if (argc != 2)
+ return JIM_ERR;
+ const char *str = Jim_GetString(argv[1], NULL);
+ LOG_USER("%s", str);
+ 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;
+ Jim_Interp *interp;
+ command_context_t *context;
+
+ /* make it a char easier to read code */
+ ptr = _ptr;
+ interp = cookie;
+ nbytes = size * n;
+ if (ptr == NULL || interp == NULL || nbytes == 0) {
+ return 0;
+ }
+
+ context = Jim_GetAssocData(interp, "context");
+ if (context == NULL)
+ {
+ LOG_ERROR("openocd_jim_fwrite: no command context");
+ /* TODO: 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(context, ptr);
+ return strlen(ptr);
+ }
+ /* 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(context, 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;
+ Jim_Interp *interp;
+ command_context_t *context;
+
+ n = -1;
+ interp = cookie;
+ if (interp == NULL)
+ return n;
+
+ context = Jim_GetAssocData(interp, "context");
+ if (context == NULL)
+ {
+ LOG_ERROR("openocd_jim_vfprintf: no command context");
+ return n;
+ }
+
+ cp = alloc_vprintf(fmt, ap);
+ if (cp)
+ {
+ command_output_text(context, 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;
+}
+
command_context_t* command_init()
{
command_context_t* context = malloc(sizeof(command_context_t));
-
+ extern unsigned const char startup_tcl[];
+
context->mode = COMMAND_EXEC;
context->commands = NULL;
context->current_target = 0;
context->output_handler = NULL;
context->output_handler_priv = NULL;
+
+#ifdef JIM_EMBEDDED
+ Jim_InitEmbedded();
+ /* Create an interpreter */
+ interp = Jim_CreateInterp();
+ /* Add all the Jim core commands */
+ Jim_RegisterCoreCommands(interp);
+#endif
+
+ Jim_CreateCommand(interp, "openocd_find", jim_find, NULL, NULL);
+ Jim_CreateCommand(interp, "echo", jim_echo, NULL, NULL);
+
+ /* Set Jim's STDIO */
+ interp->cookie_stdin = interp;
+ interp->cookie_stdout = interp;
+ interp->cookie_stderr = interp;
+ 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;
+ add_default_dirs();
+
+ if (Jim_Eval(interp, startup_tcl)==JIM_ERR)
+ {
+ LOG_ERROR("Failed to run startup.tcl (embedded into OpenOCD compile time)");
+ Jim_PrintErrorMessage(interp);
+ exit(-1);
+ }
+
register_command(context, NULL, "sleep", handle_sleep_command,
COMMAND_ANY, "sleep for <n> milliseconds");
return ERROR_OK;
}
+
+void register_jim(struct command_context_s *cmd_ctx, const char *name, int (*cmd)(Jim_Interp *interp, int argc, Jim_Obj *const *argv), const char *help)
+{
+ Jim_CreateCommand(interp, name, cmd, NULL, NULL);
+
+ /* FIX!!! it would be prettier to invoke add_help_text...
+ accumulate help text in Tcl helptext list. */
+ Jim_Obj *helptext=Jim_GetGlobalVariableStr(interp, "ocd_helptext", JIM_ERRMSG);
+ if (Jim_IsShared(helptext))
+ helptext = Jim_DuplicateObj(interp, helptext);
+
+ Jim_Obj *cmd_entry=Jim_NewListObj(interp, NULL, 0);
+
+ Jim_Obj *cmd_list=Jim_NewListObj(interp, NULL, 0);
+ Jim_ListAppendElement(interp, cmd_list, Jim_NewStringObj(interp, name, -1));
+
+ Jim_ListAppendElement(interp, cmd_entry, cmd_list);
+ Jim_ListAppendElement(interp, cmd_entry, Jim_NewStringObj(interp, help, -1));
+ Jim_ListAppendElement(interp, helptext, cmd_entry);
+}
extern int fast_and_dangerous;
+
+/* Integrate the JIM TCL interpretor into the command processing. */
+#include <stdarg.h>
+#ifdef __ECOS
+/* Jim is provied by eCos */
+#include <cyg/jimtcl/jim.h>
+#else
+#define JIM_EMBEDDED
+#include "jim.h"
+#endif
+
+extern Jim_Interp *interp;
+
+void register_jim(command_context_t *context, const char *name, int (*cmd)(Jim_Interp *interp, int argc, Jim_Obj *const *argv), const char *help);
+
#endif /* COMMAND_H */
#include "string.h"
#include <unistd.h>
-#include "openocd_tcl.h"
-
-
/* note that this is not marked as static as it must be available from outside jtag.c for those
that implement the jtag_xxx() minidriver layer
*/
COMMAND_EXEC, "move to Run-Test/Idle, and execute <num_cycles>");
register_command(cmd_ctx, NULL, "irscan", handle_irscan_command,
COMMAND_EXEC, "execute IR scan <device> <instr> [dev2] [instr2] ...");
- add_jim("drscan", Jim_Command_drscan, "execute DR scan <device> <num_bits> <value> <num_bits1> <value2> ...");
+ register_jim(cmd_ctx, "drscan", Jim_Command_drscan, "execute DR scan <device> <num_bits> <value> <num_bits1> <value2> ...");
register_command(cmd_ctx, NULL, "verify_ircapture", handle_verify_ircapture_command,
COMMAND_ANY, "verify value captured during Capture-IR <enable|disable>");
#include <alloca.h>
#endif
-#ifdef __ECOS
-/* Jim is provied by eCos */
-#include <cyg/jimtcl/jim.h>
-#else
-#define JIM_EMBEDDED
-#include "jim.h"
-#endif
-
#include "replacements.h"
return ERROR_OK;
}
-Jim_Interp *interp;
-
-static int new_int_array_element(Jim_Interp * interp, const char *varname, int idx, u32 val)
-{
- char *namebuf;
- Jim_Obj *nameObjPtr, *valObjPtr;
- int result;
-
- namebuf = alloc_printf("%s(%d)", varname, idx);
- if (!namebuf)
- return JIM_ERR;
-
- nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
- valObjPtr = Jim_NewIntObj(interp, val);
- if (!nameObjPtr || !valObjPtr)
- {
- free(namebuf);
- return JIM_ERR;
- }
-
- Jim_IncrRefCount(nameObjPtr);
- Jim_IncrRefCount(valObjPtr);
- result = Jim_SetVariable(interp, nameObjPtr, valObjPtr);
- Jim_DecrRefCount(interp, nameObjPtr);
- Jim_DecrRefCount(interp, valObjPtr);
- free(namebuf);
- /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */
- return result;
-}
-
-static int Jim_Command_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- target_t *target;
- command_context_t *context;
- long l;
- u32 width;
- u32 len;
- u32 addr;
- u32 count;
- u32 v;
- const char *varname;
- u8 buffer[4096];
- int i, n, e, retval;
-
- /* argv[1] = name of array to receive the data
- * argv[2] = desired width
- * argv[3] = memory address
- * argv[4] = count of times to read
- */
- if (argc != 5) {
- Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
- return JIM_ERR;
- }
- varname = Jim_GetString(argv[1], &len);
- /* given "foo" get space for worse case "foo(%d)" .. add 20 */
-
- e = Jim_GetLong(interp, argv[2], &l);
- width = l;
- if (e != JIM_OK) {
- return e;
- }
-
- e = Jim_GetLong(interp, argv[3], &l);
- addr = l;
- if (e != JIM_OK) {
- return e;
- }
- e = Jim_GetLong(interp, argv[4], &l);
- len = l;
- if (e != JIM_OK) {
- return e;
- }
- switch (width) {
- case 8:
- width = 1;
- break;
- case 16:
- width = 2;
- break;
- case 32:
- width = 4;
- break;
- default:
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings( interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL );
- return JIM_ERR;
- }
- if (len == 0) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: zero width read?", NULL);
- return JIM_ERR;
- }
- if ((addr + (len * width)) < addr) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: addr + len - wraps to zero?", NULL);
- return JIM_ERR;
- }
- /* absurd transfer size? */
- if (len > 65536) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: absurd > 64K item request", NULL);
- return JIM_ERR;
- }
-
- if ((width == 1) ||
- ((width == 2) && ((addr & 1) == 0)) ||
- ((width == 4) && ((addr & 3) == 0))) {
- /* all is well */
- } else {
- char buf[100];
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- sprintf(buf, "mem2array address: 0x%08x is not aligned for %d byte reads", addr, width);
- Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
- return JIM_ERR;
- }
-
- context = Jim_GetAssocData(interp, "context");
- if (context == NULL)
- {
- LOG_ERROR("mem2array: no command context");
- return JIM_ERR;
- }
- target = get_current_target(context);
- if (target == NULL)
- {
- LOG_ERROR("mem2array: no current target");
- return JIM_ERR;
- }
-
- /* Transfer loop */
-
- /* index counter */
- n = 0;
- /* assume ok */
- e = JIM_OK;
- while (len) {
- /* Slurp... in buffer size chunks */
-
- count = len; /* in objects.. */
- if (count > (sizeof(buffer)/width)) {
- count = (sizeof(buffer)/width);
- }
-
- retval = target->type->read_memory( target, addr, width, count, buffer );
- if (retval != ERROR_OK) {
- /* BOO !*/
- LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count);
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL);
- e = JIM_ERR;
- len = 0;
- } else {
- v = 0; /* shut up gcc */
- for (i = 0 ;i < count ;i++, n++) {
- switch (width) {
- case 4:
- v = target_buffer_get_u32(target, &buffer[i*width]);
- break;
- case 2:
- v = target_buffer_get_u16(target, &buffer[i*width]);
- break;
- case 1:
- v = buffer[i] & 0x0ff;
- break;
- }
- new_int_array_element(interp, varname, n, v);
- }
- len -= count;
- }
- }
-
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
-
- return JIM_OK;
-}
-
-static int get_int_array_element(Jim_Interp * interp, const char *varname, int idx, u32 *val)
-{
- char *namebuf;
- Jim_Obj *nameObjPtr, *valObjPtr;
- int result;
- long l;
-
- namebuf = alloc_printf("%s(%d)", varname, idx);
- if (!namebuf)
- return JIM_ERR;
-
- nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
- if (!nameObjPtr)
- {
- free(namebuf);
- return JIM_ERR;
- }
-
- Jim_IncrRefCount(nameObjPtr);
- valObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_ERRMSG);
- Jim_DecrRefCount(interp, nameObjPtr);
- free(namebuf);
- if (valObjPtr == NULL)
- return JIM_ERR;
-
- result = Jim_GetLong(interp, valObjPtr, &l);
- /* printf("%s(%d) => 0%08x\n", varname, idx, val); */
- *val = l;
- return result;
-}
-
-static int Jim_Command_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- target_t *target;
- command_context_t *context;
- long l;
- u32 width;
- u32 len;
- u32 addr;
- u32 count;
- u32 v;
- const char *varname;
- u8 buffer[4096];
- int i, n, e, retval;
-
- /* argv[1] = name of array to get the data
- * argv[2] = desired width
- * argv[3] = memory address
- * argv[4] = count to write
- */
- if (argc != 5) {
- Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
- return JIM_ERR;
- }
- varname = Jim_GetString(argv[1], &len);
- /* given "foo" get space for worse case "foo(%d)" .. add 20 */
-
- e = Jim_GetLong(interp, argv[2], &l);
- width = l;
- if (e != JIM_OK) {
- return e;
- }
-
- e = Jim_GetLong(interp, argv[3], &l);
- addr = l;
- if (e != JIM_OK) {
- return e;
- }
- e = Jim_GetLong(interp, argv[4], &l);
- len = l;
- if (e != JIM_OK) {
- return e;
- }
- switch (width) {
- case 8:
- width = 1;
- break;
- case 16:
- width = 2;
- break;
- case 32:
- width = 4;
- break;
- default:
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings( interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL );
- return JIM_ERR;
- }
- if (len == 0) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: zero width read?", NULL);
- return JIM_ERR;
- }
- if ((addr + (len * width)) < addr) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: addr + len - wraps to zero?", NULL);
- return JIM_ERR;
- }
- /* absurd transfer size? */
- if (len > 65536) {
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: absurd > 64K item request", NULL);
- return JIM_ERR;
- }
-
- if ((width == 1) ||
- ((width == 2) && ((addr & 1) == 0)) ||
- ((width == 4) && ((addr & 3) == 0))) {
- /* all is well */
- } else {
- char buf[100];
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- sprintf(buf, "array2mem address: 0x%08x is not aligned for %d byte reads", addr, width);
- Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
- return JIM_ERR;
- }
-
- context = Jim_GetAssocData(interp, "context");
- if (context == NULL)
- {
- LOG_ERROR("array2mem: no command context");
- return JIM_ERR;
- }
- target = get_current_target(context);
- if (target == NULL)
- {
- LOG_ERROR("array2mem: no current target");
- return JIM_ERR;
- }
-
- /* Transfer loop */
-
- /* index counter */
- n = 0;
- /* assume ok */
- e = JIM_OK;
- while (len) {
- /* Slurp... in buffer size chunks */
-
- count = len; /* in objects.. */
- if (count > (sizeof(buffer)/width)) {
- count = (sizeof(buffer)/width);
- }
-
- v = 0; /* shut up gcc */
- for (i = 0 ;i < count ;i++, n++) {
- get_int_array_element(interp, varname, n, &v);
- switch (width) {
- case 4:
- target_buffer_set_u32(target, &buffer[i*width], v);
- break;
- case 2:
- target_buffer_set_u16(target, &buffer[i*width], v);
- break;
- case 1:
- buffer[i] = v & 0x0ff;
- break;
- }
- }
- len -= count;
-
- retval = target->type->write_memory(target, addr, width, count, buffer);
- if (retval != ERROR_OK) {
- /* BOO !*/
- LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count);
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
- Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL);
- e = JIM_ERR;
- len = 0;
- }
- }
-
- Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
-
- return JIM_OK;
-}
-
-
-
-/* find full path to file */
-static int Jim_Command_find(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- if (argc != 2)
- return JIM_ERR;
- const char *file = Jim_GetString(argv[1], NULL);
- char *full_path = find_file(file);
- if (full_path == NULL)
- return JIM_ERR;
- Jim_Obj *result = Jim_NewStringObj(interp, full_path, strlen(full_path));
- free(full_path);
-
- Jim_SetResult(interp, result);
- return JIM_OK;
-}
-
-static int Jim_Command_echo(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
- if (argc != 2)
- return JIM_ERR;
- const char *str = Jim_GetString(argv[1], NULL);
- LOG_USER("%s", str);
- 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;
- Jim_Interp *interp;
- command_context_t *context;
-
- /* make it a char easier to read code */
- ptr = _ptr;
- interp = cookie;
- nbytes = size * n;
- if (ptr == NULL || interp == NULL || nbytes == 0) {
- return 0;
- }
-
- context = Jim_GetAssocData(interp, "context");
- if (context == NULL)
- {
- LOG_ERROR("openocd_jim_fwrite: no command context");
- /* TODO: 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(context, ptr);
- return strlen(ptr);
- }
- /* 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(context, 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;
- Jim_Interp *interp;
- command_context_t *context;
-
- n = -1;
- interp = cookie;
- if (interp == NULL)
- return n;
-
- context = Jim_GetAssocData(interp, "context");
- if (context == NULL)
- {
- LOG_ERROR("openocd_jim_vfprintf: no command context");
- return n;
- }
-
- cp = alloc_vprintf(fmt, ap);
- if (cp)
- {
- command_output_text(context, 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 add_jim(const char *name, int (*cmd)(Jim_Interp *interp, int argc, Jim_Obj *const *argv), const char *help)
-{
- Jim_CreateCommand(interp, name, cmd, NULL, NULL);
-
- /* FIX!!! it would be prettier to invoke add_help_text...
- accumulate help text in Tcl helptext list. */
- Jim_Obj *helptext=Jim_GetGlobalVariableStr(interp, "ocd_helptext", JIM_ERRMSG);
- if (Jim_IsShared(helptext))
- helptext = Jim_DuplicateObj(interp, helptext);
-
- Jim_Obj *cmd_entry=Jim_NewListObj(interp, NULL, 0);
-
- Jim_Obj *cmd_list=Jim_NewListObj(interp, NULL, 0);
- Jim_ListAppendElement(interp, cmd_list, Jim_NewStringObj(interp, name, -1));
-
- Jim_ListAppendElement(interp, cmd_entry, cmd_list);
- Jim_ListAppendElement(interp, cmd_entry, Jim_NewStringObj(interp, help, -1));
- Jim_ListAppendElement(interp, helptext, cmd_entry);
-}
-
-extern unsigned const char startup_tcl[];
-
-void initJim(void)
-{
- Jim_CreateCommand(interp, "openocd_find", Jim_Command_find, NULL, NULL);
- Jim_CreateCommand(interp, "echo", Jim_Command_echo, NULL, NULL);
- Jim_CreateCommand(interp, "mem2array", Jim_Command_mem2array, NULL, NULL );
- Jim_CreateCommand(interp, "array2mem", Jim_Command_array2mem, NULL, NULL );
-
- /* Set Jim's STDIO */
- interp->cookie_stdin = interp;
- interp->cookie_stdout = interp;
- interp->cookie_stderr = interp;
- 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;
-
- add_default_dirs();
-
- if (Jim_Eval(interp, startup_tcl)==JIM_ERR)
- {
- LOG_ERROR("Failed to run startup.tcl (embedded into OpenOCD compile time)");
- Jim_PrintErrorMessage(interp);
- exit(-1);
- }
-}
-
command_context_t *setup_command_handler(void)
{
command_context_t *cmd_ctx;
* application will have it's own implementation of main(). */
int openocd_main(int argc, char *argv[])
{
-#ifdef JIM_EMBEDDED
- Jim_InitEmbedded();
- /* Create an interpreter */
- interp = Jim_CreateInterp();
- /* Add all the Jim core commands */
- Jim_RegisterCoreCommands(interp);
-#endif
-
- initJim();
-
/* initialize commandline interface */
command_context_t *cmd_ctx;
- cmd_ctx=setup_command_handler();
-
+
+ cmd_ctx = setup_command_handler();
+
/* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
/* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
/* DANGER!!! make sure that the line below does not appear in a patch, do not remove */
+++ /dev/null
-/***************************************************************************\r
- * Copyright (C) 2008 by Øyvind Harboe *\r
- * oyvind.harboe@zylin.com *\r
- * *\r
- * This program is free software; you can redistribute it and/or modify *\r
- * it under the terms of the GNU General Public License as published by *\r
- * the Free Software Foundation; either version 2 of the License, or *\r
- * (at your option) any later version. *\r
- * *\r
- * This program is distributed in the hope that it will be useful, *\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *\r
- * GNU General Public License for more details. *\r
- * *\r
- * You should have received a copy of the GNU General Public License *\r
- * along with this program; if not, write to the *\r
- * Free Software Foundation, Inc., *\r
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *\r
- ***************************************************************************/\r
-#ifndef OPENOCD_TCL_H\r
-#define OPENOCD_TCL_H\r
-#include <jim.h>\r
-void add_jim(const char *name, int (*cmd)(Jim_Interp *interp, int argc, Jim_Obj *const *argv), const char *help);\r
-extern Jim_Interp *interp;\r
-#endif\r
int handle_rwp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc);
int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
+static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
-/* targets
- */
+
+/* targets */
extern target_type_t arm7tdmi_target;
extern target_type_t arm720t_target;
extern target_type_t arm9tdmi_target;
register_command(cmd_ctx, NULL, "virt2phys", handle_virt2phys_command, COMMAND_ANY, "virt2phys <virtual address>");
register_command(cmd_ctx, NULL, "profile", handle_profile_command, COMMAND_EXEC, "PRELIMINARY! - profile <seconds> <gmon.out>");
+
+ /* script procedures */
+ register_jim(cmd_ctx, "openocd_mem2array", jim_mem2array, "read memory and return as a TCL array for script processing");
+ register_jim(cmd_ctx, "openocd_array2mem", jim_mem2array, "convert a TCL array to memory locations and write the values");
return ERROR_OK;
}
return ERROR_OK;
}
+
+static int new_int_array_element(Jim_Interp * interp, const char *varname, int idx, u32 val)
+{
+ char *namebuf;
+ Jim_Obj *nameObjPtr, *valObjPtr;
+ int result;
+
+ namebuf = alloc_printf("%s(%d)", varname, idx);
+ if (!namebuf)
+ return JIM_ERR;
+
+ nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
+ valObjPtr = Jim_NewIntObj(interp, val);
+ if (!nameObjPtr || !valObjPtr)
+ {
+ free(namebuf);
+ return JIM_ERR;
+ }
+
+ Jim_IncrRefCount(nameObjPtr);
+ Jim_IncrRefCount(valObjPtr);
+ result = Jim_SetVariable(interp, nameObjPtr, valObjPtr);
+ Jim_DecrRefCount(interp, nameObjPtr);
+ Jim_DecrRefCount(interp, valObjPtr);
+ free(namebuf);
+ /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */
+ return result;
+}
+
+static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ target_t *target;
+ command_context_t *context;
+ long l;
+ u32 width;
+ 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] = count of times to read
+ */
+ if (argc != 5) {
+ Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
+ return JIM_ERR;
+ }
+ varname = Jim_GetString(argv[1], &len);
+ /* given "foo" get space for worse case "foo(%d)" .. add 20 */
+
+ e = Jim_GetLong(interp, argv[2], &l);
+ width = l;
+ if (e != JIM_OK) {
+ return e;
+ }
+
+ e = Jim_GetLong(interp, argv[3], &l);
+ addr = l;
+ if (e != JIM_OK) {
+ return e;
+ }
+ e = Jim_GetLong(interp, argv[4], &l);
+ len = l;
+ if (e != JIM_OK) {
+ return e;
+ }
+ switch (width) {
+ case 8:
+ width = 1;
+ break;
+ case 16:
+ width = 2;
+ break;
+ case 32:
+ width = 4;
+ break;
+ default:
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings( interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL );
+ return JIM_ERR;
+ }
+ if (len == 0) {
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: zero width read?", NULL);
+ return JIM_ERR;
+ }
+ if ((addr + (len * width)) < addr) {
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: addr + len - wraps to zero?", NULL);
+ return JIM_ERR;
+ }
+ /* absurd transfer size? */
+ if (len > 65536) {
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: absurd > 64K item request", NULL);
+ return JIM_ERR;
+ }
+
+ if ((width == 1) ||
+ ((width == 2) && ((addr & 1) == 0)) ||
+ ((width == 4) && ((addr & 3) == 0))) {
+ /* all is well */
+ } else {
+ char buf[100];
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ sprintf(buf, "mem2array address: 0x%08x is not aligned for %d byte reads", addr, width);
+ Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
+ return JIM_ERR;
+ }
+
+ context = Jim_GetAssocData(interp, "context");
+ if (context == NULL)
+ {
+ LOG_ERROR("mem2array: no command context");
+ return JIM_ERR;
+ }
+ target = get_current_target(context);
+ if (target == NULL)
+ {
+ LOG_ERROR("mem2array: no current target");
+ return JIM_ERR;
+ }
+
+ /* Transfer loop */
+
+ /* index counter */
+ n = 0;
+ /* assume ok */
+ e = JIM_OK;
+ while (len) {
+ /* Slurp... in buffer size chunks */
+
+ count = len; /* in objects.. */
+ if (count > (sizeof(buffer)/width)) {
+ count = (sizeof(buffer)/width);
+ }
+
+ retval = target->type->read_memory( target, addr, width, count, buffer );
+ if (retval != ERROR_OK) {
+ /* BOO !*/
+ LOG_ERROR("mem2array: Read @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count);
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL);
+ e = JIM_ERR;
+ len = 0;
+ } else {
+ v = 0; /* shut up gcc */
+ for (i = 0 ;i < count ;i++, n++) {
+ switch (width) {
+ case 4:
+ v = target_buffer_get_u32(target, &buffer[i*width]);
+ break;
+ case 2:
+ v = target_buffer_get_u16(target, &buffer[i*width]);
+ break;
+ case 1:
+ v = buffer[i] & 0x0ff;
+ break;
+ }
+ new_int_array_element(interp, varname, n, v);
+ }
+ len -= count;
+ }
+ }
+
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+
+ return JIM_OK;
+}
+
+static int get_int_array_element(Jim_Interp * interp, const char *varname, int idx, u32 *val)
+{
+ char *namebuf;
+ Jim_Obj *nameObjPtr, *valObjPtr;
+ int result;
+ long l;
+
+ namebuf = alloc_printf("%s(%d)", varname, idx);
+ if (!namebuf)
+ return JIM_ERR;
+
+ nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
+ if (!nameObjPtr)
+ {
+ free(namebuf);
+ return JIM_ERR;
+ }
+
+ Jim_IncrRefCount(nameObjPtr);
+ valObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_ERRMSG);
+ Jim_DecrRefCount(interp, nameObjPtr);
+ free(namebuf);
+ if (valObjPtr == NULL)
+ return JIM_ERR;
+
+ result = Jim_GetLong(interp, valObjPtr, &l);
+ /* printf("%s(%d) => 0%08x\n", varname, idx, val); */
+ *val = l;
+ return result;
+}
+
+static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ target_t *target;
+ command_context_t *context;
+ long l;
+ u32 width;
+ u32 len;
+ u32 addr;
+ u32 count;
+ u32 v;
+ const char *varname;
+ u8 buffer[4096];
+ int i, n, e, retval;
+
+ /* argv[1] = name of array to get the data
+ * argv[2] = desired width
+ * argv[3] = memory address
+ * argv[4] = count to write
+ */
+ if (argc != 5) {
+ Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
+ return JIM_ERR;
+ }
+ varname = Jim_GetString(argv[1], &len);
+ /* given "foo" get space for worse case "foo(%d)" .. add 20 */
+
+ e = Jim_GetLong(interp, argv[2], &l);
+ width = l;
+ if (e != JIM_OK) {
+ return e;
+ }
+
+ e = Jim_GetLong(interp, argv[3], &l);
+ addr = l;
+ if (e != JIM_OK) {
+ return e;
+ }
+ e = Jim_GetLong(interp, argv[4], &l);
+ len = l;
+ if (e != JIM_OK) {
+ return e;
+ }
+ switch (width) {
+ case 8:
+ width = 1;
+ break;
+ case 16:
+ width = 2;
+ break;
+ case 32:
+ width = 4;
+ break;
+ default:
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings( interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL );
+ return JIM_ERR;
+ }
+ if (len == 0) {
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: zero width read?", NULL);
+ return JIM_ERR;
+ }
+ if ((addr + (len * width)) < addr) {
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: addr + len - wraps to zero?", NULL);
+ return JIM_ERR;
+ }
+ /* absurd transfer size? */
+ if (len > 65536) {
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: absurd > 64K item request", NULL);
+ return JIM_ERR;
+ }
+
+ if ((width == 1) ||
+ ((width == 2) && ((addr & 1) == 0)) ||
+ ((width == 4) && ((addr & 3) == 0))) {
+ /* all is well */
+ } else {
+ char buf[100];
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ sprintf(buf, "array2mem address: 0x%08x is not aligned for %d byte reads", addr, width);
+ Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
+ return JIM_ERR;
+ }
+
+ context = Jim_GetAssocData(interp, "context");
+ if (context == NULL)
+ {
+ LOG_ERROR("array2mem: no command context");
+ return JIM_ERR;
+ }
+ target = get_current_target(context);
+ if (target == NULL)
+ {
+ LOG_ERROR("array2mem: no current target");
+ return JIM_ERR;
+ }
+
+ /* Transfer loop */
+
+ /* index counter */
+ n = 0;
+ /* assume ok */
+ e = JIM_OK;
+ while (len) {
+ /* Slurp... in buffer size chunks */
+
+ count = len; /* in objects.. */
+ if (count > (sizeof(buffer)/width)) {
+ count = (sizeof(buffer)/width);
+ }
+
+ v = 0; /* shut up gcc */
+ for (i = 0 ;i < count ;i++, n++) {
+ get_int_array_element(interp, varname, n, &v);
+ switch (width) {
+ case 4:
+ target_buffer_set_u32(target, &buffer[i*width], v);
+ break;
+ case 2:
+ target_buffer_set_u16(target, &buffer[i*width], v);
+ break;
+ case 1:
+ buffer[i] = v & 0x0ff;
+ break;
+ }
+ }
+ len -= count;
+
+ retval = target->type->write_memory(target, addr, width, count, buffer);
+ if (retval != ERROR_OK) {
+ /* BOO !*/
+ LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count);
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL);
+ e = JIM_ERR;
+ len = 0;
+ }
+ }
+
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+
+ return JIM_OK;
+}