[Openocd-development] [PATCH] Skip halt check in cortex_a8_mmu

2010-09-24 Thread Zachary T Welch
Without this patch, omap3_dbginit's attempt to set DBGEN will fail
when the CPU is running, and the debugger cannot halt the CPU without
that bit set.  This patch does not need to be committed as-is; rather,
I want to know: how is it that no one else reported this issue?
What negative consequences can result from removing this check?

---
 src/target/cortex_a8.c |5 -
 1 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/src/target/cortex_a8.c b/src/target/cortex_a8.c
index 8b4ced5..9e09ddb 100644
--- a/src/target/cortex_a8.c
+++ b/src/target/cortex_a8.c
@@ -2014,11 +2014,6 @@ static int cortex_a8_enable_mmu_caches(struct target 
*target, int mmu,
 
 static int cortex_a8_mmu(struct target *target, int *enabled)
 {
-   if (target->state != TARGET_HALTED) {
-   LOG_ERROR("%s: target not halted", __func__);
-   return ERROR_TARGET_INVALID;
-   }
-
*enabled = 
target_to_cortex_a8(target)->armv7a_common.armv4_5_mmu.mmu_enabled;
return ERROR_OK;
 }
-- 
1.7.2.2

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH] fix bitq driver to compile with -Wshadow

2010-07-19 Thread Zachary T Welch
* Rename 'pause' variable to 'enter_pause'
* Change its type from 'int' to 'bool' to reflect usage.

Signed-off-by: Zachary T Welch 
---
 src/jtag/drivers/bitq.c |   12 ++--
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/jtag/drivers/bitq.c b/src/jtag/drivers/bitq.c
index a58f633..a0f3bf8 100644
--- a/src/jtag/drivers/bitq.c
+++ b/src/jtag/drivers/bitq.c
@@ -221,7 +221,7 @@ void bitq_runtest(int num_cycles)
 }
 
 
-void bitq_scan_field(struct scan_field* field, int pause)
+void bitq_scan_field(struct scan_field* field, bool enter_pause)
 {
int bit_cnt;
int tdo_req;
@@ -240,7 +240,7 @@ void bitq_scan_field(struct scan_field* field, int pause)
for (bit_cnt = field->num_bits; bit_cnt > 1; bit_cnt--)
bitq_io(0, 0, tdo_req);
 
-   bitq_io(pause, 0, tdo_req);
+   bitq_io(enter_pause, 0, tdo_req);
}
else
{
@@ -259,10 +259,10 @@ void bitq_scan_field(struct scan_field* field, int pause)
out_mask <<= 1;
}
 
-   bitq_io(pause, ((*out_ptr) & out_mask) != 0, tdo_req);
+   bitq_io(enter_pause, ((*out_ptr) & out_mask) != 0, tdo_req);
}
 
-   if (pause)
+   if (enter_pause)
{
bitq_io(0, 0, 0);
if (tap_get_state() == TAP_IRSHIFT)
@@ -283,9 +283,9 @@ void bitq_scan(struct scan_command* cmd)
bitq_state_move(TAP_DRSHIFT);
 
for (i = 0; i < cmd->num_fields - 1; i++)
-   bitq_scan_field(&cmd->fields[i], 0);
+   bitq_scan_field(&cmd->fields[i], false);
 
-   bitq_scan_field(&cmd->fields[i], 1);
+   bitq_scan_field(&cmd->fields[i], true);
 }
 
 
-- 
1.7.1

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 3/4] add flash/nor/{tcl.c, imp.h} from flash/flash.c

2009-12-03 Thread Zachary T Welch
Moves the top-level 'flash' command handlers into flash/nor/tcl.c,
with flash/nor/imp.h providing an internal implementation header
to share non-public API components.

Signed-off-by: Zachary T Welch 
---
 src/flash/flash.c |  175 --
 src/flash/nor/Makefile.am |5 +
 src/flash/nor/imp.h   |   27 ++
 src/flash/nor/tcl.c   |  203 +
 4 files changed, 235 insertions(+), 175 deletions(-)
 create mode 100644 src/flash/nor/imp.h
 create mode 100644 src/flash/nor/tcl.c

diff --git a/src/flash/flash.c b/src/flash/flash.c
index d16949d..b21838c 100644
--- a/src/flash/flash.c
+++ b/src/flash/flash.c
@@ -120,39 +120,6 @@ int flash_driver_protect(struct flash_bank *bank, int set, 
int first, int last)
return retval;
 }
 
-static int jim_flash_banks(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
-   struct flash_bank *p;
-
-   if (argc != 1) {
-   Jim_WrongNumArgs(interp, 1, argv, "no arguments to flash_banks 
command");
-   return JIM_ERR;
-   }
-
-   Jim_Obj *list = Jim_NewListObj(interp, NULL, 0);
-   for (p = flash_banks; p; p = p->next)
-   {
-   Jim_Obj *elem = Jim_NewListObj(interp, NULL, 0);
-
-   Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, 
"name", -1));
-   Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, 
p->driver->name, -1));
-   Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, 
"base", -1));
-   Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, 
p->base));
-   Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, 
"size", -1));
-   Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, 
p->size));
-   Jim_ListAppendElement(interp, elem, Jim_NewStringObj(interp, 
"bus_width", -1));
-   Jim_ListAppendElement(interp, elem, Jim_NewIntObj(interp, 
p->bus_width));
-   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_SetResult(interp, list);
-
-   return JIM_OK;
-}
-
 struct flash_bank *get_flash_bank_by_num_noprobe(int num)
 {
struct flash_bank *p;
@@ -238,92 +205,6 @@ COMMAND_HELPER(flash_command_get_bank, unsigned name_index,
 }
 
 
-COMMAND_HANDLER(handle_flash_bank_command)
-{
-   if (CMD_ARGC < 7)
-   {
-   LOG_ERROR("usage: flash bank   "
-   "   ");
-   return ERROR_COMMAND_SYNTAX_ERROR;
-   }
-   // save bank name and advance arguments for compatibility
-   const char *bank_name = *CMD_ARGV++;
-   CMD_ARGC--;
-
-   struct target *target;
-   if ((target = get_target(CMD_ARGV[5])) == NULL)
-   {
-   LOG_ERROR("target '%s' not defined", CMD_ARGV[5]);
-   return ERROR_FAIL;
-   }
-
-   const char *driver_name = CMD_ARGV[0];
-   for (unsigned i = 0; flash_drivers[i]; i++)
-   {
-   if (strcmp(driver_name, flash_drivers[i]->name) != 0)
-   continue;
-
-   /* register flash specific commands */
-   if (NULL != flash_drivers[i]->commands)
-   {
-   int retval = register_commands(CMD_CTX, NULL,
-   flash_drivers[i]->commands);
-   if (ERROR_OK != retval)
-   {
-   LOG_ERROR("couldn't register '%s' commands",
-   driver_name);
-   return ERROR_FAIL;
-   }
-   }
-
-   struct flash_bank *p, *c;
-   c = malloc(sizeof(struct flash_bank));
-   c->name = strdup(bank_name);
-   c->target = target;
-   c->driver = flash_drivers[i];
-   c->driver_priv = NULL;
-   COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], c->base);
-   COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], c->size);
-   COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], c->chip_width);
-   COMMAND_PARSE_NUMBER(int, CMD_ARGV[4], c->bus_width);
-   c->num_sectors = 0;
-   c->sectors = NULL;
-   c->next = NULL;
-
-   int retval;
-   retval = 
CALL_COMMAND_HANDLER(flash_drivers[i]->flash_bank_command, c);
-   if (ERROR_OK != retval)
-   {
-   LOG_ERROR("'%s' driver rejected fla

[Openocd-development] [PATCH 0/4] split nor flash core/tcl

2009-12-03 Thread Zachary T Welch
Hi all,

The first two patches work to eliminate some Jim handling in the
helper and JTAG modules, with the later being nearly purged.
If the command layer provides some wrappers for Jim's return
handling mechanisms, then all handlers can be converted to use the
high-level command mechanisms -- and Jim can be isolated therein.
It's simple refactoring, but are there objections to doing this?

The last two patches begin to split the NOR flash layer into
public and private APIS (, respectively)
and into core and TCL modules (flash/nor/{core,tcl}.c, likewise).

More patches will be required to finish this job, and these changes
will be both disruptive and boring.  The result will be much better
separation of mechanism and policy in this area of the tree, then
I will move on to the next module deseriving such treatment.

Cheers,

Zach

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 2/4] separate Jim from jtag/core.c

2009-12-03 Thread Zachary T Welch
After previous efforts, only one Jim routine remained in jtag/core.c,
and moving it to jtag/tcl.c painlessly finishes separating these layers.
The headers need separating, but the implementation is clean.

Signed-off-by: Zachary T Welch 
---
 src/jtag/core.c |   11 ---
 src/jtag/tcl.c  |   11 +++
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/src/jtag/core.c b/src/jtag/core.c
index 9230cc2..433b50b 100644
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -244,17 +244,6 @@ struct jtag_tap *jtag_tap_by_string(const char *s)
return t;
 }
 
-struct jtag_tap *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)
-{
-   const char *cp = Jim_GetString(o, NULL);
-   struct jtag_tap *t = cp ? jtag_tap_by_string(cp) : NULL;
-   if (NULL == cp)
-   cp = "(unknown)";
-   if (NULL == t)
-   Jim_SetResult_sprintf(interp, "Tap '%s' could not be found", 
cp);
-   return t;
-}
-
 struct jtag_tap* jtag_tap_next_enabled(struct jtag_tap* p)
 {
p = p ? p->next_tap : jtag_all_taps();
diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index cc89080..a4c7053 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -51,6 +51,17 @@ static const Jim_Nvp nvp_jtag_tap_event[] = {
 
 extern struct jtag_interface *jtag_interface;
 
+struct jtag_tap *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)
+{
+   const char *cp = Jim_GetString(o, NULL);
+   struct jtag_tap *t = cp ? jtag_tap_by_string(cp) : NULL;
+   if (NULL == cp)
+   cp = "(unknown)";
+   if (NULL == t)
+   Jim_SetResult_sprintf(interp, "Tap '%s' could not be found", 
cp);
+   return t;
+}
+
 static bool scan_is_safe(tap_state_t state)
 {
switch (state)
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 4/4] add flash/nor/core.[ch]

2009-12-03 Thread Zachary T Welch
The newly moved flash TCL routines access the internals of the module
too much.  Fix the layering issues by adding new core NOR flash APIs:

:
  - flash_driver_find_by_name() - self-descriptive

:
  - flash_bank_add()- encapsulates adding banks to bank list
  - flash_bank_list()   - encapsulates retreiving bank list

This allows the externs in flash/nor/imp.h to be removed, and
these mechanisms may now be re-used by other flash module code.

Signed-off-by: Zachary T Welch 
---
 src/flash/nor/Makefile.am |1 +
 src/flash/nor/core.c  |   65 +
 src/flash/nor/core.h  |   31 +
 src/flash/nor/imp.h   |   15 --
 src/flash/nor/tcl.c   |   45 +--
 5 files changed, 122 insertions(+), 35 deletions(-)
 create mode 100644 src/flash/nor/core.c
 create mode 100644 src/flash/nor/core.h

diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am
index ed9ebb3..499ebfa 100644
--- a/src/flash/nor/Makefile.am
+++ b/src/flash/nor/Makefile.am
@@ -2,6 +2,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/src
 
 noinst_LTLIBRARIES = libocdflashnor.la
 libocdflashnor_la_SOURCES = \
+   core.c \
tcl.c \
$(NOR_DRIVERS)
 
diff --git a/src/flash/nor/core.c b/src/flash/nor/core.c
new file mode 100644
index 000..a69c3f4
--- /dev/null
+++ b/src/flash/nor/core.c
@@ -0,0 +1,65 @@
+/***
+ *   Copyright (C) 2009 Zachary T Welch  *
+ * *
+ *   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 
+#endif
+#include 
+#include 
+
+// in flash.c, to be moved here
+extern struct flash_driver *flash_drivers[];
+extern struct flash_bank *flash_banks;
+
+struct flash_driver *flash_driver_find_by_name(const char *name)
+{
+   for (unsigned i = 0; flash_drivers[i]; i++)
+   {
+   if (strcmp(name, flash_drivers[i]->name) == 0)
+   return flash_drivers[i];
+   }
+   return NULL;
+}
+
+void flash_bank_add(struct flash_bank *bank)
+{
+   /* put flash bank in linked list */
+   unsigned bank_num = 0;
+   if (flash_banks)
+   {
+   /* find last flash bank */
+   struct flash_bank *p = flash_banks;
+   while (NULL != p->next)
+   {
+   bank_num += 1;
+   p = p->next;
+   }
+   p->next = bank;
+   bank_num += 1;
+   }
+   else
+   flash_banks = bank;
+
+   bank->bank_number = bank_num;
+}
+
+struct flash_bank *flash_bank_list(void)
+{
+   return flash_banks;
+}
diff --git a/src/flash/nor/core.h b/src/flash/nor/core.h
new file mode 100644
index 000..0c6a804
--- /dev/null
+++ b/src/flash/nor/core.h
@@ -0,0 +1,31 @@
+/***
+ *   Copyright (C) 2009 Zachary T Welch  *
+ * *
+ *   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 f

[Openocd-development] [PATCH 1/4] switch 'rm' command away from using Jim

2009-12-03 Thread Zachary T Welch
Commands that do not need to use Jim should be registered as
high-level command handlers.

Signed-off-by: Zachary T Welch 
---
 src/helper/ioutil.c |   29 +++--
 1 files changed, 11 insertions(+), 18 deletions(-)

diff --git a/src/helper/ioutil.c b/src/helper/ioutil.c
index ed82ba1..27bffad 100644
--- a/src/helper/ioutil.c
+++ b/src/helper/ioutil.c
@@ -401,25 +401,18 @@ void copydir(char *name, char *destdir)
 
 
 
-static int
-zylinjtag_Jim_Command_rm(Jim_Interp *interp,
-   int argc,
-   Jim_Obj * const *argv)
+COMMAND_HANDLER(handle_rm_command)
 {
-   int del;
-   if (argc != 2)
-   {
-   Jim_WrongNumArgs(interp, 1, argv, "rm ?dirorfile?");
-   return JIM_ERR;
-   }
+   if (CMD_ARGC != 1)
+   return ERROR_INVALID_ARGUMENTS;
 
-   del = 0;
-   if (unlink(Jim_GetString(argv[1], NULL)) == 0)
-   del = 1;
-   if (rmdir(Jim_GetString(argv[1], NULL)) == 0)
-   del = 1;
+   bool del = false;
+   if (rmdir(CMD_ARGV[0]) == 0)
+   del = true;
+   else if (unlink(CMD_ARGV[0]) == 0)
+   del = true;
 
-   return del ? JIM_OK : JIM_ERR;
+   return del ? ERROR_OK : ERROR_FAIL;
 }
 
 
@@ -658,14 +651,14 @@ static const struct command_registration 
ioutil_command_handlers[] = {
.mode = COMMAND_ANY,
.help = "display available ram memory",
},
-   // jim handlers
{
.name = "rm",
.mode = COMMAND_ANY,
-   .jim_handler = &zylinjtag_Jim_Command_rm,
+   .handler = &handle_rm_command,
.help = "remove a file",
.usage = "",
},
+   // jim handlers
{
.name = "peek",
.mode = COMMAND_ANY,
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 1/4] move nand drivers to src/flash/nand/

2009-12-02 Thread Zachary T Welch
Moves NAND drivers to src/flash/nand/.
Adds src/flash/nand/Makefile.am.
Builds libocdflashnand.la.

Signed-off-by: Zachary T Welch 
---
 configure.in   |1 +
 src/flash/Makefile.am  |   26 +--
 src/flash/nand/Makefile.am |   27 
 src/flash/{davinci_nand.c => nand/davinci.c}   |0
 .../{lpc3180_nand_controller.c => nand/lpc3180.c}  |2 +-
 .../{lpc3180_nand_controller.h => nand/lpc3180.h}  |0
 src/flash/{mx3_nand.c => nand/mx3.c}   |2 +-
 src/flash/{mx3_nand.h => nand/mx3.h}   |0
 src/flash/{nonce_nand.c => nand/nonce.c}   |0
 src/flash/{orion_nand.c => nand/orion.c}   |0
 src/flash/{s3c2410_nand.c => nand/s3c2410.c}   |2 +-
 src/flash/{s3c2412_nand.c => nand/s3c2412.c}   |2 +-
 src/flash/{s3c2440_nand.c => nand/s3c2440.c}   |2 +-
 src/flash/{s3c2443_nand.c => nand/s3c2443.c}   |2 +-
 src/flash/{s3c24xx_nand.c => nand/s3c24xx.c}   |2 +-
 src/flash/{s3c24xx_nand.h => nand/s3c24xx.h}   |2 +-
 .../{s3c24xx_regs_nand.h => nand/s3c24xx_regs.h}   |0
 17 files changed, 43 insertions(+), 27 deletions(-)
 create mode 100644 src/flash/nand/Makefile.am
 rename src/flash/{davinci_nand.c => nand/davinci.c} (100%)
 rename src/flash/{lpc3180_nand_controller.c => nand/lpc3180.c} (99%)
 rename src/flash/{lpc3180_nand_controller.h => nand/lpc3180.h} (100%)
 rename src/flash/{mx3_nand.c => nand/mx3.c} (99%)
 rename src/flash/{mx3_nand.h => nand/mx3.h} (100%)
 rename src/flash/{nonce_nand.c => nand/nonce.c} (100%)
 rename src/flash/{orion_nand.c => nand/orion.c} (100%)
 rename src/flash/{s3c2410_nand.c => nand/s3c2410.c} (99%)
 rename src/flash/{s3c2412_nand.c => nand/s3c2412.c} (99%)
 rename src/flash/{s3c2440_nand.c => nand/s3c2440.c} (99%)
 rename src/flash/{s3c2443_nand.c => nand/s3c2443.c} (99%)
 rename src/flash/{s3c24xx_nand.c => nand/s3c24xx.c} (99%)
 rename src/flash/{s3c24xx_nand.h => nand/s3c24xx.h} (99%)
 rename src/flash/{s3c24xx_regs_nand.h => nand/s3c24xx_regs.h} (100%)

diff --git a/configure.in b/configure.in
index 9cb2b0f..0b304b5 100644
--- a/configure.in
+++ b/configure.in
@@ -1121,6 +1121,7 @@ AC_OUTPUT(dnl
 src/target/Makefile dnl
 src/server/Makefile dnl
 src/flash/Makefile dnl
+src/flash/nand/Makefile dnl
 src/pld/Makefile dnl
 doc/Makefile dnl
   )
diff --git a/src/flash/Makefile.am b/src/flash/Makefile.am
index 94cc86e..353fcf1 100644
--- a/src/flash/Makefile.am
+++ b/src/flash/Makefile.am
@@ -1,3 +1,6 @@
+SUBDIRS = \
+   nand
+
 AM_CPPFLAGS = \
-I$(top_srcdir)/src/helper \
-I$(top_srcdir)/src/jtag \
@@ -10,6 +13,9 @@ libflash_la_SOURCES = \
$(NAND_SRCS) \
mflash.c
 
+libflash_la_LIBADD = \
+   $(top_builddir)/src/flash/nand/libocdflashnand.la
+
 FLASH_SRCS = \
common.c \
cfi.c \
@@ -40,22 +46,8 @@ NAND_SRCS = \
arm_nandio.c \
nand_ecc.c \
nand_ecc_kw.c \
-   $(NAND_DEVICES_SRCS) \
nand.c
 
-NAND_DEVICES_SRCS = \
-   nonce_nand.c \
-   davinci_nand.c \
-   lpc3180_nand_controller.c \
-   mx3_nand.c \
-   orion_nand.c \
-   s3c24xx_nand.c \
-   s3c2410_nand.c \
-   s3c2412_nand.c \
-   s3c2440_nand.c \
-   s3c2443_nand.c
-
-
 noinst_HEADERS = \
arm_nandio.h \
at91sam7.h \
@@ -66,9 +58,7 @@ noinst_HEADERS = \
flash.h \
lpc2000.h \
lpc288x.h \
-   lpc3180_nand_controller.h \
mflash.h \
-   mx3_nand.h \
non_cfi.h \
nand.h \
ocl.h \
@@ -78,9 +68,7 @@ noinst_HEADERS = \
str7x.h \
str9x.h \
str9xpec.h \
-   tms470.h \
-   s3c24xx_nand.h \
-   s3c24xx_regs_nand.h
+   tms470.h
 
 EXTRA_DIST = startup.tcl
 
diff --git a/src/flash/nand/Makefile.am b/src/flash/nand/Makefile.am
new file mode 100644
index 000..e95717e
--- /dev/null
+++ b/src/flash/nand/Makefile.am
@@ -0,0 +1,27 @@
+AM_CPPFLAGS = \
+   -I$(top_srcdir)/src/flash \
+   -I$(top_srcdir)/src/helper \
+   -I$(top_srcdir)/src/jtag \
+   -I$(top_srcdir)/src/target
+
+noinst_LTLIBRARIES = libocdflashnand.la
+
+libocdflashnand_la_SOURCES = \
+   nonce.c \
+   davinci.c \
+   lpc3180.c \
+   mx3.c \
+   orion.c \
+   s3c24xx.c \
+   s3c2410.c \
+   s3c2412.c \
+   s3c2440.c \
+   s3c2443.c
+
+noinst_HEADERS = \
+   lpc3180.h \
+   mx3.h \
+   s3c24xx.h \
+   s3c24xx_regs.h
+
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
diff --git a/src/flash/davinci_nand.c b/src/flash/nand/davinci.c
similarity index 100%
rename from src/flash/davinci_nand.c
rename to src/flash/nand/davinci.c
diff --git a/src/flash/lpc3180_nand_controller.c b/src/flash/nand/lpc3180.c
similarity index 99%
rename from 

[Openocd-development] [PATCH 3/4] move jtag drivers to src/jtag/drivers

2009-12-02 Thread Zachary T Welch
Moves JTAG interface drivers to src/jtag/drivers/,
Adds src/jtag/drivers/Makefile.am.
Builds libocdjtagdrivers.la.

Flattens the rlink driver files into the drivers/ directory, adding
the 'rlink_' prefix or '.rlink' suffix as appropriate.

Signed-off-by: Zachary T Welch 
---
 configure.in   |1 +
 src/jtag/Makefile.am   |   68 ++
 src/jtag/drivers/Makefile.am   |   74 
 .../{rlink/Makefile => drivers/Makefile.rlink} |0
 src/jtag/{ => drivers}/amt_jtagaccel.c |0
 src/jtag/{ => drivers}/arm-jtag-ew.c   |0
 src/jtag/{ => drivers}/at91rm9200.c|0
 src/jtag/{ => drivers}/bitbang.c   |0
 src/jtag/{ => drivers}/bitbang.h   |0
 src/jtag/{ => drivers}/bitq.c  |0
 src/jtag/{ => drivers}/bitq.h  |0
 src/jtag/{ => drivers}/driver.c|0
 src/jtag/{ => drivers}/dummy.c |0
 src/jtag/{ => drivers}/ep93xx.c|0
 src/jtag/{ => drivers}/ft2232.c|0
 src/jtag/{ => drivers}/gw16012.c   |0
 src/jtag/{ => drivers}/jlink.c |0
 src/jtag/{ => drivers}/parport.c   |0
 src/jtag/{ => drivers}/presto.c|0
 src/jtag/{rlink => drivers}/rlink.c|6 +-
 src/jtag/{rlink => drivers}/rlink.h|0
 src/jtag/{rlink/call.m4 => drivers/rlink_call.m4}  |0
 .../{rlink/dtc_cmd.h => drivers/rlink_dtc_cmd.h}   |0
 .../{rlink/ep1_cmd.h => drivers/rlink_ep1_cmd.h}   |0
 src/jtag/{rlink/init.m4 => drivers/rlink_init.m4}  |0
 src/jtag/{rlink => drivers}/rlink_speed_table.c|2 +-
 src/jtag/{rlink/st7.h => drivers/rlink_st7.h}  |0
 src/jtag/{ => drivers}/usb_common.c|0
 src/jtag/{ => drivers}/usb_common.h|0
 src/jtag/{ => drivers}/usbprog.c   |0
 src/jtag/{ => drivers}/vsllink.c   |0
 31 files changed, 86 insertions(+), 65 deletions(-)
 create mode 100644 src/jtag/drivers/Makefile.am
 rename src/jtag/{rlink/Makefile => drivers/Makefile.rlink} (100%)
 rename src/jtag/{ => drivers}/amt_jtagaccel.c (100%)
 rename src/jtag/{ => drivers}/arm-jtag-ew.c (100%)
 rename src/jtag/{ => drivers}/at91rm9200.c (100%)
 rename src/jtag/{ => drivers}/bitbang.c (100%)
 rename src/jtag/{ => drivers}/bitbang.h (100%)
 rename src/jtag/{ => drivers}/bitq.c (100%)
 rename src/jtag/{ => drivers}/bitq.h (100%)
 rename src/jtag/{ => drivers}/driver.c (100%)
 rename src/jtag/{ => drivers}/dummy.c (100%)
 rename src/jtag/{ => drivers}/ep93xx.c (100%)
 rename src/jtag/{ => drivers}/ft2232.c (100%)
 rename src/jtag/{ => drivers}/gw16012.c (100%)
 rename src/jtag/{ => drivers}/jlink.c (100%)
 rename src/jtag/{ => drivers}/parport.c (100%)
 rename src/jtag/{ => drivers}/presto.c (100%)
 rename src/jtag/{rlink => drivers}/rlink.c (99%)
 rename src/jtag/{rlink => drivers}/rlink.h (100%)
 rename src/jtag/{rlink/call.m4 => drivers/rlink_call.m4} (100%)
 rename src/jtag/{rlink/dtc_cmd.h => drivers/rlink_dtc_cmd.h} (100%)
 rename src/jtag/{rlink/ep1_cmd.h => drivers/rlink_ep1_cmd.h} (100%)
 rename src/jtag/{rlink/init.m4 => drivers/rlink_init.m4} (100%)
 rename src/jtag/{rlink => drivers}/rlink_speed_table.c (99%)
 rename src/jtag/{rlink/st7.h => drivers/rlink_st7.h} (100%)
 rename src/jtag/{ => drivers}/usb_common.c (100%)
 rename src/jtag/{ => drivers}/usb_common.h (100%)
 rename src/jtag/{ => drivers}/usbprog.c (100%)
 rename src/jtag/{ => drivers}/vsllink.c (100%)

diff --git a/configure.in b/configure.in
index 6ca648d..661cdeb 100644
--- a/configure.in
+++ b/configure.in
@@ -1116,6 +1116,7 @@ AC_OUTPUT(dnl
 src/Makefile dnl
 src/helper/Makefile dnl
 src/jtag/Makefile dnl
+src/jtag/drivers/Makefile dnl
 src/xsvf/Makefile dnl
 src/svf/Makefile dnl
 src/target/Makefile dnl
diff --git a/src/jtag/Makefile.am b/src/jtag/Makefile.am
index 5254a2b..c735897 100644
--- a/src/jtag/Makefile.am
+++ b/src/jtag/Makefile.am
@@ -5,7 +5,9 @@ AM_CPPFLAGS = \
 METASOURCES = AUTO
 noinst_LTLIBRARIES = libjtag.la
 
+SUBDIRS =
 DRIVERFILES =
+libjtag_la_LIBADD =
 
 if MINIDRIVER
 
@@ -20,63 +22,14 @@ endif
 
 else
 
-# Standard Driver: common files
-DRIVERFILES += driver.c commands.c
+DRIVERFILES += commands.c
 
-if USB
-DRIVERFILES += usb_common.c
-endif
-
-if BITBANG
-DRIVERFILES += bitbang.c
-endif
-if PARPORT
-DRIVERFILES += parport.c
-endif
-if DUMMY
-DRIVERFILES += dummy.c
-endif
-if FT2232_DRIVER
-DRIVERFILES += ft2232.c
-endif
-if AMTJTAGACCEL
-DRIVERFILES += amt_jtagaccel.c
-endif
-if EP93XX
-DRIVERFI

[Openocd-development] [PATCH 2/4] move nor drivers to src/flash/nor

2009-12-02 Thread Zachary T Welch
Moves NOR flash drivers to 'src/flash/nor/'.
Adds 'src/flash/nor/Makefile.am'.
Builds 'libocdflashnor.la'.

Signed-off-by: Zachary T Welch 
---
 configure.in|1 +
 src/flash/Makefile.am   |   59 ++-
 src/flash/nor/Makefile.am   |   46 ++
 src/flash/{ => nor}/aduc702x.c  |0
 src/flash/{ => nor}/at91sam3.c  |0
 src/flash/{ => nor}/at91sam3.h  |0
 src/flash/{ => nor}/at91sam7.c  |0
 src/flash/{ => nor}/at91sam7.h  |0
 src/flash/{ => nor}/avrf.c  |0
 src/flash/{ => nor}/avrf.h  |0
 src/flash/{ => nor}/cfi.c   |0
 src/flash/{ => nor}/cfi.h   |0
 src/flash/{ => nor}/ecos.c  |0
 src/flash/{ => nor}/faux.c  |0
 src/flash/{ => nor}/lpc2000.c   |0
 src/flash/{ => nor}/lpc2000.h   |0
 src/flash/{ => nor}/lpc288x.c   |0
 src/flash/{ => nor}/lpc288x.h   |0
 src/flash/{ => nor}/lpc2900.c   |0
 src/flash/{ => nor}/non_cfi.c   |0
 src/flash/{ => nor}/non_cfi.h   |0
 src/flash/{ => nor}/ocl.c   |0
 src/flash/{ => nor}/ocl.h   |0
 src/flash/{ => nor}/pic32mx.c   |0
 src/flash/{ => nor}/pic32mx.h   |0
 src/flash/{ => nor}/stellaris.c |0
 src/flash/{ => nor}/stellaris.h |0
 src/flash/{ => nor}/stm32x.c|0
 src/flash/{ => nor}/stm32x.h|0
 src/flash/{ => nor}/str7x.c |0
 src/flash/{ => nor}/str7x.h |0
 src/flash/{ => nor}/str9x.c |0
 src/flash/{ => nor}/str9x.h |0
 src/flash/{ => nor}/str9xpec.c  |0
 src/flash/{ => nor}/str9xpec.h  |0
 src/flash/{ => nor}/tms470.c|0
 src/flash/{ => nor}/tms470.h|0
 37 files changed, 56 insertions(+), 50 deletions(-)
 create mode 100644 src/flash/nor/Makefile.am
 rename src/flash/{ => nor}/aduc702x.c (100%)
 rename src/flash/{ => nor}/at91sam3.c (100%)
 rename src/flash/{ => nor}/at91sam3.h (100%)
 rename src/flash/{ => nor}/at91sam7.c (100%)
 rename src/flash/{ => nor}/at91sam7.h (100%)
 rename src/flash/{ => nor}/avrf.c (100%)
 rename src/flash/{ => nor}/avrf.h (100%)
 rename src/flash/{ => nor}/cfi.c (100%)
 rename src/flash/{ => nor}/cfi.h (100%)
 rename src/flash/{ => nor}/ecos.c (100%)
 rename src/flash/{ => nor}/faux.c (100%)
 rename src/flash/{ => nor}/lpc2000.c (100%)
 rename src/flash/{ => nor}/lpc2000.h (100%)
 rename src/flash/{ => nor}/lpc288x.c (100%)
 rename src/flash/{ => nor}/lpc288x.h (100%)
 rename src/flash/{ => nor}/lpc2900.c (100%)
 rename src/flash/{ => nor}/non_cfi.c (100%)
 rename src/flash/{ => nor}/non_cfi.h (100%)
 rename src/flash/{ => nor}/ocl.c (100%)
 rename src/flash/{ => nor}/ocl.h (100%)
 rename src/flash/{ => nor}/pic32mx.c (100%)
 rename src/flash/{ => nor}/pic32mx.h (100%)
 rename src/flash/{ => nor}/stellaris.c (100%)
 rename src/flash/{ => nor}/stellaris.h (100%)
 rename src/flash/{ => nor}/stm32x.c (100%)
 rename src/flash/{ => nor}/stm32x.h (100%)
 rename src/flash/{ => nor}/str7x.c (100%)
 rename src/flash/{ => nor}/str7x.h (100%)
 rename src/flash/{ => nor}/str9x.c (100%)
 rename src/flash/{ => nor}/str9x.h (100%)
 rename src/flash/{ => nor}/str9xpec.c (100%)
 rename src/flash/{ => nor}/str9xpec.h (100%)
 rename src/flash/{ => nor}/tms470.c (100%)
 rename src/flash/{ => nor}/tms470.h (100%)

diff --git a/configure.in b/configure.in
index 0b304b5..6ca648d 100644
--- a/configure.in
+++ b/configure.in
@@ -1121,6 +1121,7 @@ AC_OUTPUT(dnl
 src/target/Makefile dnl
 src/server/Makefile dnl
 src/flash/Makefile dnl
+src/flash/nor/Makefile dnl
 src/flash/nand/Makefile dnl
 src/pld/Makefile dnl
 doc/Makefile dnl
diff --git a/src/flash/Makefile.am b/src/flash/Makefile.am
index 353fcf1..54a5116 100644
--- a/src/flash/Makefile.am
+++ b/src/flash/Makefile.am
@@ -1,4 +1,5 @@
 SUBDIRS = \
+   nor \
nand
 
 AM_CPPFLAGS = \
@@ -9,66 +10,24 @@ AM_CPPFLAGS = \
 METASOURCES = AUTO
 noinst_LTLIBRARIES = libflash.la
 libflash_la_SOURCES = \
-   $(FLASH_SRCS) \
-   $(NAND_SRCS) \
-   mflash.c
-
-libflash_la_LIBADD = \
-   $(top_builddir)/src/flash/nand/libocdflashnand.la
-
-FLASH_SRCS = \
common.c \
-   cfi.c \
-   non_cfi.c \
-   faux.c \
-   $(FLASH_DEVICES_SRCS) \
-   flash.c
-
-FLASH_DEVICES_SRCS = \
-   aduc702x.c \
-   at91sam3.c \
-   at91sam7.c \
-   avrf.c \
-   ecos.c \
-   lpc2000.c \
-   lpc288x.c \
-   lpc2900.c \
-   ocl.c \
-   pic32mx.c \
-   stellaris.c \
-   stm32x.c \
-   str7x.c \
-   str9x.c \
-   str9xpec.c \
-   tms470.c
-
-NAND_SRCS = \
+   flash.c \
arm_nandio.c \
nand_ecc.c \
nand_ecc_kw.c \
-   nand.c
+   nand.c \
+   mflash.c
+
+libfla

[Openocd-development] [PATCH 0/4] move drivers to subdirectories

2009-12-02 Thread Zachary T Welch
Hi all,

This series contains the changes required to move the jtag, nor flash,
and nand flash drivers into their own subdirectories.  The last patch
makes some magic happen with Makefiles to remove #ifdef logic from
minidriver.h, allowing it to be usable as an external API.

I am posting the patches here in their abbreviated format, anticipating
that they will look terrible on the commit list (which won't use -M to
detect all of the renamed files).  I have tested that things continue to
build properly, so I plan to push these in the next hour or two.

Cheers,

Zach
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 4/4] remove #if HAVE_JTAG_INTERFACE_H from minidriver.h

2009-12-02 Thread Zachary T Welch
Adds two "minidriver_imp.h" files, so the right one is allowed to be
"#included" by the Makefile logic.

Signed-off-by: Zachary T Welch 
---
 src/jtag/Makefile.am |7 
 src/jtag/drivers/Makefile.am |1 +
 src/jtag/drivers/minidriver_imp.h|   47 
 src/jtag/minidriver.h|   56 --
 src/jtag/minidriver/minidriver_imp.h |   44 ++
 5 files changed, 105 insertions(+), 50 deletions(-)
 create mode 100644 src/jtag/drivers/minidriver_imp.h
 create mode 100644 src/jtag/minidriver/minidriver_imp.h

diff --git a/src/jtag/Makefile.am b/src/jtag/Makefile.am
index c735897..421987c 100644
--- a/src/jtag/Makefile.am
+++ b/src/jtag/Makefile.am
@@ -11,6 +11,9 @@ libjtag_la_LIBADD =
 
 if MINIDRIVER
 
+# for minidriver_imp.h
+AM_CPPFLAGS += -I$(srcdir)/minidriver
+
 if ZY1000
 DRIVERFILES += zy1000/zy1000.c
 AM_CPPFLAGS += -I$(srcdir)/zy1000
@@ -27,6 +30,9 @@ DRIVERFILES += commands.c
 SUBDIRS += drivers
 libjtag_la_LIBADD += $(top_builddir)/src/jtag/drivers/libocdjtagdrivers.la
 
+# for minidriver_imp.h
+AM_CPPFLAGS += -I$(srcdir)/drivers
+
 endif
 # endif // MINIDRIVER
 
@@ -43,6 +49,7 @@ noinst_HEADERS = \
interfaces.h \
minidriver.h \
jtag.h \
+   minidriver/minidriver_imp.h \
minidummy/jtag_minidriver.h
 
 EXTRA_DIST = startup.tcl
diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am
index 0a007b4..15fbae3 100644
--- a/src/jtag/drivers/Makefile.am
+++ b/src/jtag/drivers/Makefile.am
@@ -65,6 +65,7 @@ endif
 noinst_HEADERS = \
bitbang.h \
bitq.h \
+   minidriver_imp.h \
rlink.h \
rlink_dtc_cmd.h \
rlink_ep1_cmd.h \
diff --git a/src/jtag/drivers/minidriver_imp.h 
b/src/jtag/drivers/minidriver_imp.h
new file mode 100644
index 000..f60580c
--- /dev/null
+++ b/src/jtag/drivers/minidriver_imp.h
@@ -0,0 +1,47 @@
+/***
+ *   Copyright (C) 2005 by Dominic Rath   *
+ *   Copyright (C) 2007,2008 Øyvind Harboe*
+ *   Copyright (C) 2009 Zachary T Welch  *
+ * *
+ *   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. *
+ ***/
+#ifndef MINIDRIVER_IMP_H
+#define MINIDRIVER_IMP_H
+
+#include "commands.h"
+
+static inline void interface_jtag_alloc_in_value32(struct scan_field *field)
+{
+   field->in_value = (uint8_t *)cmd_queue_alloc(4);
+}
+
+static inline void interface_jtag_add_scan_check_alloc(struct scan_field 
*field)
+{
+   unsigned num_bytes = DIV_ROUND_UP(field->num_bits, 8);
+   field->in_value = (uint8_t *)cmd_queue_alloc(num_bytes);
+}
+
+void interface_jtag_add_dr_out(struct jtag_tap* tap,
+   int num_fields, const int* num_bits, const uint32_t* value,
+   tap_state_t end_state);
+
+void interface_jtag_add_callback(jtag_callback1_t f, jtag_callback_data_t 
data0);
+
+void interface_jtag_add_callback4(jtag_callback_t f, jtag_callback_data_t 
data0,
+   jtag_callback_data_t data1, jtag_callback_data_t data2,
+   jtag_callback_data_t data3);
+
+#endif // MINIDRIVER_IMP_H
diff --git a/src/jtag/minidriver.h b/src/jtag/minidriver.h
index 392a190..ea780fa 100644
--- a/src/jtag/minidriver.h
+++ b/src/jtag/minidriver.h
@@ -26,13 +26,14 @@
 #ifndef MINIDRIVER_H
 #define MINIDRIVER_H
 
-/* @page jtagminidriver JTAG Mini-Driver
+/**
+ * @page jtagminidriver JTAG Mini-Driver
  *
  * The JTAG minidriver interface allows the definition of alternate
  * interface functions, instead of the built-in asynchronous driver
  * module that is used by the standard JTAG interface drivers.
  *
- * In addtion to the functions defined in the c minidriver.h fi

[Openocd-development] [PATCH] fix 'target init' command registration

2009-12-02 Thread Zachary T Welch
The command handler registration was put at the top level, rather
than as a subcommand.  Move it to where it belongs.

Signed-off-by: Zachary T Welch 
---
 src/target/target.c |   12 ++--
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/target/target.c b/src/target/target.c
index 4013442..9a605f3 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -4591,6 +4591,12 @@ static int jim_target_count(Jim_Interp *interp, int 
argc, Jim_Obj *const *argv)
 
 static const struct command_registration target_subcommand_handlers[] = {
{
+   .name = "init",
+   .mode = COMMAND_CONFIG,
+   .handler = &handle_target_init_command,
+   .help = "initialize targets",
+   },
+   {
.name = "create",
.mode = COMMAND_ANY,
.jim_handler = &jim_target_create,
@@ -4804,12 +4810,6 @@ COMMAND_HANDLER(handle_fast_load_command)
 
 static const struct command_registration target_command_handlers[] = {
{
-   .name = "init",
-   .mode = COMMAND_CONFIG,
-   .handler = &handle_target_init_command,
-   .help = "initialize targets",
-   },
-   {
.name = "targets",
.handler = &handle_targets_command,
.mode = COMMAND_ANY,
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 2/3] remove BUILD_IOUTIL symbol

2009-12-01 Thread Zachary T Welch
Add ioutil_stubs.c to provide an empty ioutil_init() routine.
Add ioutil.h to prevent applications from needing to declare it.

Allows unconditionally calling that function during startup, and the
resulting libocdhelper library API is now more stable.

Prints a DEBUG message when the stub implementation is included.

Signed-off-by: Zachary T Welch 
---
 configure.in  |6 --
 src/ecosboard.c   |8 +---
 src/helper/Makefile.am|3 +++
 src/helper/ioutil.h   |   27 +++
 src/helper/ioutil_stubs.c |   29 +
 src/openocd.c |7 +--
 6 files changed, 61 insertions(+), 19 deletions(-)
 create mode 100644 src/helper/ioutil.h
 create mode 100644 src/helper/ioutil_stubs.c

diff --git a/configure.in b/configure.in
index 81e4326..1a4299d 100644
--- a/configure.in
+++ b/configure.in
@@ -614,12 +614,6 @@ else
   AC_DEFINE(BUILD_ZY1000, 0, [0 if you don't want ZY1000.])
 fi
 
-if test $build_ioutil = yes; then
-  AC_DEFINE(BUILD_IOUTIL, 1, [1 if you want ioutils.])
-else
-  AC_DEFINE(BUILD_IOUTIL, 0, [0 if you don't want ioutils.])
-fi
-
 if test $build_httpd = yes; then
   AC_DEFINE(BUILD_HTTPD, 1, [1 if you want httpd.])
 else
diff --git a/src/ecosboard.c b/src/ecosboard.c
index 36e807e..fe2c024 100644
--- a/src/ecosboard.c
+++ b/src/ecosboard.c
@@ -23,6 +23,7 @@
 
 #include "types.h"
 #include "jtag.h"
+#include "ioutil.h"
 #include "configuration.h"
 #include "xsvf.h"
 #include "svf.h"
@@ -942,8 +943,6 @@ static int add_default_dirs(void)
return ERROR_OK;
 }
 
-int ioutil_init(struct command_context *cmd_ctx);
-
 int main(int argc, char *argv[])
 {
/* ramblockdevice will be the same address every time. The deflate app 
uses a buffer 16mBytes out, so we
@@ -1080,13 +1079,8 @@ int main(int argc, char *argv[])
command_set_output_handler(cmd_ctx, configuration_output_handler, NULL);
command_context_mode(cmd_ctx, COMMAND_CONFIG);
 
-#if BUILD_IOUTIL
if (ioutil_init(cmd_ctx) != ERROR_OK)
-   {
return EXIT_FAILURE;
-   }
-#endif
-
 
 #ifdef CYGPKG_PROFILE_GPROF
COMMAND_REGISTER(cmd_ctx, NULL, "ecosboard_profile", 
eCosBoard_handle_eCosBoard_profile_command,
diff --git a/src/helper/Makefile.am b/src/helper/Makefile.am
index 22b3c33..01e805e 100644
--- a/src/helper/Makefile.am
+++ b/src/helper/Makefile.am
@@ -27,6 +27,8 @@ libhelper_la_SOURCES = \
 
 if IOUTIL
 libhelper_la_SOURCES += ioutil.c
+else
+libhelper_la_SOURCES += ioutil_stubs.c
 endif
 
 libhelper_la_CFLAGS =
@@ -38,6 +40,7 @@ endif
 noinst_HEADERS = \
binarybuffer.h \
configuration.h \
+   ioutil.h \
types.h \
log.h \
command.h \
diff --git a/src/helper/ioutil.h b/src/helper/ioutil.h
new file mode 100644
index 000..855ae55
--- /dev/null
+++ b/src/helper/ioutil.h
@@ -0,0 +1,27 @@
+/***********
+ *   Copyright (C) 2009 Zachary T Welch  *
+ * *
+ *   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. *
+ ***/
+
+#ifndef HELPER_IOUTILS_H
+#define HELPER_IOUTILS_H
+
+struct command_context;
+
+int ioutil_init(struct command_context *cmd_ctx);
+
+#endif // HELPER_IOUTILS_H
diff --git a/src/helper/ioutil_stubs.c b/src/helper/ioutil_stubs.c
new file mode 100644
index 000..1171a6f
--- /dev/null
+++ b/src/helper/ioutil_stubs.c
@@ -0,0 +1,29 @@
+/***********
+ *   Copyright (C) 2009 Zachary T Welch  *
+ * *
+ *   This program is free software; you can redistribute it and/or modi

[Openocd-development] [PATCH 1/3] remove #if logic for openocd_sleep_*lude

2009-12-01 Thread Zachary T Welch
Adds server_stubs.c to hold these routines, using automake logic to
ensure it gets included under the right conditions.

Signed-off-by: Zachary T Welch 
---
 src/openocd.c |   14 --
 src/openocd.h |5 -
 src/server/Makefile.am|4 
 src/server/server.h   |9 +
 src/server/server_stubs.c |   32 
 5 files changed, 45 insertions(+), 19 deletions(-)
 create mode 100644 src/server/server_stubs.c

diff --git a/src/openocd.c b/src/openocd.c
index 12bcf44..2043a92 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -215,20 +215,6 @@ struct command_context *setup_command_handler(Jim_Interp 
*interp)
return cmd_ctx;
 }
 
-#if !BUILD_HTTPD && !BUILD_ECOSBOARD
-/* implementations of OpenOCD that uses multithreading needs to know when
- * OpenOCD is sleeping. No-op in vanilla OpenOCD
- */
-void openocd_sleep_prelude(void)
-{
-}
-
-void openocd_sleep_postlude(void)
-{
-}
-#endif
-
-
 /* normally this is the main() function entry, but if OpenOCD is linked
  * into application, then this fn will not be invoked, but rather that
  * application will have it's own implementation of main(). */
diff --git a/src/openocd.h b/src/openocd.h
index a91d46f..e43f156 100644
--- a/src/openocd.h
+++ b/src/openocd.h
@@ -31,11 +31,6 @@
  */
 int openocd_main(int argc, char *argv[]);
 
-/// used by the server_loop() function in src/server/server.c
-void openocd_sleep_prelude(void);
-/// used by the server_loop() function in src/server/server.c
-void openocd_sleep_postlude(void);
-
 /// provides a hard-coded command environment setup
 extern const char openocd_startup_tcl[];
 
diff --git a/src/server/Makefile.am b/src/server/Makefile.am
index 95fb519..b47b8d0 100644
--- a/src/server/Makefile.am
+++ b/src/server/Makefile.am
@@ -13,6 +13,10 @@ libserver_la_SOURCES = server.c telnet_server.c gdb_server.c
 
 if HTTPD
 libserver_la_SOURCES += httpd.c
+else
+if !ECOSBOARD
+libserver_la_SOURCES += server_stubs.c
+endif
 endif
 noinst_HEADERS += httpd.h
 
diff --git a/src/server/server.h b/src/server/server.h
index 173de95..e632bf1 100644
--- a/src/server/server.h
+++ b/src/server/server.h
@@ -82,6 +82,15 @@ int server_loop(struct command_context *command_context);
 int server_register_commands(struct command_context *context);
 
 /**
+ * Used by server_loop(), defined in server_stubs.c, httpd.c, or ecosboard.c
+ */
+void openocd_sleep_prelude(void);
+/**
+ * Used by server_loop(), defined in server_stubs.c, httpd.c, or ecosboard.c
+ */
+void openocd_sleep_postlude(void);
+
+/**
  * Defines an extended command handler function declaration to enable
  * access to (and manipulation of) the server port number.
  * Call server_port like a normal COMMAND_HANDLER with an extra @a out 
parameter
diff --git a/src/server/server_stubs.c b/src/server/server_stubs.c
new file mode 100644
index 000..dcddec0
--- /dev/null
+++ b/src/server/server_stubs.c
@@ -0,0 +1,32 @@
+/***
+ *   Copyright (C) 2009 Zachary T Welch  *
+ * *
+ *   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 
+#endif
+#include "server.h"
+
+void openocd_sleep_prelude(void)
+{
+   // no-op
+}
+void openocd_sleep_postlude(void)
+{
+   // no-op
+}
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 3/3] remove #if BUILD_HTTPD

2009-12-01 Thread Zachary T Welch
Add httpd_stubs.c to provide no-op implementations of httpd_start()
and httpd_stop().

Allows these routines to be called unconditionally and ensures the
libocdserver ABI remains unchanged regardless of whether this feature
was built-in or not.

Prints a DEBUG message when the stub implementation is included.

Signed-off-by: Zachary T Welch 
---
 configure.in |6 --
 src/openocd.c|4 
 src/server/Makefile.am   |1 +
 src/server/httpd_stubs.c |   32 
 4 files changed, 33 insertions(+), 10 deletions(-)
 create mode 100644 src/server/httpd_stubs.c

diff --git a/configure.in b/configure.in
index 1a4299d..9cb2b0f 100644
--- a/configure.in
+++ b/configure.in
@@ -614,12 +614,6 @@ else
   AC_DEFINE(BUILD_ZY1000, 0, [0 if you don't want ZY1000.])
 fi
 
-if test $build_httpd = yes; then
-  AC_DEFINE(BUILD_HTTPD, 1, [1 if you want httpd.])
-else
-  AC_DEFINE(BUILD_HTTPD, 0, [0 if you don't want httpd.])
-fi
-
 if test $build_at91rm9200 = yes; then
   build_bitbang=yes
   AC_DEFINE(BUILD_AT91RM9200, 1, [1 if you want at91rm9200.])
diff --git a/src/openocd.c b/src/openocd.c
index 1f45837..9a08019 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -244,10 +244,8 @@ int openocd_main(int argc, char *argv[])
if (ret != ERROR_OK)
return EXIT_FAILURE;
 
-#if BUILD_HTTPD
if (httpd_start(cmd_ctx) != ERROR_OK)
return EXIT_FAILURE;
-#endif
 
ret = server_init(cmd_ctx);
if (ERROR_OK != ret)
@@ -266,9 +264,7 @@ int openocd_main(int argc, char *argv[])
 
server_quit();
 
-#if BUILD_HTTPD
httpd_stop();
-#endif
 
unregister_all_commands(cmd_ctx, NULL);
 
diff --git a/src/server/Makefile.am b/src/server/Makefile.am
index b47b8d0..989a682 100644
--- a/src/server/Makefile.am
+++ b/src/server/Makefile.am
@@ -14,6 +14,7 @@ libserver_la_SOURCES = server.c telnet_server.c gdb_server.c
 if HTTPD
 libserver_la_SOURCES += httpd.c
 else
+libserver_la_SOURCES += httpd_stubs.c
 if !ECOSBOARD
 libserver_la_SOURCES += server_stubs.c
 endif
diff --git a/src/server/httpd_stubs.c b/src/server/httpd_stubs.c
new file mode 100644
index 000..0a63362
--- /dev/null
+++ b/src/server/httpd_stubs.c
@@ -0,0 +1,32 @@
+/***
+ *   Copyright (C) 2009 Zachary T Welch  *
+ * *
+ *   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 
+#endif
+#include "httpd.h"
+
+int httpd_start(struct command_context *cmd_ctx)
+{
+   LOG_DEBUG("libocdserver was built without HTTPD support");
+   return ERROR_OK;
+}
+void httpd_stop(void)
+{
+}
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 0/3] remove all #if logic from openocd.c

2009-12-01 Thread Zachary T Welch
Hi all,

This series removes all #if logic from the src/openocd.c file, making
it look much nicer and helping to stablize our ABI in the process.

If these look good, I will continue this quest in future series.

Cheers,

Zach

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 4/7] add stack_assert for an improved assert macro

2009-12-01 Thread Zachary T Welch
Adds backtraces to all assert messages, so developers receive the
context of the problem.  After all, finding the problem often requires
knowing how the code managed to reach the call that contains the
assertion that has failed.

Signed-off-by: Zachary T Welch 
---
NOTE: The complete series is available in my mirror on repo.or.cz
in the 'stack' branch:

git://repo.or.cz/openocd/ztw.git
---
 src/helper/stack.c  |   10 ++
 src/helper/stack.h  |   16 
 src/helper/system.h |3 +++
 3 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/src/helper/stack.c b/src/helper/stack.c
index 599b983..fc1e038 100644
--- a/src/helper/stack.c
+++ b/src/helper/stack.c
@@ -181,3 +181,13 @@ int stack_walk(unsigned depth, stack_walker_t walker, 
intptr_t data)
};
return stack_dump(depth, &stack_walk_dumper, (intptr_t)&walk);
 }
+
+void stack_assert(const char *file, unsigned line,
+   const char *function, const char *condition)
+{
+   LOG_ERROR("Assertion failed:\n\t%s\n\tFunc:\t%s\n"
+   "\tLine:\t%u:\n\tFile:\t%s",
+   condition, function, line, file);
+   stack_walk(100, &stack_log_walker, 0);
+   exit(1);
+}
diff --git a/src/helper/stack.h b/src/helper/stack.h
index e18be14..6155f34 100644
--- a/src/helper/stack.h
+++ b/src/helper/stack.h
@@ -105,4 +105,20 @@ int stack_log_walker(struct stack_walk_state *state, 
intptr_t cmd_ctx);
  */
 int stack_walk(unsigned depth, stack_walker_t walker, intptr_t data);
 
+#ifndef NDEBUG
+
+void stack_assert(const char *file, unsigned line,
+   const char *function, const char *condition);
+
+// remove assert macro from namespace
+#undef assert
+// replace assert with call to inline and original version (C9x-portable)
+#define assert(__x) \
+   ((__x) \
+? (void)(0) \
+: stack_assert(__FILE__, __LINE__, __func__, stringify(__x)))
+
+#endif // NDEBUG
+
+
 #endif // HELPER_STACK_H
diff --git a/src/helper/system.h b/src/helper/system.h
index 169df1c..e15dbef 100644
--- a/src/helper/system.h
+++ b/src/helper/system.h
@@ -30,6 +30,9 @@
 #include 
 #include 
 
+// for stack_assert()
+#include "stack.h"
+
 // +++ AC_HEADER_TIME +++
 #ifdef TIME_WITH_SYS_TIME
 # include 
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 7/7] target: factor init to 'target init'

2009-12-01 Thread Zachary T Welch
Adds 'target init' command handler, called as part of 'init'.

Signed-off-by: Zachary T Welch 
---
 src/openocd.c   |7 ++-
 src/target/target.c |   23 +++
 2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/src/openocd.c b/src/openocd.c
index 79a30e7..12bcf44 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -111,11 +111,9 @@ COMMAND_HANDLER(handle_init_command)
 
initialized = 1;
 
-   command_context_mode(CMD_CTX, COMMAND_EXEC);
-
-   if (target_init(CMD_CTX) != ERROR_OK)
+   retval = command_run_line(CMD_CTX, "target init");
+   if (ERROR_OK != retval)
return ERROR_FAIL;
-   LOG_DEBUG("target init complete");
 
if ((retval = jtag_interface_init(CMD_CTX)) != ERROR_OK)
{
@@ -126,7 +124,6 @@ COMMAND_HANDLER(handle_init_command)
 
/* Try to initialize & examine the JTAG chain at this point, but
 * continue startup regardless */
-   command_context_mode(CMD_CTX, COMMAND_CONFIG);
if (command_run_line(CMD_CTX, "jtag init") == ERROR_OK)
{
command_context_mode(CMD_CTX, COMMAND_EXEC);
diff --git a/src/target/target.c b/src/target/target.c
index abf8bfd..4013442 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -787,6 +787,23 @@ int target_init(struct command_context *cmd_ctx)
return ERROR_OK;
 }
 
+COMMAND_HANDLER(handle_target_init_command)
+{
+   if (CMD_ARGC != 0)
+   return ERROR_COMMAND_SYNTAX_ERROR;
+
+   static bool target_initialized = false;
+   if (target_initialized)
+   {
+   LOG_INFO("'target init' has already been called");
+   return ERROR_OK;
+   }
+   target_initialized = true;
+
+   LOG_DEBUG("Initializing targets...");
+   return target_init(CMD_CTX);
+}
+
 int target_register_event_callback(int (*callback)(struct target *target, enum 
target_event event, void *priv), void *priv)
 {
struct target_event_callback **callbacks_p = &target_event_callbacks;
@@ -4787,6 +4804,12 @@ COMMAND_HANDLER(handle_fast_load_command)
 
 static const struct command_registration target_command_handlers[] = {
{
+   .name = "init",
+   .mode = COMMAND_CONFIG,
+   .handler = &handle_target_init_command,
+   .help = "initialize targets",
+   },
+   {
.name = "targets",
.handler = &handle_targets_command,
.mode = COMMAND_ANY,
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 6/7] target: factor target_init() into pieces

2009-12-01 Thread Zachary T Welch
Moves body of target initialization loop into a helper function,
cleaning up its visual flow in the process.

Signed-off-by: Zachary T Welch 
---
 src/target/target.c |  153 ---
 1 files changed, 84 insertions(+), 69 deletions(-)

diff --git a/src/target/target.c b/src/target/target.c
index 88931b5..abf8bfd 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -681,94 +681,109 @@ err_write_phys_memory(struct target *target, uint32_t 
address,
 
 static int handle_target(void *priv);
 
-int target_init(struct command_context *cmd_ctx)
+static int target_init_one(struct command_context *cmd_ctx,
+   struct target *target)
 {
-   struct target *target;
-   int retval;
+   target_reset_examined(target);
 
-   for (target = all_targets; target; target = target->next) {
-   struct target_type *type = target->type;
+   struct target_type *type = target->type;
+   if (type->examine == NULL)
+   type->examine = default_examine;
 
-   target_reset_examined(target);
-   if (target->type->examine == NULL)
-   {
-   target->type->examine = default_examine;
-   }
+   int retval = type->init_target(cmd_ctx, target);
+   if (ERROR_OK != retval)
+   {
+   LOG_ERROR("target '%s' init failed", target_name(target));
+   return retval;
+   }
 
-   if ((retval = target->type->init_target(cmd_ctx, target)) != 
ERROR_OK)
-   {
-   LOG_ERROR("target '%s' init failed", 
target_name(target));
-   return retval;
-   }
+   /**
+* @todo get rid of those *memory_imp() methods, now that all
+* callers are using target_*_memory() accessors ... and make
+* sure the "physical" paths handle the same issues.
+*/
+   /* a non-invasive way(in terms of patches) to add some code that
+* runs before the type->write/read_memory implementation
+*/
+   type->write_memory_imp = target->type->write_memory;
+   type->write_memory = target_write_memory_imp;
 
+   type->read_memory_imp = target->type->read_memory;
+   type->read_memory = target_read_memory_imp;
 
-   /**
-* @todo get rid of those *memory_imp() methods, now that all
-* callers are using target_*_memory() accessors ... and make
-* sure the "physical" paths handle the same issues.
-*/
+   type->soft_reset_halt_imp = target->type->soft_reset_halt;
+   type->soft_reset_halt = target_soft_reset_halt_imp;
 
-   /* a non-invasive way(in terms of patches) to add some code that
-* runs before the type->write/read_memory implementation
-*/
-   target->type->write_memory_imp = target->type->write_memory;
-   target->type->write_memory = target_write_memory_imp;
-   target->type->read_memory_imp = target->type->read_memory;
-   target->type->read_memory = target_read_memory_imp;
-   target->type->soft_reset_halt_imp = 
target->type->soft_reset_halt;
-   target->type->soft_reset_halt = target_soft_reset_halt_imp;
-   target->type->run_algorithm_imp = target->type->run_algorithm;
-   target->type->run_algorithm = target_run_algorithm_imp;
-
-   /* Sanity-check MMU support ... stub in what we must, to help
-* implement it in stages, but warn if we need to do so.
-*/
-   if (type->mmu) {
-   if (type->write_phys_memory == NULL) {
-   LOG_ERROR("type '%s' is missing %s",
-   type->name,
-   "write_phys_memory");
-   type->write_phys_memory = err_write_phys_memory;
-   }
-   if (type->read_phys_memory == NULL) {
-   LOG_ERROR("type '%s' is missing %s",
-   type->name,
-   "read_phys_memory");
-   type->read_phys_memory = err_read_phys_memory;
-   }
-   if (type->virt2phys == NULL) {
-   LOG_ERROR("type '%s' is missing %s",
-   type->name,
-   "virt2phys&q

[Openocd-development] [PATCH 0/7] split the 'init' command

2009-12-01 Thread Zachary T Welch
Hi all,

This series makes most of the individual steps in 'init' accessible to
direct invocation.  The changes should allow recovery in cases when
OpenOCD is run interactively and (for example) you fail to specify an
interface before trying to to run 'init'.  These new subcommands help
with the transition to fine-grained, context-sensitive commands.

It also includes one patch to refactor target_init, whose previous
monolithic form bugged me more than I could stand.

Cheers,

Zach

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 1/7] pld: factor init to 'pld init'

2009-12-01 Thread Zachary T Welch
Split PLD initialization into 'pld init', which gets called from 'init'.

Signed-off-by: Zachary T Welch 
---
 src/openocd.c |5 +++--
 src/pld/pld.c |   23 +++
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/src/openocd.c b/src/openocd.c
index 44e0292..777e630 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -147,9 +147,10 @@ COMMAND_HANDLER(handle_init_command)
return ERROR_FAIL;
LOG_DEBUG("NAND init complete");
 
-   if (pld_init(CMD_CTX) != ERROR_OK)
+   command_context_mode(CMD_CTX, COMMAND_CONFIG);
+   if (command_run_line(CMD_CTX, "pld init") != ERROR_OK)
return ERROR_FAIL;
-   LOG_DEBUG("pld init complete");
+   command_context_mode(CMD_CTX, COMMAND_EXEC);
 
/* initialize telnet subsystem */
gdb_target_add_all(all_targets);
diff --git a/src/pld/pld.c b/src/pld/pld.c
index 24afd07..df7ac0d 100644
--- a/src/pld/pld.c
+++ b/src/pld/pld.c
@@ -213,6 +213,23 @@ int pld_init(struct command_context *cmd_ctx)
return register_commands(cmd_ctx, parent, pld_exec_command_handlers);
 }
 
+COMMAND_HANDLER(handle_pld_init_command)
+{
+   if (CMD_ARGC != 0)
+   return ERROR_COMMAND_SYNTAX_ERROR;
+
+   static bool pld_initialized = false;
+   if (pld_initialized)
+   {
+   LOG_INFO("'pld init' has already been called");
+   return ERROR_OK;
+   }
+   pld_initialized = true;
+
+   LOG_DEBUG("Initializing PLDs...");
+   return pld_init(CMD_CTX);
+}
+
 static const struct command_registration pld_config_command_handlers[] = {
{
.name = "device",
@@ -221,6 +238,12 @@ static const struct command_registration 
pld_config_command_handlers[] = {
.help = "configure a PLD device",
.usage = " ...",
},
+   {
+   .name = "init",
+   .mode = COMMAND_CONFIG,
+   .handler = &handle_pld_init_command,
+   .help = "initialize PLD devices",
+   },
COMMAND_REGISTRATION_DONE
 };
 static const struct command_registration pld_command_handler[] = {
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 5/7] jtag: factor init into 'jtag init'

2009-12-01 Thread Zachary T Welch
Adds 'jtag init' command handler, which can be called as part of a
fine-grained 'init' process.

Signed-off-by: Zachary T Welch 
---
 src/jtag/tcl.c |   23 +++
 src/openocd.c  |   16 +---
 2 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index 68bb21e..cc89080 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -808,8 +808,31 @@ static int jim_jtag_names(Jim_Interp *interp, int argc, 
Jim_Obj *const *argv)
return JIM_OK;
 }
 
+COMMAND_HANDLER(handle_jtag_init_command)
+{
+   if (CMD_ARGC != 0)
+   return ERROR_COMMAND_SYNTAX_ERROR;
+
+   static bool jtag_initialized = false;
+   if (jtag_initialized)
+   {
+   LOG_INFO("'jtag init' has already been called");
+   return ERROR_OK;
+   }
+   jtag_initialized = true;
+
+   LOG_DEBUG("Initializing jtag devices...");
+   return jtag_init(CMD_CTX);
+}
+
 static const struct command_registration jtag_subcommand_handlers[] = {
{
+   .name = "init",
+   .mode = COMMAND_CONFIG,
+   .handler = &handle_jtag_init_command,
+   .help = "initialize jtag scan chain",
+   },
+   {
.name = "interface",
.mode = COMMAND_ANY,
.jim_handler = &jim_jtag_interface,
diff --git a/src/openocd.c b/src/openocd.c
index aaa4531..79a30e7 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -126,16 +126,18 @@ COMMAND_HANDLER(handle_init_command)
 
/* Try to initialize & examine the JTAG chain at this point, but
 * continue startup regardless */
-   if (jtag_init(CMD_CTX) == ERROR_OK)
+   command_context_mode(CMD_CTX, COMMAND_CONFIG);
+   if (command_run_line(CMD_CTX, "jtag init") == ERROR_OK)
{
-   LOG_DEBUG("jtag init complete");
-   if (target_examine() == ERROR_OK)
-   {
-   LOG_DEBUG("jtag examine complete");
-   }
+   command_context_mode(CMD_CTX, COMMAND_EXEC);
+   LOG_DEBUG("Examining targets...");
+   if (target_examine() != ERROR_OK)
+   LOG_DEBUG("target examination failed");
+   command_context_mode(CMD_CTX, COMMAND_CONFIG);
}
+   else
+   LOG_WARNING("jtag initialization failed; try 'jtag init' 
again.");
 
-   command_context_mode(CMD_CTX, COMMAND_CONFIG);
if (command_run_line(CMD_CTX, "flash init") != ERROR_OK)
return ERROR_FAIL;
 
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 4/7] flash: factor init to 'flash init'

2009-12-01 Thread Zachary T Welch
Split flash initialiation into 'flash init', called from 'init'.

Signed-off-by: Zachary T Welch 
---
 src/flash/flash.c |   23 +++
 src/openocd.c |5 ++---
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/src/flash/flash.c b/src/flash/flash.c
index 7023ef9..1e5ac9a 100644
--- a/src/flash/flash.c
+++ b/src/flash/flash.c
@@ -1375,6 +1375,23 @@ int flash_init_drivers(struct command_context *cmd_ctx)
return register_commands(cmd_ctx, parent, flash_exec_command_handlers);
 }
 
+COMMAND_HANDLER(handle_flash_init_command)
+{
+   if (CMD_ARGC != 0)
+   return ERROR_COMMAND_SYNTAX_ERROR;
+
+   static bool flash_initialized = false;
+   if (flash_initialized)
+   {
+   LOG_INFO("'flash init' has already been called");
+   return ERROR_OK;
+   }
+   flash_initialized = true;
+
+   LOG_DEBUG("Initializing flash devices...");
+   return flash_init_drivers(CMD_CTX);
+}
+
 static const struct command_registration flash_config_command_handlers[] = {
{
.name = "bank",
@@ -1387,6 +1404,12 @@ static const struct command_registration 
flash_config_command_handlers[] = {
"using the specified NOR flash driver.",
},
{
+   .name = "init",
+   .mode = COMMAND_CONFIG,
+   .handler = &handle_flash_init_command,
+   .help = "initialize flash devices",
+   },
+   {
.name = "banks",
.mode = COMMAND_ANY,
.jim_handler = &jim_flash_banks,
diff --git a/src/openocd.c b/src/openocd.c
index ff35f87..aaa4531 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -135,11 +135,10 @@ COMMAND_HANDLER(handle_init_command)
}
}
 
-   if (flash_init_drivers(CMD_CTX) != ERROR_OK)
+   command_context_mode(CMD_CTX, COMMAND_CONFIG);
+   if (command_run_line(CMD_CTX, "flash init") != ERROR_OK)
return ERROR_FAIL;
-   LOG_DEBUG("flash init complete");
 
-   command_context_mode(CMD_CTX, COMMAND_CONFIG);
if (command_run_line(CMD_CTX, "mflash init") != ERROR_OK)
return ERROR_FAIL;
 
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 2/7] nand: factor init to 'nand init'

2009-12-01 Thread Zachary T Welch
Split NAND initialization into 'nand init', which gets called from
the main 'init' command.

Signed-off-by: Zachary T Welch 
---
 src/flash/nand.c |   26 ++
 src/openocd.c|5 ++---
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/src/flash/nand.c b/src/flash/nand.c
index 94cec8d..1c8c0c8 100644
--- a/src/flash/nand.c
+++ b/src/flash/nand.c
@@ -281,6 +281,9 @@ COMMAND_HANDLER(handle_nand_device_command)
return CALL_COMMAND_HANDLER(handle_nand_list_drivers);
 }
 
+
+COMMAND_HANDLER(handle_nand_init_command);
+
 static const struct command_registration nand_config_command_handlers[] = {
{
.name = "device",
@@ -294,6 +297,12 @@ static const struct command_registration 
nand_config_command_handlers[] = {
.mode = COMMAND_ANY,
.help = "lists available NAND drivers",
},
+   {
+   .name = "init",
+   .mode = COMMAND_CONFIG,
+   .handler = &handle_nand_init_command,
+   .help = "initialize NAND devices",
+   },
COMMAND_REGISTRATION_DONE
 };
 static const struct command_registration nand_command_handlers[] = {
@@ -1794,3 +1803,20 @@ int nand_init(struct command_context *cmd_ctx)
struct command *parent = command_find_in_context(cmd_ctx, "nand");
return register_commands(cmd_ctx, parent, nand_exec_command_handlers);
 }
+
+COMMAND_HANDLER(handle_nand_init_command)
+{
+   if (CMD_ARGC != 0)
+   return ERROR_COMMAND_SYNTAX_ERROR;
+
+   static bool nand_initialized = false;
+   if (nand_initialized)
+   {
+   LOG_INFO("'nand init' has already been called");
+   return ERROR_OK;
+   }
+   nand_initialized = true;
+
+   LOG_DEBUG("Initializing NAND devices...");
+   return nand_init(CMD_CTX);
+}
diff --git a/src/openocd.c b/src/openocd.c
index 777e630..1026379 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -143,11 +143,10 @@ COMMAND_HANDLER(handle_init_command)
return ERROR_FAIL;
LOG_DEBUG("mflash init complete");
 
-   if (nand_init(CMD_CTX) != ERROR_OK)
+   command_context_mode(CMD_CTX, COMMAND_CONFIG);
+   if (command_run_line(CMD_CTX, "nand init") != ERROR_OK)
return ERROR_FAIL;
-   LOG_DEBUG("NAND init complete");
 
-   command_context_mode(CMD_CTX, COMMAND_CONFIG);
if (command_run_line(CMD_CTX, "pld init") != ERROR_OK)
return ERROR_FAIL;
command_context_mode(CMD_CTX, COMMAND_EXEC);
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 3/7] mflash: factor init to 'mflash init'

2009-12-01 Thread Zachary T Welch
Splits mflash initialiation to 'mflash init', called from 'init'.

Signed-off-by: Zachary T Welch 
---
 src/flash/mflash.c |   23 +++
 src/openocd.c  |5 ++---
 2 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/src/flash/mflash.c b/src/flash/mflash.c
index 03a56e2..8f42aa6 100644
--- a/src/flash/mflash.c
+++ b/src/flash/mflash.c
@@ -1304,6 +1304,23 @@ int mflash_init_drivers(struct command_context *cmd_ctx)
return register_commands(cmd_ctx, NULL, mflash_exec_command_handlers);
 }
 
+COMMAND_HANDLER(handle_mflash_init_command)
+{
+   if (CMD_ARGC != 0)
+   return ERROR_COMMAND_SYNTAX_ERROR;
+
+   static bool mflash_initialized = false;
+   if (mflash_initialized)
+   {
+   LOG_INFO("'mflash init' has already been called");
+   return ERROR_OK;
+   }
+   mflash_initialized = true;
+
+   LOG_DEBUG("Initializing mflash devices...");
+   return mflash_init_drivers(CMD_CTX);
+}
+
 COMMAND_HANDLER(mg_bank_cmd)
 {
struct target *target;
@@ -1352,6 +1369,12 @@ static const struct command_registration 
mflash_config_command_handlers[] = {
.help = "configure a mflash device bank",
.usage = "   ",
},
+   {
+   .name = "init",
+   .mode = COMMAND_CONFIG,
+   .handler = &handle_mflash_init_command,
+   .help = "initialize mflash devices",
+   },
COMMAND_REGISTRATION_DONE
 };
 static const struct command_registration mflash_command_handler[] = {
diff --git a/src/openocd.c b/src/openocd.c
index 1026379..ff35f87 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -139,11 +139,10 @@ COMMAND_HANDLER(handle_init_command)
return ERROR_FAIL;
LOG_DEBUG("flash init complete");
 
-   if (mflash_init_drivers(CMD_CTX) != ERROR_OK)
+   command_context_mode(CMD_CTX, COMMAND_CONFIG);
+   if (command_run_line(CMD_CTX, "mflash init") != ERROR_OK)
return ERROR_FAIL;
-   LOG_DEBUG("mflash init complete");
 
-   command_context_mode(CMD_CTX, COMMAND_CONFIG);
if (command_run_line(CMD_CTX, "nand init") != ERROR_OK)
return ERROR_FAIL;
 
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 4/4] add 'stack' command handler

2009-11-30 Thread Zachary T Welch
The new 'stack' command displays the openocd C stack from TCL as a
debugging aid.  Takes an optional parameter: the depth of the stack
or 'fault' (which creates an immediate segfault by dereferencing
a bad pointer).  This demonstrates the new segfault handling nicely.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c |   40 
 1 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index 1cbedae..ca7418b 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -42,6 +42,7 @@
 #include "log.h"
 #include "time_support.h"
 #include "jim-eventloop.h"
+#include "stack.h"
 
 
 /* nice short description of source file */
@@ -1201,6 +1202,36 @@ COMMAND_HANDLER(handle_sleep_command)
return ERROR_OK;
 }
 
+static int stack_command_walker(struct stack_walk_state *state, intptr_t data)
+{
+   struct command_context *cmd_ctx = (struct command_context *)data;
+   command_print(cmd_ctx, "%d: %s", state->level, state->frame);
+   return 0;
+}
+
+COMMAND_HANDLER(handle_stack_command)
+{
+   if (CMD_ARGC > 1)
+   return ERROR_INVALID_ARGUMENTS;
+
+   unsigned depth = 10;
+   if (CMD_ARGC == 1)
+   {
+   if (strcmp(CMD_ARGV[0], "fault") == 0)
+   {
+   long *bad_ptr = (void*)-1;
+   *bad_ptr = 0xDEADBEEF;
+   // unreachable... we should have just caused a crash!
+   LOG_ERROR("unable to fake a segmentation fault?!?!");
+   }
+   COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], depth);
+   if (depth > 200)
+   return ERROR_INVALID_ARGUMENTS;
+   }
+
+   return stack_walk(depth, &stack_command_walker, (intptr_t)CMD_CTX);
+}
+
 static const struct command_registration command_subcommand_handlers[] = {
{
.name = "mode",
@@ -1246,6 +1277,15 @@ static const struct command_registration 
command_builtin_handlers[] = {
.usage = " [busy]",
},
{
+   .name = "stack",
+   .mode = COMMAND_ANY,
+   .handler = &handle_stack_command,
+   .usage = "[]",
+   .help = "Display the C stack up to , with the "
+   "default of 10 and limit of 200.",
+
+   },
+   {
.name = "help",
.handler = &handle_help_command,
.mode = COMMAND_ANY,
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 2/4] produce stack traces on segfaults

2009-11-30 Thread Zachary T Welch
Registers a signal handler to catch SIGSEGV in order to display the
stack where the program crashed.

Adds the 'stack' helper module with generic stack trace routines that
can be used to implement better debugging messages.

Signed-off-by: Zachary T Welch 
---
 src/helper/Makefile.am |2 +
 src/helper/stack.c |  173 
 src/helper/stack.h |  101 
 src/openocd.c  |   10 ++--
 4 files changed, 281 insertions(+), 5 deletions(-)
 create mode 100644 src/helper/stack.c
 create mode 100644 src/helper/stack.h

diff --git a/src/helper/Makefile.am b/src/helper/Makefile.am
index 13bcbd1..51d5550 100644
--- a/src/helper/Makefile.am
+++ b/src/helper/Makefile.am
@@ -15,6 +15,7 @@ endif
 
 
 libhelper_la_SOURCES = \
+   stack.c \
binarybuffer.c \
$(CONFIGFILES) \
configuration.c \
@@ -49,6 +50,7 @@ noinst_HEADERS = \
fileio.h \
jim.h \
jim-eventloop.h \
+   stack.h \
system.h \
bin2char.c
 
diff --git a/src/helper/stack.c b/src/helper/stack.c
new file mode 100644
index 000..7f31358
--- /dev/null
+++ b/src/helper/stack.c
@@ -0,0 +1,173 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "stack.h"
+#include "module.h"
+#include "log.h"
+
+#include 
+#include 
+
+
+static void stack_dump_symbols_free(struct stack_dump_state *dump)
+{
+   if (NULL == dump->symbols)
+   return;
+
+   unsigned count = dump->available;
+   for (unsigned i = 0; NULL != dump->symbols[i] && i < count; i++)
+   module_symbol_free(dump->symbols[i]);
+   free((void *)dump->symbols);
+   dump->symbols = NULL;
+}
+int stack_dump_symbols_fill(struct stack_dump_state *dump)
+{
+   if (NULL != dump->symbols)
+   return 0;
+
+   unsigned count = dump->available;
+   struct module_symbol **symbols = calloc(count, sizeof(*symbols));
+   if (NULL == symbols)
+   return -ENOMEM;
+
+   dump->symbols = symbols;
+
+   for (unsigned i = 0; i < count; i++)
+   {
+   void *addr = dump->raw[i];
+   symbols[i] = module_symbol_by_addr(addr);
+   if (NULL == symbols[i])
+   return -ENOMEM;
+   }
+
+   return 0;
+}
+
+//#define STACK_SIMPLE_STRINGS
+
+static void stack_dump_strings_free(struct stack_dump_state *dump)
+{
+   if (NULL == dump->stack)
+   return;
+
+#ifndef STACK_SIMPLE_STRINGS
+   unsigned count = dump->available;
+   for (unsigned i = 0; i < count; i++)
+   free(dump->stack[i]);
+#endif
+
+   free((void *)dump->stack);
+}
+int stack_dump_strings_fill(struct stack_dump_state *dump)
+{
+   if (NULL != dump->stack)
+   return 0;
+
+#ifdef STACK_SIMPLE_STRINGS
+   dump->stack = backtrace_symbols(dump->raw, dump->available);
+   return dump->stack ? 0 : -ENOMEM;
+#else
+   int retval = stack_dump_symbols_fill(dump);
+   if (0 != retval)
+   return retval;
+
+   unsigned count = dump->available;
+   char **stack = calloc(count, sizeof(char *));
+   if (NULL == stack)
+   return -ENOMEM;
+
+   dump->stack = stack;
+
+   for (unsigned i = 0; i < count; i++)
+   {
+   struct module_symbol *sym = dump->symbols[i];
+   stack[i] = alloc_printf("[0x%8.8x] %s+0x%2.2zu "
+   "soname=%s (base=%8.8x)",
+   sym->sym_addr, sym->sym_name, sym->sym_offset,
+   sym->so_name, sym->so_addr); 
+   if (NULL == stack[i])
+   return -ENOMEM;
+   }
+
+   return 0;
+#endif
+}
+
+void stack_dump_to_fd(struct stack_dump_state *dump, int fd)
+{
+   backtrace_symbols_fd(dump->raw, dump->available, fd);
+}
+
+int stack_fd_dumper(struct stack_dump_state *dump, intptr_t data)
+{
+   stack_dump_to_fd(dump, (int)data);
+   return 0;
+}
+
+int stack_dump(unsigned depth, stack_dumper_t dumper, intptr_t data)
+{
+   void *stack[depth];
+   unsigned nsyms = backtrace(stack, depth);
+
+   struct stack_dump_state state = {
+   .raw = stack,
+   .available = nsyms,
+   .requested = depth,
+   };
+   int retval = (*dumper)(&state, data);
+
+   // stack_dump_fill_symbols() list may need tear-down
+   stack_dump_strings_free(&state);
+   stack_dump_symbols_free(&state);
+
+   return retval;
+}
+
+static void stack_segfault_sighandler(int sig)
+{
+   stack_dump(10, &stack_fd_dumper, 2);
+   exit(1);
+}
+
+int stack_trace_segfaults(void)
+{
+   sighandler_t old = signal(SIGSEGV, &stack_segfault_sighandler);
+   

[Openocd-development] [PATCH 3/4] add -rdynamic to CFLAGS

2009-11-30 Thread Zachary T Welch
The -rdynamic flag provides the information required to produce
more meaningful stack traces.

Signed-off-by: Zachary T Welch 
---
 configure.in |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/configure.in b/configure.in
index 81e4326..224e1b3 100644
--- a/configure.in
+++ b/configure.in
@@ -1082,6 +1082,8 @@ if test $gcc_warnings = yes; then
   CFLAGS="$CFLAGS $GCC_WARNINGS"
 fi
 
+CFLAGS="${CFLAGS} -rdynamic"
+
 # Setup for compiling build tools
 AC_MSG_CHECKING([for a C compiler for build tools])
 if test $cross_compiling = yes; then
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 1/4] add 'module' helper module

2009-11-30 Thread Zachary T Welch
Adds a fully-documented API for dynamically loading libraries and
looking up symbols or addresses in them.

Signed-off-by: Zachary T Welch 
---
 src/helper/Makefile.am |2 +
 src/helper/module.c|   96 
 src/helper/module.h|   73 
 3 files changed, 171 insertions(+), 0 deletions(-)
 create mode 100644 src/helper/module.c
 create mode 100644 src/helper/module.h

diff --git a/src/helper/Makefile.am b/src/helper/Makefile.am
index 22b3c33..13bcbd1 100644
--- a/src/helper/Makefile.am
+++ b/src/helper/Makefile.am
@@ -20,6 +20,7 @@ libhelper_la_SOURCES = \
configuration.c \
log.c \
command.c \
+   module.c \
time_support.c \
replacements.c \
fileio.c \
@@ -42,6 +43,7 @@ noinst_HEADERS = \
log.h \
command.h \
membuf.h \
+   module.h \
time_support.h \
replacements.h \
fileio.h \
diff --git a/src/helper/module.c b/src/helper/module.c
new file mode 100644
index 000..145baa4
--- /dev/null
+++ b/src/helper/module.c
@@ -0,0 +1,96 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "module.h"
+#include 
+#include "log.h"
+
+struct module_instance {
+   /// Name of the module.
+   char *name;
+   /// The handle returned from dlopen
+   void *dlhandle;
+};
+
+void module_free(struct module_instance *module)
+{
+   if (NULL != module->name)
+   free(module->name);
+   if (NULL != module->dlhandle)
+   dlclose(module->dlhandle);
+   free(module);
+}
+
+struct module_instance *module_load(const char *name)
+{
+   struct module_instance *module = calloc(1, sizeof(*module));
+   if (NULL == module)
+   return NULL;
+
+   module->dlhandle = dlopen(name, RTLD_NOW);
+   if (NULL == module->dlhandle)
+   goto module_load_error;
+
+   if (NULL == name)
+   name = "";
+
+   module->name = strdup(name);
+   if (NULL == module->name)
+   goto module_load_error;
+
+   return module;
+
+module_load_error:
+   module_free(module);
+   return NULL;
+}
+
+struct module_symbol *module_symbol_by_addr(void *addr)
+{
+   struct module_symbol *sym = calloc(1, sizeof(*sym));
+   if (NULL == sym)
+   return NULL;
+
+   Dl_info info;
+   int retval = dladdr(addr, &info);
+   if (0 == retval)
+   {
+   free(sym);
+   return NULL;
+   }
+
+   sym->so_name = info.dli_fname;
+   sym->so_addr = info.dli_fbase;
+   sym->sym_name = info.dli_sname;
+   if (NULL != sym->sym_name) {
+   sym->sym_addr = info.dli_saddr;
+   sym->sym_offset = addr - sym->sym_addr;
+   } else {
+   sym->sym_addr = addr;
+   sym->sym_offset = 0;
+   }
+
+   if (NULL == sym->so_name)
+   sym->so_name =  "";
+   if (NULL == sym->sym_name)
+   sym->sym_name = "";
+   return sym;
+}
+
+struct module_symbol *module_symbol_by_name(struct module_instance *module,
+   const char *name)
+{
+   void *addr = dlsym(module->dlhandle, name);
+   return module_symbol_by_addr(addr);
+}
+
+void module_symbol_free(struct module_symbol *sym)
+{
+   assert(sym);
+   free(sym);
+}
+
+const char *module_last_error(void)
+{
+   return dlerror();
+}
diff --git a/src/helper/module.h b/src/helper/module.h
new file mode 100644
index 000..d6d75d7
--- /dev/null
+++ b/src/helper/module.h
@@ -0,0 +1,73 @@
+#ifndef HELPER_MODULE_H
+#define HELPER_MODULE_H
+
+#include "types.h"
+
+struct module_instance;
+
+struct module_symbol {
+   /// shared library name
+   const char *so_name;
+   /// shared library base address
+   void *so_addr;
+   /// current symbol name
+   const char *sym_name;
+   /// current symbol base address
+   void *sym_addr;
+   /// current location (on or after the current symbol, but before next)
+   ssize_t sym_offset;
+};
+
+/**
+ * Load the module with the given name.
+ * @param name The name of the module to load, or NULL to load the
+ * main application.
+ * @returns Returns the new module_instance for the named module, or
+ * NULL on failure.  Use module_last_error() to discover the cause.
+ */
+struct module_instance *module_load(const char *name);
+
+/** 
+ * Release the resources associated with a loaded module instance.
+ * No code may be called from this module after this call, so any
+ * provided entities must be unregistered and deallocated first.
+ * @param module The module that should be unloaded.
+ */
+void module_free(struct module_instance *module);
+
+/**
+ * Find a symbol by name in the specified module.
+ * @param module The mod

[Openocd-development] [PATCH 0/4] add stack backtracing

2009-11-30 Thread Zachary T Welch
Hi all,

This series creates two new helper APIs: 'module' and 'stack'.
It applies on top of my outstanding patches; pull from repo.or.cz.

The 'module' API provides the ability to perform dynamic library
loading and symbol lookup therein.

The 'stack' API provides the ability to obtain backtraces of
the C stack.  It is used to register a SIGSEGV handler to provide
a stack dump on crashs.

The command module is updated to provide a 'stack' command that allows
scripts to see the C stack too.  It's also fun to run 'stack fault' and
receive exactly what you requested.

Unfortunately, the current implementation falls short of a simple
post-processing script that uses 'addr2line'; however, I have looked at
that utility's source code.  It should be possible to use libbfd
(or libelf, or even image.[ch]) to parse our own symbol table and
improve the stack trace output considerably.  This could be done such
that the best available method will be detected and used automatically,
with a configure option to select a specific implementation (i.e. to 
limit dependencies for a binary package releases).

I expect these patches are non-portable at present, but they can be
improved to support different platforms with relative ease.  The same
tricks to acheive this goal will be required to provide selectable
Linux implementations (as suggested above).

Cheers,

Zach

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH] deprecate the global_cmd_ctx pointer

2009-11-29 Thread Zachary T Welch
The global_cmd_ctx variable is never used in-tree, but rather serves the
eCos build.  As such, it does not seem safe remove directly; however, it
represents an architectural blemish and needs to be removed.

Adds comments and ouputs warnings regarding this feature's deprecation.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c |   12 
 src/openocd.c|5 -
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index 9b9c5ec..1cbedae 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -106,8 +106,6 @@ static int command_retval_set(Jim_Interp *interp, int 
retval)
return (retval == ERROR_OK) ? JIM_OK : JIM_ERR;
 }
 
-extern struct command_context *global_cmd_ctx;
-
 void script_debug(Jim_Interp *interp, const char *name,
unsigned argc, Jim_Obj *const *argv)
 {
@@ -164,9 +162,15 @@ static struct command_context 
*current_command_context(Jim_Interp *interp)
struct command_context *cmd_ctx = Jim_GetAssocData(interp, "context");
if (NULL == cmd_ctx)
{
-   /* Tcl can invoke commands directly instead of via 
command_run_line(). This would
-* happen when the Jim Tcl interpreter is provided by eCos.
+   /**
+* Tcl can invoke commands directly instead of via
+* command_run_line(). This would happen when the Jim Tcl
+* interpreter is provided by eCos.
+* NOTE: THIS IS A FUNDAMENTAL DESIGN FLAW.  IT MUST DIE!!!
 */
+   LOG_WARNING("You are using a global command context!!!");
+   LOG_WARNING("This support will be removed in the future!");
+   extern struct command_context *global_cmd_ctx;
cmd_ctx = global_cmd_ctx;
}
return cmd_ctx;
diff --git a/src/openocd.c b/src/openocd.c
index 1be209a..73a24dd 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -191,6 +191,7 @@ static const struct command_registration 
openocd_command_handlers[] = {
COMMAND_REGISTRATION_DONE
 };
 
+/// @todo Remove the global_cmd_ctx pointer; it has been deprecated.
 struct command_context *global_cmd_ctx;
 
 /* NB! this fn can be invoked outside this file for non PC hosted builds */
@@ -201,7 +202,9 @@ struct command_context *setup_command_handler(void)
 
struct command_context *cmd_ctx;
 
-   global_cmd_ctx = cmd_ctx = command_init(openocd_startup_tcl);
+   cmd_ctx = command_init(openocd_startup_tcl);
+   // global that needs to be removed (see definition above)
+   global_cmd_ctx = cmd_ctx;
 
register_commands(cmd_ctx, NULL, openocd_command_handlers);
/* register subsystem commands */
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 5/5] remove interp global variable!

2009-11-29 Thread Zachary T Welch
Finish removing references to the 'interp' global variable from the
command module, encapsulating all reference via command_context.

Eliminates use of the global entirely, so it can be removed.  Hurrah!

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c |   38 --
 src/helper/command.h |2 +-
 src/server/server.c  |2 +-
 3 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index 607693c..9b9c5ec 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -47,7 +47,6 @@
 /* nice short description of source file */
 #define __THIS__FILE__ "command.c"
 
-Jim_Interp *interp = NULL;
 
 static int run_command(struct command_context *context,
struct command *c, const char *words[], unsigned num_words);
@@ -159,7 +158,7 @@ static const char **script_command_args_alloc(
return words;
 }
 
-static struct command_context *current_command_context(void)
+static struct command_context *current_command_context(Jim_Interp *interp)
 {
/* grab the command context from the associated data */
struct command_context *cmd_ctx = Jim_GetAssocData(interp, "context");
@@ -188,7 +187,7 @@ static int script_command_run(Jim_Interp *interp,
if (capture)
state = command_log_capture_start(interp);
 
-   struct command_context *cmd_ctx = current_command_context();
+   struct command_context *cmd_ctx = current_command_context(interp);
int retval = run_command(cmd_ctx, c, (const char **)words, nwords);
 
command_log_capture_finish(state);
@@ -327,8 +326,10 @@ command_new_error:
 
 static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
 
-static int register_command_handler(struct command *c)
+static int register_command_handler(struct command_context *cmd_ctx,
+   struct command *c)
 {
+   Jim_Interp *interp = cmd_ctx->interp;
const char *ocd_name = alloc_printf("ocd_%s", c->name);
if (NULL == ocd_name)
return JIM_ERR;
@@ -377,11 +378,11 @@ struct command* register_command(struct command_context 
*context,
int retval = ERROR_OK;
if (NULL != cr->jim_handler && NULL == parent)
{
-   retval = Jim_CreateCommand(interp, cr->name,
+   retval = Jim_CreateCommand(context->interp, cr->name,
cr->jim_handler, cr->jim_handler_data, NULL);
}
else if (NULL != cr->handler || NULL != parent)
-   retval = register_command_handler(command_root(c));
+   retval = register_command_handler(context, command_root(c));
 
if (ERROR_OK != retval)
{
@@ -615,6 +616,7 @@ int command_run_line(struct command_context *context, char 
*line)
 * happen when the Jim Tcl interpreter is provided by eCos for
 * instance.
 */
+   Jim_Interp *interp = context->interp;
Jim_DeleteAssocData(interp, "context");
retcode = Jim_SetAssocData(interp, "context", NULL, context);
if (retcode == JIM_OK)
@@ -977,7 +979,7 @@ static int command_unknown(Jim_Interp *interp, int argc, 
Jim_Obj *const *argv)
}
script_debug(interp, cmd_name, argc, argv);
 
-   struct command_context *cmd_ctx = current_command_context();
+   struct command_context *cmd_ctx = current_command_context(interp);
struct command *c = cmd_ctx->commands;
int remaining = command_unknown_find(argc, argv, c, &c, true);
// if nothing could be consumed, then it's really an unknown command
@@ -1021,7 +1023,7 @@ static int command_unknown(Jim_Interp *interp, int argc, 
Jim_Obj *const *argv)
 
 static int jim_command_mode(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 {
-   struct command_context *cmd_ctx = current_command_context();
+   struct command_context *cmd_ctx = current_command_context(interp);
enum command_mode mode;
if (argc > 1)
{
@@ -1054,7 +1056,7 @@ static int jim_command_type(Jim_Interp *interp, int argc, 
Jim_Obj *const *argv)
if (1 == argc)
return JIM_ERR;
 
-   struct command_context *cmd_ctx = current_command_context();
+   struct command_context *cmd_ctx = current_command_context(interp);
struct command *c = cmd_ctx->commands;
int remaining = command_unknown_find(argc - 1, argv + 1, c, &c, true);
// if nothing could be consumed, then it's an unknown command
@@ -1276,11 +1278,12 @@ struct command_context* command_init(const char 
*startup_tcl)
 #if !BUILD_ECOSBOARD
Jim_InitEmbedded();
/* Create an interpreter */
-   interp = context->interp = Jim_CreateInterp();
+   context->interp = Jim_CreateInterp();
/* Add all the Jim core commands */
-   Jim_RegisterCo

[Openocd-development] [PATCH 3/5] do not extern 'interp' from command.c

2009-11-29 Thread Zachary T Welch
Adds 'interp' field to command_context, chasing the few remaining
references to the global variable outside of the command module.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c|2 +-
 src/helper/command.h|3 +--
 src/jtag/core.c |2 +-
 src/openocd.c   |2 +-
 src/server/httpd.c  |   18 +++---
 src/server/server.c |4 ++--
 src/server/server.h |2 +-
 src/server/tcl_server.c |7 +--
 src/server/tcl_server.h |2 +-
 src/target/target.c |   11 +++
 src/target/target.h |1 -
 11 files changed, 31 insertions(+), 23 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index 319f081..5df4a45 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -1257,7 +1257,7 @@ struct command_context* command_init(const char 
*startup_tcl)
 #if !BUILD_ECOSBOARD
Jim_InitEmbedded();
/* Create an interpreter */
-   interp = Jim_CreateInterp();
+   interp = context->interp = Jim_CreateInterp();
/* Add all the Jim core commands */
Jim_RegisterCoreCommands(interp);
 #endif
diff --git a/src/helper/command.h b/src/helper/command.h
index 0723596..f27364e 100644
--- a/src/helper/command.h
+++ b/src/helper/command.h
@@ -59,6 +59,7 @@ typedef int (*command_output_handler_t)(struct 
command_context *context,
 
 struct command_context
 {
+   Jim_Interp *interp;
enum command_mode mode;
struct command *commands;
int current_target;
@@ -359,8 +360,6 @@ void process_jim_events(void);
 #defineERROR_COMMAND_ARGUMENT_OVERFLOW (-604)
 #defineERROR_COMMAND_ARGUMENT_UNDERFLOW(-605)
 
-extern Jim_Interp *interp;
-
 int parse_ulong(const char *str, unsigned long *ul);
 int parse_ullong(const char *str, unsigned long long *ul);
 
diff --git a/src/jtag/core.c b/src/jtag/core.c
index 211b9d5..9230cc2 100644
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -1535,7 +1535,7 @@ int jtag_init(struct command_context *cmd_ctx)
if ((retval = jtag_execute_queue()) != ERROR_OK)
return retval;
 
-   if (Jim_Eval_Named(interp, "jtag_init", __FILE__, __LINE__) != JIM_OK)
+   if (Jim_Eval_Named(cmd_ctx->interp, "jtag_init", __FILE__, __LINE__) != 
JIM_OK)
return ERROR_FAIL;
 
return ERROR_OK;
diff --git a/src/openocd.c b/src/openocd.c
index 2a65b4d..1be209a 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -277,7 +277,7 @@ int openocd_main(int argc, char *argv[])
return EXIT_FAILURE;
 #endif
 
-   ret = server_init();
+   ret = server_init(cmd_ctx);
if (ERROR_OK != ret)
return EXIT_FAILURE;
 
diff --git a/src/server/httpd.c b/src/server/httpd.c
index 9fa5879..b346ca2 100644
--- a/src/server/httpd.c
+++ b/src/server/httpd.c
@@ -180,6 +180,7 @@ httpd_Jim_Command_formfetch(Jim_Interp *interp,
 struct httpd_request
 {
int post;
+   Jim_Interp *interp;
struct MHD_PostProcessor *postprocessor;
 
//Jim_Obj *dict;
@@ -208,7 +209,8 @@ static void request_completed(void *cls, struct 
MHD_Connection *connection,
 }
 
 /* append to said key in dictionary */
-static void append_key(struct httpd_request *r, const char *key,
+static void append_key(Jim_Interp *interp,
+   struct httpd_request *r, const char *key,
const char *data, size_t off, size_t size)
 {
Jim_Obj *keyObj = Jim_NewStringObj(interp, key, -1);
@@ -259,7 +261,7 @@ static int iterate_post(void *con_cls, enum MHD_ValueKind 
kind,
 {
struct httpd_request *r = (struct httpd_request*) con_cls;
 
-   append_key(r, key, data, off, size);
+   append_key(r->interp, r, key, data, off, size);
 
return MHD_YES;
 }
@@ -268,12 +270,13 @@ static int record_arg(void *cls, enum MHD_ValueKind kind, 
const char *key,
const char *value)
 {
struct httpd_request *r = (struct httpd_request*) cls;
-   append_key(r, key, value, 0, strlen(value));
+   append_key(r->interp, r, key, value, 0, strlen(value));
return MHD_YES;
 }
 
 
-static int handle_request(struct MHD_Connection * connection, const char * url)
+static int handle_request(Jim_Interp *interp,
+   struct MHD_Connection * connection, const char * url)
 {
struct MHD_Response * response;
 
@@ -358,6 +361,7 @@ static int ahc_echo_inner(void * cls, struct MHD_Connection 
* connection,
const char * url, const char * method, const char * version,
const char * upload_data, size_t * upload_data_size, void ** 
ptr)
 {
+   Jim_Interp *interp = (Jim_Interp *)cls;
int post = 0;
 
if (0 == strcmp(method, "POST"))
@@ -384,7 +388,7 @@ static int ahc_echo_inner(void * cls, struct MHD_Connection 
* connection,
memset(*ptr, 0, sizeof(struct httpd_request));
 
r = (struc

[Openocd-development] [PATCH 1/5] jtag: avoid using interp global variable

2009-11-29 Thread Zachary T Welch
Adds 'interp' field to jtag_tap_event_action structure to avoid
using the global variable of same name.

Signed-off-by: Zachary T Welch 
---
 src/jtag/jtag.h |   11 ---
 src/jtag/tcl.c  |8 +---
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h
index d4fafa3..ee96775 100644
--- a/src/jtag/jtag.h
+++ b/src/jtag/jtag.h
@@ -209,9 +209,14 @@ enum jtag_event {
 
 struct jtag_tap_event_action
 {
-   enum jtag_event event;
-   Jim_Obj* body;
-   struct jtag_tap_event_action* next;
+   /// The event for which this action will be triggered.
+   enum jtag_event event;
+   /// The interpreter to use for evaluating the @c body.
+   Jim_Interp *interp;
+   /// Contains a script to 'eval' when the @c event is triggered.
+   Jim_Obj *body;
+   // next action in linked list
+   struct jtag_tap_event_action *next;
 };
 
 /**
diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index 7ec7fa4..68bb21e 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -341,8 +341,9 @@ static int jtag_tap_configure_event(Jim_GetOptInfo *goi, 
struct jtag_tap * tap)
if (!found)
jteap = calloc(1, sizeof(*jteap));
else if (NULL != jteap->body)
-   Jim_DecrRefCount(interp, jteap->body);
+   Jim_DecrRefCount(goi->interp, jteap->body);
 
+   jteap->interp = goi->interp;
jteap->event = n->value;
 
Jim_Obj *o;
@@ -359,6 +360,7 @@ static int jtag_tap_configure_event(Jim_GetOptInfo *goi, 
struct jtag_tap * tap)
}
else if (found)
{
+   jteap->interp = goi->interp;
Jim_SetResult(goi->interp,
Jim_DuplicateObj(goi->interp, jteap->body));
}
@@ -616,9 +618,9 @@ static void jtag_tap_handle_event(struct jtag_tap *tap, 
enum jtag_event e)
tap->dotted_name, e, nvp->name,
Jim_GetString(jteap->body, NULL));
 
-   if (Jim_EvalObj(interp, jteap->body) != JIM_OK)
+   if (Jim_EvalObj(jteap->interp, jteap->body) != JIM_OK)
{
-   Jim_PrintErrorMessage(interp);
+   Jim_PrintErrorMessage(jteap->interp);
continue;
}
 
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 4/5] command output capture: do not use interp global

2009-11-29 Thread Zachary T Welch
Adds a log_capture_state structure to pass to the log capture
callback used by the command module.  Ensures that the capture occurs
in the proper context.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c |   49 ++---
 1 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index 5df4a45..607693c 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -52,30 +52,50 @@ Jim_Interp *interp = NULL;
 static int run_command(struct command_context *context,
struct command *c, const char *words[], unsigned num_words);
 
+struct log_capture_state {
+   Jim_Interp *interp;
+   Jim_Obj *output;
+};
+
 static void tcl_output(void *privData, const char *file, unsigned line,
const char *function, const char *string)
 {
-   Jim_Obj *tclOutput = (Jim_Obj *)privData;
-   Jim_AppendString(interp, tclOutput, string, strlen(string));
+   struct log_capture_state *state = (struct log_capture_state *)privData;
+   Jim_AppendString(state->interp, state->output, string, strlen(string));
 }
 
-static Jim_Obj *command_log_capture_start(Jim_Interp *interp)
+static struct log_capture_state *command_log_capture_start(Jim_Interp *interp)
 {
/* capture log output and return it. A garbage collect can
 * happen, so we need a reference count to this object */
Jim_Obj *tclOutput = Jim_NewStringObj(interp, "", 0);
if (NULL == tclOutput)
return NULL;
+
+   struct log_capture_state *state = malloc(sizeof(*state));
+   if (NULL == state)
+   return NULL;
+
+   state->interp = interp;
Jim_IncrRefCount(tclOutput);
-   log_add_callback(tcl_output, tclOutput);
-   return tclOutput;
+   state->output = tclOutput;
+
+   log_add_callback(tcl_output, state);
+
+   return state;
 }
 
-static void command_log_capture_finish(Jim_Interp *interp, Jim_Obj *tclOutput)
+static void command_log_capture_finish(struct log_capture_state *state)
 {
-   log_remove_callback(tcl_output, tclOutput);
-   Jim_SetResult(interp, tclOutput);
-   Jim_DecrRefCount(interp, tclOutput);
+   if (NULL == state)
+   return;
+
+   log_remove_callback(tcl_output, state);
+
+   Jim_SetResult(state->interp, state->output);
+   Jim_DecrRefCount(state->interp, state->output);
+
+   free(state);
 }
 
 static int command_retval_set(Jim_Interp *interp, int retval)
@@ -164,15 +184,14 @@ static int script_command_run(Jim_Interp *interp,
if (NULL == words)
return JIM_ERR;
 
-   Jim_Obj *tclOutput = NULL;
+   struct log_capture_state *state = NULL;
if (capture)
-   tclOutput = command_log_capture_start(interp);
+   state = command_log_capture_start(interp);
 
struct command_context *cmd_ctx = current_command_context();
int retval = run_command(cmd_ctx, c, (const char **)words, nwords);
 
-   if (capture)
-   command_log_capture_finish(interp, tclOutput);
+   command_log_capture_finish(state);
 
script_command_args_free(words, nwords);
return command_retval_set(interp, retval);
@@ -804,12 +823,12 @@ static int jim_capture(Jim_Interp *interp, int argc, 
Jim_Obj *const *argv)
if (argc != 2)
return JIM_ERR;
 
-   Jim_Obj *tclOutput = command_log_capture_start(interp);
+   struct log_capture_state *state = command_log_capture_start(interp);
 
const char *str = Jim_GetString(argv[1], NULL);
int retcode = Jim_Eval_Named(interp, str, __THIS__FILE__, __LINE__);
 
-   command_log_capture_finish(interp, tclOutput);
+   command_log_capture_finish(state);
 
return retcode;
 }
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 2/5] target: avoid using interp global variable

2009-11-29 Thread Zachary T Welch
Adds 'interp' to target_event_action structure to avoid using the
global variable of the same name.

Signed-off-by: Zachary T Welch 
---
 src/target/target.c |   19 ++-
 src/target/target.h |1 +
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/src/target/target.c b/src/target/target.c
index 3a84040..4297258 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -3524,9 +3524,9 @@ void target_handle_event(struct target *target, enum 
target_event e)
   e,
   
Jim_Nvp_value2name_simple(nvp_target_event, e)->name,
   Jim_GetString(teap->body, NULL));
-   if (Jim_EvalObj(interp, teap->body) != JIM_OK)
+   if (Jim_EvalObj(teap->interp, teap->body) != JIM_OK)
{
-   Jim_PrintErrorMessage(interp);
+   Jim_PrintErrorMessage(teap->interp);
}
}
}
@@ -3668,9 +3668,10 @@ static int target_configure(Jim_GetOptInfo *goi, struct 
target *target)
replace = false;
}
teap->event = n->value;
+   teap->interp = goi->interp;
Jim_GetOpt_Obj(goi, &o);
if (teap->body) {
-   Jim_DecrRefCount(interp, 
teap->body);
+   Jim_DecrRefCount(teap->interp, 
teap->body);
}
teap->body  = 
Jim_DuplicateObj(goi->interp, o);
/*
@@ -3718,7 +3719,7 @@ static int target_configure(Jim_GetOptInfo *goi, struct 
target *target)
goto no_params;
}
}
-   Jim_SetResult(interp, Jim_NewIntObj(goi->interp, 
target->working_area_virt));
+   Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, 
target->working_area_virt));
/* loop for more */
break;
 
@@ -3736,7 +3737,7 @@ static int target_configure(Jim_GetOptInfo *goi, struct 
target *target)
goto no_params;
}
}
-   Jim_SetResult(interp, Jim_NewIntObj(goi->interp, 
target->working_area_phys));
+   Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, 
target->working_area_phys));
/* loop for more */
break;
 
@@ -3753,7 +3754,7 @@ static int target_configure(Jim_GetOptInfo *goi, struct 
target *target)
goto no_params;
}
}
-   Jim_SetResult(interp, Jim_NewIntObj(goi->interp, 
target->working_area_size));
+   Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, 
target->working_area_size));
/* loop for more */
break;
 
@@ -3771,7 +3772,7 @@ static int target_configure(Jim_GetOptInfo *goi, struct 
target *target)
goto no_params;
}
}
-   Jim_SetResult(interp, Jim_NewIntObj(goi->interp, 
target->backup_working_area));
+   Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, 
target->backup_working_area));
/* loop for more e*/
break;
 
@@ -3838,7 +3839,7 @@ static int target_configure(Jim_GetOptInfo *goi, struct 
target *target)
goto no_params;
}
}
-   Jim_SetResultString(interp, target->tap->dotted_name, 
-1);
+   Jim_SetResultString(goi->interp, 
target->tap->dotted_name, -1);
/* loop for more e*/
break;
}
@@ -4486,7 +4487,7 @@ static int target_create(Jim_GetOptInfo *goi)
 
if (target->tap == NULL)
{
-   Jim_SetResultString(interp, "-chain-position required when 
creating target", -1);
+   Jim_SetResultString(goi->interp, "-chain-position required when 
creating target", -1);
e = JIM_ERR;
}
 
diff --git a/src/target/target.h b/src/target/target.h
index 009ec17..af4727c 100644
--- a/src/target/t

[Openocd-development] [PATCH 0/5] remove interp global variable

2009-11-29 Thread Zachary T Welch
Hi all,

This series removes the 'interp' global variable from the system,
bringing us a step closer to supporting several active command contexts.

Applies on top of the last to series.  All three may be pulled from
my repo.or.cz mirror master branch.

Cheers,

Zach

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 4/4] fix foo command group help messages

2009-11-29 Thread Zachary T Welch
Splits the old help strings to provide proper usage as well.

Signed-off-by: Zachary T Welch 
---
 src/hello.c |9 ++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/src/hello.c b/src/hello.c
index 2e5c928..cfd6e2f 100644
--- a/src/hello.c
+++ b/src/hello.c
@@ -58,19 +58,22 @@ static const struct command_registration 
foo_command_handlers[] = {
.name = "bar",
.handler = &handle_foo_command,
.mode = COMMAND_ANY,
-   .help = " [enable|disable] - an example command",
+   .usage = " [enable|disable]",
+   .help = "an example command",
},
{
.name = "baz",
.handler = &handle_foo_command,
.mode = COMMAND_ANY,
-   .help = " [enable|disable] - a sample command",
+   .usage = " [enable|disable]",
+   .help = "a sample command",
},
{
.name = "flag",
.handler = &handle_flag_command,
.mode = COMMAND_ANY,
-   .help = "[on|off] - set a flag",
+   .usage = "[on|off]",
+   .help = "set a flag",
},
COMMAND_REGISTRATION_DONE
 };
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 3/4] make syntax errors respond with 'usage'

2009-11-29 Thread Zachary T Welch
The 'help' text will become more verbose, so its entire text will be
far more than desired when you only borked your syntax.  The usage
still allows the commands to be looked up for more help.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c   |6 +++---
 src/helper/startup.tcl |2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index 6031ce6..319f081 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -562,7 +562,7 @@ static int run_command(struct command_context *context,
/* Print help for command */
char *full_name = command_name(c, ' ');
if (NULL != full_name) {
-   command_run_linef(context, "help %s", full_name);
+   command_run_linef(context, "usage %s", full_name);
free(full_name);
} else
retval = -ENOMEM;
@@ -980,10 +980,10 @@ static int command_unknown(Jim_Interp *interp, int argc, 
Jim_Obj *const *argv)
}
else
{
-   c = command_find(cmd_ctx->commands, "help");
+   c = command_find(cmd_ctx->commands, "usage");
if (NULL == c)
{
-   LOG_ERROR("unknown command, but help is missing too");
+   LOG_ERROR("unknown command, but usage is missing too");
return JIM_ERR;
}
count = argc - remaining;
diff --git a/src/helper/startup.tcl b/src/helper/startup.tcl
index dda89c8..d1c73ef 100644
--- a/src/helper/startup.tcl
+++ b/src/helper/startup.tcl
@@ -25,7 +25,7 @@ proc ocd_bouncer {name args} {
set errmsg "Command handler execution failed"
}
} else {if {$type == "group"} {
-   catch {eval ocd_help $name $args}
+   catch {eval ocd_usage $name $args}
set errmsg [format "%s: command requires more arguments" \
[concat $name " " $args]]
} else {
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 2/4] move improperly located documentation

2009-11-29 Thread Zachary T Welch
Somehow, the comment block for command handlers ended up associated
with the output_handler.  Move it to the command_handler_t declaration.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.h |   32 +---
 1 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/src/helper/command.h b/src/helper/command.h
index 72c5647..0723596 100644
--- a/src/helper/command.h
+++ b/src/helper/command.h
@@ -62,20 +62,6 @@ struct command_context
enum command_mode mode;
struct command *commands;
int current_target;
-   /* Execute a command.
-*
-* If the command fails, it *MUST* return a value != ERROR_OK
-* (many commands break this rule, patches welcome!)
-*
-* This is *especially* important for commands such as writing
-* to flash or verifying memory. The reason is that those commands
-* can be used by programs to determine if the operation succeded
-* or not. If the operation failed, then a program can try
-* an alternative approach.
-*
-* Returning ERROR_COMMAND_SYNTAX_ERROR will have the effect of
-* printing out the syntax of the command.
-*/
command_output_handler_t output_handler;
void *output_handler_priv;
 };
@@ -166,7 +152,23 @@ struct command_invocation {
 #define CMD_DATA CMD_CURRENT->jim_handler_data
 
 
-/// The type signature for commands' handler functions.
+/**
+ * The type signature for command handling functions.  They are
+ * usually registered as part of command_registration, providing
+ * a high-level means for executing a command.
+ *
+ * If the command fails, it *MUST* return a value != ERROR_OK
+ * (many commands break this rule, patches welcome!)
+ *
+ * This is *especially* important for commands such as writing
+ * to flash or verifying memory. The reason is that those commands
+ * can be used by programs to determine if the operation succeded
+ * or not. If the operation failed, then a program can try
+ * an alternative approach.
+ *
+ * Returning ERROR_COMMAND_SYNTAX_ERROR will have the effect of
+ * printing out the syntax of the command.
+ */
 typedef __COMMAND_HANDLER((*command_handler_t));
 
 struct command
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 1/4] improve command_done() API and docs

2009-11-29 Thread Zachary T Welch
command_done() does not need to return an error, but it needed
Doxygen comment.  Provide some for copy_command_context as well.

Note: this audit revealed some potential bugs with the command context
implementation.  There was a reason that commands were added at the
end of the list.  Shallow copying of command_context means that
the list is shared between them.  And commands added at the top-level
before the pre-existing commands will not be available in the shared
context as they were before.  Yikes!

Fortunately, this does not seem to occur in general use, as
'add_help_text' gets registered in startup.tcl and claims the first slot
in my own test cases.  Thus, it seems that we have been masking the issue
for now, but it shows the need for further architectural improvement in
the core command module.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c |8 
 src/helper/command.h |   17 +++--
 2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index ac7c8d8..6031ce6 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -683,12 +683,12 @@ struct command_context* copy_command_context(struct 
command_context* context)
return copy_context;
 }
 
-int command_done(struct command_context *context)
+void command_done(struct command_context *cmd_ctx)
 {
-   free(context);
-   context = NULL;
+   if (NULL == cmd_ctx)
+   return;
 
-   return ERROR_OK;
+   free(cmd_ctx);
 }
 
 /* find full path to file */
diff --git a/src/helper/command.h b/src/helper/command.h
index 2d33484..72c5647 100644
--- a/src/helper/command.h
+++ b/src/helper/command.h
@@ -316,7 +316,6 @@ void command_set_handler_data(struct command *c, void *p);
 void command_set_output_handler(struct command_context* context,
command_output_handler_t output_handler, void *priv);
 
-struct command_context* copy_command_context(struct command_context* context);
 
 int command_context_mode(struct command_context *context, enum command_mode 
mode);
 
@@ -324,7 +323,21 @@ int command_context_mode(struct command_context *context, 
enum command_mode mode
  * Creates a new command context using the startup TCL provided.
  */
 struct command_context* command_init(const char *startup_tcl);
-int command_done(struct command_context *context);
+/**
+ * Creates a copy of an existing command context.  This does not create
+ * a deep copy of the command list, so modifications in one context will
+ * affect all shared contexts.  The caller must track reference counting
+ * and ensure the commands are freed before destroying the last instance.
+ * @param cmd_ctx The command_context that will be copied.
+ * @returns A new command_context with the same state as the original.
+ */
+struct command_context* copy_command_context(struct command_context* cmd_ctx);
+/**
+ * Frees the resources associated with a command context.  The commands
+ * are not removed, so unregister_all_commands() must be called first.
+ * @param cmd_ctx The command_context that will be destroyed.
+ */
+void command_done(struct command_context *context);
 
 void command_print(struct command_context *context, const char *format, ...)
__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3)));
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 0/4] minor cleaning and audit

2009-11-29 Thread Zachary T Welch
Hi all,

This series includes only minor changes.  Applies on top of the last
series to allow deferred 'init'.

Cheers,

Zach

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 2/3->3/4] allow deferal of init

2009-11-29 Thread Zachary T Welch
Adds 'noinit' command to prevent OpenOCD from running 'init' at the end
up startup, allowing it to be given from telnet or TCL.  This provides
the old behavior by default, and users can add this command to their
scripts to get the new behavior.

Signed-off-by: Zachary T Welch 
---
 src/openocd.c |   27 +++
 1 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/src/openocd.c b/src/openocd.c
index 287a819..2a65b4d 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -91,6 +91,16 @@ static int log_target_callback_event_handler(struct target 
*target, enum target_
 
 int ioutil_init(struct command_context *cmd_ctx);
 
+static bool init_at_startup = true;
+
+COMMAND_HANDLER(handle_noinit_command)
+{
+   if (CMD_ARGC != 0)
+   return ERROR_COMMAND_SYNTAX_ERROR;
+   init_at_startup = false;
+   return ERROR_OK;
+}
+
 /* OpenOCD can't really handle failure of this command. Patches welcome! :-) */
 COMMAND_HANDLER(handle_init_command)
 {
@@ -159,15 +169,24 @@ static const struct command_registration 
openocd_command_handlers[] = {
{
.name = "version",
.handler = &handle_version_command,
-   .mode = COMMAND_EXEC,
+   .mode = COMMAND_ANY,
.help = "show program version",
},
{
+   .name = "noinit",
+   .handler = &handle_noinit_command,
+   .mode = COMMAND_CONFIG,
+   .help = "Prevent 'init' from being called at startup.",
+   },
+   {
.name = "init",
.handler = &handle_init_command,
-   .mode = COMMAND_ANY,
+   .mode = COMMAND_CONFIG,
.help = "Initializes configured targets and servers.  "
-   "If called more than once, does nothing.",
+   "Changes command mode from CONFIG to EXEC.  "
+   "Unless 'noinit' is called, this command is "
+   "called automatically at the end of startup.",
+
},
COMMAND_REGISTRATION_DONE
 };
@@ -262,7 +281,7 @@ int openocd_main(int argc, char *argv[])
if (ERROR_OK != ret)
return EXIT_FAILURE;
 
-   if (1)
+   if (init_at_startup)
{
ret = command_run_line(cmd_ctx, "init");
if (ERROR_OK != ret)
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 2/3->2/4] move server_init() to openocd_main()

2009-11-29 Thread Zachary T Welch
Moves the telnet and TCL server startup to server_init(), moving their
respective command registration in to server_register_commands().
Adds proper error checking for these particular startup processes.

Moves the core server startup to openocd_main(), improving related error
checking and preparing to defer 'init'.

Signed-off-by: Zachary T Welch 
---
 src/openocd.c   |   31 +--
 src/server/server.c |   16 +++-
 2 files changed, 28 insertions(+), 19 deletions(-)

diff --git a/src/openocd.c b/src/openocd.c
index 7f6af4c..287a819 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -38,9 +38,7 @@
 #include "mflash.h"
 
 #include "server.h"
-#include "telnet_server.h"
 #include "gdb_server.h"
-#include "tcl_server.h"
 #include "httpd.h"
 
 #ifdef HAVE_STRINGS_H
@@ -149,13 +147,8 @@ COMMAND_HANDLER(handle_init_command)
return ERROR_FAIL;
LOG_DEBUG("pld init complete");
 
-   /* initialize tcp server */
-   server_init();
-
/* initialize telnet subsystem */
-   telnet_init("Open On-Chip Debugger");
gdb_target_add_all(all_targets);
-   tcl_init(); /* allows tcl to just connect without going thru telnet */
 
target_register_event_callback(log_target_callback_event_handler, 
CMD_CTX);
 
@@ -194,9 +187,7 @@ struct command_context *setup_command_handler(void)
register_commands(cmd_ctx, NULL, openocd_command_handlers);
/* register subsystem commands */
server_register_commands(cmd_ctx);
-   telnet_register_commands(cmd_ctx);
gdb_register_commands(cmd_ctx);
-   tcl_register_commands(cmd_ctx); /* tcl server commands */
log_register_commands(cmd_ctx);
jtag_register_commands(cmd_ctx);
xsvf_register_commands(cmd_ctx);
@@ -259,7 +250,7 @@ int openocd_main(int argc, char *argv[])
return EXIT_FAILURE;
 
ret = parse_config_file(cmd_ctx);
-   if ((ret != ERROR_OK) && (ret != ERROR_COMMAND_CLOSE_CONNECTION))
+   if (ret != ERROR_OK)
return EXIT_FAILURE;
 
 #if BUILD_HTTPD
@@ -267,16 +258,21 @@ int openocd_main(int argc, char *argv[])
return EXIT_FAILURE;
 #endif
 
-   if (ret != ERROR_COMMAND_CLOSE_CONNECTION)
+   ret = server_init();
+   if (ERROR_OK != ret)
+   return EXIT_FAILURE;
+
+   if (1)
{
-   if (command_run_line(cmd_ctx, "init") != ERROR_OK)
-   return EXIT_FAILURE;
+   ret = command_run_line(cmd_ctx, "init");
+   if (ERROR_OK != ret)
+   ret = EXIT_FAILURE;
+   }
 
-   /* handle network connections */
+   /* handle network connections */
+   if (ERROR_OK == ret)
server_loop(cmd_ctx);
-   }
 
-   /* shut server down */
server_quit();
 
 #if BUILD_HTTPD
@@ -288,6 +284,5 @@ int openocd_main(int argc, char *argv[])
/* free commandline interface */
command_done(cmd_ctx);
 
-
-   return EXIT_SUCCESS;
+   return ret;
 }
diff --git a/src/server/server.c b/src/server/server.c
index 3ba433e..256c590 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -30,6 +30,8 @@
 #include "server.h"
 #include "target.h"
 #include "openocd.h"
+#include "tcl_server.h"
+#include "telnet_server.h"
 
 #include 
 
@@ -516,7 +518,11 @@ int server_init(void)
signal(SIGABRT, sig_handler);
 #endif
 
-   return ERROR_OK;
+   int ret = tcl_init();
+   if (ERROR_OK != ret)
+   return ret;
+
+   return telnet_init("Open On-Chip Debugger");
 }
 
 int server_quit(void)
@@ -551,6 +557,14 @@ static const struct command_registration 
server_command_handlers[] = {
 
 int server_register_commands(struct command_context *cmd_ctx)
 {
+   int retval = telnet_register_commands(cmd_ctx);
+   if (ERROR_OK != retval)
+   return retval;
+
+   retval = tcl_register_commands(cmd_ctx);
+   if (ERROR_OK != retval)
+   return retval;
+
return register_commands(cmd_ctx, NULL, server_command_handlers);
 }
 
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 3/3] only display usable commands in help

2009-11-29 Thread Zachary T Welch
With the ability to defer 'init', users can access the help system while
still in CONFIG mode.  This patch omits commands from the help and usage
list when they cannot be run in the current command mode, making it much
easier to see what can be done at a given time.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index ce857dd..ac7c8d8 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -872,6 +872,9 @@ static void command_help_show_wrap(const char *str, 
unsigned n, unsigned n2)
 static COMMAND_HELPER(command_help_show, struct command *c, unsigned n,
bool show_help)
 {
+   if (!command_can_run(CMD_CTX, c))
+   return ERROR_OK;
+
char *cmd_name = command_name(c, ' ');
if (NULL == cmd_name)
return -ENOMEM;
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 2/3] allow deferal of init

2009-11-29 Thread Zachary T Welch
Moves the telnet and TCL server startup to server_init(), moving their
respective command registration in to server_register_commands().
Adds proper error checking for these particular startup processes.

Adds 'noinit' command to prevent OpenOCD from running 'init' at the end
up startup, allowing it to be given from telnet or TCL.  This provides
the old behavior by default, and users can add this command to their
scripts to get the new behavior.

Improves related error checking in openocd_main().

Signed-off-by: Zachary T Welch 
---
 src/openocd.c   |   56 +++---
 src/server/server.c |   16 +-
 2 files changed, 50 insertions(+), 22 deletions(-)

diff --git a/src/openocd.c b/src/openocd.c
index 7f6af4c..2a65b4d 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -38,9 +38,7 @@
 #include "mflash.h"
 
 #include "server.h"
-#include "telnet_server.h"
 #include "gdb_server.h"
-#include "tcl_server.h"
 #include "httpd.h"
 
 #ifdef HAVE_STRINGS_H
@@ -93,6 +91,16 @@ static int log_target_callback_event_handler(struct target 
*target, enum target_
 
 int ioutil_init(struct command_context *cmd_ctx);
 
+static bool init_at_startup = true;
+
+COMMAND_HANDLER(handle_noinit_command)
+{
+   if (CMD_ARGC != 0)
+   return ERROR_COMMAND_SYNTAX_ERROR;
+   init_at_startup = false;
+   return ERROR_OK;
+}
+
 /* OpenOCD can't really handle failure of this command. Patches welcome! :-) */
 COMMAND_HANDLER(handle_init_command)
 {
@@ -149,13 +157,8 @@ COMMAND_HANDLER(handle_init_command)
return ERROR_FAIL;
LOG_DEBUG("pld init complete");
 
-   /* initialize tcp server */
-   server_init();
-
/* initialize telnet subsystem */
-   telnet_init("Open On-Chip Debugger");
gdb_target_add_all(all_targets);
-   tcl_init(); /* allows tcl to just connect without going thru telnet */
 
target_register_event_callback(log_target_callback_event_handler, 
CMD_CTX);
 
@@ -166,15 +169,24 @@ static const struct command_registration 
openocd_command_handlers[] = {
{
.name = "version",
.handler = &handle_version_command,
-   .mode = COMMAND_EXEC,
+   .mode = COMMAND_ANY,
.help = "show program version",
},
{
+   .name = "noinit",
+   .handler = &handle_noinit_command,
+   .mode = COMMAND_CONFIG,
+   .help = "Prevent 'init' from being called at startup.",
+   },
+   {
.name = "init",
.handler = &handle_init_command,
-   .mode = COMMAND_ANY,
+   .mode = COMMAND_CONFIG,
.help = "Initializes configured targets and servers.  "
-   "If called more than once, does nothing.",
+   "Changes command mode from CONFIG to EXEC.  "
+   "Unless 'noinit' is called, this command is "
+   "called automatically at the end of startup.",
+
},
COMMAND_REGISTRATION_DONE
 };
@@ -194,9 +206,7 @@ struct command_context *setup_command_handler(void)
register_commands(cmd_ctx, NULL, openocd_command_handlers);
/* register subsystem commands */
server_register_commands(cmd_ctx);
-   telnet_register_commands(cmd_ctx);
gdb_register_commands(cmd_ctx);
-   tcl_register_commands(cmd_ctx); /* tcl server commands */
log_register_commands(cmd_ctx);
jtag_register_commands(cmd_ctx);
xsvf_register_commands(cmd_ctx);
@@ -259,7 +269,7 @@ int openocd_main(int argc, char *argv[])
return EXIT_FAILURE;
 
ret = parse_config_file(cmd_ctx);
-   if ((ret != ERROR_OK) && (ret != ERROR_COMMAND_CLOSE_CONNECTION))
+   if (ret != ERROR_OK)
return EXIT_FAILURE;
 
 #if BUILD_HTTPD
@@ -267,16 +277,21 @@ int openocd_main(int argc, char *argv[])
return EXIT_FAILURE;
 #endif
 
-   if (ret != ERROR_COMMAND_CLOSE_CONNECTION)
+   ret = server_init();
+   if (ERROR_OK != ret)
+   return EXIT_FAILURE;
+
+   if (init_at_startup)
{
-   if (command_run_line(cmd_ctx, "init") != ERROR_OK)
-   return EXIT_FAILURE;
+   ret = command_run_line(cmd_ctx, "init");
+   if (ERROR_OK != ret)
+   ret = EXIT_FAILURE;
+   }
 
-   /* handle network connections */
+   /* handle network connections */
+   if (ERROR_OK == ret)
server_loop(cmd_ctx);
-   }
 
-   /* shut server down */
server_quit();
 
 #if BUILD_HTTPD
@@ -288,6 +303

[Openocd-development] [PATCH 1/3] improve gdb_init() sequence

2009-11-29 Thread Zachary T Welch
Rework gdb_init to create flexible APIs (gdb_target_add_{one,all}) and
static helper (gdb_target_start) for starting GDB services.  Eliminates
duplicated code and provides general mechanisms for adding GDB services.
The 'init' command is updated to call the new API, and later patches can
decouple its policy of adding all targets therein.

Provides the new capability to use both piped and TCP servers when
multiple targets are defined.  The first target fills the pipe, and
others will be started on TCP ports (unless disabled, i.e. gdb_port=0).

Signed-off-by: Zachary T Welch 
---
 src/openocd.c   |2 +-
 src/server/gdb_server.c |   79 +++---
 src/server/gdb_server.h |3 +-
 3 files changed, 49 insertions(+), 35 deletions(-)

diff --git a/src/openocd.c b/src/openocd.c
index 01e9e79..7f6af4c 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -154,7 +154,7 @@ COMMAND_HANDLER(handle_init_command)
 
/* initialize telnet subsystem */
telnet_init("Open On-Chip Debugger");
-   gdb_init();
+   gdb_target_add_all(all_targets);
tcl_init(); /* allows tcl to just connect without going thru telnet */
 
target_register_event_callback(log_target_callback_event_handler, 
CMD_CTX);
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
index 3c099fa..7fb36e4 100644
--- a/src/server/gdb_server.c
+++ b/src/server/gdb_server.c
@@ -2189,55 +2189,68 @@ int gdb_input(struct connection *connection)
return ERROR_OK;
 }
 
-int gdb_init(void)
+static int gdb_target_start(struct target *target, uint16_t port)
 {
-   struct gdb_service *gdb_service;
-   struct target *target = all_targets;
+   bool use_pipes = 0 == port;
+   struct gdb_service *gdb_service = malloc(sizeof(struct gdb_service));
+   if (NULL == gdb_service)
+   return -ENOMEM;
 
-   if (!target)
-   {
-   LOG_WARNING("no gdb ports allocated as no target has been 
specified");
-   return ERROR_OK;
-   }
+   gdb_service->target = target;
 
+   add_service("gdb", use_pipes ? CONNECTION_PIPE : CONNECTION_TCP,
+   port, 1, &gdb_new_connection, &gdb_input,
+   &gdb_connection_closed, gdb_service);
+
+   const char *name = target_name(target);
+   if (use_pipes)
+   LOG_DEBUG("gdb service for target '%s' using pipes", name);
+   else
+   LOG_DEBUG("gdb service for target '%s' on TCP port %u", name, 
port);
+   return ERROR_OK;
+}
+
+int gdb_target_add_one(struct target *target)
+{
if (gdb_port == 0 && server_use_pipes == 0)
{
LOG_INFO("gdb port disabled");
return ERROR_OK;
}
 
-   if (server_use_pipes)
+   bool use_pipes = server_use_pipes;
+   static bool server_started_with_pipes = false;
+   if (server_started_with_pipes)
{
-   /* only a single gdb connection when using a pipe */
+   LOG_WARNING("gdb service permits one target when using pipes");
+   if (0 == gdb_port)
+   return ERROR_OK;
 
-   gdb_service = malloc(sizeof(struct gdb_service));
-   gdb_service->target = target;
+   use_pipes = false;
+   }
 
-   add_service("gdb", CONNECTION_PIPE, 0, 1, gdb_new_connection, 
gdb_input, gdb_connection_closed, gdb_service);
+   int e = gdb_target_start(target, use_pipes ? 0 : gdb_port++);
+   if (ERROR_OK == e)
+   server_started_with_pipes |= use_pipes;
 
-   LOG_DEBUG("gdb service for target %s using pipes",
-   target_name(target));
+   return e;
+}
+
+int gdb_target_add_all(struct target *target)
+{
+   if (NULL == target)
+   {
+   LOG_WARNING("gdb services need one or more targets defined");
+   return ERROR_OK;
}
-   else
+
+   while (NULL != target)
{
-   unsigned short port = gdb_port;
+   int retval = gdb_target_add_one(target);
+   if (ERROR_OK != retval)
+   return retval;
 
-   while (target)
-   {
-   gdb_service = malloc(sizeof(struct gdb_service));
-   gdb_service->target = target;
-
-   add_service("gdb", CONNECTION_TCP,
-   port, 1,
-   gdb_new_connection, gdb_input,
-   gdb_connection_closed, gdb_service);
-
-   LOG_DEBUG("gdb service for target %s at TCP port %i",
-   target_name(target),
- 

[Openocd-development] [PATCH 0/3] deferred 'init' and leaner 'help'

2009-11-29 Thread Zachary T Welch
Hi all,

These patches clean up the server and system startup.  The first patch
factors the GDB server setup to be more conducive to deferred
initialization of targets (in a later series).

The second provides the 'noinit' command which can be used in a script
to removing 'init' from the end of the startup sequence.  Scripts
that do not add this command will continue to see the same behavior, but
this allows new scripts to defer initialization to be done through the
TCL server or by hand over telnet.  

The later use case is particular useful in order to interactively learn
the command set with help.  The final patch takes advantage of this and
hides those commands which cannot be used in the current command mode.

Cheers,

Zach


___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 3/2] remove unknown handler

2009-11-28 Thread Zachary T Welch
Updates command registration to provide top-level handlers for all
commands, rather than falling back onto the 'unknown' command. Instead,
that same handler is registered for placeholders, providing the same
functionality under the root verb command name instead.  This permits
users to implement their own 'unknown' function, and it resolves some
mind-bending breakage related to function object lookup while recursing.

Changes 'ocd_bounce' to call 'ocd_command' and 'ocd_help' from the
wrapper directly, rather than bouncing through their wrappers. This
prevents endless recursion caused by the above changes, whereby the
'command' wrapper's type check would blow the stack to hell and gone.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c   |   70 ---
 src/helper/startup.tcl |4 +-
 2 files changed, 38 insertions(+), 36 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index 64db95d..4e92ed4 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -296,37 +296,32 @@ static void command_free(struct command *c)
free(c);
 }
 
+static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
+
 static int register_command_handler(struct command *c)
 {
-   int retval = -ENOMEM;
-   const char *full_name = command_name(c, '_');
-   if (NULL == full_name)
-   return retval;
+   const char *ocd_name = alloc_printf("ocd_%s", c->name);
+   if (NULL == ocd_name)
+   return JIM_ERR;
 
-   if (NULL != c->handler)
-   {
-   const char *ocd_name = alloc_printf("ocd_%s", full_name);
-   if (NULL == full_name)
-   goto free_full_name;
+   LOG_DEBUG("registering '%s'...", ocd_name);
 
-   Jim_CreateCommand(interp, ocd_name, script_command, c, NULL);
-   free((void *)ocd_name);
-   }
+   Jim_CmdProc func = c->handler ? &script_command : &command_unknown;
+   int retval = Jim_CreateCommand(interp, ocd_name, func, c, NULL);
+   free((void *)ocd_name);
+   if (JIM_OK != retval)
+   return retval;
 
/* we now need to add an overrideable proc */
const char *override_name = alloc_printf(
"proc %s {args} {eval ocd_bouncer %s $args}",
-   full_name, full_name);
+   c->name, c->name);
if (NULL == override_name)
-   goto free_full_name;
+   return JIM_ERR;
 
-   Jim_Eval_Named(interp, override_name, __THIS__FILE__, __LINE__);
+   retval = Jim_Eval_Named(interp, override_name, __FILE__, __LINE__);
free((void *)override_name);
 
-   retval = ERROR_OK;
-
-free_full_name:
-   free((void *)full_name);
return retval;
 }
 
@@ -350,19 +345,20 @@ struct command* register_command(struct command_context 
*context,
if (NULL == c)
return NULL;
 
-   if (NULL != c->handler)
+   int retval = ERROR_OK;
+   if (NULL != cr->jim_handler && NULL == parent)
{
-   int retval = register_command_handler(command_root(c));
-   if (ERROR_OK != retval)
-   {
-   unregister_command(context, parent, name);
-   return NULL;
-   }
+   retval = Jim_CreateCommand(interp, cr->name,
+   cr->jim_handler, cr->jim_handler_data, NULL);
}
+   else if (NULL != cr->handler || NULL != parent)
+   retval = register_command_handler(command_root(c));
 
-   if (NULL != cr->jim_handler && NULL == parent)
-   Jim_CreateCommand(interp, cr->name, cr->jim_handler, 
cr->jim_handler_data, NULL);
-
+   if (ERROR_OK != retval)
+   {
+   unregister_command(context, parent, name);
+   c = NULL;
+   }
return c;
 }
 
@@ -903,15 +899,22 @@ static int command_unknown_find(unsigned argc, Jim_Obj 
*const *argv,
 static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 {
const char *cmd_name = Jim_GetString(argv[0], NULL);
-   script_debug(interp, cmd_name, argc - 1, argv + 1);
+   if (strcmp(cmd_name, "unknown") == 0)
+   {
+   if (argc == 1)
+   return JIM_OK;
+   argc--;
+   argv++;
+   }
+   script_debug(interp, cmd_name, argc, argv);
 
struct command_context *cmd_ctx = current_command_context();
struct command *c = cmd_ctx->commands;
-   int remaining = command_unknown_find(argc - 1, argv + 1, c, &c, true);
+   int remaining = command_unknown_find(argc, argv, c, &c, true);
// if nothing could be co

[Openocd-development] [PATCH 2/2] improve command handler wrapper script

2009-11-27 Thread Zachary T Welch
Adds 'ocd_bouncer' in startup.tcl that is called as a helper for
all command handlers, shrinking the embedded C wrapper to a mere stub.

Jim handlers are called directly, simple handlers get called with the
wrapper to capture and discard their output on error, and placeholders
call help directly (though the unknown handler still does this too).
It attempts to improve the quality of the error messages as well.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c   |5 ++---
 src/helper/startup.tcl |   24 
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index b34847b..64db95d 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -314,9 +314,8 @@ static int register_command_handler(struct command *c)
}
 
/* we now need to add an overrideable proc */
-   const char *override_name = alloc_printf("proc %s {args} {"
-   "if {[catch {eval ocd_%s $args}] == 0} "
-   "{return \"\"} else {return -code error}}",
+   const char *override_name = alloc_printf(
+   "proc %s {args} {eval ocd_bouncer %s $args}",
full_name, full_name);
if (NULL == override_name)
goto free_full_name;
diff --git a/src/helper/startup.tcl b/src/helper/startup.tcl
index f11d5b6..cb5fb02 100644
--- a/src/helper/startup.tcl
+++ b/src/helper/startup.tcl
@@ -10,6 +10,30 @@ proc exit {} {
ocd_throw exit
 }
 
+# All commands are registered with an 'ocd_' prefix, while the "real"
+# command is a wrapper that calls this function.  Its primary purpose is
+# to discard 'handler' command output,
+proc ocd_bouncer {name args} {
+   set cmd [format "ocd_%s" $name]
+   set type [eval command type $cmd $args]
+   if {$type == "native"} {
+   return [eval $cmd $args]
+   } else {if {$type == "simple"} {
+   if {[catch {eval $cmd $args}] == 0} {
+   return ""
+   } else {
+   set errmsg "Command handler execution failed"
+   }
+   } else {if {$type == "group"} {
+   catch {eval help $name $args}
+   set errmsg [format "%s: command requires more arguments" \
+   [concat $name " " $args]]
+   } else {
+   set errmsg [format "Unknown command type: %s" $type]
+   }}}
+   return -code error $errmsg
+}
+
 # Try flipping / and \ to find file if the filename does not
 # match the precise spelling
 proc find {filename} {
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 1/2] add 'command type' introspective handler

2009-11-27 Thread Zachary T Welch
Adds the 'command' group handler, with the 'type' command producing
a string that tells whether the given command is 'native' (for Jim-based
command handlers), 'simple' (for simple built-in commands), 'group'
for command group placeholders, and 'unknown' if not found in the
command registration tables (e.g. core built-ins functions).

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c |   43 +++
 1 files changed, 43 insertions(+), 0 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index 65421f5..b34847b 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -948,6 +948,31 @@ static int command_unknown(Jim_Interp *interp, int argc, 
Jim_Obj *const *argv)
return script_command_run(interp, count, start, c, found);
 }
 
+int jim_command_type(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+   if (1 == argc)
+   return JIM_ERR;
+
+   struct command_context *cmd_ctx = current_command_context();
+   struct command *c = cmd_ctx->commands;
+   int remaining = command_unknown_find(argc - 1, argv + 1, c, &c, true);
+   // if nothing could be consumed, then it's an unknown command
+   if (remaining == argc - 1)
+   {
+   Jim_SetResultString(interp, "unknown", -1);
+   return JIM_OK;
+   }
+
+   if (c->jim_handler)
+   Jim_SetResultString(interp, "native", -1);
+   else if (c->handler)
+   Jim_SetResultString(interp, "simple", -1);
+   else
+   Jim_SetResultString(interp, "group", -1);
+
+   return JIM_OK;
+}
+
 int help_add_command(struct command_context *cmd_ctx, struct command *parent,
const char *cmd_name, const char *help_text, const char *usage)
 {
@@ -1069,6 +1094,18 @@ COMMAND_HANDLER(handle_sleep_command)
return ERROR_OK;
 }
 
+static const struct command_registration command_subcommand_handlers[] = {
+   {
+   .name = "type",
+   .mode = COMMAND_ANY,
+   .jim_handler = &jim_command_type,
+   .usage = " ...",
+   .help = "Returns the type of built-in command:"
+   "'native', 'simple', 'group', or 'unknown'",
+   },
+   COMMAND_REGISTRATION_DONE
+};
+
 static const struct command_registration command_builtin_handlers[] = {
{
.name = "add_help_text",
@@ -1106,6 +1143,12 @@ static const struct command_registration 
command_builtin_handlers[] = {
.help = "show basic command usage",
.usage = "[ ...]",
},
+   {
+   .name = "command",
+   .mode= COMMAND_ANY,
+   .help = "core command group (introspection)",
+   .chain = command_subcommand_handlers,
+   },
COMMAND_REGISTRATION_DONE
 };
 
-- 
1.6.4.4


>From aafcd6e134f413bb610f26a342d9cbf13d923a14 Mon Sep 17 00:00:00 2001
From: Zachary T Welch 
Date: Fri, 27 Nov 2009 19:14:30 -0800
Subject: [PATCH 2/2] improve command handler wrapper script

Adds 'ocd_bouncer' in startup.tcl that is called as a helper for
all command handlers, shrinking the embedded C wrapper to a mere stub.

Jim handlers are called directly, simple handlers get called with the
wrapper to capture and discard their output on error, and placeholders
call help directly (though the unknown handler still does this too).
It attempts to improve the quality of the error messages as well.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c   |5 ++---
 src/helper/startup.tcl |   24 
 2 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index b34847b..64db95d 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -314,9 +314,8 @@ static int register_command_handler(struct command *c)
}
 
/* we now need to add an overrideable proc */
-   const char *override_name = alloc_printf("proc %s {args} {"
-   "if {[catch {eval ocd_%s $args}] == 0} "
-   "{return \"\"} else {return -code error}}",
+   const char *override_name = alloc_printf(
+   "proc %s {args} {eval ocd_bouncer %s $args}",
full_name, full_name);
if (NULL == override_name)
goto free_full_name;
diff --git a/src/helper/startup.tcl b/src/helper/startup.tcl
index f11d5b6..cb5fb02 100644
--- a/src/helper/startup.tcl
+++ b/src/helper/startup.tcl
@@ -10,6 +10,30 @@ proc exit {} {
ocd_throw exit
 }
 
+# All commands are registered with an 'ocd_' prefix

[Openocd-development] [PATCH] fix regression causing duplicated output

2009-11-27 Thread Zachary T Welch
The command refactoring caused subcommand handlers to produce duplicate
output when run.  The problem was introduced by failing to ensure all
such invocations went through a top-level "catcher" script, prefixing
the command name with the 'ocd_' prefix and consuming its results.

The fix is to ensure such a top-level "catcher" script gets created
for each top-level command, regardless of whether it has a handler.
Indeed, this patch removes all command registrations for sub-commands,
which would not have worked in the new registration scheme anyway.

For now, dispatch of subcommands continues to be handled by the new
'unknown' command handler, which gets fixed here to strip the 'ocd_'
prefix if searching for the top-level command name fails initially.
Some Jim commands may be registered with this prefix, and that situation
seems to require the current fallback approach.  Otherwise, that prefix
could be stripped unconditionally and the logic made a little simpler.

Overall, the command dispatching remains more complicated than desired,
but this patch fixes the immediate regressions.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c |   45 +++--
 1 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index 62fb487..135cd3f 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -44,6 +44,9 @@
 #include "jim-eventloop.h"
 
 
+/* nice short description of source file */
+#define __THIS__FILE__ "command.c"
+
 Jim_Interp *interp = NULL;
 
 static int run_command(struct command_context *context,
@@ -185,8 +188,12 @@ static int script_command(Jim_Interp *interp, int argc, 
Jim_Obj *const *argv)
return script_command_run(interp, argc, argv, c, true);
 }
 
-/* nice short description of source file */
-#define __THIS__FILE__ "command.c"
+static struct command *command_root(struct command *c)
+{
+   while (NULL != c->parent)
+   c = c->parent;
+   return c;
+}
 
 /**
  * Find a command by name from a list of commands.
@@ -296,19 +303,22 @@ static int register_command_handler(struct command *c)
if (NULL == full_name)
return retval;
 
-   const char *ocd_name = alloc_printf("ocd_%s", full_name);
-   if (NULL == full_name)
-   goto free_full_name;
+   if (NULL != c->handler)
+   {
+   const char *ocd_name = alloc_printf("ocd_%s", full_name);
+   if (NULL == full_name)
+   goto free_full_name;
 
-   Jim_CreateCommand(interp, ocd_name, script_command, c, NULL);
-   free((void *)ocd_name);
+   Jim_CreateCommand(interp, ocd_name, script_command, c, NULL);
+   free((void *)ocd_name);
+   }
 
/* we now need to add an overrideable proc */
const char *override_name = alloc_printf("proc %s {args} {"
"if {[catch {eval ocd_%s $args}] == 0} "
"{return \"\"} else {return -code error}}",
full_name, full_name);
-   if (NULL == full_name)
+   if (NULL == override_name)
goto free_full_name;
 
Jim_Eval_Named(interp, override_name, __THIS__FILE__, __LINE__);
@@ -343,7 +353,7 @@ struct command* register_command(struct command_context 
*context,
 
if (NULL != c->handler)
{
-   int retval = register_command_handler(c);
+   int retval = register_command_handler(command_root(c));
if (ERROR_OK != retval)
{
unregister_command(context, parent, name);
@@ -875,15 +885,22 @@ COMMAND_HANDLER(handle_help_command)
 }
 
 static int command_unknown_find(unsigned argc, Jim_Obj *const *argv,
-   struct command *head, struct command **out)
+   struct command *head, struct command **out, bool top_level)
 {
if (0 == argc)
return argc;
-   struct command *c = command_find(head, Jim_GetString(argv[0], NULL));
+   const char *cmd_name = Jim_GetString(argv[0], NULL);
+   struct command *c = command_find(head, cmd_name);
if (NULL == c)
-   return argc;
+   {
+   if (top_level && strncmp(cmd_name, "ocd_", 4) == 0)
+   c = command_find(head, cmd_name + 4);
+
+   if (NULL == c)
+   return argc;
+   }
*out = c;
-   return command_unknown_find(--argc, ++argv, (*out)->children, out);
+   return command_unknown_find(--argc, ++argv, (*out)->children, out, 
false);
 }
 
 static int command_unknown(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -893,7 +910,7 @@ static int command_unknown(Jim_Interp *interp, int argc, 
Jim_Obj *const *argv)
 
st

[Openocd-development] [PATCH 7/8] improve jtag_tap_configure

2009-11-26 Thread Zachary T Welch
Splits bulk of the jtag_tap_configure into jtag_tap_configure_event,
removing three or four levels of indentation in the process.
The resulting code was stylistically improved in other ways, but it
should be functionally identical.

Signed-off-by: Zachary T Welch 
---
 src/jtag/tcl.c |  165 ++--
 1 files changed, 88 insertions(+), 77 deletions(-)

diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index 8371967..bb86a32 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -293,94 +293,105 @@ static Jim_Nvp nvp_config_opts[] = {
{ .name = NULL,  .value = -1 }
 };
 
-static int jtag_tap_configure_cmd(Jim_GetOptInfo *goi, struct jtag_tap * tap)
+static int jtag_tap_configure_event(Jim_GetOptInfo *goi, struct jtag_tap * tap)
 {
+   if (goi->argc == 0)
+   {
+   Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event 
 ...");
+   return JIM_ERR;
+   }
+
Jim_Nvp *n;
-   Jim_Obj *o;
-   int e;
+   int e = Jim_GetOpt_Nvp(goi, nvp_jtag_tap_event, &n);
+   if (e != JIM_OK)
+   {
+   Jim_GetOpt_NvpUnknown(goi, nvp_jtag_tap_event, 1);
+   return e;
+   }
+
+   if (goi->isconfigure) {
+   if (goi->argc != 1) {
+   Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, 
"-event  ");
+   return JIM_ERR;
+   }
+   } else {
+   if (goi->argc != 0) {
+   Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, 
"-event ");
+   return JIM_ERR;
+   }
+   }
+
+   struct jtag_tap_event_action *jteap  = tap->event_action;
+   /* replace existing event body */
+   bool found = false;
+   while (jteap)
+   {
+   if (jteap->event == (enum jtag_event)n->value)
+   {
+   found = true;
+   break;
+   }
+   jteap = jteap->next;
+   }
+
+   Jim_SetEmptyResult(goi->interp);
+
+   if (goi->isconfigure)
+   {
+   if (!found)
+   jteap = calloc(1, sizeof(*jteap));
+   else if (NULL != jteap->body)
+   Jim_DecrRefCount(interp, jteap->body);
+
+   jteap->event = n->value;
+
+   Jim_Obj *o;
+   Jim_GetOpt_Obj(goi, &o);
+   jteap->body = Jim_DuplicateObj(goi->interp, o);
+   Jim_IncrRefCount(jteap->body);
+
+   if (!found)
+   {
+   /* add to head of event list */
+   jteap->next = tap->event_action;
+   tap->event_action = jteap;
+   }
+   }
+   else if (found)
+   {
+   Jim_SetResult(goi->interp,
+   Jim_DuplicateObj(goi->interp, jteap->body));
+   }
+   return JIM_OK;
+}
 
+static int jtag_tap_configure_cmd(Jim_GetOptInfo *goi, struct jtag_tap * tap)
+{
/* parse config or cget options */
-   while (goi->argc > 0) {
+   while (goi->argc > 0)
+   {
Jim_SetEmptyResult (goi->interp);
 
-   e = Jim_GetOpt_Nvp(goi, nvp_config_opts, &n);
-   if (e != JIM_OK) {
+   Jim_Nvp *n;
+   int e = Jim_GetOpt_Nvp(goi, nvp_config_opts, &n);
+   if (e != JIM_OK)
+   {
Jim_GetOpt_NvpUnknown(goi, nvp_config_opts, 0);
return e;
}
 
-   switch (n->value) {
-   case JCFG_EVENT:
-   if (goi->argc == 0) {
-   Jim_WrongNumArgs(goi->interp, 
goi->argc, goi->argv, "-event ?event-name? ...");
-   return JIM_ERR;
-   }
-
-   e = Jim_GetOpt_Nvp(goi, nvp_jtag_tap_event, &n);
-   if (e != JIM_OK) {
-   Jim_GetOpt_NvpUnknown(goi, 
nvp_jtag_tap_event, 1);
-   return e;
-   }
-
-   if (goi->isconfigure) {
-   if (goi->argc != 1) {
-   Jim_WrongNumArgs(goi->interp, 
goi->argc, goi->argv, "-event ?event-name? ?EVENT-BODY?");
-   return JIM_ERR;
-   }
-   } else {
- 

[Openocd-development] [PATCH 8/8] split jim_newtap_cmd into pieces

2009-11-26 Thread Zachary T Welch
Moves the ID and IR-related option parsing to static helpers, removing
two levels of indent.

Signed-off-by: Zachary T Welch 
---
 src/jtag/tcl.c |  164 
 1 files changed, 94 insertions(+), 70 deletions(-)

diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index bb86a32..7ec7fa4 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -406,26 +406,106 @@ static int is_bad_irval(int ir_length, jim_wide w)
return (w & v) != 0;
 }
 
+static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi,
+   struct jtag_tap *pTap)
+{
+   jim_wide w;
+   int e = Jim_GetOpt_Wide(goi, &w);
+   if (e != JIM_OK) {
+   Jim_SetResult_sprintf(goi->interp, "option: %s bad parameter", 
n->name);
+   return e;
+   }
+
+   unsigned expected_len = sizeof(uint32_t) * pTap->expected_ids_cnt;
+   uint32_t *new_expected_ids = malloc(expected_len + sizeof(uint32_t));
+   if (new_expected_ids == NULL)
+   {
+   Jim_SetResult_sprintf(goi->interp, "no memory");
+   return JIM_ERR;
+   }
+
+   memcpy(new_expected_ids, pTap->expected_ids, expected_len);
+
+   new_expected_ids[pTap->expected_ids_cnt] = w;
+
+   free(pTap->expected_ids);
+   pTap->expected_ids = new_expected_ids;
+   pTap->expected_ids_cnt++;
+
+   return JIM_OK;
+}
+
+#define NTAP_OPT_IRLEN 0
+#define NTAP_OPT_IRMASK1
+#define NTAP_OPT_IRCAPTURE 2
+#define NTAP_OPT_ENABLED   3
+#define NTAP_OPT_DISABLED  4
+#define NTAP_OPT_EXPECTED_ID 5
+
+static int jim_newtap_ir_param(Jim_Nvp *n, Jim_GetOptInfo *goi,
+   struct jtag_tap *pTap)
+{
+   jim_wide w;
+   int e = Jim_GetOpt_Wide(goi, &w);
+   if (e != JIM_OK)
+   {
+   Jim_SetResult_sprintf(goi->interp,
+   "option: %s bad parameter", n->name);
+   free((void *)pTap->dotted_name);
+   return e;
+   }
+   switch (n->value) {
+   case NTAP_OPT_IRLEN:
+   if (w > (jim_wide) (8 * sizeof(pTap->ir_capture_value)))
+   {
+   LOG_WARNING("%s: huge IR length %d",
+   pTap->dotted_name, (int) w);
+   }
+   pTap->ir_length = w;
+   break;
+   case NTAP_OPT_IRMASK:
+   if (is_bad_irval(pTap->ir_length, w))
+   {
+   LOG_ERROR("%s: IR mask %x too big",
+   pTap->dotted_name,
+   (int) w);
+   return JIM_ERR;
+   }
+   if ((w & 3) != 3)
+   LOG_WARNING("%s: nonstandard IR mask", 
pTap->dotted_name);
+   pTap->ir_capture_mask = w;
+   break;
+   case NTAP_OPT_IRCAPTURE:
+   if (is_bad_irval(pTap->ir_length, w))
+   {
+   LOG_ERROR("%s: IR capture %x too big",
+   pTap->dotted_name, (int) w);
+   return JIM_ERR;
+   }
+   if ((w & 3) != 1)
+   LOG_WARNING("%s: nonstandard IR value",
+   pTap->dotted_name);
+   pTap->ir_capture_value = w;
+   break;
+   default:
+   return JIM_ERR;
+   }
+   return JIM_OK;
+}
+
 static int jim_newtap_cmd(Jim_GetOptInfo *goi)
 {
struct jtag_tap *pTap;
-   jim_wide w;
int x;
int e;
Jim_Nvp *n;
char *cp;
const Jim_Nvp opts[] = {
-#define NTAP_OPT_IRLEN 0
{ .name = "-irlen"  ,   .value = 
NTAP_OPT_IRLEN },
-#define NTAP_OPT_IRMASK1
{ .name = "-irmask" ,   .value = 
NTAP_OPT_IRMASK },
-#define NTAP_OPT_IRCAPTURE 2
{ .name = "-ircapture"  ,   .value = 
NTAP_OPT_IRCAPTURE },
-#define NTAP_OPT_ENABLED   3
{ .name = "-enable" ,   .value = 
NTAP_OPT_ENABLED },
-#define NTAP_OPT_DISABLED  4
{ .name = "-disable",   .value = 
NTAP_OPT_DISABLED },
-#define NTAP_OPT_EXPECTED_ID 5
{ .name = "-expected-id",   .value = 
NTAP_OPT_EXPECTED_ID },
{ .name = NULL  ,   .value = -1 },
};
@@ -483,81 +563,25 @@ static int jim_newtap_cmd(Jim_GetOptInfo *goi)
pTap->disabled_after_reset = true;
break;
case NTAP_OPT_EXPECTED_ID:
-   {
-   uint32_t *new_expect

[Openocd-development] [PATCH 6/8] improve jtag_tap_handle_event indentation

2009-11-26 Thread Zachary T Welch
Use 'continue' to reduce identation levels and superfluous logic.

Signed-off-by: Zachary T Welch 
---
 src/jtag/tcl.c |   53 ++---
 1 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index 929c784..8371967 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -571,29 +571,36 @@ static void jtag_tap_handle_event(struct jtag_tap *tap, 
enum jtag_event e)
 {
struct jtag_tap_event_action * jteap;
 
-   for (jteap = tap->event_action; jteap != NULL; jteap = jteap->next) {
-   if (jteap->event == e) {
-   LOG_DEBUG("JTAG tap: %s event: %d (%s)\n\taction: %s",
-   tap->dotted_name,
-   e,
-   
Jim_Nvp_value2name_simple(nvp_jtag_tap_event, e)->name,
-   Jim_GetString(jteap->body, NULL));
-   if (Jim_EvalObj(interp, jteap->body) != JIM_OK) {
-   Jim_PrintErrorMessage(interp);
-   } else switch (e) {
-   case JTAG_TAP_EVENT_ENABLE:
-   case JTAG_TAP_EVENT_DISABLE:
-   /* NOTE:  we currently assume the handlers
-* can't fail.  Right here is where we should
-* really be verifying the scan chains ...
-*/
-   tap->enabled = (e == JTAG_TAP_EVENT_ENABLE);
-   LOG_INFO("JTAG tap: %s %s", tap->dotted_name,
-   tap->enabled ? "enabled" : "disabled");
-   break;
-   default:
-   break;
-   }
+   for (jteap = tap->event_action; jteap != NULL; jteap = jteap->next)
+   {
+   if (jteap->event != e)
+   continue;
+
+   Jim_Nvp *nvp = Jim_Nvp_value2name_simple(nvp_jtag_tap_event, e);
+   LOG_DEBUG("JTAG tap: %s event: %d (%s)\n\taction: %s",
+   tap->dotted_name, e, nvp->name,
+   Jim_GetString(jteap->body, NULL));
+
+   if (Jim_EvalObj(interp, jteap->body) != JIM_OK)
+   {
+   Jim_PrintErrorMessage(interp);
+   continue;
+   }
+
+   switch (e)
+   {
+   case JTAG_TAP_EVENT_ENABLE:
+   case JTAG_TAP_EVENT_DISABLE:
+   /* NOTE:  we currently assume the handlers
+* can't fail.  Right here is where we should
+* really be verifying the scan chains ...
+*/
+   tap->enabled = (e == JTAG_TAP_EVENT_ENABLE);
+   LOG_INFO("JTAG tap: %s %s", tap->dotted_name,
+   tap->enabled ? "enabled" : "disabled");
+   break;
+   default:
+   break;
}
}
 }
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 4/8] explode tcl_target_func into many handlers

2009-11-26 Thread Zachary T Welch
Eliminate the monolithic tcl_target_func by registering each of its
commands using the new chained command registration mechanism.

Also chains the target's commands under the CPU command, though these
may not work properly without some further modification.

Signed-off-by: Zachary T Welch 
---
 src/target/target.c |  918 +--
 1 files changed, 531 insertions(+), 387 deletions(-)

diff --git a/src/target/target.c b/src/target/target.c
index fddf983..856936f 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -3357,7 +3357,7 @@ static int target_array2mem(Jim_Interp *interp, struct 
target *target, int argc,
 * argv[4] = count to write
 */
if (argc != 4) {
-   Jim_WrongNumArgs(interp, 1, argv, "varname width addr nelems");
+   Jim_WrongNumArgs(interp, 0, argv, "varname width addr nelems");
return JIM_ERR;
}
varname = Jim_GetString(argv[0], &len);
@@ -3826,422 +3826,553 @@ static int target_configure(Jim_GetOptInfo *goi, 
struct target *target)
return JIM_OK;
 }
 
-/** this is the 'tcl' handler for the target specific command */
-static int tcl_target_func(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+static int jim_target_configure(Jim_Interp *interp, int argc, Jim_Obj *const 
*argv)
 {
Jim_GetOptInfo goi;
-   jim_wide a,b,c;
-   int x,y,z;
-   uint8_t  target_buf[32];
-   Jim_Nvp *n;
-   struct target *target;
-   struct command_context *cmd_ctx;
-   int e;
+   Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
+   goi.isconfigure = strcmp(Jim_GetString(argv[0], NULL), "configure") == 
0;
+   int need_args = 1 + goi.isconfigure;
+   if (goi.argc < need_args)
+   {
+   Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
+   goi.isconfigure
+   ? "missing: -option VALUE ..."
+   : "missing: -option ...");
+   return JIM_ERR;
+   }
+   struct target *target = Jim_CmdPrivData(goi.interp);
+   return target_configure(&goi, target);
+}
 
-   enum {
-   TS_CMD_CONFIGURE,
-   TS_CMD_CGET,
-
-   TS_CMD_MWW, TS_CMD_MWH, TS_CMD_MWB,
-   TS_CMD_MDW, TS_CMD_MDH, TS_CMD_MDB,
-   TS_CMD_MRW, TS_CMD_MRH, TS_CMD_MRB,
-   TS_CMD_MEM2ARRAY, TS_CMD_ARRAY2MEM,
-   TS_CMD_EXAMINE,
-   TS_CMD_POLL,
-   TS_CMD_RESET,
-   TS_CMD_HALT,
-   TS_CMD_WAITSTATE,
-   TS_CMD_EVENTLIST,
-   TS_CMD_CURSTATE,
-   TS_CMD_INVOKE_EVENT,
-   };
+static int jim_target_mw(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+   const char *cmd_name = Jim_GetString(argv[0], NULL);
 
-   static const Jim_Nvp target_options[] = {
-   { .name = "configure", .value = TS_CMD_CONFIGURE },
-   { .name = "cget", .value = TS_CMD_CGET },
-   { .name = "mww", .value = TS_CMD_MWW },
-   { .name = "mwh", .value = TS_CMD_MWH },
-   { .name = "mwb", .value = TS_CMD_MWB },
-   { .name = "mdw", .value = TS_CMD_MDW },
-   { .name = "mdh", .value = TS_CMD_MDH },
-   { .name = "mdb", .value = TS_CMD_MDB },
-   { .name = "mem2array", .value = TS_CMD_MEM2ARRAY },
-   { .name = "array2mem", .value = TS_CMD_ARRAY2MEM },
-   { .name = "eventlist", .value = TS_CMD_EVENTLIST },
-   { .name = "curstate",  .value = TS_CMD_CURSTATE },
-
-   { .name = "arp_examine", .value = TS_CMD_EXAMINE },
-   { .name = "arp_poll", .value = TS_CMD_POLL },
-   { .name = "arp_reset", .value = TS_CMD_RESET },
-   { .name = "arp_halt", .value = TS_CMD_HALT },
-   { .name = "arp_waitstate", .value = TS_CMD_WAITSTATE },
-   { .name = "invoke-event", .value = TS_CMD_INVOKE_EVENT },
-
-   { .name = NULL, .value = -1 },
-   };
+   Jim_GetOptInfo goi;
+   Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
 
-   /* go past the "command" */
-   Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
+   if (goi.argc != 2 && goi.argc != 3)
+   {
+   Jim_SetResult_sprintf(goi.interp,
+   "usage: %s   []", 
cmd_name);
+   return JIM_ERR;
+   }
 
-   target = Jim_CmdPrivData(goi.interp);
-   cmd_ctx = Jim_GetAssocData(goi.interp, "context");
+   jim_wide a;
+   int e = Jim_GetOpt_Wide(&go

[Openocd-development] [PATCH 3/8] split jim_target into multiple handlers

2009-11-26 Thread Zachary T Welch
The 'target' command group was implemented using its own command
dispatching, which can be eliminated by using the new chained command
registration mechanism.  This patch splits the jim_target() function
into individual handlers, which makes them to be visible to the help and
usage commands.  These one-trick handlers are much easier to understand.

Signed-off-by: Zachary T Welch 
---
 src/target/target.c |  246 ---
 1 files changed, 137 insertions(+), 109 deletions(-)

diff --git a/src/target/target.c b/src/target/target.c
index 3de9f2c..fddf983 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -4401,129 +4401,156 @@ static int target_create(Jim_GetOptInfo *goi)
return (NULL != c) ? ERROR_OK : ERROR_FAIL;
 }
 
-static int jim_target(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+static int jim_target_current(Jim_Interp *interp, int argc, Jim_Obj *const 
*argv)
 {
-   int x,r,e;
-   jim_wide w;
-   struct command_context *cmd_ctx;
-   struct target *target;
-   Jim_GetOptInfo goi;
-   enum tcmd {
-   /* TG = target generic */
-   TG_CMD_CREATE,
-   TG_CMD_TYPES,
-   TG_CMD_NAMES,
-   TG_CMD_CURRENT,
-   TG_CMD_NUMBER,
-   TG_CMD_COUNT,
-   };
-   const char *target_cmds[] = {
-   "create", "types", "names", "current", "number",
-   "count",
-   NULL /* terminate */
-   };
-
-   LOG_DEBUG("Target command params:");
-   LOG_DEBUG("%s", Jim_Debug_ArgvString(interp, argc, argv));
-
-   cmd_ctx = Jim_GetAssocData(interp, "context");
+   if (argc != 1)
+   {
+   Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
+   return JIM_ERR;
+   }
+   struct command_context *cmd_ctx = Jim_GetAssocData(interp, "context");
+   Jim_SetResultString(interp, get_current_target(cmd_ctx)->cmd_name, -1);
+   return JIM_OK;
+}
 
-   Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
+static int jim_target_types(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+   if (argc != 1)
+   {
+   Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
+   return JIM_ERR;
+   }
+   Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0));
+   for (unsigned x = 0; NULL != target_types[x]; x++)
+   {
+   Jim_ListAppendElement(interp, Jim_GetResult(interp),
+   Jim_NewStringObj(interp, target_types[x]->name, -1));
+   }
+   return JIM_OK;
+}
 
-   if (goi.argc == 0) {
-   Jim_WrongNumArgs(interp, 1, argv, "missing: command ...");
+static int jim_target_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+   if (argc != 1)
+   {
+   Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
return JIM_ERR;
}
+   Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0));
+   struct target *target = all_targets;
+   while (target)
+   {
+   Jim_ListAppendElement(interp, Jim_GetResult(interp),
+   Jim_NewStringObj(interp, target_name(target), -1));
+   target = target->next;
+   }
+   return JIM_OK;
+}
 
-   /* Jim_GetOpt_Debug(&goi); */
-   r = Jim_GetOpt_Enum(&goi, target_cmds, &x);
-   if (r != JIM_OK) {
-   return r;
+static int jim_target_create(Jim_Interp *interp, int argc, Jim_Obj *const 
*argv)
+{
+   Jim_GetOptInfo goi;
+   Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
+   if (goi.argc < 3)
+   {
+   Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
+   "  [ ...]");
+   return JIM_ERR;
}
+   return target_create(&goi);
+}
 
-   switch (x) {
-   default:
-   Jim_Panic(goi.interp,"Why am I here?");
+static int jim_target_number(Jim_Interp *interp, int argc, Jim_Obj *const 
*argv)
+{
+   Jim_GetOptInfo goi;
+   Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
+
+   /* It's OK to remove this mechanism sometime after August 2010 or so */
+   LOG_WARNING("don't use numbers as target identifiers; use names");
+   if (goi.argc != 1)
+   {
+   Jim_SetResult_sprintf(goi.interp, "usage: target number 
");
return JIM_ERR;
-   case TG_CMD_CURRENT:
-   if (goi.argc != 0) {
-   Jim_WrongNumArgs(goi.interp, 1, goi.argv, "Too many 
parameters");
-   return JIM_ERR;
-   }
-   Jim_SetResultString(goi.interp,
-  

[Openocd-development] [PATCH 5/8] add more stub handlers to testee target

2009-11-26 Thread Zachary T Welch
Prevent everything from crashing when exercising various commands.

Signed-off-by: Zachary T Welch 
---
 src/target/testee.c |   24 ++--
 1 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/src/target/testee.c b/src/target/testee.c
index ca3d56e..f858232 100644
--- a/src/target/testee.c
+++ b/src/target/testee.c
@@ -40,9 +40,29 @@ static int testee_init(struct command_context *cmd_ctx, 
struct target *target)
 {
return ERROR_OK;
 }
-
+static int testee_poll(struct target *target)
+{
+   return ERROR_OK;
+}
+static int testee_halt(struct target *target)
+{
+   return ERROR_OK;
+}
+static int testee_reset_assert(struct target *target)
+{
+   return ERROR_OK;
+}
+static int testee_reset_deassert(struct target *target)
+{
+   return ERROR_OK;
+}
 struct target_type testee_target = {
.name = "testee",
-   .init_target = &testee_init,
.commands = testee_command_handlers,
+
+   .init_target = &testee_init,
+   .poll = &testee_poll,
+   .halt = &testee_halt,
+   .assert_reset = &testee_reset_assert,
+   .deassert_reset = &testee_reset_deassert,
 };
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [Patch 0/8] more command cleaning

2009-11-26 Thread Zachary T Welch
Hi all,

This series continues to work to simplify OpenOCD's command handling.

Herein, you'll find some rather crude and heavy-handed attempts to
cleave apart some monolithic top-level command handlers into individual
handlers that get registered using the new command chaining mechanism.
The code is easier to read and maintain as a result, and the help/usage
commands now provide meaningful output for all of these commands.

As a final coup, it hooks in the JTAG and target_type command chain
under the target command during target_create(), paving the way to
migrate those per-instance target commands out of the top-level
namespace.  The last three patches are very simple refactoring to
clean up the code.

Cheers,

Zach


___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 1/8] split jim_jtag_command into multiple handlers

2009-11-26 Thread Zachary T Welch
Explodes the 'jtag' into separate command handlers, which are easier
to understand and extend.  Makes the code much easier to understand,
though further simplifications are possible.  This patch tries to
minimize the noise when viewed with 'git diff -w'.

Gives these commands improved built-in help and usage information.

Signed-off-by: Zachary T Welch 
---
 src/jtag/tcl.c |  392 ++--
 1 files changed, 212 insertions(+), 180 deletions(-)

diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index e755dd7..e7a0f67 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -366,209 +366,240 @@ static void jtag_tap_handle_event(struct jtag_tap *tap, 
enum jtag_event e)
}
 }
 
-
-static int jim_jtag_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+static int jim_jtag_interface(Jim_Interp *interp, int argc, Jim_Obj *const 
*argv)
 {
Jim_GetOptInfo goi;
-   int e;
-   Jim_Nvp *n;
-   Jim_Obj *o;
-   struct command_context *context;
-
-   enum {
-   JTAG_CMD_INTERFACE,
-   JTAG_CMD_INIT,
-   JTAG_CMD_INIT_RESET,
-   JTAG_CMD_NEWTAP,
-   JTAG_CMD_TAPENABLE,
-   JTAG_CMD_TAPDISABLE,
-   JTAG_CMD_TAPISENABLED,
-   JTAG_CMD_CONFIGURE,
-   JTAG_CMD_CGET,
-   JTAG_CMD_NAMES,
-   };
-
-   const Jim_Nvp jtag_cmds[] = {
-   { .name = "interface" , .value = JTAG_CMD_INTERFACE },
-   { .name = "arp_init"  , .value = JTAG_CMD_INIT },
-   { .name = "arp_init-reset", .value = JTAG_CMD_INIT_RESET },
-   { .name = "newtap", .value = JTAG_CMD_NEWTAP },
-   { .name = "tapisenabled" , .value = JTAG_CMD_TAPISENABLED },
-   { .name = "tapenable" , .value = JTAG_CMD_TAPENABLE },
-   { .name = "tapdisable", .value = JTAG_CMD_TAPDISABLE },
-   { .name = "configure" , .value = JTAG_CMD_CONFIGURE },
-   { .name = "cget"  , .value = JTAG_CMD_CGET },
-   { .name = "names" , .value = JTAG_CMD_NAMES },
-
-   { .name = NULL, .value = -1 },
-   };
-
-   context = Jim_GetAssocData(interp, "context");
-   /* go past the command */
Jim_GetOpt_Setup(&goi, interp, argc-1, argv + 1);
 
-   e = Jim_GetOpt_Nvp(&goi, jtag_cmds, &n);
-   if (e != JIM_OK) {
-   Jim_GetOpt_NvpUnknown(&goi, jtag_cmds, 0);
-   return e;
+   /* return the name of the interface */
+   /* TCL code might need to know the exact type... */
+   /* FUTURE: we allow this as a means to "set" the interface. */
+   if (goi.argc != 0) {
+   Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no params)");
+   return JIM_ERR;
}
-   Jim_SetEmptyResult(goi.interp);
-   switch (n->value) {
-   case JTAG_CMD_INTERFACE:
-   /* return the name of the interface */
-   /* TCL code might need to know the exact type... */
-   /* FUTURE: we allow this as a means to "set" the interface. */
-   if (goi.argc != 0) {
-   Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no 
params)");
-   return JIM_ERR;
-   }
-   const char *name = jtag_interface ? jtag_interface->name : NULL;
-   Jim_SetResultString(goi.interp, name ? : "undefined", -1);
-   return JIM_OK;
-   case JTAG_CMD_INIT:
-   if (goi.argc != 0) {
-   Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no 
params)");
-   return JIM_ERR;
-   }
-   e = jtag_init_inner(context);
-   if (e != ERROR_OK) {
-   Jim_SetResult_sprintf(goi.interp, "error: %d", e);
-   return JIM_ERR;
-   }
-   return JIM_OK;
-   case JTAG_CMD_INIT_RESET:
-   if (goi.argc != 0) {
-   Jim_WrongNumArgs(goi.interp, 1, goi.argv-1, "(no 
params)");
-   return JIM_ERR;
-   }
-   e = jtag_init_reset(context);
-   if (e != ERROR_OK) {
-   Jim_SetResult_sprintf(goi.interp, "error: %d", e);
-   return JIM_ERR;
-   }
-   return JIM_OK;
-   case JTAG_CMD_NEWTAP:
-   return jim_newtap_cmd(&goi);
-   break;
-   case JTAG_CMD_TAPISENABLED:
-   case JTAG_CMD_TAPENABLE:
-   case JTAG_CMD_TAPDISABLE:
-   if (goi.argc != 1) {
-   Jim_Set

[Openocd-development] [PATCH 2/8] begin moving JTAG jim handlers/helpers

2009-11-26 Thread Zachary T Welch
Moves the tertiary jim handlers and required static helpers to the top
of tcl.c, defining them in a new registration array that is chained in
both the top-level context and under the jtag command.  The top-level
commands can be removed at some point in the future to reduce clutter.

Signed-off-by: Zachary T Welch 
---
 src/jtag/tcl.c |  463 ---
 1 files changed, 236 insertions(+), 227 deletions(-)

diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index e7a0f67..929c784 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -51,6 +51,238 @@ static const Jim_Nvp nvp_jtag_tap_event[] = {
 
 extern struct jtag_interface *jtag_interface;
 
+static bool scan_is_safe(tap_state_t state)
+{
+   switch (state)
+   {
+   case TAP_RESET:
+   case TAP_IDLE:
+   case TAP_DRPAUSE:
+   case TAP_IRPAUSE:
+   return true;
+   default:
+   return false;
+   }
+}
+
+static int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const 
*args)
+{
+   int retval;
+   struct scan_field *fields;
+   int num_fields;
+   int field_count = 0;
+   int i, e;
+   struct jtag_tap *tap;
+   tap_state_t endstate;
+
+   /* args[1] = device
+* args[2] = num_bits
+* args[3] = hex string
+* ... repeat num bits and hex string ...
+*
+* .. optionally:
+   * args[N-2] = "-endstate"
+* args[N-1] = statename
+*/
+   if ((argc < 4) || ((argc % 2) != 0))
+   {
+   Jim_WrongNumArgs(interp, 1, args, "wrong arguments");
+   return JIM_ERR;
+   }
+
+   endstate = TAP_IDLE;
+
+   script_debug(interp, "drscan", argc, args);
+
+   /* validate arguments as numbers */
+   e = JIM_OK;
+   for (i = 2; i < argc; i += 2)
+   {
+   long bits;
+   const char *cp;
+
+   e = Jim_GetLong(interp, args[i], &bits);
+   /* If valid - try next arg */
+   if (e == JIM_OK) {
+   continue;
+   }
+
+   /* Not valid.. are we at the end? */
+   if (((i + 2) != argc)) {
+   /* nope, then error */
+   return e;
+   }
+
+   /* it could be: "-endstate FOO"
+* e.g. DRPAUSE so we can issue more instructions
+* before entering RUN/IDLE and executing them.
+*/
+
+   /* get arg as a string. */
+   cp = Jim_GetString(args[i], NULL);
+   /* is it the magic? */
+   if (0 == strcmp("-endstate", cp)) {
+   /* is the statename valid? */
+   cp = Jim_GetString(args[i + 1], NULL);
+
+   /* see if it is a valid state name */
+   endstate = tap_state_by_name(cp);
+   if (endstate < 0) {
+   /* update the error message */
+   Jim_SetResult_sprintf(interp,"endstate: %s 
invalid", cp);
+   } else {
+   if (!scan_is_safe(endstate))
+   LOG_WARNING("drscan with unsafe "
+   "endstate \"%s\"", cp);
+
+   /* valid - so clear the error */
+   e = JIM_OK;
+   /* and remove the last 2 args */
+   argc -= 2;
+   }
+   }
+
+   /* Still an error? */
+   if (e != JIM_OK) {
+   return e; /* too bad */
+   }
+   } /* validate args */
+
+   tap = jtag_tap_by_jim_obj(interp, args[1]);
+   if (tap == NULL) {
+   return JIM_ERR;
+   }
+
+   num_fields = (argc-2)/2;
+   fields = malloc(sizeof(struct scan_field) * num_fields);
+   for (i = 2; i < argc; i += 2)
+   {
+   long bits;
+   int len;
+   const char *str;
+
+   Jim_GetLong(interp, args[i], &bits);
+   str = Jim_GetString(args[i + 1], &len);
+
+   fields[field_count].tap = tap;
+   fields[field_count].num_bits = bits;
+   fields[field_count].out_value = malloc(DIV_ROUND_UP(bits, 8));
+   str_to_buf(str, len, fields[field_count].out_value, bits, 0);
+   fields[field_count].in_value = fields[field_count].out_value;
+   field_count++;
+   }
+
+   jtag_add_dr_scan(num_fields, fields, endstate);
+
+   retval = jtag_execute_queue();
+   if (retval != ERROR_OK)
+   {
+   Jim_SetResultString(interp, "drscan: jtag execute failed&q

[Openocd-development] [PATCH 09/12] presto: use register_commands()

2009-11-21 Thread Zachary T Welch
Use register_commands() with command registration array.

Signed-off-by: Zachary T Welch 
---
 src/jtag/presto.c |   16 +---
 1 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/src/jtag/presto.c b/src/jtag/presto.c
index f22bd9e..6f5833a 100644
--- a/src/jtag/presto.c
+++ b/src/jtag/presto.c
@@ -739,11 +739,21 @@ COMMAND_HANDLER(presto_handle_serial_command)
return ERROR_OK;
 }
 
+static const struct command_registration presto_command_handlers[] = {
+   {
+   .name = "presto_serial",
+   .handler = &presto_handle_serial_command,
+   .mode = COMMAND_CONFIG,
+   .help = "configure serial port",
+   .usage = "",
+   },
+   };
+
 static int presto_jtag_register_commands(struct command_context *cmd_ctx)
 {
-   COMMAND_REGISTER(cmd_ctx, NULL, "presto_serial", 
presto_handle_serial_command,
-   COMMAND_CONFIG, NULL);
-   return ERROR_OK;
+   return register_commands(cmd_ctx, NULL,
+   ARRAY_SIZE(presto_command_handlers),
+   presto_command_handlers);
 }
 
 static int presto_jtag_init(void)
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 12/12] remove register_callbacks from jtag interface

2009-11-21 Thread Zachary T Welch
Changes the jtag_interface->register_callbacks field to a list of
commands to be registered.  Changes callback to invocation of
register_commands() with that command registration list.  Removes all
JTAG interface driver register_command callback functions, which the
previous commits had converted into identical calls.

Signed-off-by: Zachary T Welch 
---
 src/jtag/amt_jtagaccel.c |   10 ++
 src/jtag/arm-jtag-ew.c   |   13 +
 src/jtag/dummy.c |9 +++--
 src/jtag/ft2232.c|   12 ++--
 src/jtag/gw16012.c   |   10 ++
 src/jtag/interface.h |3 ++-
 src/jtag/jlink.c |   13 +
 src/jtag/parport.c   |   29 +
 src/jtag/presto.c|   13 +
 src/jtag/rlink/rlink.c   |   44 
 src/jtag/tcl.c   |   11 +--
 src/jtag/vsllink.c   |   11 +++
 12 files changed, 47 insertions(+), 131 deletions(-)

diff --git a/src/jtag/amt_jtagaccel.c b/src/jtag/amt_jtagaccel.c
index 7729714..0d22634 100644
--- a/src/jtag/amt_jtagaccel.c
+++ b/src/jtag/amt_jtagaccel.c
@@ -557,16 +557,10 @@ static const struct command_registration 
amtjtagaccel_command_handlers[] = {
},
};
 
-static int amt_jtagaccel_register_commands(struct command_context *cmd_ctx)
-{
-   return register_commands(cmd_ctx, NULL,
-   ARRAY_SIZE(amtjtagaccel_command_handlers),
-   amtjtagaccel_command_handlers);
-}
-
 struct jtag_interface amt_jtagaccel_interface = {
.name = "amt_jtagaccel",
-   .register_commands = &amt_jtagaccel_register_commands,
+   .num_commands = ARRAY_SIZE(amtjtagaccel_command_handlers),
+   .commands = amtjtagaccel_command_handlers,
.init = &amt_jtagaccel_init,
.quit = &amt_jtagaccel_quit,
.speed = &amt_jtagaccel_speed,
diff --git a/src/jtag/arm-jtag-ew.c b/src/jtag/arm-jtag-ew.c
index 5363ae8..698e5e2 100644
--- a/src/jtag/arm-jtag-ew.c
+++ b/src/jtag/arm-jtag-ew.c
@@ -510,19 +510,16 @@ static const struct command_registration 
armjtagew_command_handlers[] = {
},
};
 
-static int armjtagew_register_commands(struct command_context *cmd_ctx)
-{
-   return register_commands(cmd_ctx, NULL,
-   ARRAY_SIZE(armjtagew_command_handlers),
-   armjtagew_command_handlers);
-}
-
 struct jtag_interface armjtagew_interface = {
.name = "arm-jtag-ew",
+
+   .num_commands = ARRAY_SIZE(armjtagew_command_handlers),
+   .commands = armjtagew_command_handlers,
+
.execute_queue = &armjtagew_execute_queue,
.speed = &armjtagew_speed,
.khz = &armjtagew_khz,
-   .register_commands = &armjtagew_register_commands,
+
.init = &armjtagew_init,
.quit = &armjtagew_quit,
};
diff --git a/src/jtag/dummy.c b/src/jtag/dummy.c
index 0516790..be804b5 100644
--- a/src/jtag/dummy.c
+++ b/src/jtag/dummy.c
@@ -134,11 +134,6 @@ static int dummy_speed(int speed)
return ERROR_OK;
 }
 
-static int dummy_register_commands(struct command_context *cmd_ctx)
-{
-   return ERROR_OK;
-}
-
 static int dummy_init(void)
 {
bitbang_interface = &dummy_bitbang;
@@ -157,10 +152,12 @@ static int dummy_quit(void)
 struct jtag_interface dummy_interface = {
.name = "dummy",
 
+   .commands = NULL,
+   .num_commands = 0,
+
.execute_queue = &bitbang_execute_queue,
 
.speed = &dummy_speed,
-   .register_commands = &dummy_register_commands,
.khz = &dummy_khz,
.speed_div = &dummy_speed_div,
 
diff --git a/src/jtag/ft2232.c b/src/jtag/ft2232.c
index d202427..8b80f87 100644
--- a/src/jtag/ft2232.c
+++ b/src/jtag/ft2232.c
@@ -4007,18 +4007,10 @@ static const struct command_registration 
ft2232_command_handlers[] = {
}
};
 
-
-static int ft2232_register_commands(struct command_context* cmd_ctx)
-{
-   return register_commands(cmd_ctx, NULL,
-   ARRAY_SIZE(ft2232_command_handlers),
-   ft2232_command_handlers);
-}
-
-
 struct jtag_interface ft2232_interface = {
.name = "ft2232",
-   .register_commands = &ft2232_register_commands,
+   .num_commands = ARRAY_SIZE(ft2232_command_handlers),
+   .commands = ft2232_command_handlers,
.init = &ft2232_init,
.quit = &ft2232_quit,
.speed = &ft2232_speed,
diff --git a/src/jtag/gw16012.c b/src/jtag/gw16012.c
index 5118562..74cdfa0 100644
--- a/src/jtag/gw16012.c
+++ b/src/jtag/gw16012.c
@@ -572,16 

[Openocd-development] [PATCH 10/12] jtag: use register_commands()

2009-11-21 Thread Zachary T Welch
Use register commands with command registration array.

Signed-off-by: Zachary T Welch 
---
 src/jtag/tcl.c |  187 
 1 files changed, 120 insertions(+), 67 deletions(-)

diff --git a/src/jtag/tcl.c b/src/jtag/tcl.c
index bd672b6..1c80245 100644
--- a/src/jtag/tcl.c
+++ b/src/jtag/tcl.c
@@ -1413,66 +1413,128 @@ COMMAND_HANDLER(handle_tms_sequence_command)
return ERROR_OK;
 }
 
+static const struct command_registration jtag_command_handlers[] = {
+   {
+   .name = "interface",
+   .handler = &handle_interface_command,
+   .mode = COMMAND_CONFIG,
+   .help = "select a JTAG interface",
+   .usage = "",
+   },
+   {
+   .name = "interface_list",
+   .handler = &handle_interface_list_command,
+   .mode = COMMAND_ANY,
+   .help = "list all built-in interfaces",
+   },
+   {
+   .name = "jtag_khz",
+   .handler = &handle_jtag_khz_command,
+   .mode = COMMAND_ANY,
+   .help = "set maximum jtag speed (if supported)",
+   .usage = "",
+   },
+   {
+   .name = "jtag_rclk",
+   .handler = &handle_jtag_rclk_command,
+   .mode = COMMAND_ANY,
+   .help = "set JTAG speed to RCLK or use fallback speed",
+   .usage = "",
+   },
+   {
+   .name = "reset_config",
+   .handler = &handle_reset_config_command,
+   .mode = COMMAND_ANY,
+   .help = "configure JTAG reset behavior",
+   .usage = "[none|trst_only|srst_only|trst_and_srst] "
+   
"[srst_pulls_trst|trst_pulls_srst|combined|separate] "
+   "[srst_gates_jtag|srst_nogate] "
+   "[trst_push_pull|trst_open_drain] "
+   "[srst_push_pull|srst_open_drain]",
+   },
+   {
+   .name = "jtag_nsrst_delay",
+   .handler = &handle_jtag_nsrst_delay_command,
+   .mode = COMMAND_ANY,
+   .help = "- delay after deasserting srst in ms",
+   .usage = "",
+   },
+   {
+   .name = "jtag_ntrst_delay",
+   .handler = &handle_jtag_ntrst_delay_command,
+   .mode = COMMAND_ANY,
+   .help = " delay after deasserting trst in ms",
+   .usage = ""
+   },
+   {
+   .name = "jtag_nsrst_assert_width",
+   .handler = &handle_jtag_nsrst_assert_width_command,
+   .mode = COMMAND_ANY,
+   .help = "- delay after asserting srst in ms",
+   .usage = ""
+   },
+   {
+   .name = "jtag_ntrst_assert_width",
+   .handler = &handle_jtag_ntrst_assert_width_command,
+   .mode = COMMAND_ANY,
+   .help = "- delay after asserting trst in ms",
+   .usage = ""
+   },
+   {
+   .name = "scan_chain",
+   .handler = &handle_scan_chain_command,
+   .mode = COMMAND_EXEC,
+   .help = "print current scan chain configuration",
+   },
+   {
+   .name = "jtag_reset",
+   .handler = &handle_jtag_reset_command,
+   .mode = COMMAND_EXEC,
+   .help = "toggle reset lines",
+   .usage = " ",
+   },
+   {
+   .name = "runtest",
+   .handler = &handle_runtest_command,
+   .mode = COMMAND_EXEC,
+   .help = "move to Run-Test/Idle, and execute 
",
+   .usage = ""
+   },
+   {
+   .name = "irscan",
+   .handler = &handle_irscan_command,
+

[Openocd-development] [PATCH 11/12] vsllink: use register_commands()

2009-11-21 Thread Zachary T Welch
Use register_commands() with command registration array.

Signed-off-by: Zachary T Welch 
---
 src/jtag/vsllink.c |   56 +--
 1 files changed, 36 insertions(+), 20 deletions(-)

diff --git a/src/jtag/vsllink.c b/src/jtag/vsllink.c
index 538ae0b..d6a2ec8 100644
--- a/src/jtag/vsllink.c
+++ b/src/jtag/vsllink.c
@@ -1880,28 +1880,44 @@ static void vsllink_debug_buffer(uint8_t *buffer, int 
length)
 }
 #endif // _DEBUG_USB_COMMS_ || _DEBUG_JTAG_IO_
 
+static const struct command_registration vsllink_command_handlers[] = {
+   {
+   .name = "vsllink_usb_vid",
+   .handler = &vsllink_handle_usb_vid_command,
+   .mode = COMMAND_CONFIG,
+   },
+   {
+   .name = "vsllink_usb_pid",
+   .handler = &vsllink_handle_usb_pid_command,
+   .mode = COMMAND_CONFIG,
+   },
+   {
+   .name = "vsllink_usb_bulkin",
+   .handler = &vsllink_handle_usb_bulkin_command,
+   .mode = COMMAND_CONFIG,
+   },
+   {
+   .name = "vsllink_usb_bulkout",
+   .handler = &vsllink_handle_usb_bulkout_command,
+   .mode = COMMAND_CONFIG,
+   },
+   {
+   .name = "vsllink_usb_interface",
+   .handler = &vsllink_handle_usb_interface_command,
+   .mode = COMMAND_CONFIG,
+   },
+   {
+   .name = "vsllink_mode",
+   .handler = &vsllink_handle_mode_command,
+   .mode = COMMAND_CONFIG,
+   },
+   };
+
 static int vsllink_register_commands(struct command_context *cmd_ctx)
 {
-   COMMAND_REGISTER(cmd_ctx, NULL, "vsllink_usb_vid",
-   vsllink_handle_usb_vid_command, COMMAND_CONFIG,
-   NULL);
-   COMMAND_REGISTER(cmd_ctx, NULL, "vsllink_usb_pid",
-   vsllink_handle_usb_pid_command, COMMAND_CONFIG,
-   NULL);
-   COMMAND_REGISTER(cmd_ctx, NULL, "vsllink_usb_bulkin",
-   vsllink_handle_usb_bulkin_command, COMMAND_CONFIG,
-   NULL);
-   COMMAND_REGISTER(cmd_ctx, NULL, "vsllink_usb_bulkout",
-   vsllink_handle_usb_bulkout_command, COMMAND_CONFIG,
-   NULL);
-   COMMAND_REGISTER(cmd_ctx, NULL, "vsllink_usb_interface",
-   vsllink_handle_usb_interface_command, COMMAND_CONFIG,
-   NULL);
-   COMMAND_REGISTER(cmd_ctx, NULL, "vsllink_mode",
-   vsllink_handle_mode_command, COMMAND_CONFIG,
-   NULL);
-
-   return ERROR_OK;
+   return register_commands(cmd_ctx, NULL,
+   ARRAY_SIZE(vsllink_command_handlers),
+   vsllink_command_handlers);
 }
 
 struct jtag_interface vsllink_interface = {
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 01/12] openocd: update version/init command registration

2009-11-21 Thread Zachary T Welch
Use register_commands() for top-level version and init command.

Signed-off-by: Zachary T Welch 
---
 src/openocd.c |   25 +++--
 1 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/src/openocd.c b/src/openocd.c
index 379373c..4d13611 100644
--- a/src/openocd.c
+++ b/src/openocd.c
@@ -159,6 +159,22 @@ COMMAND_HANDLER(handle_init_command)
return ERROR_OK;
 }
 
+static const struct command_registration openocd_command_handlers[] = {
+   {
+   .name = "version",
+   .handler = &handle_version_command,
+   .mode = COMMAND_EXEC,
+   .help = "show program version",
+   },
+   {
+   .name = "init",
+   .handler = &handle_init_command,
+   .mode = COMMAND_ANY,
+   .help = "Initializes configured targets and servers.  "
+   "If called more than once, does nothing.",
+   },
+   };
+
 struct command_context *global_cmd_ctx;
 
 /// src/hello.c gives a simple example for writing new command modules
@@ -171,9 +187,9 @@ struct command_context *setup_command_handler(void)
 
global_cmd_ctx = cmd_ctx = command_init(openocd_startup_tcl);
 
-   COMMAND_REGISTER(cmd_ctx, NULL, "version", handle_version_command,
-COMMAND_EXEC, "show OpenOCD version");
-
+   register_commands(cmd_ctx, NULL,
+   ARRAY_SIZE(openocd_command_handlers),
+   openocd_command_handlers);
/* register subsystem commands */
hello_register_commands(cmd_ctx);
server_register_commands(cmd_ctx);
@@ -198,9 +214,6 @@ struct command_context *setup_command_handler(void)
 
LOG_OUTPUT(OPENOCD_VERSION "\n");
 
-   COMMAND_REGISTER(cmd_ctx, NULL, "init", handle_init_command,
-COMMAND_ANY, "initializes target and 
servers - nop on subsequent invocations");
-
return cmd_ctx;
 }
 
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 08/12] parport: use register_commands()

2009-11-21 Thread Zachary T Welch
Use register_commands() with a command registration array.

Signed-off-by: Zachary T Welch 
---
 src/jtag/parport.c |   58 ++--
 1 files changed, 38 insertions(+), 20 deletions(-)

diff --git a/src/jtag/parport.c b/src/jtag/parport.c
index 4b4df09..cfc3405 100644
--- a/src/jtag/parport.c
+++ b/src/jtag/parport.c
@@ -482,28 +482,46 @@ 
COMMAND_HANDLER(parport_handle_parport_toggling_time_command)
return ERROR_OK;
 }
 
-static int parport_register_commands(struct command_context *cmd_ctx)
-{
-   COMMAND_REGISTER(cmd_ctx, NULL, "parport_port",
-   parport_handle_parport_port_command, COMMAND_CONFIG,
-   "either the address of the I/O port "
-   "or the number of the '/dev/parport' device");
-
-   COMMAND_REGISTER(cmd_ctx, NULL, "parport_cable",
-   parport_handle_parport_cable_command, COMMAND_CONFIG,
-   "the layout of the parallel port cable "
-   "used to connect to the target");
-
-   COMMAND_REGISTER(cmd_ctx, NULL, "parport_write_on_exit",
-   parport_handle_write_on_exit_command, COMMAND_CONFIG,
-   "configure the parallel driver to write "
-   "a known value to the parallel interface");
+static const struct command_registration parport_command_handlers[] = {
+   {
+   .name = "parport_port",
+   .handler = &parport_handle_parport_port_command,
+   .mode = COMMAND_CONFIG,
+   .help = "either the address of the I/O port "
+   "or the number of the '/dev/parport' device",
+   .usage = "[]",
+   },
+   {
+   .name = "parport_cable",
+   .handler = &parport_handle_parport_cable_command,
+   .mode = COMMAND_CONFIG,
+   .help = "the layout of the parallel port cable "
+   "used to connect to the target",
+   .usage = "[]",
+   },
+   {
+   .name = "parport_write_on_exit",
+   .handler = &parport_handle_write_on_exit_command,
+   .mode = COMMAND_CONFIG,
+   .help = "configure the parallel driver to write "
+   "a known value to the parallel interface",
+   .usage = "[]",
+   },
+   {
+   .name = "parport_toggling_time",
+   .handler = 
&parport_handle_parport_toggling_time_command,
+   .mode = COMMAND_CONFIG,
+   .help = "time  it takes for the hardware to toggle 
TCK",
+   .usage = "[]",
+   },
+   };
 
-   COMMAND_REGISTER(cmd_ctx, NULL, "parport_toggling_time",
-   parport_handle_parport_toggling_time_command, 
COMMAND_ANY,
-   "time  it takes for the hardware to toggle TCK");
 
-   return ERROR_OK;
+static int parport_register_commands(struct command_context *cmd_ctx)
+{
+   return register_commands(cmd_ctx, NULL,
+   ARRAY_SIZE(parport_command_handlers),
+   parport_command_handlers);
 }
 
 struct jtag_interface parport_interface = {
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 07/12] jlink: use register_commands()

2009-11-21 Thread Zachary T Welch
Use register_commands() with command registration array.

Signed-off-by: Zachary T Welch 
---
 src/jtag/jlink.c |   27 +++
 1 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/src/jtag/jlink.c b/src/jtag/jlink.c
index 0f76c9f..200dfe4 100644
--- a/src/jtag/jlink.c
+++ b/src/jtag/jlink.c
@@ -628,16 +628,27 @@ COMMAND_HANDLER(jlink_handle_jlink_hw_jtag_command)
return ERROR_OK;
 }
 
+static const struct command_registration jlink_command_handlers[] = {
+   {
+   .name = "jlink_info",
+   .handler = &jlink_handle_jlink_info_command,
+   .mode = COMMAND_EXEC,
+   .help = "show jlink info",
+   },
+   {
+   .name = "jlink_hw_jtag",
+   .handler = &jlink_handle_jlink_hw_jtag_command,
+   .mode = COMMAND_EXEC,
+   .help = "access J-Link HW JTAG command version",
+   .usage = "[2|3]",
+   },
+   };
+
 static int jlink_register_commands(struct command_context *cmd_ctx)
 {
-
-   COMMAND_REGISTER(cmd_ctx, NULL, "jlink_info",
-   &jlink_handle_jlink_info_command, COMMAND_EXEC,
-   "query jlink info");
-   COMMAND_REGISTER(cmd_ctx, NULL, "jlink_hw_jtag",
-   &jlink_handle_jlink_hw_jtag_command, COMMAND_EXEC,
-   "set/get jlink hw jtag command version [2 | 3]");
-   return ERROR_OK;
+   return register_commands(cmd_ctx, NULL,
+   ARRAY_SIZE(jlink_command_handlers),
+   jlink_command_handlers);
 }
 
 struct jtag_interface jlink_interface = {
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 06/12] gw16012: use register_commands()

2009-11-21 Thread Zachary T Welch
Use register_commands() with command registration array.

Signed-off-by: Zachary T Welch 
---
 src/jtag/gw16012.c |   18 +-
 1 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/src/jtag/gw16012.c b/src/jtag/gw16012.c
index bc0e472..5118562 100644
--- a/src/jtag/gw16012.c
+++ b/src/jtag/gw16012.c
@@ -562,13 +562,21 @@ COMMAND_HANDLER(gw16012_handle_parport_port_command)
return ERROR_OK;
 }
 
+static const struct command_registration gw16012_command_handlers[] = {
+   {
+   .name = "parport_port",
+   .handler = &gw16012_handle_parport_port_command,
+   .mode = COMMAND_CONFIG,
+   .help = "configure the parallel port to use",
+   .usage = "",
+   },
+   };
+
 static int gw16012_register_commands(struct command_context *cmd_ctx)
 {
-   COMMAND_REGISTER(cmd_ctx, NULL, "parport_port",
-   gw16012_handle_parport_port_command, COMMAND_CONFIG,
-   NULL);
-
-   return ERROR_OK;
+   return register_commands(cmd_ctx, NULL,
+   ARRAY_SIZE(gw16012_command_handlers),
+   gw16012_command_handlers);
 }
 
 struct jtag_interface gw16012_interface = {
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 04/12] at91rm9200: use register_commands()

2009-11-21 Thread Zachary T Welch
Use register_commands() with command registration array.
---
This module was broken by previous changes, but no one has complained.
Are there still users for this modules?

Signed-off-by: Zachary T Welch 
---
 src/jtag/at91rm9200.c |   15 ---
 1 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/jtag/at91rm9200.c b/src/jtag/at91rm9200.c
index 024dd6d..34bcd60 100644
--- a/src/jtag/at91rm9200.c
+++ b/src/jtag/at91rm9200.c
@@ -200,11 +200,20 @@ static int at91rm9200_handle_device_command(struct 
command_context *cmd_ctx, cha
return ERROR_OK;
 }
 
+static const struct command_registration at91rm9200_command_handlers[] = {
+   {
+   .name = "at91rm9200_device",
+   .handler = &at91rm9200_handle_device_command,
+   .mode = COMMAND_CONFIG,
+   .help = "query armjtagew info",
+   },
+   };
+
 static int at91rm9200_register_commands(struct command_context *cmd_ctx)
 {
-   COMMAND_REGISTER(cmd_ctx, NULL, "at91rm9200_device", 
at91rm9200_handle_device_command,
-   COMMAND_CONFIG, NULL);
-   return ERROR_OK;
+   return register_commands(cmd_ctx, NULL,
+   ARRAY_SIZE(at91rm9200_command_handlers),
+   at91rm9200_command_handlers);
 }
 
 static int at91rm9200_init(void)
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 03/12] arm-jtag-ew: use register_commands()

2009-11-21 Thread Zachary T Welch
Uses register_commands() with command registration array.

Signed-off-by: Zachary T Welch 
---
 src/jtag/arm-jtag-ew.c |   16 
 1 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/src/jtag/arm-jtag-ew.c b/src/jtag/arm-jtag-ew.c
index 82ff2a0..5363ae8 100644
--- a/src/jtag/arm-jtag-ew.c
+++ b/src/jtag/arm-jtag-ew.c
@@ -501,12 +501,20 @@ COMMAND_HANDLER(armjtagew_handle_armjtagew_info_command)
return ERROR_OK;
 }
 
+static const struct command_registration armjtagew_command_handlers[] = {
+   {
+   .name = "armjtagew_info",
+   .handler = &armjtagew_handle_armjtagew_info_command,
+   .mode = COMMAND_EXEC,
+   .help = "query armjtagew info",
+   },
+   };
+
 static int armjtagew_register_commands(struct command_context *cmd_ctx)
 {
-   COMMAND_REGISTER(cmd_ctx, NULL, "armjtagew_info",
-   &armjtagew_handle_armjtagew_info_command, COMMAND_EXEC,
-   "query armjtagew info");
-   return ERROR_OK;
+   return register_commands(cmd_ctx, NULL,
+   ARRAY_SIZE(armjtagew_command_handlers),
+   armjtagew_command_handlers);
 }
 
 struct jtag_interface armjtagew_interface = {
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 05/12] ft2232: use register_commands()

2009-11-21 Thread Zachary T Welch
Use register_commands() with a command registration array.

Signed-off-by: Zachary T Welch 
---
 src/jtag/ft2232.c |   60 +---
 1 files changed, 42 insertions(+), 18 deletions(-)

diff --git a/src/jtag/ft2232.c b/src/jtag/ft2232.c
index e560b22..d202427 100644
--- a/src/jtag/ft2232.c
+++ b/src/jtag/ft2232.c
@@ -3968,27 +3968,51 @@ static void ktlink_blink(void)
buffer_write(high_output);
buffer_write(high_direction);
 }
+static const struct command_registration ft2232_command_handlers[] = {
+   {
+   .name = "ft2232_device_desc",
+   .handler = &ft2232_handle_device_desc_command,
+   .mode = COMMAND_CONFIG,
+   .help = "set the USB device description of the FTDI 
FT2232 device",
+   .usage = "",
+   },
+   {
+   .name = "ft2232_serial",
+   .handler = &ft2232_handle_serial_command,
+   .mode = COMMAND_CONFIG,
+   .help = "set the serial number of the FTDI FT2232 
device",
+   .usage = "",
+   },
+   {
+   .name = "ft2232_layout",
+   .handler = &ft2232_handle_layout_command,
+   .mode = COMMAND_CONFIG,
+   .help = "set the layout of the FT2232 GPIO signals used 
"
+   "to control output-enables and reset signals",
+   .usage = "",
+   },
+   {
+   .name = "ft2232_vid_pid",
+   .handler = &ft2232_handle_vid_pid_command,
+   .mode = COMMAND_CONFIG,
+   .help = "the vendor ID and product ID of the FTDI 
FT2232 device",
+   .usage = "  [...]",
+   },
+   {
+   .name = "ft2232_latency",
+   .handler = &ft2232_handle_latency_command,
+   .mode = COMMAND_CONFIG,
+   .help = "set the FT2232 latency timer to a new value",
+   .usage = "  [...]",
+   }
+   };
+
 
 static int ft2232_register_commands(struct command_context* cmd_ctx)
 {
-   COMMAND_REGISTER(cmd_ctx, NULL, "ft2232_device_desc",
-   ft2232_handle_device_desc_command, COMMAND_CONFIG,
-   "the USB device description of the FTDI FT2232 device");
-   COMMAND_REGISTER(cmd_ctx, NULL, "ft2232_serial",
-   ft2232_handle_serial_command, COMMAND_CONFIG,
-   "the serial number of the FTDI FT2232 device");
-   COMMAND_REGISTER(cmd_ctx, NULL, "ft2232_layout",
-   ft2232_handle_layout_command, COMMAND_CONFIG,
-   "the layout of the FT2232 GPIO signals used "
-   "to control output-enables and reset signals");
-   COMMAND_REGISTER(cmd_ctx, NULL, "ft2232_vid_pid",
-   ft2232_handle_vid_pid_command, COMMAND_CONFIG,
-   "the vendor ID and product ID of the FTDI FT2232 
device");
-   COMMAND_REGISTER(cmd_ctx, NULL, "ft2232_latency",
-   ft2232_handle_latency_command, COMMAND_CONFIG,
-   "set the FT2232 latency timer to a new value");
-
-   return ERROR_OK;
+   return register_commands(cmd_ctx, NULL,
+   ARRAY_SIZE(ft2232_command_handlers),
+   ft2232_command_handlers);
 }
 
 
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 0/12] jtag command registration cleanup

2009-11-21 Thread Zachary T Welch
Hi all,

This series builds upon the last to cleanup the JTAG layer command
handler registration.  First, each module gets converted to use
register_commands() with a command registration array.  The final patch
converts the jtag_interface structure to contain the registration list
(and its size), removing the register_commands callback functions from
all of the interface drivers.

Cheers,

Zach
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 02/12] amt_jtagaccel: use register_commands()

2009-11-21 Thread Zachary T Welch
Use register_commands() with command_registration array.

Signed-off-by: Zachary T Welch 
---
 src/jtag/amt_jtagaccel.c |   28 
 1 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/src/jtag/amt_jtagaccel.c b/src/jtag/amt_jtagaccel.c
index 0aabdc9..7729714 100644
--- a/src/jtag/amt_jtagaccel.c
+++ b/src/jtag/amt_jtagaccel.c
@@ -540,16 +540,28 @@ COMMAND_HANDLER(amt_jtagaccel_handle_rtck_command)
return ERROR_OK;
 }
 
+static const struct command_registration amtjtagaccel_command_handlers[] = {
+   {
+   .name = "parport_port",
+   .handler = &amt_jtagaccel_handle_parport_port_command,
+   .mode = COMMAND_CONFIG,
+   .help = "configure the parallel port to use",
+   .usage = "",
+   },
+   {
+   .name = "parport_port",
+   .handler = &amt_jtagaccel_handle_rtck_command,
+   .mode = COMMAND_CONFIG,
+   .help = "enable RTCK",
+   .usage = "",
+   },
+   };
+
 static int amt_jtagaccel_register_commands(struct command_context *cmd_ctx)
 {
-   COMMAND_REGISTER(cmd_ctx, NULL, "parport_port",
-   amt_jtagaccel_handle_parport_port_command, 
COMMAND_CONFIG,
-   NULL);
-   COMMAND_REGISTER(cmd_ctx, NULL, "rtck",
-   amt_jtagaccel_handle_rtck_command, COMMAND_CONFIG,
-   NULL);
-
-   return ERROR_OK;
+   return register_commands(cmd_ctx, NULL,
+   ARRAY_SIZE(amtjtagaccel_command_handlers),
+   amtjtagaccel_command_handlers);
 }
 
 struct jtag_interface amt_jtagaccel_interface = {
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 7/8] ioutil: use register_commands()

2009-11-20 Thread Zachary T Welch
Use table instead of individual calls.  Add proper usage information.

Signed-off-by: Zachary T Welch 
---
 src/helper/ioutil.c |   63 +-
 1 files changed, 46 insertions(+), 17 deletions(-)

diff --git a/src/helper/ioutil.c b/src/helper/ioutil.c
index 52ecb9f..dbc88c6 100644
--- a/src/helper/ioutil.c
+++ b/src/helper/ioutil.c
@@ -643,27 +643,56 @@ static int zylinjtag_Jim_Command_mac(Jim_Interp *interp, 
int argc,
 
 }
 
+static const struct command_registration ioutil_command_handlers[] = {
+   {
+   .name = "rm",
+   .handler = &handle_rm_command,
+   .mode = COMMAND_ANY,
+   .help = "remove file",
+   .usage= "",
+   },
+   {
+   .name = "cat",
+   .handler = &handle_cat_command,
+   .mode = COMMAND_ANY,
+   .help = "display file content",
+   .usage= "",
+   },
+   {
+   .name = "trunc",
+   .handler = &handle_trunc_command,
+   .mode = COMMAND_ANY,
+   .help = "truncate a file 0 size",
+   .usage= "",
+   },
+   {
+   .name = "cp",
+   .handler = &handle_cp_command,
+   .mode = COMMAND_ANY,
+   .help = "copy a file",
+   .usage = " ",
+   },
+   {
+   .name = "append_file",
+   .handler = &handle_append_command,
+   .mode = COMMAND_ANY,
+   .help = "append a variable number of strings to a file",
+   .usage= " [ ...]",
+   },
+   {
+   .name = "meminfo",
+   .handler = &handle_meminfo_command,
+   .mode = COMMAND_ANY,
+   .help = "display available ram memory",
+   },
+   };
 
 
 int ioutil_init(struct command_context *cmd_ctx)
 {
-   COMMAND_REGISTER(cmd_ctx, NULL, "rm", handle_rm_command, COMMAND_ANY,
-   "remove file");
-
-   COMMAND_REGISTER(cmd_ctx, NULL, "cat", handle_cat_command, COMMAND_ANY,
-   "display file content");
-
-   COMMAND_REGISTER(cmd_ctx, NULL, "trunc", handle_trunc_command, 
COMMAND_ANY,
-   "truncate a file to 0 size");
-
-   COMMAND_REGISTER(cmd_ctx, NULL, "cp", handle_cp_command,
-COMMAND_ANY, "copy a file  
");
-
-   COMMAND_REGISTER(cmd_ctx, NULL, "append_file", handle_append_command,
-   COMMAND_ANY, "append a variable number of strings to a 
file");
-
-   COMMAND_REGISTER(cmd_ctx, NULL, "meminfo", handle_meminfo_command,
-   COMMAND_ANY, "display available ram memory");
+   register_commands(cmd_ctx, NULL,
+   ARRAY_SIZE(ioutil_command_handlers),
+   ioutil_command_handlers);
 
 Jim_CreateCommand(interp, "rm", zylinjtag_Jim_Command_rm, NULL, NULL);
 
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 6/8] command: use register_commands for handlers

2009-11-20 Thread Zachary T Welch
Use register_commands() to register low-level command handlers,
adding a builtin_command_handlers declaration that is easy to understand.
Splits help and usage information into their appropriate fields.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c |   52 +
 1 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index aa97806..36ad7af 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -903,6 +903,38 @@ COMMAND_HANDLER(handle_sleep_command)
return ERROR_OK;
 }
 
+static const struct command_registration command_builtin_handlers[] = {
+   {
+   .name = "add_help_text",
+   .handler = &handle_help_add_command,
+   .mode = COMMAND_ANY,
+   .help = "add new command help text",
+   .usage = " [...] ]",
+   },
+   {
+   .name = "sleep",
+   .handler = &handle_sleep_command,
+   .mode = COMMAND_ANY,
+   .help = "sleep for n milliseconds.  "
+   "\"busy\" will busy wait",
+   .usage = " [busy]",
+   },
+   {
+   .name = "help",
+   .handler = &handle_help_command,
+   .mode = COMMAND_ANY,
+   .help = "show built-in command help",
+   .usage = "[ ...]",
+   },
+   {
+   .name = "usage",
+   .handler = &handle_usage_command,
+   .mode = COMMAND_ANY,
+   .help = "show command usage",
+   .usage = "[ ...]",
+   },
+   };
+
 struct command_context* command_init(const char *startup_tcl)
 {
struct command_context* context = malloc(sizeof(struct 
command_context));
@@ -962,10 +994,9 @@ struct command_context* command_init(const char 
*startup_tcl)
interp->cb_fflush = openocd_jim_fflush;
interp->cb_fgets = openocd_jim_fgets;
 
-   COMMAND_REGISTER(context, NULL, "add_help_text",
-   handle_help_add_command, COMMAND_ANY,
-   " [...] ] - "
-   "add new command help text");
+   register_commands(context, NULL,
+   ARRAY_SIZE(command_builtin_handlers),
+   command_builtin_handlers);
 
 #if !BUILD_ECOSBOARD
Jim_EventLoopOnLoad(interp);
@@ -979,19 +1010,6 @@ struct command_context* command_init(const char 
*startup_tcl)
}
Jim_DeleteAssocData(interp, "context");
 
-   COMMAND_REGISTER(context, NULL, "sleep",
-   handle_sleep_command, COMMAND_ANY,
-   " [busy] - sleep for n milliseconds. "
-   "\"busy\" means busy wait");
-
-   COMMAND_REGISTER(context, NULL, "help",
-   &handle_help_command, COMMAND_ANY,
-   "[ ...] - show built-in command help");
-   COMMAND_REGISTER(context, NULL, "usage",
-   &handle_usage_command, COMMAND_ANY,
-   "[ ...] | "
-   "show command usage");
-
return context;
 }
 
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 8/8] log: use register_commands()

2009-11-20 Thread Zachary T Welch
Use register_commands() for logging callbacks.  Improve help and add
proper usage.

Signed-off-by: Zachary T Welch 
---
 src/helper/log.c |   25 -
 1 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/src/helper/log.c b/src/helper/log.c
index 09fe60b..77a6b4b 100644
--- a/src/helper/log.c
+++ b/src/helper/log.c
@@ -316,15 +316,30 @@ COMMAND_HANDLER(handle_log_output_command)
return ERROR_OK;
 }
 
+static struct command_registration log_command_handlers[] = {
+   {
+   .name = "log_output",
+   .handler = &handle_log_output_command,
+   .mode = COMMAND_ANY,
+   .help = "redirect logging to a file (default: stderr)",
+   .usage = "",
+   },
+   {
+   .name = "debug_level",
+   .handler = &handle_debug_level_command,
+   .mode = COMMAND_ANY,
+   .help = "sets the verbosity level of debugging output",
+   .usage = "",
+   },
+   };
+
 int log_register_commands(struct command_context *cmd_ctx)
 {
start = timeval_ms();
-   COMMAND_REGISTER(cmd_ctx, NULL, "log_output", handle_log_output_command,
-   COMMAND_ANY, "redirect logging to  (default: stderr)");
-   COMMAND_REGISTER(cmd_ctx, NULL, "debug_level", 
handle_debug_level_command,
-   COMMAND_ANY, "adjust debug level <0-3>");
 
-   return ERROR_OK;
+   return register_commands(cmd_ctx, NULL,
+   ARRAY_SIZE(log_command_handlers),
+   log_command_handlers);
 }
 
 int log_init(struct command_context *cmd_ctx)
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 5/8] add command usage, separate from help

2009-11-20 Thread Zachary T Welch
Adds the usage command, to display usage information for commands.
The output for this command will remain erronenously empty until
commands are updated to use these new coventions.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c |   63 ++---
 src/helper/command.h |3 ++
 2 files changed, 52 insertions(+), 14 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index 29e645b..aa97806 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -226,7 +226,7 @@ static struct command **command_list_for_parent(
 static struct command *command_new(struct command_context *cmd_ctx,
struct command *parent, const char *name,
command_handler_t handler, enum command_mode mode,
-   const char *help)
+   const char *help, const char *usage)
 {
assert(name);
 
@@ -236,6 +236,8 @@ static struct command *command_new(struct command_context 
*cmd_ctx,
c->name = strdup(name);
if (help)
c->help = strdup(help);
+   if (usage)
+   c->usage = strdup(usage);
c->parent = parent;
c->handler = handler;
c->mode = mode;
@@ -259,6 +261,8 @@ static void command_free(struct command *c)
free(c->name);
if (c->help)
free((void*)c->help);
+   if (c->usage)
+   free((void*)c->usage);
free(c);
 }
 
@@ -278,7 +282,7 @@ struct command* register_command(struct command_context 
*context,
return c;
}
 
-   c = command_new(context, parent, name, cr->handler, cr->mode, cr->help);
+   c = command_new(context, parent, name, cr->handler, cr->mode, cr->help, 
cr->usage);
/* if allocation failed or it is a placeholder (no handler), we're done 
*/
if (NULL == c || NULL == c->handler)
return c;
@@ -740,41 +744,67 @@ static COMMAND_HELPER(command_help_find, struct command 
*head,
return CALL_COMMAND_HANDLER(command_help_find, (*out)->children, out);
 }
 
-static COMMAND_HELPER(command_help_show, struct command *c, unsigned n);
+static COMMAND_HELPER(command_help_show, struct command *c, unsigned n,
+   bool show_help);
 
-static COMMAND_HELPER(command_help_show_list, struct command *head, unsigned n)
+static COMMAND_HELPER(command_help_show_list, struct command *head, unsigned n,
+   bool show_help)
 {
for (struct command *c = head; NULL != c; c = c->next)
-   CALL_COMMAND_HANDLER(command_help_show, c, n);
+   CALL_COMMAND_HANDLER(command_help_show, c, n, show_help);
return ERROR_OK;
 }
-static COMMAND_HELPER(command_help_show, struct command *c, unsigned n)
+static COMMAND_HELPER(command_help_show, struct command *c, unsigned n,
+   bool show_help)
 {
-   command_run_linef(CMD_CTX, "cmd_help {%s} {%s} %d", command_name(c, ' 
'),
-   c->help ? : "no help available", n);
+   const char *usage = c->usage ? : "";
+   const char *help = "";
+   const char *sep = "";
+   if (show_help && c->help)
+   {
+   help = c->help ? : "";
+   sep = c->usage ? " | " : "";
+   }
+   command_run_linef(CMD_CTX, "cmd_help {%s} {%s%s%s} %d",
+   command_name(c, ' '), usage, sep, help, n);
 
if (++n >= 2)
return ERROR_OK;
 
-   return CALL_COMMAND_HANDLER(command_help_show_list, c->children, n);
+   return CALL_COMMAND_HANDLER(command_help_show_list,
+   c->children, n, show_help);
 }
 COMMAND_HANDLER(handle_help_command)
 {
struct command *c = CMD_CTX->commands;
 
if (0 == CMD_ARGC)
-   return CALL_COMMAND_HANDLER(command_help_show_list, c, 0);
+   return CALL_COMMAND_HANDLER(command_help_show_list, c, 0, true);
+
+   int retval = CALL_COMMAND_HANDLER(command_help_find, c, &c);
+   if (ERROR_OK != retval)
+   return retval;
+
+   return CALL_COMMAND_HANDLER(command_help_show, c, 0, true);
+}
+
+COMMAND_HANDLER(handle_usage_command)
+{
+   struct command *c = CMD_CTX->commands;
+
+   if (0 == CMD_ARGC)
+   return CALL_COMMAND_HANDLER(command_help_show_list, c, 0, 
false);
 
int retval = CALL_COMMAND_HANDLER(command_help_find, c, &c);
if (ERROR_OK != retval)
return retval;
 
-   return CALL_COMMAND_HANDLER(command_help_show, c, 0);
+   return CALL_COMMAND_HANDLER(command_help_show, c, 0, false);
 }
 
 
 int help_add_command(struct command_context *cmd_ctx, struct command *parent,
-   const char *cmd_name, const char *help_text)
+   const char *cmd_n

[Openocd-development] [PATCH 3/8] add struct command_registration

2009-11-20 Thread Zachary T Welch
Add a structure to encapsulate command registration information, rather
than passing them all as parameters.  Enables further API changes that
require additional required or optional parameters.

Updates the register_command API and COMMAND_REGISTER macro to use it,
along with their documentation.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c |   17 +--
 src/helper/command.h |   52 ++---
 2 files changed, 46 insertions(+), 23 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index ace7a2b..3df60b6 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -263,13 +263,12 @@ static void command_free(struct command *c)
 }
 
 struct command* register_command(struct command_context *context,
-   struct command *parent, const char *name,
-   command_handler_t handler, enum command_mode mode,
-   const char *help)
+   struct command *parent, const struct command_registration *cr)
 {
-   if (!context || !name)
+   if (!context || !cr->name)
return NULL;
 
+   const char *name = cr->name;
struct command **head = command_list_for_parent(context, parent);
struct command *c = command_find(*head, name);
if (NULL != c)
@@ -279,7 +278,7 @@ struct command* register_command(struct command_context 
*context,
return c;
}
 
-   c = command_new(context, parent, name, handler, mode, help);
+   c = command_new(context, parent, name, cr->handler, cr->mode, cr->help);
/* if allocation failed or it is a placeholder (no handler), we're done 
*/
if (NULL == c || NULL == c->handler)
return c;
@@ -762,8 +761,12 @@ int help_add_command(struct command_context *cmd_ctx, 
struct command *parent,
if (NULL == nc)
{
// add a new command with help text
-   nc = command_register(cmd_ctx, parent, cmd_name,
-   NULL, COMMAND_ANY, help_text);
+   struct command_registration cr = {
+   .name = cmd_name,
+   .mode = COMMAND_ANY,
+   .help = help_text,
+   };
+   nc = register_command(cmd_ctx, parent, &cr);
if (NULL == nc)
{
LOG_ERROR("failed to add '%s' help text", cmd_name);
diff --git a/src/helper/command.h b/src/helper/command.h
index 25c0501..14ad73e 100644
--- a/src/helper/command.h
+++ b/src/helper/command.h
@@ -177,13 +177,9 @@ struct command
  */
 char *command_name(struct command *c, char delim);
 
-/**
- * Register a command @c handler that can be called from scripts during
- * the execution @c mode specified.
- *
- * If @c parent is non-NULL, the new command will be registered as a
- * sub-command under it; otherwise, it will be available as a top-level
- * command.
+/*
+ * Commands should be registered by filling in one or more of these
+ * structures and passing them to register_command().
  *
  * A conventioal format should be used for help strings, to provide both
  * usage and basic information:
@@ -191,25 +187,49 @@ char *command_name(struct command *c, char delim);
  * "@ ... - some explanation text"
  * @endcode
  *
- * @param cmd_ctx The command_context in which to register the command.
- * @param parent Register this command as a child of this, or NULL to
- * register a top-level command.
  * @param name The name of the command to register, which must not have
- * been registered previously.
+ * been registered previously in the intended context.
  * @param handler The callback function that will be called.  If NULL,
  * then the command serves as a placeholder for its children or a script.
  * @param mode The command mode(s) in which this command may be run.
  * @param help The help text that will be displayed to the user.
+ */
+struct command_registration {
+   struct command *parent;
+   const char *name;
+   command_handler_t handler;
+   enum command_mode mode;
+   const char *help;
+};
+
+/**
+ * Register a command @c handler that can be called from scripts during
+ * the execution @c mode specified.
+ *
+ * If @c parent is non-NULL, the new command will be registered as a
+ * sub-command under it; otherwise, it will be available as a top-level
+ * command.
+ *
+ * @param cmd_ctx The command_context in which to register the command.
+ * @param parent Register this command as a child of this, or NULL to
+ * register a top-level command.
+ * @param rec A command_registration record that contains the desired
+ * command parameters.
  * @returns The new command, if successful; otherwise, NULL.
  */
 struct command* register_command(struct command_context *cmd_ctx,
-   struct command *parent, const char *name,
-   

[Openocd-development] [PATCH 4/8] add register_commands for batch registration

2009-11-20 Thread Zachary T Welch
The register_commands API takes multiple commands in one call, allowing
modules to declare and pass a much simpler (and more explicit) array of
command_registration records.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c |   20 
 src/helper/command.h |   14 ++
 2 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index 3df60b6..29e645b 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -302,6 +302,26 @@ struct command* register_command(struct command_context 
*context,
return c;
 }
 
+int register_commands(struct command_context *cmd_ctx,
+   struct command *parent, unsigned ncmds,
+   const struct command_registration *cmds)
+{
+   unsigned i;
+   for (i = 0; i < ncmds; i++)
+   {
+   struct command *c = register_command(cmd_ctx, parent, cmds + i);
+   if (NULL == c)
+   break;
+   }
+   if (i == ncmds)
+   return ERROR_OK;
+
+   for (unsigned j = 0; j < i; j++)
+   unregister_command(cmd_ctx, parent, cmds[j].name);
+
+   return ERROR_FAIL;
+}
+
 int unregister_all_commands(struct command_context *context,
struct command *parent)
 {
diff --git a/src/helper/command.h b/src/helper/command.h
index 14ad73e..b16361e 100644
--- a/src/helper/command.h
+++ b/src/helper/command.h
@@ -219,6 +219,20 @@ struct command_registration {
  */
 struct command* register_command(struct command_context *cmd_ctx,
struct command *parent, const struct command_registration *rec);
+/**
+ * Register one or more commands in the specified context, as children
+ * of @c parent (or top-level commends, if NULL).
+ *
+ * @param cmd_ctx The command_context in which to register the command.
+ * @param parent Register this command as a child of this, or NULL to
+ * register a top-level command.
+ * @param cmds Pointer to an array of command_registration records that
+ * contains the desired command parameters.
+ * @returns ERROR_OK on success; ERROR_FAIL if any registration fails.
+ */
+int register_commands(struct command_context *cmd_ctx,
+   struct command *parent, unsigned ncmds,
+   const struct command_registration *cmds);
 
 #define COMMAND_REGISTER(_cmd_ctx, _parent, _name, _handler, _mode, _help) \
({ \
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 1/8] add COMMAND_REGISTER macro

2009-11-20 Thread Zachary T Welch
Provides a migration path for the widely used register_command API,
which needs to be updated to provide new functionality.

This macro allows the API to change without having to update all of its
callers at the same time.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.h |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/src/helper/command.h b/src/helper/command.h
index 837b4bd..25c0501 100644
--- a/src/helper/command.h
+++ b/src/helper/command.h
@@ -207,6 +207,10 @@ struct command* register_command(struct command_context 
*cmd_ctx,
command_handler_t handler, enum command_mode mode,
const char *help);
 
+// provide a simple shim, for now; allows parameters to be migrated
+#define COMMAND_REGISTER(_cmd_ctx, _parent, _name, _handler, _mode, _help) \
+   register_command(_cmd_ctx, _parent, _name, _handler, _mode, 
_help)
+
 /**
  * Unregisters command @c name from the given context, @c cmd_ctx.
  * @param cmd_ctx The context of the registered command.
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 0/8] improve command registration

2009-11-20 Thread Zachary T Welch
Hi all,

This series begins to improve the process of command registration.

First, it adds a migration macro (COMMAND_REGISTER), which is used
instead of direct calls to register_command().  That API is converted to
use a structure, and a batch helper added.  With the new API in place,
another patch adds support for separate 'usage' command, then all of the
src/helper source files are updated to use the new batch registration.
Simultaneously, these last patches provide correct help and usage text.

This also provides the foundation for removing all 'register_commands'
callbacks (from the JTAG interface, target, and flash structures).  In
their place, these modules will provide a list of command registration
records that will be passed to register_commands.  This will eliminate
this slew of identical looking functions from the tree once and for all.

Cheers,

Zach
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 8/8] maintain command lists in sorted order

2009-11-20 Thread Zachary T Welch
Use insertion sort to the command link lists.  The only practical effect
of this is to order the output of the new 'help' command.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c |   24 +---
 1 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index 9b65249..3d6023a 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -177,7 +177,8 @@ static int script_command(Jim_Interp *interp, int argc, 
Jim_Obj *const *argv)
 
 /**
  * Find a command by name from a list of commands.
- * @returns The named command if found, or NULL.
+ * @returns Returns the named command if it exists in the list.
+ * Returns NULL otherwise.
  */
 static struct command *command_find(struct command *head, const char *name)
 {
@@ -190,9 +191,10 @@ static struct command *command_find(struct command *head, 
const char *name)
 }
 
 /**
- * Add the command to the end of linked list.
- * @returns Returns false if the named command already exists in the list.
- * Returns true otherwise.
+ * Add the command into the linked list, sorted by name.
+ * @param head Address to head of command list pointer, which may be
+ * updated if @c c gets inserted at the beginning of the list.
+ * @param c The command to add to the list pointed to by @c head.
  */
 static void command_add_child(struct command **head, struct command *c)
 {
@@ -202,9 +204,17 @@ static void command_add_child(struct command **head, 
struct command *c)
*head = c;
return;
}
-   struct command *cc = *head;
-   while (cc->next) cc = cc->next;
-   cc->next = c;
+
+   while ((*head)->next && (strcmp(c->name, (*head)->name) > 0))
+   head = &(*head)->next;
+
+   if (strcmp(c->name, (*head)->name) > 0) {
+   c->next = (*head)->next;
+   (*head)->next = c;
+   } else {
+   c->next = *head;
+   *head = c;
+   }
 }
 
 static struct command **command_list_for_parent(
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 7/8] add add_help_text command handler

2009-11-20 Thread Zachary T Welch
Rewrite means for scripts to register help text for commands.  These
cause the new commands to be stored in the command heirarchy, with
built-in commands; however, they will never be invoked there because
they do not receive a command handler.  The same trick is used for
the Jim commands.

Remove the old helpers that were used to register commands.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c   |   94 +---
 src/helper/startup.tcl |   16 +
 2 files changed, 66 insertions(+), 44 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index 0958147..9b65249 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -172,32 +172,6 @@ static int script_command(Jim_Interp *interp, int argc, 
Jim_Obj *const *argv)
return (retval == ERROR_OK)?JIM_OK:JIM_ERR;
 }
 
-static Jim_Obj *command_name_list(struct command *c)
-{
-   Jim_Obj *cmd_list = c->parent ?
-   command_name_list(c->parent) :
-   Jim_NewListObj(interp, NULL, 0);
-   Jim_ListAppendElement(interp, cmd_list,
-   Jim_NewStringObj(interp, c->name, -1));
-
-   return cmd_list;
-}
-
-static void command_helptext_add(Jim_Obj *cmd_list, const char *help)
-{
-   Jim_Obj *cmd_entry = Jim_NewListObj(interp, NULL, 0);
-   Jim_ListAppendElement(interp, cmd_entry, cmd_list);
-   Jim_ListAppendElement(interp, cmd_entry,
-   Jim_NewStringObj(interp, help ? : "", -1));
-
-   /* 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_ListAppendElement(interp, helptext, cmd_entry);
-}
-
 /* nice short description of source file */
 #define __THIS__FILE__ "command.c"
 
@@ -258,8 +232,6 @@ static struct command *command_new(struct command_context 
*cmd_ctx,
 
command_add_child(command_list_for_parent(cmd_ctx, parent), c);
 
-   command_helptext_add(command_name_list(c), help);
-
return c;
 }
 static void command_free(struct command *c)
@@ -771,6 +743,65 @@ COMMAND_HANDLER(handle_help_command)
return CALL_COMMAND_HANDLER(command_help_show, c, 0);
 }
 
+
+int help_add_command(struct command_context *cmd_ctx, struct command *parent,
+   const char *cmd_name, const char *help_text)
+{
+   struct command *nc = command_find(parent, cmd_name);
+   if (NULL == nc)
+   {
+   // add a new command with help text
+   nc = register_command(cmd_ctx, parent, cmd_name,
+   NULL, COMMAND_ANY, help_text);
+   if (NULL == nc)
+   {
+   LOG_INFO("failed to add '%s' help text", cmd_name);
+   return ERROR_FAIL;
+   }
+   LOG_INFO("added '%s' help text", cmd_name);
+   }
+   else
+   {
+   bool replaced = false;
+   if (nc->help)
+   {
+   free((void *)nc->help);
+   replaced = true;
+   }
+   nc->help = strdup(help_text);
+
+   if (replaced)
+   LOG_WARNING("replaced existing '%s' help", cmd_name);
+   else
+   LOG_INFO("added '%s' help text", cmd_name);
+   }
+   return ERROR_OK;
+}
+
+COMMAND_HANDLER(handle_help_add_command)
+{
+   if (CMD_ARGC < 2)
+   {
+   LOG_ERROR("%s: insufficient arguments", CMD_NAME);
+   return ERROR_INVALID_ARGUMENTS;
+   }
+
+   // save help text and remove it from argument list
+   const char *help_text = CMD_ARGV[--CMD_ARGC];
+   // likewise for the leaf command name
+   const char *cmd_name = CMD_ARGV[--CMD_ARGC];
+
+   struct command *c = NULL;
+   if (CMD_ARGC > 0)
+   {
+   c = CMD_CTX->commands;
+   int retval = CALL_COMMAND_HANDLER(command_help_find, c, &c);
+   if (ERROR_OK != retval)
+   return retval;
+   }
+   return help_add_command(CMD_CTX, c, cmd_name, help_text);
+}
+
 /* sleep command sleeps for  miliseconds
  * this is useful in target startup scripts
  */
@@ -866,6 +897,11 @@ struct command_context* command_init(const char 
*startup_tcl)
interp->cb_fflush = openocd_jim_fflush;
interp->cb_fgets = openocd_jim_fgets;
 
+   register_command(context, NULL, "add_help_text",
+   handle_help_add_command, COMMAND_ANY,
+   " [...] ] - "
+   "add new command help text");
+
 #if !BUILD_ECOS

[Openocd-development] [PATCH 4/8] factor help script command into parts

2009-11-20 Thread Zachary T Welch
Creates a helper function, cmd_help, which displays the help string
for a single command.  Presently, it is called from the loop in help.

The routine has been extended to allow indentation of command groups,
so an improved help command can improve the display of information.

Signed-off-by: Zachary T Welch 
---
 src/helper/startup.tcl |   62 ++-
 1 files changed, 34 insertions(+), 28 deletions(-)

diff --git a/src/helper/startup.tcl b/src/helper/startup.tcl
index eefb690..30dc184 100644
--- a/src/helper/startup.tcl
+++ b/src/helper/startup.tcl
@@ -25,6 +25,39 @@ proc exit {} {
ocd_throw exit
 }
 
+proc cmd_help {cmdname h indent} {
+   set indent [expr $indent * 2]
+
+   set fmt_str [format "%%%ds%%-%ds %%s" $indent [expr 25 - $indent]]
+   set w [expr 50 - $indent]
+   set n 0
+
+   while 1 {
+   if {$n > [string length $h]} {break}
+
+   set next_a [expr $n + $w]
+   if {[string length $h] > $n + $w} \
+   {
+   set  [string range $h $n [expr $n + $w]]
+   for {set lastpos [expr [string length $] - 1]} \
+   {$lastpos >= 0 && [string compare \
+   [string range $ $lastpos $lastpos] 
" "] != 0} \
+   {set lastpos [expr $lastpos - 1]} \
+   {
+   }
+   #set next_a -1
+   if {$lastpos != -1} {
+   set next_a [expr $lastpos + $n + 1]
+   }
+   }
+
+   puts [format $fmt_str "" $cmdname \
+   [string range $h $n [expr $next_a - 1]] ]
+   set cmdname ""
+   set n [expr $next_a]
+   }
+}
+
 #Print help text for a command. Word wrap
 #help text that is too wide inside column.
 proc help {args} {
@@ -35,34 +68,7 @@ proc help {args} {
[string first $cmd $a] != -1 || \
[string first $cmd [lindex $a 1]] != -1} \
{
-   set w 50
-   set cmdname [lindex $a 0]
-   set h [lindex $a 1]
-   set n 0
-   while 1 {
-   if {$n > [string length $h]} {break}
-
-   set next_a [expr $n + $w]
-   if {[string length $h] > $n + $w} \
-   {
-   set  [string range $h $n [expr $n + 
$w]]
-   for {set lastpos [expr [string length 
$] - 1]} \
-   {$lastpos >= 0 && [string 
compare \
-   [string range $ 
$lastpos $lastpos] " "] != 0} \
-   {set lastpos [expr $lastpos - 
1]} \
-   {
-   }
-   #set next_a -1
-   if {$lastpos != -1} {
-   set next_a [expr $lastpos + $n 
+ 1]
-   }
-   }
-
-   puts [format "%-25s %s" $cmdname \
-   [string range $h $n [expr 
$next_a-1]] ]
-   set cmdname ""
-   set n [expr $next_a]
-   }
+   cmd_help [lindex $a 0] [lindex $a 1] 0
}
}
 }
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 6/8] provide command context during cmd_init

2009-11-20 Thread Zachary T Welch
For the startup.tcl code to use built-in commands, the context must be
associated with the interpreter temporarily.  This will be required to
add help text.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index f135bb0..0958147 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -869,12 +869,14 @@ struct command_context* command_init(const char 
*startup_tcl)
 #if !BUILD_ECOSBOARD
Jim_EventLoopOnLoad(interp);
 #endif
+   Jim_SetAssocData(interp, "context", NULL, context);
if (Jim_Eval_Named(interp, startup_tcl, "embedded:startup.tcl",1) == 
JIM_ERR)
{
LOG_ERROR("Failed to run startup.tcl (embedded into OpenOCD)");
Jim_PrintErrorMessage(interp);
exit(-1);
}
+   Jim_DeleteAssocData(interp, "context");
 
register_command(context, NULL, "sleep",
handle_sleep_command, COMMAND_ANY,
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 2/8] change command_find helper interface

2009-11-20 Thread Zachary T Welch
Avoid requiring double pointers where a single would suffice.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c |7 +++
 1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index ba28784..538c07b 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -205,10 +205,9 @@ static void command_helptext_add(Jim_Obj *cmd_list, const 
char *help)
  * Find a command by name from a list of commands.
  * @returns The named command if found, or NULL.
  */
-static struct command *command_find(struct command **head, const char *name)
+static struct command *command_find(struct command *head, const char *name)
 {
-   assert(head);
-   for (struct command *cc = *head; cc; cc = cc->next)
+   for (struct command *cc = head; cc; cc = cc->next)
{
if (strcmp(cc->name, name) == 0)
return cc;
@@ -242,7 +241,7 @@ struct command* register_command(struct command_context 
*context,
return NULL;
 
struct command **head = parent ? &parent->children : &context->commands;
-   struct command *c = command_find(head, name);
+   struct command *c = command_find(*head, name);
if (NULL != c)
return c;
 
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 5/8] improve 'help' command

2009-11-20 Thread Zachary T Welch
Rewrites 'help' command in C, using new 'cmd_help' for display.  Adds the
built-in 'help' COMMAND_HANDLER to provide better output than the
TCL-based script command (e.g. heirarchical listing of commands).

The help string is stored in the command structure, though it conitnues
to be pushed into the Jim environment.  The current idiomatic usage
suggests the addition of a usage field as well, to provide two levels
of detail for users to consume (i.e. terse usage list, or verbose help).

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c   |   56 ++-
 src/helper/command.h   |1 +
 src/helper/startup.tcl |   18 ---
 3 files changed, 55 insertions(+), 20 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index 87a898f..f135bb0 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -250,6 +250,8 @@ static struct command *command_new(struct command_context 
*cmd_ctx,
memset(c, 0, sizeof(struct command));
 
c->name = strdup(name);
+   if (help)
+   c->help = strdup(help);
c->parent = parent;
c->handler = handler;
c->mode = mode;
@@ -273,6 +275,8 @@ static void command_free(struct command *c)
 
if (c->name)
free(c->name);
+   if (c->help)
+   free((void*)c->help);
free(c);
 }
 
@@ -721,6 +725,52 @@ static int jim_capture(Jim_Interp *interp, int argc, 
Jim_Obj *const *argv)
return retcode;
 }
 
+static COMMAND_HELPER(command_help_find, struct command *head,
+   struct command **out)
+{
+   if (0 == CMD_ARGC)
+   return ERROR_INVALID_ARGUMENTS;
+   *out = command_find(head, CMD_ARGV[0]);
+   if (NULL == *out)
+   return ERROR_INVALID_ARGUMENTS;
+   if (--CMD_ARGC == 0)
+   return ERROR_OK;
+   CMD_ARGV++;
+   return CALL_COMMAND_HANDLER(command_help_find, (*out)->children, out);
+}
+
+static COMMAND_HELPER(command_help_show, struct command *c, unsigned n);
+
+static COMMAND_HELPER(command_help_show_list, struct command *head, unsigned n)
+{
+   for (struct command *c = head; NULL != c; c = c->next)
+   CALL_COMMAND_HANDLER(command_help_show, c, n);
+   return ERROR_OK;
+}
+static COMMAND_HELPER(command_help_show, struct command *c, unsigned n)
+{
+   command_run_linef(CMD_CTX, "cmd_help {%s} {%s} %d", command_name(c, ' 
'),
+   c->help ? : "no help available", n);
+
+   if (++n >= 2)
+   return ERROR_OK;
+
+   return CALL_COMMAND_HANDLER(command_help_show_list, c->children, n);
+}
+COMMAND_HANDLER(handle_help_command)
+{
+   struct command *c = CMD_CTX->commands;
+
+   if (0 == CMD_ARGC)
+   return CALL_COMMAND_HANDLER(command_help_show_list, c, 0);
+
+   int retval = CALL_COMMAND_HANDLER(command_help_find, c, &c);
+   if (ERROR_OK != retval)
+   return retval;
+
+   return CALL_COMMAND_HANDLER(command_help_show, c, 0);
+}
+
 /* sleep command sleeps for  miliseconds
  * this is useful in target startup scripts
  */
@@ -831,6 +881,10 @@ struct command_context* command_init(const char 
*startup_tcl)
" [busy] - sleep for n milliseconds. "
"\"busy\" means busy wait");
 
+   register_command(context, NULL, "help",
+   &handle_help_command, COMMAND_ANY,
+   "[ ...] - show built-in command help");
+
return context;
 }
 
@@ -977,5 +1031,3 @@ COMMAND_HELPER(handle_command_parse_bool, bool *out, const 
char *label)
}
return ERROR_OK;
 }
-
-
diff --git a/src/helper/command.h b/src/helper/command.h
index 56bd149..34593f7 100644
--- a/src/helper/command.h
+++ b/src/helper/command.h
@@ -159,6 +159,7 @@ typedef __COMMAND_HANDLER((*command_handler_t));
 struct command
 {
char *name;
+   const char *help;
struct command *parent;
struct command *children;
command_handler_t handler;
diff --git a/src/helper/startup.tcl b/src/helper/startup.tcl
index 30dc184..ddfef1d 100644
--- a/src/helper/startup.tcl
+++ b/src/helper/startup.tcl
@@ -58,24 +58,6 @@ proc cmd_help {cmdname h indent} {
}
 }
 
-#Print help text for a command. Word wrap
-#help text that is too wide inside column.
-proc help {args} {
-   global ocd_helptext
-   set cmd $args
-   foreach a [lsort $ocd_helptext] {
-   if {[string length $cmd] == 0 || \
-   [string first $cmd $a] != -1 || \
-   [string first $cmd [lindex $a 1]] != -1} \
-   {
-   cmd_help [lindex $a 0] [lindex $a 1] 0
-   }
-   }
-}
-
-add_help_text help "Tcl implementation of help co

[Openocd-development] [PATCH 3/8] refactor command registration

2009-11-20 Thread Zachary T Welch
Refactors the command registration to use helpers to simplify the code.
The unregistration routines were made more flexible by allowing them
to operate on a single command, such that one can remove all of a
commands children in one step (perhaps before adding back a 'config'
subcommand that allows getting the others back).  Eliminates a bit
of duplicated code and adds full API documentation for these routines.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c |  150 --
 src/helper/command.h |   51 +++--
 src/openocd.c|2 +-
 3 files changed, 119 insertions(+), 84 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index 538c07b..87a898f 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -233,33 +233,69 @@ static void command_add_child(struct command **head, 
struct command *c)
cc->next = c;
 }
 
-struct command* register_command(struct command_context *context,
-   struct command *parent, char *name, command_handler_t handler,
-   enum command_mode mode, char *help)
+static struct command **command_list_for_parent(
+   struct command_context *cmd_ctx, struct command *parent)
 {
-   if (!context || !name)
-   return NULL;
+   return parent ? &parent->children : &cmd_ctx->commands;
+}
 
-   struct command **head = parent ? &parent->children : &context->commands;
-   struct command *c = command_find(*head, name);
-   if (NULL != c)
-   return c;
+static struct command *command_new(struct command_context *cmd_ctx,
+   struct command *parent, const char *name,
+   command_handler_t handler, enum command_mode mode,
+   const char *help)
+{
+   assert(name);
 
-   c = malloc(sizeof(struct command));
+   struct command *c = malloc(sizeof(struct command));
+   memset(c, 0, sizeof(struct command));
 
c->name = strdup(name);
c->parent = parent;
-   c->children = NULL;
c->handler = handler;
c->mode = mode;
-   c->next = NULL;
 
-   command_add_child(head, c);
+   command_add_child(command_list_for_parent(cmd_ctx, parent), c);
 
command_helptext_add(command_name_list(c), help);
 
-   /* just a placeholder, no handler */
-   if (c->handler == NULL)
+   return c;
+}
+static void command_free(struct command *c)
+{
+   /// @todo if command has a handler, unregister its jim command!
+
+   while (NULL != c->children)
+   {
+   struct command *tmp = c->children;
+   c->children = tmp->next;
+   command_free(tmp);
+   }
+
+   if (c->name)
+   free(c->name);
+   free(c);
+}
+
+struct command* register_command(struct command_context *context,
+   struct command *parent, const char *name,
+   command_handler_t handler, enum command_mode mode,
+   const char *help)
+{
+   if (!context || !name)
+   return NULL;
+
+   struct command **head = command_list_for_parent(context, parent);
+   struct command *c = command_find(*head, name);
+   if (NULL != c)
+   {
+   LOG_ERROR("command '%s' is already registered in '%s' context",
+   name, parent ? parent->name : "");
+   return c;
+   }
+
+   c = command_new(context, parent, name, handler, mode, help);
+   /* if allocation failed or it is a placeholder (no handler), we're done 
*/
+   if (NULL == c || NULL == c->handler)
return c;
 
const char *full_name = command_name(c, '_');
@@ -281,85 +317,43 @@ struct command* register_command(struct command_context 
*context,
return c;
 }
 
-int unregister_all_commands(struct command_context *context)
+int unregister_all_commands(struct command_context *context,
+   struct command *parent)
 {
-   struct command *c, *c2;
-
if (context == NULL)
return ERROR_OK;
 
-   while (NULL != context->commands)
+   struct command **head = command_list_for_parent(context, parent);
+   while (NULL != *head)
{
-   c = context->commands;
-
-   while (NULL != c->children)
-   {
-   c2 = c->children;
-   c->children = c->children->next;
-   free(c2->name);
-   c2->name = NULL;
-   free(c2);
-   c2 = NULL;
-   }
-
-   context->commands = context->commands->next;
-
-   free(c->name);
-   c->name = NULL;
-   free(c);
-   c = NULL;
+   stru

[Openocd-development] [PATCH 1/8] factor script_command argv allocation

2009-11-20 Thread Zachary T Welch
Splits argument allocation out from script command, reusing free() code.

Signed-off-by: Zachary T Welch 
---
 src/helper/command.c |   65 +
 1 files changed, 38 insertions(+), 27 deletions(-)

diff --git a/src/helper/command.c b/src/helper/command.c
index ba689b0..ba28784 100644
--- a/src/helper/command.c
+++ b/src/helper/command.c
@@ -75,15 +75,45 @@ void script_debug(Jim_Interp *interp, const char *name,
}
 }
 
+static void script_command_args_free(const char **words, unsigned nwords)
+{
+   for (unsigned i = 0; i < nwords; i++)
+   free((void *)words[i]);
+   free(words);
+}
+static const char **script_command_args_alloc(
+   unsigned argc, Jim_Obj *const *argv, unsigned *nwords)
+{
+   const char **words = malloc(argc * sizeof(char *));
+   if (NULL == words)
+   return NULL;
+
+   unsigned i;
+   for (i = 0; i < argc; i++)
+   {
+   int len;
+   const char *w = Jim_GetString(argv[i], &len);
+   /* a comment may end the line early */
+   if (*w == '#')
+   break;
+
+   words[i] = strdup(w);
+   if (words[i] == NULL)
+   {
+   script_command_args_free(words, i);
+   return NULL;
+   }
+   }
+   *nwords = i;
+   return words;
+}
+
 static int script_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 {
/* the private data is stashed in the interp structure */
struct command *c;
struct command_context *context;
int retval;
-   int i;
-   int nwords;
-   char **words;
 
/* DANGER be careful what we invoke here, since interp->cmdPrivData 
might
 * get overwritten by running other Jim commands! Treat it as an
@@ -101,27 +131,10 @@ static int script_command(Jim_Interp *interp, int argc, 
Jim_Obj *const *argv)
 
script_debug(interp, c->name, argc, argv);
 
-   words = malloc(argc * sizeof(char *));
-   for (i = 0; i < argc; i++)
-   {
-   int len;
-   const char *w = Jim_GetString(argv[i], &len);
-   if (*w=='#')
-   {
-   /* hit an end of line comment */
-   break;
-   }
-   words[i] = strdup(w);
-   if (words[i] == NULL)
-   {
-   int j;
-   for (j = 0; j < i; j++)
-   free(words[j]);
-   free(words);
-   return JIM_ERR;
-   }
-   }
-   nwords = i;
+   unsigned nwords;
+   const char **words = script_command_args_alloc(argc, argv, &nwords);
+   if (NULL == words)
+   return JIM_ERR;
 
/* grab the command context from the associated data */
context = Jim_GetAssocData(interp, "context");
@@ -148,9 +161,7 @@ static int script_command(Jim_Interp *interp, int argc, 
Jim_Obj *const *argv)
Jim_SetResult(interp, tclOutput);
Jim_DecrRefCount(interp, tclOutput);
 
-   for (i = 0; i < nwords; i++)
-   free(words[i]);
-   free(words);
+   script_command_args_free(words, nwords);
 
int *return_retval = Jim_GetAssocData(interp, "retval");
if (return_retval != NULL)
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 0/8] improve built-in help

2009-11-20 Thread Zachary T Welch
Hi all,

This series rewrites the built-in 'help' and 'add_help_text' routines
to use C command handlers, providing an improved experience for the user.
Commands are listed in a properly indented tree, sorted alphabetically.

The registration routines are rewritten to store the help text in the
command structure, with a helper provided that can be used to register
the Jim commands as placeholders to provide help text.

After doing this work, I think it would be beneficial split the help
text into two fields: usage and description.

Cheers,

Zach
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 1/8] add jtag/usb_common.[ch] files

2009-11-19 Thread Zachary T Welch
Begins to consolidate code used by several USB JTAG interfaces.
This first patch provides the required build system changes and
a common jtag_usb_open routine, which will replace the guts for
probing the busses and devices for possible VID/PID matches.
The following patches convert each driver to use it.

Signed-off-by: Zachary T Welch 
---
 configure.in  |2 +
 src/jtag/Makefile.am  |7 +-
 src/jtag/usb_common.c |   61 +
 src/jtag/usb_common.h |   30 
 4 files changed, 99 insertions(+), 1 deletions(-)
 create mode 100644 src/jtag/usb_common.c
 create mode 100644 src/jtag/usb_common.h

diff --git a/configure.in b/configure.in
index 8ba8951..81e4326 100644
--- a/configure.in
+++ b/configure.in
@@ -996,6 +996,7 @@ if test $build_jlink = yes -o $build_vsllink = yes -o 
$build_usbprog = yes -o \
 then
   AC_CHECK_HEADERS([usb.h],[],
   [AC_MSG_ERROR([usb.h is required to build some OpenOCD driver(s)])])
+  build_usb=yes
 fi
 
 AM_CONDITIONAL(RELEASE, test $build_release = yes)
@@ -1021,6 +1022,7 @@ AM_CONDITIONAL(JLINK, test $build_jlink = yes)
 AM_CONDITIONAL(VSLLINK, test $build_vsllink = yes)
 AM_CONDITIONAL(RLINK, test $build_rlink = yes)
 AM_CONDITIONAL(ARMJTAGEW, test $build_armjtagew = yes)
+AM_CONDITIONAL(USB, test $build_usb = yes)
 AM_CONDITIONAL(IS_CYGWIN, test $is_cygwin = yes)
 AM_CONDITIONAL(IS_MINGW, test $is_mingw = yes)
 AM_CONDITIONAL(IS_WIN32, test $is_win32 = yes)
diff --git a/src/jtag/Makefile.am b/src/jtag/Makefile.am
index 85d98c0..5254a2b 100644
--- a/src/jtag/Makefile.am
+++ b/src/jtag/Makefile.am
@@ -23,6 +23,10 @@ else
 # Standard Driver: common files
 DRIVERFILES += driver.c commands.c
 
+if USB
+DRIVERFILES += usb_common.c
+endif
+
 if BITBANG
 DRIVERFILES += bitbang.c
 endif
@@ -92,7 +96,8 @@ noinst_HEADERS = \
rlink/ep1_cmd.h \
rlink/rlink.h \
rlink/st7.h \
-   minidummy/jtag_minidriver.h
+   minidummy/jtag_minidriver.h \
+   usb_common.h
 
 EXTRA_DIST = startup.tcl
 
diff --git a/src/jtag/usb_common.c b/src/jtag/usb_common.c
new file mode 100644
index 000..463f1af
--- /dev/null
+++ b/src/jtag/usb_common.c
@@ -0,0 +1,61 @@
+/***
+ *   Copyright (C) 2009 by Zachary T Welch   *
+ * *
+ *   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 "usb_common.h"
+
+
+static bool jtag_usb_match(struct usb_device *dev,
+   const uint16_t vids[], const uint16_t pids[])
+{
+   for (unsigned i = 0; vids[i] && pids[i]; i++)
+   {
+   if (dev->descriptor.idVendor == vids[i] &&
+   dev->descriptor.idProduct == pids[i])
+   {
+   return true;
+   }
+   }
+   return false;
+}
+
+int jtag_usb_open(const uint16_t vids[], const uint16_t pids[],
+   struct usb_dev_handle **out)
+{
+   usb_find_busses();
+   usb_find_devices();
+
+   struct usb_bus *busses = usb_get_busses();
+   for (struct usb_bus *bus = busses; bus; bus = bus->next)
+   {
+   for (struct usb_device *dev = bus->devices; dev; dev = 
dev->next)
+   {
+   if (!jtag_usb_match(dev, vids, pids))
+   continue;
+
+   *out = usb_open(dev);
+   if (NULL == *out)
+   return -errno;
+   return 0;
+   }
+   }
+   return -ENODEV;
+}
diff --git a/src/jtag/usb_common.h b/src/jtag/usb_common.h
new file mode 100644
index 000..da395ad
--- 

[Openocd-development] [PATCH 6/8] rlink: use jtag_usb_open helper

2009-11-19 Thread Zachary T Welch
Rewrite rlink_init routine to use jtag_usb_open helper.  Eliminates
some spurious calls to exit().

Wraps a tremendously long line of comment to fit 80 columns too.

Signed-off-by: Zachary T Welch 
---
 src/jtag/rlink/rlink.c |  131 ++--
 1 files changed, 49 insertions(+), 82 deletions(-)

diff --git a/src/jtag/rlink/rlink.c b/src/jtag/rlink/rlink.c
index 2cdc70a..6fb721d 100644
--- a/src/jtag/rlink/rlink.c
+++ b/src/jtag/rlink/rlink.c
@@ -34,9 +34,7 @@
 #include "st7.h"
 #include "ep1_cmd.h"
 #include "dtc_cmd.h"
-
-/* system includes */
-#include 
+#include "usb_common.h"
 
 
 /* This feature is made useless by running the DTC all the time.  When 
automatic, the LED is on whenever the DTC is running.  Otherwise, USB messages 
are sent to turn it on and off. */
@@ -1616,103 +1614,72 @@ int rlink_register_commands(struct command_context 
*cmd_ctx)
 static
 int rlink_init(void)
 {
-   struct usb_bus *busses;
-   struct usb_bus *bus;
int i, j, retries;
-   int found = 0;
-   int success = 0;
uint8_t reply_buffer[USB_EP1IN_SIZE];
 
usb_init();
-   usb_find_busses();
-   usb_find_devices();
-
-   busses = usb_get_busses();
+   const uint16_t vids[] = { USB_IDVENDOR, 0 };
+   const uint16_t pids[] = { USB_IDPRODUCT, 0 };
+   if (jtag_usb_open(vids, pids, &pHDev) != ERROR_OK)
+   return ERROR_FAIL;
 
-   for (bus = busses; bus; bus = bus->next)
+   struct usb_device *dev = usb_device(pHDev);
+   if (dev->descriptor.bNumConfigurations > 1)
{
-   struct usb_device *dev;
-
-   for (dev = bus->devices; dev; dev = dev->next)
-   {
-   if ((dev->descriptor.idVendor != USB_IDVENDOR) ||
-   (dev->descriptor.idProduct != USB_IDPRODUCT))
-   {
-   continue;
-   }
-   found = 1;
-   LOG_DEBUG("Found device on bus.\n");
-
-   if (dev->descriptor.bNumConfigurations > 1)
-   {
-   LOG_ERROR("Whoops! NumConfigurations is not 1, 
don't know what to do...\n");
-   break;
-   }
-   if (dev->config->bNumInterfaces > 1)
-   {
-   LOG_ERROR("Whoops! NumInterfaces is not 1, 
don't know what to do...\n");
-   break;
-   }
+   LOG_ERROR("Whoops! NumConfigurations is not 1, don't know what 
to do...\n");
+   return ERROR_FAIL;
+   }
+   if (dev->config->bNumInterfaces > 1)
+   {
+   LOG_ERROR("Whoops! NumInterfaces is not 1, don't know what to 
do...\n");
+   return ERROR_FAIL;
+   }
 
-   pHDev = usb_open(dev);
-   if (!pHDev)
-   {
-   LOG_ERROR ("Failed to open device.\n");
-   break;
-   }
-   LOG_DEBUG("Opened device, pHDev = %p\n",pHDev);
+   LOG_DEBUG("Opened device, pHDev = %p\n", pHDev);
 
-   /* usb_set_configuration required under win32 */
-   usb_set_configuration(pHDev, 
dev->config[0].bConfigurationValue);
+   /* usb_set_configuration required under win32 */
+   usb_set_configuration(pHDev, dev->config[0].bConfigurationValue);
 
-   retries = 3;
-   do
-   {
-   i = usb_claim_interface(pHDev,0);
-   if (i)
-   {
-   LOG_ERROR("usb_claim_interface: %s", 
usb_strerror());
+   retries = 3;
+   do
+   {
+   i = usb_claim_interface(pHDev,0);
+   if (i)
+   {
+   LOG_ERROR("usb_claim_interface: %s", usb_strerror());
 #ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
-   j = usb_detach_kernel_driver_np(pHDev, 
0);
-   if (j)
-   LOG_ERROR("detach kernel 
driver: %s", usb_strerror());
+   j = usb_detach_kernel_driver_np(pHDev, 0);
+   if (j)
+   LOG_ERROR("detach kernel driver: %s", 
usb_strerror());
 #endif
-   }
-   else
-   

[Openocd-development] [PATCH 8/8] jlink: rewrite to use jtag_usb_open

2009-11-19 Thread Zachary T Welch
Rewrite jlink_usb_open to use jtag_usb_open helper.

Signed-off-by: Zachary T Welch 
---
 src/jtag/jlink.c |   76 ++---
 1 files changed, 15 insertions(+), 61 deletions(-)

diff --git a/src/jtag/jlink.c b/src/jtag/jlink.c
index a69f09e..cf3f251 100644
--- a/src/jtag/jlink.c
+++ b/src/jtag/jlink.c
@@ -27,8 +27,7 @@
 
 #include "interface.h"
 #include "commands.h"
-
-#include 
+#include "usb_common.h"
 
 
 #define VID 0x1366
@@ -828,53 +827,17 @@ static int jlink_tap_execute(void)
return ERROR_OK;
 }
 
-static struct usb_device* find_jlink_device(void)
-{
-   struct usb_bus *busses;
-   struct usb_bus *bus;
-   struct usb_device *dev;
-
-   usb_find_busses();
-   usb_find_devices();
-
-   busses = usb_get_busses();
-
-   /* find jlink device in usb bus */
-
-   for (bus = busses; bus; bus = bus->next)
-   {
-   for (dev = bus->devices; dev; dev = dev->next)
-   {
-   if ((dev->descriptor.idVendor == VID) && 
(dev->descriptor.idProduct == PID)) {
-   return dev;
-   }
-   }
-   }
-
-   return NULL;
-}
-
 /*/
 /* JLink USB low-level functions */
 
 static struct jlink* jlink_usb_open()
 {
-   struct usb_device *dev;
-
-   struct jlink *result;
-
-   result = (struct jlink*) malloc(sizeof(struct jlink));
-
usb_init();
 
-   if ((dev = find_jlink_device()) == NULL) {
-   free(result);
-   return NULL;
-   }
-
-   result->usb_handle = usb_open(dev);
-
-   if (NULL == result->usb_handle)
+   const uint16_t vids[] = { VID, 0 };
+   const uint16_t pids[] = { PID, 0 };
+   struct usb_dev_handle *dev;
+   if (jtag_usb_open(vids, pids, &dev) != ERROR_OK)
return NULL;
 
/* BE ***VERY CAREFUL*** ABOUT MAKING CHANGES IN THIS
@@ -890,15 +853,15 @@ static struct jlink* jlink_usb_open()
 
 #if IS_WIN32 == 0
 
-   usb_reset(result->usb_handle);
+   usb_reset(dev);
 
 #if IS_DARWIN == 0
 
int timeout = 5;
-
/* reopen jlink after usb_reset
 * on win32 this may take a second or two to re-enumerate */
-   while ((dev = find_jlink_device()) == NULL)
+   int retval;
+   while ((retval = jtag_usb_open(vids, pids, &dev)) != ERROR_OK)
{
usleep(1000);
timeout--;
@@ -906,27 +869,16 @@ static struct jlink* jlink_usb_open()
break;
}
}
-
-   if (dev == NULL)
-   {
-   free(result);
+   if (ERROR_OK != retval)
return NULL;
-   }
-
-   result->usb_handle = usb_open(dev);
 #endif
 
 #endif
 
-   if (NULL == result->usb_handle)
-   {
-   free(result);
-   return NULL;
-   }
-
/* usb_set_configuration required under win32 */
-   usb_set_configuration(result->usb_handle, 
dev->config[0].bConfigurationValue);
-   usb_claim_interface(result->usb_handle, 0);
+   struct usb_device *udev = usb_device(dev);
+   usb_set_configuration(dev, udev->config[0].bConfigurationValue);
+   usb_claim_interface(dev, 0);
 
 #if 0
/*
@@ -935,7 +887,7 @@ static struct jlink* jlink_usb_open()
 */
usb_set_altinterface(result->usb_handle, 0);
 #endif
-   struct usb_interface *iface = dev->config->interface;
+   struct usb_interface *iface = udev->config->interface;
struct usb_interface_descriptor *desc = iface->altsetting;
for (int i = 0; i < desc->bNumEndpoints; i++)
{
@@ -948,6 +900,8 @@ static struct jlink* jlink_usb_open()
jlink_write_ep = epnum;
}
 
+   struct jlink *result = malloc(sizeof(struct jlink));
+   result->usb_handle = dev;
return result;
 }
 
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 7/8] jlink: remove superfluous indentation

2009-11-19 Thread Zachary T Welch
Rewrite logic to remove indentation in jlink_usb_open, in prep
for further surgery.

Signed-off-by: Zachary T Welch 
---
 src/jtag/jlink.c |  107 --
 1 files changed, 55 insertions(+), 52 deletions(-)

diff --git a/src/jtag/jlink.c b/src/jtag/jlink.c
index dbbddb8..a69f09e 100644
--- a/src/jtag/jlink.c
+++ b/src/jtag/jlink.c
@@ -874,78 +874,81 @@ static struct jlink* jlink_usb_open()
 
result->usb_handle = usb_open(dev);
 
-   if (result->usb_handle)
-   {
+   if (NULL == result->usb_handle)
+   return NULL;
 
-   /* BE ***VERY CAREFUL*** ABOUT MAKING CHANGES IN THIS 
AREA!!!
-* The behavior of libusb is not completely consistent across 
Windows, Linux, and Mac OS X platforms.  The actions taken
-* in the following compiler conditionals may not agree with 
published documentation for libusb, but were found
-* to be necessary through trials and tribulations.  Even 
little tweaks can break one or more platforms, so if you do make changes
-* test them carefully on all platforms before committing them!
-*/
+   /* BE ***VERY CAREFUL*** ABOUT MAKING CHANGES IN THIS
+* AREA!!!  The behavior of libusb is not completely
+* consistent across Windows, Linux, and Mac OS X platforms.
+* The actions taken in the following compiler conditionals may
+* not agree with published documentation for libusb, but were
+* found to be necessary through trials and tribulations.  Even
+* little tweaks can break one or more platforms, so if you do
+* make changes test them carefully on all platforms before
+* committing them!
+*/
 
 #if IS_WIN32 == 0
 
-   usb_reset(result->usb_handle);
+   usb_reset(result->usb_handle);
 
 #if IS_DARWIN == 0
 
-   int timeout = 5;
+   int timeout = 5;
 
-   /* reopen jlink after usb_reset
-* on win32 this may take a second or two to re-enumerate */
-   while ((dev = find_jlink_device()) == NULL)
-   {
-   usleep(1000);
-   timeout--;
-   if (!timeout) {
-   break;
-   }
+   /* reopen jlink after usb_reset
+* on win32 this may take a second or two to re-enumerate */
+   while ((dev = find_jlink_device()) == NULL)
+   {
+   usleep(1000);
+   timeout--;
+   if (!timeout) {
+   break;
}
+   }
 
-   if (dev == NULL)
-   {
-   free(result);
-   return NULL;
-   }
+   if (dev == NULL)
+   {
+   free(result);
+   return NULL;
+   }
 
-   result->usb_handle = usb_open(dev);
+   result->usb_handle = usb_open(dev);
 #endif
 
 #endif
 
-   if (result->usb_handle)
-   {
-   /* usb_set_configuration required under win32 */
-   usb_set_configuration(result->usb_handle, 
dev->config[0].bConfigurationValue);
-   usb_claim_interface(result->usb_handle, 0);
+   if (NULL == result->usb_handle)
+   {
+   free(result);
+   return NULL;
+   }
+
+   /* usb_set_configuration required under win32 */
+   usb_set_configuration(result->usb_handle, 
dev->config[0].bConfigurationValue);
+   usb_claim_interface(result->usb_handle, 0);
 
 #if 0
-   /*
-* This makes problems under Mac OS X. And is not needed
-* under Windows. Hopefully this will not break a linux 
build
-*/
-   usb_set_altinterface(result->usb_handle, 0);
+   /*
+* This makes problems under Mac OS X. And is not needed
+* under Windows. Hopefully this will not break a linux build
+*/
+   usb_set_altinterface(result->usb_handle, 0);
 #endif
-   struct usb_interface *iface = dev->config->interface;
-   struct usb_interface_descriptor *desc = 
iface->altsetting;
-   for (int i = 0; i < desc->bNumEndpoints; i++)
-   {
-   uint8_t epnum = 
desc->endpoint[i].bEndpointAddress;
-   bool is_input = epnum & 0x80;
-   LOG_DEBUG("usb ep %s %02x", is_input ? "in" : 
"out", epnum);
-   if (is_input)
-   jlink_read_ep = epnum;
-   else
- 

[Openocd-development] [PATCH 4/8] vsllink: rewrite to use jtag_usb_open

2009-11-19 Thread Zachary T Welch
Rewrite vsllink_usb_open to use jtag_usb_open helper.

Eliminates spurious calls to exit().

Signed-off-by: Zachary T Welch 
---
 src/jtag/vsllink.c |   84 ++-
 1 files changed, 30 insertions(+), 54 deletions(-)

diff --git a/src/jtag/vsllink.c b/src/jtag/vsllink.c
index 7962249..d28854d 100644
--- a/src/jtag/vsllink.c
+++ b/src/jtag/vsllink.c
@@ -28,9 +28,7 @@
 
 #include "interface.h"
 #include "commands.h"
-
-#include 
-
+#include "usb_common.h"
 
 //#define _VSLLINK_IN_DEBUG_MODE_
 
@@ -1703,64 +1701,42 @@ static int vsllink_tap_execute_dma(void)
 
 static struct vsllink* vsllink_usb_open(void)
 {
-   struct usb_bus *busses;
-   struct usb_bus *bus;
-   struct usb_device *dev;
-   int ret;
-
-   struct vsllink *result;
-
-   result = (struct vsllink*) malloc(sizeof(struct vsllink));
-
usb_init();
-   usb_find_busses();
-   usb_find_devices();
 
-   busses = usb_get_busses();
+   const uint16_t vids[] = { vsllink_usb_vid, 0 };
+   const uint16_t pids[] = { vsllink_usb_pid, 0 };
+   struct usb_dev_handle *dev;
+   if (jtag_usb_open(vids, pids, &dev) != ERROR_OK)
+   return NULL;
 
-   /* find vsllink device in usb bus */
-
-   for (bus = busses; bus; bus = bus->next)
+   /* usb_set_configuration required under win32 */
+   struct usb_device *udev = usb_device(dev);
+   int ret = usb_set_configuration(dev, 
udev->config[0].bConfigurationValue);
+   if (ret != 0)
{
-   for (dev = bus->devices; dev; dev = dev->next)
-   {
-   if ((dev->descriptor.idVendor == vsllink_usb_vid) && 
(dev->descriptor.idProduct == vsllink_usb_pid))
-   {
-   result->usb_handle = usb_open(dev);
-   if (NULL == result->usb_handle)
-   {
-   LOG_ERROR("failed to open %04X:%04X, 
not enough permissions?", vsllink_usb_vid, vsllink_usb_pid);
-   exit(-1);
-   }
-
-   /* usb_set_configuration required under win32 */
-   ret = usb_set_configuration(result->usb_handle, 
dev->config[0].bConfigurationValue);
-   if (ret != 0)
-   {
-   LOG_ERROR("fail to set configuration to 
%d, %d returned, not enough permissions?", dev->config[0].bConfigurationValue, 
ret);
-   exit(-1);
-   }
-   ret = usb_claim_interface(result->usb_handle, 
vsllink_usb_interface);
-   if (ret != 0)
-   {
-   LOG_ERROR("fail to claim interface %d, 
%d returned", vsllink_usb_interface, ret);
-   exit(-1);
-   }
-
+   LOG_ERROR("fail to set configuration to %d (error %d)."
+   "Not enough permissions for the device?",
+   udev->config[0].bConfigurationValue, ret);
+   return NULL;
+   }
+   ret = usb_claim_interface(dev, vsllink_usb_interface);
+   if (ret != 0)
+   {
+   LOG_ERROR("fail to claim interface %d, %d returned",
+   vsllink_usb_interface, ret);
+   return NULL;
+   }
 #if 0
-   /*
-* This makes problems under Mac OS X. And is 
not needed
-* under Windows. Hopefully this will not break 
a linux build
-*/
-   usb_set_altinterface(result->usb_handle, 0);
+   /*
+   * This makes problems under Mac OS X. And is not needed
+   * under Windows. Hopefully this will not break a linux build
+   */
+   usb_set_altinterface(dev, 0);
 #endif
-   return result;
-   }
-   }
-   }
 
-   free(result);
-   return NULL;
+   struct vsllink *result = malloc(sizeof(struct vsllink));
+   result->usb_handle = dev;
+   return result;
 }
 
 static void vsllink_usb_close(struct vsllink *vsllink)
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 5/8] rlink: eliminate spurious indentation

2009-11-19 Thread Zachary T Welch
Rework rlink_init to use less indentation.  Best viewed with diff -w.

Signed-off-by: Zachary T Welch 
---
 src/jtag/rlink/rlink.c |  109 
 1 files changed, 54 insertions(+), 55 deletions(-)

diff --git a/src/jtag/rlink/rlink.c b/src/jtag/rlink/rlink.c
index c88067c..2cdc70a 100644
--- a/src/jtag/rlink/rlink.c
+++ b/src/jtag/rlink/rlink.c
@@ -1635,66 +1635,65 @@ int rlink_init(void)
 
for (dev = bus->devices; dev; dev = dev->next)
{
-   if ((dev->descriptor.idVendor == USB_IDVENDOR) && 
(dev->descriptor.idProduct == USB_IDPRODUCT))
+   if ((dev->descriptor.idVendor != USB_IDVENDOR) ||
+   (dev->descriptor.idProduct != USB_IDPRODUCT))
{
-   found = 1;
-   LOG_DEBUG("Found device on bus.\n");
+   continue;
+   }
+   found = 1;
+   LOG_DEBUG("Found device on bus.\n");
 
-   do
-   {
-   if (dev->descriptor.bNumConfigurations 
> 1)
-   {
-   LOG_ERROR("Whoops! 
NumConfigurations is not 1, don't know what to do...\n");
-   break;
-   }
-   if (dev->config->bNumInterfaces > 1)
-   {
-   LOG_ERROR("Whoops! 
NumInterfaces is not 1, don't know what to do...\n");
-   break;
-   }
+   if (dev->descriptor.bNumConfigurations > 1)
+   {
+   LOG_ERROR("Whoops! NumConfigurations is not 1, 
don't know what to do...\n");
+   break;
+   }
+   if (dev->config->bNumInterfaces > 1)
+   {
+   LOG_ERROR("Whoops! NumInterfaces is not 1, 
don't know what to do...\n");
+   break;
+   }
+
+   pHDev = usb_open(dev);
+   if (!pHDev)
+   {
+   LOG_ERROR ("Failed to open device.\n");
+   break;
+   }
+   LOG_DEBUG("Opened device, pHDev = %p\n",pHDev);
+
+   /* usb_set_configuration required under win32 */
+   usb_set_configuration(pHDev, 
dev->config[0].bConfigurationValue);
 
-   pHDev = usb_open(dev);
-   if (!pHDev)
-   LOG_ERROR ("Failed to open 
device.\n");
-   else
-   {
-   LOG_DEBUG("Opened device, pHDev 
= %p\n",pHDev);
-
-   /* usb_set_configuration 
required under win32 */
-   usb_set_configuration(pHDev, 
dev->config[0].bConfigurationValue);
-
-   retries = 3;
-   do
-   {
-   i = 
usb_claim_interface(pHDev,0);
-   if (i)
-   {
-   
LOG_ERROR("usb_claim_interface: %s", usb_strerror());
+   retries = 3;
+   do
+   {
+   i = usb_claim_interface(pHDev,0);
+   if (i)
+   {
+   LOG_ERROR("usb_claim_interface: %s", 
usb_strerror());
 #ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
-   j = 
usb_detach_kernel_driver_np(pHDev, 0);
-   if (j)
-   
LOG_ERROR("detach kernel driver: %s", usb_strerror());
+ 

[Openocd-development] [PATCH 3/8] usbprog: use jtag_usb_open

2009-11-19 Thread Zachary T Welch
Rewrite usbprob_jtag_open to use jtag_usb_open helper.

Signed-off-by: Zachary T Welch 
---
 src/jtag/usbprog.c |   43 +--
 1 files changed, 13 insertions(+), 30 deletions(-)

diff --git a/src/jtag/usbprog.c b/src/jtag/usbprog.c
index 10dfe06..d6b45d1 100644
--- a/src/jtag/usbprog.c
+++ b/src/jtag/usbprog.c
@@ -36,8 +36,7 @@
 
 #include "interface.h"
 #include "commands.h"
-
-#include 
+#include "usb_common.h"
 
 
 #define VID 0x1781
@@ -404,39 +403,23 @@ struct usb_bus *busses;
 
 struct usbprog_jtag* usbprog_jtag_open(void)
 {
-   struct usb_bus *bus;
-   struct usb_device *dev;
-
-   struct usbprog_jtag *tmp;
-
-   tmp = (struct usbprog_jtag*)malloc(sizeof(struct usbprog_jtag));
-
usb_set_debug(10);
usb_init();
-   usb_find_busses();
-   usb_find_devices();
 
-   busses = usb_get_busses();
+   const uint16_t vids[] = { VID, 0 };
+   const uint16_t pids[] = { PID, 0 };
+   struct usb_dev_handle *dev;
+   if (jtag_usb_open(vids, pids, &dev) != ERROR_OK)
+   return NULL;
 
-   /* find usbprog_jtag device in usb bus */
+   struct usbprog_jtag *tmp = malloc(sizeof(struct usbprog_jtag));
+   tmp->usb_handle = dev;
 
-   for (bus = busses; bus; bus = bus->next)
-   {
-   for (dev = bus->devices; dev; dev = dev->next)
-   {
-   /* condition for sucessfully hit (too bad, I only check 
the vendor id)*/
-   if (dev->descriptor.idVendor == VID && 
dev->descriptor.idProduct == PID)
-   {
-   tmp->usb_handle = usb_open(dev);
-   usb_set_configuration(tmp->usb_handle, 1);
-   usb_claim_interface(tmp->usb_handle, 0);
-   usb_set_altinterface(tmp->usb_handle, 0);
-   return tmp;
-   }
-   }
-   }
-   free(tmp);
-   return 0;
+   usb_set_configuration(dev, 1);
+   usb_claim_interface(dev, 0);
+   usb_set_altinterface(dev, 0);
+
+   return tmp;
 }
 
 #if 0
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] [PATCH 2/8] arm-jtag-ew: use jtag_usb_open

2009-11-19 Thread Zachary T Welch
Rewrite armjtagwe_usb_open to use jtag_usb_open.

Signed-off-by: Zachary T Welch 
---
 src/jtag/arm-jtag-ew.c |   53 +++
 1 files changed, 17 insertions(+), 36 deletions(-)

diff --git a/src/jtag/arm-jtag-ew.c b/src/jtag/arm-jtag-ew.c
index 18b353a..68fcb34 100644
--- a/src/jtag/arm-jtag-ew.c
+++ b/src/jtag/arm-jtag-ew.c
@@ -25,6 +25,7 @@
 #include "interface.h"
 #include "commands.h"
 #include 
+#include "usb_common.h"
 
 
 #define USB_VID0x15ba
@@ -724,50 +725,30 @@ static int armjtagew_tap_execute(void)
 
 static struct armjtagew* armjtagew_usb_open()
 {
-   struct usb_bus *busses;
-   struct usb_bus *bus;
-   struct usb_device *dev;
-
-   struct armjtagew *result;
-
-   result = (struct armjtagew*) malloc(sizeof(struct armjtagew));
-
usb_init();
-   usb_find_busses();
-   usb_find_devices();
-
-   busses = usb_get_busses();
 
-   /* find armjtagew device in usb bus */
+   const uint16_t vids[] = { USB_VID, 0 };
+   const uint16_t pids[] = { USB_PID, 0 };
+   struct usb_dev_handle *dev;
+   if (jtag_usb_open(vids, pids, &dev) != ERROR_OK)
+   return NULL;
 
-   for (bus = busses; bus; bus = bus->next)
-   {
-   for (dev = bus->devices; dev; dev = dev->next)
-   {
-   if ((dev->descriptor.idVendor == USB_VID) && 
(dev->descriptor.idProduct == USB_PID))
-   {
-   result->usb_handle = usb_open(dev);
+   struct armjtagew *result = malloc(sizeof(struct armjtagew));
+   result->usb_handle = dev;
 
 #if 0
-   /* usb_set_configuration required under win32 */
-   usb_set_configuration(result->usb_handle, 
dev->config[0].bConfigurationValue);
+   /* usb_set_configuration required under win32 */
+   usb_set_configuration(dev, dev->config[0].bConfigurationValue);
 #endif
-   usb_claim_interface(result->usb_handle, 0);
-
+   usb_claim_interface(dev, 0);
 #if 0
-   /*
-* This makes problems under Mac OS X. And is 
not needed
-* under Windows. Hopefully this will not break 
a linux build
-*/
-   usb_set_altinterface(result->usb_handle, 0);
+   /*
+* This makes problems under Mac OS X. And is not needed
+* under Windows. Hopefully this will not break a linux build
+*/
+   usb_set_altinterface(dev, 0);
 #endif
-   return result;
-   }
-   }
-   }
-
-   free(result);
-   return NULL;
+   return result;
 }
 
 static void armjtagew_usb_close(struct armjtagew *armjtagew)
-- 
1.6.4.4

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


  1   2   3   >