Commit c5b718f5 authored by oharboe's avatar oharboe
Browse files

- retired variable stuff.

- drscan is now a low level tcl command:
 execute DR scan <device> <num_bits> <value> <num_bits1> <value2> 
- removed obsolete partial command text support

git-svn-id: svn://svn.berlios.de/openocd/trunk@791 b42882b7-edfa-0310-969c-e2dbd0fdcd60
parent 381f9a2e
......@@ -10,7 +10,7 @@ endif
openocd_SOURCES = $(MAINFILE) openocd.c startup.c
# set the include path found by configure
INCLUDES = -I$(top_srcdir)/src/helper \
INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/helper \
-I$(top_srcdir)/src/jtag -I$(top_srcdir)/src/target -I$(top_srcdir)/src/xsvf -I$(top_srcdir)/src/server \
-I$(top_srcdir)/src/flash -I$(top_srcdir)/src/pld $(all_includes)
......
......@@ -9,7 +9,7 @@ else
CONFIGFILES = options.c
endif
libhelper_a_SOURCES = binarybuffer.c $(CONFIGFILES) configuration.c log.c interpreter.c command.c time_support.c \
libhelper_a_SOURCES = binarybuffer.c $(CONFIGFILES) configuration.c log.c command.c time_support.c \
replacements.c fileio.c
noinst_HEADERS = binarybuffer.h configuration.h types.h log.h command.h \
interpreter.h time_support.h replacements.h fileio.h
time_support.h replacements.h fileio.h
......@@ -49,52 +49,11 @@ int handle_fast_command(struct command_context_s *cmd_ctx, char *cmd, char **arg
/* forward declaration of jim_command */
extern int jim_command(command_context_t *context, char *line);
int build_unique_lengths(command_context_t *context, command_t *commands)
{
command_t *c, *p;
/* iterate through all commands */
for (c = commands; c; c = c->next)
{
/* find out how many characters are required to uniquely identify a command */
for (c->unique_len = 1; c->unique_len <= strlen(c->name); c->unique_len++)
{
int foundmatch = 0;
/* for every command, see if the current length is enough */
for (p = commands; p; p = p->next)
{
/* ignore the command itself */
if (c == p)
continue;
/* compare commands up to the current length */
if (strncmp(p->name, c->name, c->unique_len) == 0)
foundmatch++;
}
/* when none of the commands matched, we've found the minimum length required */
if (!foundmatch)
break;
}
/* if the current command has children, build the unique lengths for them */
if (c->children)
build_unique_lengths(context, c->children);
}
return ERROR_OK;
}
/* Avoid evaluating this each time we add a command. Reduces overhead from O(n^2) to O(n).
* Makes a difference on ARM7 types machines and is not observable on GHz machines.
*/
static int unique_length_dirty = 1;
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)
{
command_t *c, *p;
unique_length_dirty = 1;
if (!context || !name)
return NULL;
......@@ -110,7 +69,6 @@ command_t* register_command(command_context_t *context, command_t *parent, char
c->help = strdup(help);
else
c->help = NULL;
c->unique_len = 0;
c->next = NULL;
/* place command in tree */
......@@ -150,8 +108,6 @@ int unregister_all_commands(command_context_t *context)
{
command_t *c, *c2;
unique_length_dirty = 1;
if (context == NULL)
return ERROR_OK;
......@@ -189,8 +145,6 @@ int unregister_command(command_context_t *context, char *name)
{
command_t *c, *p = NULL, *c2;
unique_length_dirty = 1;
if ((!context) || (!name))
return ERROR_INVALID_ARGUMENTS;
......@@ -351,21 +305,11 @@ command_t *find_command(command_context_t *context, command_t *commands, char *w
{
command_t *c;
if (unique_length_dirty)
{
unique_length_dirty = 0;
/* update unique lengths */
build_unique_lengths(context, context->commands);
}
for (c = commands; c; c = c->next)
{
if (strncasecmp(c->name, words[start_word], c->unique_len))
if (strcasecmp(c->name, words[start_word]))
continue;
if (strncasecmp(c->name, words[start_word], strlen(words[start_word])))
continue;
if ((context->mode == COMMAND_CONFIG) || (c->mode == COMMAND_ANY) || (c->mode == context->mode) )
{
if (!c->children)
......@@ -533,10 +477,7 @@ int command_print_help_match(command_context_t* context, command_t* c_first, cha
{
if (argc > 0)
{
if (strncasecmp(c->name, args[0], c->unique_len))
continue;
if (strncasecmp(c->name, args[0], strlen(args[0])))
if (strcasecmp(c->name, args[0]))
continue;
if (argc > 1)
......
......@@ -60,7 +60,6 @@ typedef struct command_s
int (*handler)(struct command_context_s *context, char* name, char** args, int argc);
enum command_mode mode;
char *help;
int unique_len;
struct command_s *next;
} command_t;
......
/***************************************************************************
* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "interpreter.h"
#include "configuration.h"
#include "binarybuffer.h"
#include <stdlib.h>
#include <string.h>
var_t *variables = NULL;
int handle_var_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_field_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_script_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int interpreter_register_commands(struct command_context_s *cmd_ctx)
{
register_command(cmd_ctx, NULL, "var", handle_var_command,
COMMAND_ANY, "allocate, display or delete variable <name> [num_fields|'del'] [size1] ...");
register_command(cmd_ctx, NULL, "field", handle_field_command,
COMMAND_ANY, "display/modify variable field <var> <field> [value|'flip']");
register_command(cmd_ctx, NULL, "script", handle_script_command,
COMMAND_ANY, "execute commands from <file>");
return ERROR_OK;
}
var_t* get_var_by_num(int num)
{
int count = 0;
var_t *var = variables;
if (var)
{
if (num == count)
return var;
while (var->next)
{
var = var->next;
count++;
if (num == count)
return var;
}
}
return NULL;
}
var_t* get_var_by_name(char *name)
{
var_t *var = variables;
if (var)
{
if (strcmp(var->name, name) == 0)
return var;
while (var->next)
{
var = var->next;
if (strcmp(var->name, name) == 0)
return var;
}
}
return NULL;
}
var_t* get_var_by_namenum(char *namenum)
{
if ((namenum[0] >= '0') && (namenum[0] <= '9'))
return get_var_by_num(strtol(namenum, NULL, 0));
else
return get_var_by_name(namenum);
}
int field_le_to_host(u8 *buffer, void *priv, struct scan_field_s *dummy)
{
var_field_t *field = priv;
field->value = buf_get_u32(buffer, 0, field->num_bits);
return ERROR_OK;
}
int handle_var_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
var_t **last_var_p = &variables;
int i;
if (argc >= 2)
{
while (*last_var_p)
{
if (strcmp((*last_var_p)->name, args[0]) == 0)
{
if (strcmp(args[1], "del") == 0)
{
var_t *next = (*last_var_p)->next;
free ((*last_var_p)->fields);
free (*last_var_p);
*last_var_p = next;
command_print(cmd_ctx, "variable %s deleted", args[0]);
}
else
command_print(cmd_ctx, "variable of that name already exists");
return ERROR_OK;
}
last_var_p = &((*last_var_p)->next);
}
if ((args[0][0] >= '0') && (args[0][0] <= '9'))
{
command_print(cmd_ctx, "invalid name specified (first character may not be a number)");
return ERROR_OK;
}
*last_var_p = malloc(sizeof(var_t));
(*last_var_p)->name = strdup(args[0]);
(*last_var_p)->num_fields = argc - 1;
(*last_var_p)->next = NULL;
(*last_var_p)->fields = malloc(sizeof(var_field_t) * (*last_var_p)->num_fields);
for (i = 0; i < (*last_var_p)->num_fields; i++)
{
(*last_var_p)->fields[i].num_bits = strtol(args[1+i], NULL, 0);
(*last_var_p)->fields[i].value = 0x0;
}
return ERROR_OK;
}
if (argc == 1)
{
var_t *var = get_var_by_namenum(args[0]);
if (var)
{
int i;
command_print(cmd_ctx, "%s (%i fields):", var->name, var->num_fields);
for (i = 0; i < (var->num_fields); i++)
{
command_print(cmd_ctx, "0x%x (/%i)", var->fields[i].value, var->fields[i].num_bits);
}
}
else
{
command_print(cmd_ctx, "variable %s doesn't exist", args[0]);
}
}
if (argc == 0)
{
var_t *var = variables;
int count = 0;
while (var)
{
command_print(cmd_ctx, "%i: %s (%i fields)", count, var->name, var->num_fields);
var = var->next;
count++;
}
}
return ERROR_OK;
}
int handle_field_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
if (argc < 2)
return ERROR_COMMAND_SYNTAX_ERROR;
if (argc >= 2)
{
var_t *var = get_var_by_namenum(args[0]);
int field_num = strtol(args[1], NULL, 0);
if (!var)
{
command_print(cmd_ctx, "variable %s doesn't exist", args[0]);
return ERROR_OK;
}
if (field_num >= var->num_fields)
command_print(cmd_ctx, "variable field %i is out of bounds (max. %i)", field_num, var->num_fields - 1);
if ((var) && (field_num < var->num_fields))
{
if (argc > 2)
{
if (strcmp(args[2], "flip") == 0)
var->fields[field_num].value = flip_u32(var->fields[field_num].value, var->fields[field_num].num_bits);
else
var->fields[field_num].value = strtoul(args[2], NULL, 0);
}
command_print(cmd_ctx, "%s(%i): 0x%x (/%i)", var->name, field_num, var->fields[field_num].value, var->fields[field_num].num_bits);
}
}
return ERROR_OK;
}
int handle_script_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
FILE *script_file;
if (argc != 1)
return ERROR_COMMAND_SYNTAX_ERROR;
/* Run a tcl script file */
return command_run_linef(cmd_ctx, "source [find {%s}]", args[0]);
}
......@@ -9,7 +9,7 @@ else
FTD2XXINC =
endif
INCLUDES = -I$(top_srcdir)/src/helper $(FTD2XXINC) $(all_includes) -I$(top_srcdir)/src/target
INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/helper $(FTD2XXINC) $(all_includes) -I$(top_srcdir)/src/target
METASOURCES = AUTO
noinst_LIBRARIES = libjtag.a
......
......@@ -27,12 +27,13 @@
#include "command.h"
#include "log.h"
#include "interpreter.h"
#include "stdlib.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
......@@ -268,7 +269,7 @@ int handle_endstate_command(struct command_context_s *cmd_ctx, char *cmd, char *
int handle_jtag_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_runtest_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int handle_drscan_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
int handle_verify_ircapture_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
......@@ -1492,8 +1493,8 @@ int jtag_register_commands(struct command_context_s *cmd_ctx)
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] ...");
register_command(cmd_ctx, NULL, "drscan", handle_drscan_command,
COMMAND_EXEC, "execute DR scan <device> <var> [dev2] [var2] ...");
add_jim("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>");
......@@ -2042,63 +2043,78 @@ int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, char **a
return ERROR_OK;
}
int handle_drscan_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
/* FIX!!! this command is busted for > 32 bits */
int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args)
{
int retval;
scan_field_t *fields;
int num_fields = 0;
int num_fields;
int field_count = 0;
var_t *var;
int i, j;
if ((argc < 2) || (argc % 2))
if ((argc < 4) || ((argc % 2)!=0))
{
return ERROR_COMMAND_SYNTAX_ERROR;
return JIM_ERR;
}
for (i = 0; i < argc; i+=2)
for (i = 2; i < argc; i+=2)
{
var = get_var_by_namenum(args[i+1]);
if (var)
{
num_fields += var->num_fields;
}
else
long bits;
Jim_GetLong(interp, args[i], &bits);
if ((bits<=0)||(bits>32))
{
command_print(cmd_ctx, "variable %s doesn't exist", args[i+1]);
return ERROR_OK;
// LOG_ERROR("minimum 1/maximum 32 bit fields - patches gratefully accepted!");
return JIM_ERR;
}
}
long device;
Jim_GetLong(interp, args[1], &device);
num_fields=(argc-2)/2;
fields = malloc(sizeof(scan_field_t) * num_fields);
for (i = 0; i < argc; i+=2)
for (i = 2; i < argc; i+=2)
{
var = get_var_by_namenum(args[i+1]);
for (j = 0; j < var->num_fields; j++)
{
fields[field_count].device = strtol(args[i], NULL, 0);
fields[field_count].num_bits = var->fields[j].num_bits;
fields[field_count].out_value = malloc(CEIL(var->fields[j].num_bits, 8));
buf_set_u32(fields[field_count].out_value, 0, var->fields[j].num_bits, var->fields[j].value);
fields[field_count].out_mask = NULL;
fields[field_count].in_value = fields[field_count].out_value;
fields[field_count].in_check_mask = NULL;
fields[field_count].in_check_value = NULL;
fields[field_count].in_handler = field_le_to_host;
fields[field_count++].in_handler_priv = &(var->fields[j]);
}
long bits;
Jim_GetLong(interp, args[i], &bits);
long val;
Jim_GetLong(interp, args[i+1], &val);
fields[field_count].device = device;
fields[field_count].num_bits = bits;
fields[field_count].out_value = malloc(CEIL(bits, 8));
buf_set_u32(fields[field_count].out_value, 0, bits, val);
fields[field_count].out_mask = NULL;
fields[field_count].in_value = fields[field_count].out_value;
fields[field_count].in_check_mask = NULL;
fields[field_count].in_check_value = NULL;
fields[field_count].in_handler = NULL;
fields[field_count++].in_handler_priv = NULL;
}
jtag_add_dr_scan(num_fields, fields, -1);
jtag_execute_queue();
retval=jtag_execute_queue();
for (i = 0; i < argc / 2; i++)
free(fields[i].out_value);
field_count=0;
Jim_Obj *list=Jim_NewListObj(interp, NULL, 0);
for (i = 2; i < argc; i+=2)
{
long bits;
Jim_GetLong(interp, args[i], &bits);
u32 val = buf_get_u32(fields[field_count].in_value, 0, bits);
Jim_ListAppendElement(interp, list, Jim_NewIntObj(interp, val));
free(fields[field_count].out_value);
field_count++;
}
Jim_SetResult(interp, list);
free(fields);
return ERROR_OK;
return retval?JIM_OK:JIM_ERR;
}
int handle_verify_ircapture_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
......
......@@ -28,7 +28,6 @@
#include "types.h"
#include "jtag.h"
#include "configuration.h"
#include "interpreter.h"
#include "xsvf.h"
#include "target.h"
#include "flash.h"
......@@ -66,33 +65,6 @@
#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)
......@@ -722,6 +694,13 @@ static char* openocd_jim_fgets(char *s, int size, void *cookie)
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!!! add scheme to accumulate help! */
}
void initJim(void)
{
Jim_CreateCommand(interp, "openocd", Jim_Command_openocd, NULL, NULL);
......@@ -755,6 +734,19 @@ void initJim2(void)
}
}
int handle_script_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
FILE *script_file;
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;
......@@ -773,7 +765,7 @@ command_context_t *setup_command_handler(void)
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);