#include "types.h"
#include "jtag.h"
#include "configuration.h"
-#include "interpreter.h"
#include "xsvf.h"
#include "target.h"
#include "flash.h"
#include "replacements.h"
-int launchTarget(struct command_context_s *cmd_ctx)
-{
- int retval;
- /* Try to examine & validate jtag chain, though this may require a reset first
- * in which case we continue setup */
- jtag_init(cmd_ctx);
-
- /* try to examine target at this point. If it fails, perhaps a reset will
- * bring it up later on via a telnet/gdb session */
- target_examine(cmd_ctx);
-
- retval=flash_init_drivers(cmd_ctx);
- if (retval!=ERROR_OK)
- return retval;
- LOG_DEBUG("flash init complete");
-
- retval=nand_init(cmd_ctx);
- if (retval!=ERROR_OK)
- return retval;
- LOG_DEBUG("NAND init complete");
-
- retval=pld_init(cmd_ctx);
- if (retval!=ERROR_OK)
- return retval;
- LOG_DEBUG("pld init complete");
- return retval;
-}
/* Give TELNET a way to find out what version this is */
int handle_version_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
int result;
namebuf = alloc_printf("%s(%d)", varname, idx);
+ if (!namebuf)
+ return JIM_ERR;
nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
valObjPtr = Jim_NewIntObj(interp, val);
+ if (!nameObjPtr || !valObjPtr)
+ {
+ free(namebuf);
+ return JIM_ERR;
+ }
+
Jim_IncrRefCount(nameObjPtr);
Jim_IncrRefCount(valObjPtr);
result = Jim_SetVariable(interp, nameObjPtr, valObjPtr);
Jim_DecrRefCount(interp, nameObjPtr);
Jim_DecrRefCount(interp, valObjPtr);
free(namebuf);
- /* printf( "%s = 0%08x\n", namebuf, val ); */
+ /* printf("%s(%d) <= 0%08x\n", varname, idx, val); */
return result;
}
/* argv[1] = name of array to receive the data
* argv[2] = desired width
* argv[3] = memory address
- * argv[4] = length in bytes to read
+ * argv[4] = count of times to read
*/
if (argc != 5) {
Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
}
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);
return JIM_OK;
}
+static int get_int_array_element(Jim_Interp * interp, const char *varname, int idx, u32 *val)
+{
+ char *namebuf;
+ Jim_Obj *nameObjPtr, *valObjPtr;
+ int result;
+ long l;
+
+ namebuf = alloc_printf("%s(%d)", varname, idx);
+ if (!namebuf)
+ return JIM_ERR;
+
+ nameObjPtr = Jim_NewStringObj(interp, namebuf, -1);
+ if (!nameObjPtr)
+ {
+ free(namebuf);
+ return JIM_ERR;
+ }
+
+ Jim_IncrRefCount(nameObjPtr);
+ valObjPtr = Jim_GetVariable(interp, nameObjPtr, JIM_ERRMSG);
+ Jim_DecrRefCount(interp, nameObjPtr);
+ free(namebuf);
+ if (valObjPtr == NULL)
+ return JIM_ERR;
+
+ result = Jim_GetLong(interp, valObjPtr, &l);
+ /* printf("%s(%d) => 0%08x\n", varname, idx, val); */
+ *val = l;
+ return result;
+}
+
+static int Jim_Command_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ target_t *target;
+ long l;
+ u32 width;
+ u32 len;
+ u32 addr;
+ u32 count;
+ u32 v;
+ const char *varname;
+ u8 buffer[4096];
+ int i, n, e, retval;
+
+ /* argv[1] = name of array to get the data
+ * argv[2] = desired width
+ * argv[3] = memory address
+ * argv[4] = count to write
+ */
+ if (argc != 5) {
+ Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
+ return JIM_ERR;
+ }
+ varname = Jim_GetString(argv[1], &len);
+ /* given "foo" get space for worse case "foo(%d)" .. add 20 */
+
+ e = Jim_GetLong(interp, argv[2], &l);
+ width = l;
+ if (e != JIM_OK) {
+ return e;
+ }
+
+ e = Jim_GetLong(interp, argv[3], &l);
+ addr = l;
+ if (e != JIM_OK) {
+ return e;
+ }
+ e = Jim_GetLong(interp, argv[4], &l);
+ len = l;
+ if (e != JIM_OK) {
+ return e;
+ }
+ switch (width) {
+ case 8:
+ width = 1;
+ break;
+ case 16:
+ width = 2;
+ break;
+ case 32:
+ width = 4;
+ break;
+ default:
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings( interp, Jim_GetResult(interp), "Invalid width param, must be 8/16/32", NULL );
+ return JIM_ERR;
+ }
+ if (len == 0) {
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: zero width read?", NULL);
+ return JIM_ERR;
+ }
+ if ((addr + (len * width)) < addr) {
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: addr + len - wraps to zero?", NULL);
+ return JIM_ERR;
+ }
+ /* absurd transfer size? */
+ if (len > 65536) {
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp), "array2mem: absurd > 64K item request", NULL);
+ return JIM_ERR;
+ }
+
+ if ((width == 1) ||
+ ((width == 2) && ((addr & 1) == 0)) ||
+ ((width == 4) && ((addr & 3) == 0))) {
+ /* all is well */
+ } else {
+ char buf[100];
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ sprintf(buf, "array2mem address: 0x%08x is not aligned for %d byte reads", addr, width);
+ Jim_AppendStrings(interp, Jim_GetResult(interp), buf , NULL);
+ return JIM_ERR;
+ }
+
+ target = get_current_target(active_cmd_ctx);
+
+ /* Transfer loop */
+
+ /* index counter */
+ n = 0;
+ /* assume ok */
+ e = JIM_OK;
+ while (len) {
+ /* Slurp... in buffer size chunks */
+
+ count = len; /* in objects.. */
+ if (count > (sizeof(buffer)/width)) {
+ count = (sizeof(buffer)/width);
+ }
+
+ v = 0; /* shut up gcc */
+ for (i = 0 ;i < count ;i++, n++) {
+ get_int_array_element(interp, varname, n, &v);
+ switch (width) {
+ case 4:
+ target_buffer_set_u32(target, &buffer[i*width], v);
+ break;
+ case 2:
+ target_buffer_set_u16(target, &buffer[i*width], v);
+ break;
+ case 1:
+ buffer[i] = v & 0x0ff;
+ break;
+ }
+ }
+ len -= count;
+
+ retval = target->type->write_memory(target, addr, width, count, buffer);
+ if (retval != ERROR_OK) {
+ /* BOO !*/
+ LOG_ERROR("array2mem: Write @ 0x%08x, w=%d, cnt=%d, failed", addr, width, count);
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+ Jim_AppendStrings(interp, Jim_GetResult(interp), "mem2array: cannot read memory", NULL);
+ e = JIM_ERR;
+ len = 0;
+ }
+ }
+
+ Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
+
+ return JIM_OK;
+}
+
static void tcl_output(void *privData, const char *file, int line, const char *function, const char *string)
{
Jim_Obj *tclOutput=(Jim_Obj *)privData;
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);
+ 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 char binary_startup_tcl_start;
+extern char binary_startup_tcl_size;
+
void initJim(void)
{
+ char *script;
+ int script_len;
+
Jim_CreateCommand(interp, "openocd", Jim_Command_openocd, NULL, NULL);
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 );
-
+ Jim_CreateCommand(interp, "array2mem", Jim_Command_array2mem, NULL, NULL );
+
/* Set Jim's STDIO */
interp->cookie_stdin = NULL;
interp->cookie_stdout = NULL;
interp->cb_vfprintf = openocd_jim_vfprintf;
interp->cb_fflush = openocd_jim_fflush;
interp->cb_fgets = openocd_jim_fgets;
+
+ add_default_dirs();
+
+ script_len = (int)&binary_startup_tcl_size;
+ script = malloc(script_len + sizeof(char));
+ memcpy(script, &binary_startup_tcl_start, script_len);
+
+ /* null terminate */
+ script[script_len] = 0;
+
+ if (Jim_Eval(interp, script)==JIM_ERR)
+ {
+ LOG_ERROR("Failed to run startup.tcl (embedded into OpenOCD compile time)");
+ Jim_PrintErrorMessage(interp);
+ exit(-1);
+ }
+
+ free(script);
}
-/* after command line parsing */
-void initJim2(void)
+int handle_script_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
- Jim_Eval(interp, "source [find tcl/commands.tcl]");
+ if (argc != 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ /* Run a tcl script file */
+ return command_run_linef(cmd_ctx, "source [find {%s}]", args[0]);
}
command_context_t *setup_command_handler(void)
command_context_t *cmd_ctx;
cmd_ctx = command_init();
-
+
register_command(cmd_ctx, NULL, "version", handle_version_command,
COMMAND_EXEC, "show OpenOCD version");
register_command(cmd_ctx, NULL, "daemon_startup", handle_daemon_startup_command, COMMAND_CONFIG,
tcl_register_commands(cmd_ctx); /* tcl server commands */
log_register_commands(cmd_ctx);
jtag_register_commands(cmd_ctx);
- interpreter_register_commands(cmd_ctx);
+ register_command(cmd_ctx, NULL, "script", handle_script_command, COMMAND_ANY, "execute commands from <file>");
xsvf_register_commands(cmd_ctx);
target_register_commands(cmd_ctx);
flash_register_commands(cmd_ctx);
active_cmd_ctx=cfg_cmd_ctx;
+
if (parse_cmdline_args(cfg_cmd_ctx, argc, argv) != ERROR_OK)
return EXIT_FAILURE;
-
- initJim2();
-
+
if (parse_config_file(cfg_cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;