[Openocd-development] [PATCH] main: invoke jtag_interface_quit() explicitly
There is no particular reason to invoke jtag_interface_quit() on the atexit() handler, it just makes the code more obtuse and stops other legitimate usage of atexit(). Signed-off-by: Øyvind Harboe oyvind.har...@zylin.com --- src/openocd.c |7 +-- 1 files changed, 1 insertions(+), 6 deletions(-) diff --git a/src/openocd.c b/src/openocd.c index 01e9e79..6ec97f5 100644 --- a/src/openocd.c +++ b/src/openocd.c @@ -62,10 +62,6 @@ COMMAND_HANDLER(handle_version_command) return ERROR_OK; } -static void exit_handler(void) -{ - jtag_interface_quit(); -} static int log_target_callback_event_handler(struct target *target, enum target_event event, void *priv) { @@ -107,8 +103,6 @@ COMMAND_HANDLER(handle_init_command) initialized = 1; - atexit(exit_handler); - command_context_mode(CMD_CTX, COMMAND_EXEC); if (target_init(CMD_CTX) != ERROR_OK) @@ -288,6 +282,7 @@ int openocd_main(int argc, char *argv[]) /* free commandline interface */ command_done(cmd_ctx); + jtag_interface_quit(); return EXIT_SUCCESS; } -- 1.6.3.3 ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [PATCH] Revert improve alloc_vprintf
Whether or not vsnprintf() allows NULL as pointer to destination string to calculate length depends on the implementation. Revert more efficient, but non-portable implementation. This reverts commit 338a674faa96ae321560efa3f1b1e8122d61aac4. --- src/helper/log.c | 43 +++ 1 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/helper/log.c b/src/helper/log.c index 3067ecc..f1aa6d7 100644 --- a/src/helper/log.c +++ b/src/helper/log.c @@ -417,26 +417,37 @@ int log_remove_callback(log_callback_fn fn, void *priv) /* return allocated string w/printf() result */ char *alloc_vprintf(const char *fmt, va_list ap) { - va_list ap_copy; - int len; - char *string; + /* no buffer at the beginning, force realloc to do the job */ + char *string = NULL; - /* determine the length of the buffer needed */ - va_copy(ap_copy, ap); - len = vsnprintf(NULL, 0, fmt, ap_copy); - va_end(ap_copy); + /* start with buffer size suitable for typical messages */ + int size = 128; - /* allocate and make room for terminating zero. */ - /* FIXME: The old version always allocated at least one byte extra and -* other code depend on that. They should be probably be fixed, but for -* now reserve the extra byte. */ - string = malloc(len + 2); - if (string == NULL) - return NULL; + for (;;) + { + char *t = string; + va_list ap_copy; + int ret; + string = realloc(string, size); + if (string == NULL) + { + if (t != NULL) + free(t); + return NULL; + } - /* do the real work */ - vsnprintf(string, len + 1, fmt, ap); + va_copy(ap_copy, ap); + + ret = vsnprintf(string, size, fmt, ap_copy); + /* NB! The result of the vsnprintf() might be an *EMPTY* string! */ + if ((ret = 0) ((ret + 1) size)) + break; + + /* there was just enough or not enough space, allocate more in the next round */ + size *= 2; /* double the buffer size */ + } + /* the returned buffer is by principle guaranteed to be at least one character longer */ return string; } -- 1.6.3.3 ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] startup.tcl should be shipped as plaintext
The error messages in embedded:startup.tcl refer to line numbers. It would be good to distribute startup.tcl for reference, even if it is not required. -- Øyvind Harboe US toll free 1-866-980-3434 / International +47 51 63 25 00 http://www.zylin.com/zy1000.html ARM7 ARM9 ARM11 XScale Cortex JTAG debugger and flash programmer ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] arm11 srst behavior
imx31pdk.cfg test results... I believe the problem with iMX31 is that it misbehaves after receiving a TAP reset... Without patch: reset halt JTAG tap: imx31.etb tap/device found: 0x2b900f0f (mfg: 0x787, part: 0xb900, ver: 0x2) JTAG tap: imx31.cpu tap/device found: 0x07b3601d (mfg: 0x00e, part: 0x7b36, ver: 0x0) TAP imx31.whatchacallit does not have IDCODE JTAG tap: imx31.smda tap/device found: 0x2190101d (mfg: 0x00e, part: 0x1901, ver: 0x2) found ARM1136 Debug entry: JTAG HALT target state: halted target halted in ARM state due to debug-request, current mode: Supervisor cpsr: 0x21d3 pc: 0x00405930 With patch: reset halt JTAG tap: imx31.etb tap/device found: 0x2b900f0f (mfg: 0x787, part: 0xb900, ver: 0x2) JTAG tap: imx31.cpu tap/device found: 0x07b3601d (mfg: 0x00e, part: 0x7b36, ver: 0x0) TAP imx31.whatchacallit does not have IDCODE JTAG tap: imx31.smda tap/device found: 0x2190101d (mfg: 0x00e, part: 0x1901, ver: 0x2) found ARM1136 'arm11 target' JTAG communication error SCREG SCAN OUT 0x07 (expected 0x10) imx31.cpu: ran after reset and before halt ... Timeout (1000ms) waiting for instructions to complete Command handler execution failed in procedure 'reset' called at file command.c, line 608 called at file /home/oyvind/workspace/zy1000/build/../openocd/src/helper/command.c, line 332 -- Øyvind Harboe US toll free 1-866-980-3434 / International +47 51 63 25 00 http://www.zylin.com/zy1000.html ARM7 ARM9 ARM11 XScale Cortex JTAG debugger and flash programmer ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PATCH] Revert improve alloc_vprintf
Do not apply. The old implementation was total crap, and your vsnprintf implementation must be too. That's not our problem, and it can be worked around without destroying the improvements for others. Use a single 'char' on the stack. One character should be enough. --Z On Mon, 2009-11-30 at 10:16 +0100, Øyvind Harboe wrote: Whether or not vsnprintf() allows NULL as pointer to destination string to calculate length depends on the implementation. Revert more efficient, but non-portable implementation. This reverts commit 338a674faa96ae321560efa3f1b1e8122d61aac4. --- src/helper/log.c | 43 +++ 1 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/helper/log.c b/src/helper/log.c index 3067ecc..f1aa6d7 100644 --- a/src/helper/log.c +++ b/src/helper/log.c @@ -417,26 +417,37 @@ int log_remove_callback(log_callback_fn fn, void *priv) /* return allocated string w/printf() result */ char *alloc_vprintf(const char *fmt, va_list ap) { - va_list ap_copy; - int len; - char *string; + /* no buffer at the beginning, force realloc to do the job */ + char *string = NULL; - /* determine the length of the buffer needed */ - va_copy(ap_copy, ap); - len = vsnprintf(NULL, 0, fmt, ap_copy); - va_end(ap_copy); + /* start with buffer size suitable for typical messages */ + int size = 128; - /* allocate and make room for terminating zero. */ - /* FIXME: The old version always allocated at least one byte extra and - * other code depend on that. They should be probably be fixed, but for - * now reserve the extra byte. */ - string = malloc(len + 2); - if (string == NULL) - return NULL; + for (;;) + { + char *t = string; + va_list ap_copy; + int ret; + string = realloc(string, size); + if (string == NULL) + { + if (t != NULL) + free(t); + return NULL; + } - /* do the real work */ - vsnprintf(string, len + 1, fmt, ap); + va_copy(ap_copy, ap); + + ret = vsnprintf(string, size, fmt, ap_copy); + /* NB! The result of the vsnprintf() might be an *EMPTY* string! */ + if ((ret = 0) ((ret + 1) size)) + break; + + /* there was just enough or not enough space, allocate more in the next round */ + size *= 2; /* double the buffer size */ + } + /* the returned buffer is by principle guaranteed to be at least one character longer */ return string; } ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] startup.tcl should be shipped as plaintext
On Mon, 2009-11-30 at 10:21 +0100, Øyvind Harboe wrote: The error messages in embedded:startup.tcl refer to line numbers. It would be good to distribute startup.tcl for reference, even if it is not required. If the user can't look in the source code, then they need to report the bug to someone. Why should it be treated differently than other built-in source code that displays line numbers? --Z ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PATCH] Revert improve alloc_vprintf
The proper solution: tell the maintainers of your vsnprintf to improve their implementation! ;) --Z On Mon, 2009-11-30 at 02:20 -0800, Zach Welch wrote: Do not apply. The old implementation was total crap, and your vsnprintf implementation must be too. That's not our problem, and it can be worked around without destroying the improvements for others. Use a single 'char' on the stack. One character should be enough. --Z On Mon, 2009-11-30 at 10:16 +0100, Øyvind Harboe wrote: Whether or not vsnprintf() allows NULL as pointer to destination string to calculate length depends on the implementation. Revert more efficient, but non-portable implementation. This reverts commit 338a674faa96ae321560efa3f1b1e8122d61aac4. --- src/helper/log.c | 43 +++ 1 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/helper/log.c b/src/helper/log.c index 3067ecc..f1aa6d7 100644 --- a/src/helper/log.c +++ b/src/helper/log.c @@ -417,26 +417,37 @@ int log_remove_callback(log_callback_fn fn, void *priv) /* return allocated string w/printf() result */ char *alloc_vprintf(const char *fmt, va_list ap) { - va_list ap_copy; - int len; - char *string; + /* no buffer at the beginning, force realloc to do the job */ + char *string = NULL; - /* determine the length of the buffer needed */ - va_copy(ap_copy, ap); - len = vsnprintf(NULL, 0, fmt, ap_copy); - va_end(ap_copy); + /* start with buffer size suitable for typical messages */ + int size = 128; - /* allocate and make room for terminating zero. */ - /* FIXME: The old version always allocated at least one byte extra and -* other code depend on that. They should be probably be fixed, but for -* now reserve the extra byte. */ - string = malloc(len + 2); - if (string == NULL) - return NULL; + for (;;) + { + char *t = string; + va_list ap_copy; + int ret; + string = realloc(string, size); + if (string == NULL) + { + if (t != NULL) + free(t); + return NULL; + } - /* do the real work */ - vsnprintf(string, len + 1, fmt, ap); + va_copy(ap_copy, ap); + + ret = vsnprintf(string, size, fmt, ap_copy); + /* NB! The result of the vsnprintf() might be an *EMPTY* string! */ + if ((ret = 0) ((ret + 1) size)) + break; + + /* there was just enough or not enough space, allocate more in the next round */ + size *= 2; /* double the buffer size */ + } + /* the returned buffer is by principle guaranteed to be at least one character longer */ return string; } ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development ___ 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
Adds a fully-documented API for dynamically loading libraries and looking up symbols or addresses in them. Signed-off-by: Zachary T Welch z...@superlucidity.net --- 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 dlfcn.h +#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 = program; + + 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 = unknown; + if (NULL == sym-sym_name) + sym-sym_name = unknown; + 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 module to search. + * @param name The name of the symbol to find. + * @returns On success, returns the symbol; otherwise, returns NULL. + *
[Openocd-development] [PATCH 3/4] add -rdynamic to CFLAGS
The -rdynamic flag provides the information required to produce more meaningful stack traces. Signed-off-by: Zachary T Welch z...@superlucidity.net --- 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 2/4] produce stack traces on segfaults
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 z...@superlucidity.net --- 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 signal.h +#include execinfo.h + + +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); + if (SIG_ERR == old) + return -errno; + return 0; +} + + +struct stack_walk_dump_state { + stack_walker_t walker; + intptr_t data; +}; + +static int stack_walk_dumper(struct
[Openocd-development] [PATCH 4/4] add 'stack' command handler
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 z...@superlucidity.net --- 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 = n [busy], }, { + .name = stack, + .mode = COMMAND_ANY, + .handler = handle_stack_command, + .usage = [depth], + .help = Display the C stack up to depth, 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
Re: [Openocd-development] [PATCH 0/4] add stack backtracing
On Mon, 2009-11-30 at 03:04 -0800, Zachary T Welch wrote: 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. FWIW, I have pushed a revised version of these to my mirror to include proper copyright blurbs at the top of the new files. All of this code was created from scratch since my last series was posted, so you must forgive me for overlooking such details It's been a long day. Cheers, Zach ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PATCH] Revert improve alloc_vprintf
On Mon, Nov 30, 2009 at 11:28 AM, Zach Welch z...@superlucidity.net wrote: The proper solution: tell the maintainers of your vsnprintf to improve their implementation! ;) --Z Actually it turns out eCos does offer a C99 compliant vsnprintf now, it just isn't enabled by default. This fix in eCos is more recent than my initial alloc_printf() implementation. eCos is not Linux. The space that this saves matters on sub megabyte memory systems. eCos does not have C99 support, which is kinda annoying, but not totally unexpected for deeply embedded systems. -- Øyvind Harboe US toll free 1-866-980-3434 / International +47 51 63 25 00 http://www.zylin.com/zy1000.html ARM7 ARM9 ARM11 XScale Cortex JTAG debugger and flash programmer ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [PATCH] arm: dcc_downloads and fast_memory_access are now enabled by default
Those few targets that have problems with fast_memory_access or dcc_downloads must add event handlers to the reset sequence to deal with this. The typical example are CPUs that run at kHz clocks. Signed-off-by: Øyvind Harboe oyvind.har...@zylin.com --- doc/openocd.texi | 15 ++- src/target/arm7_9_common.c |8 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index ea30092..43ea0d8 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -5642,18 +5642,23 @@ including ARM9TDMI, ARM920T, and ARM926EJ-S. @deffn Command {arm7_9 dcc_downloads} (@option{enable}|@option{disable}) @cindex DCC -Control the use of the debug communications channel (DCC) to write larger (128 byte) +Enabled by default. Control the use of the debug communications channel (DCC) to write larger (128 byte) amounts of memory. DCC downloads offer a huge speed increase, but might be -unsafe, especially with targets running at very low speeds. This command was introduced -with OpenOCD rev. 60, and requires a few bytes of working area. +unsafe, especially with targets running at very low speeds. This command requires +a few bytes of working area. This is implemented as an open loop where +OpenOCD pours data into the target. If the target is not able to keep +up, then OpenOCD will print an error message after the transfer +from OpenOCD is complete. @end deffn @anchor{arm7_9 fast_memory_access} @deffn Command {arm7_9 fast_memory_access} (@option{enable}|@option{disable}) -Enable or disable memory writes and reads that don't check completion of +Enabled by default. Enable or disable memory writes and reads that don't check completion of the operation. This provides a huge speed increase, especially with USB JTAG cables (FT2232), but might be unsafe if used with targets running at very low -speeds, like the 32kHz startup clock of an AT91RM9200. +speeds, like the 32kHz startup clock of an AT91RM9200. Targets that +require such low speeds during reset, will have to add reset event +handlers to turn this option off temporarily. @end deffn @subsection ARM720T specific commands diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index b5553cd..5438855 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -2828,8 +2828,8 @@ int arm7_9_init_arch_info(struct target *target, struct arm7_9_common *arm7_9) arm7_9-wp_available_max = 2; - arm7_9-fast_memory_access = false; - arm7_9-dcc_downloads = false; + arm7_9-fast_memory_access = true; + arm7_9-dcc_downloads = true; armv4_5-arch_info = arm7_9; armv4_5-read_core_reg = arm7_9_read_core_reg; @@ -2858,14 +2858,14 @@ static const struct command_registration arm7_9_any_command_handlers[] = { .mode = COMMAND_ANY, .usage = enable|disable, .help = use fast memory accesses instead of slower - but potentially safer accesses, + but potentially safer accesses. Enabled by default., }, { dcc_downloads, .handler = handle_arm7_9_dcc_downloads_command, .mode = COMMAND_ANY, .usage = enable | disable, - .help = use DCC downloads for larger memory writes, + .help = use DCC downloads for larger memory writes. Enabled by default., }, COMMAND_REGISTRATION_DONE }; -- 1.6.3.3 ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PATCH] arm: dcc_downloads and fast_memory_access are now enabled by default
On Monday 30 November 2009, Øyvind Harboe wrote: doc/openocd.texi | 15 ++- You should also update the chapter on config files to include a @quotation Warning ... @quotation that these (may?) need to be disabled during slow clock operations, like early boot with a 32 KHz clock. That's what I most dislike about this patch ... I can't easily see how to ensure that everything is safe-by-default, or even how to clearly identify whether an OpenOCD user would need to worry. - Dave ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PATCH] Revert improve alloc_vprintf
On Monday 30 November 2009, Øyvind Harboe wrote: eCos does not have C99 support, which is kinda annoying, but not totally unexpected for deeply embedded systems. Could you elaborate on what's missing? I'm guessing some aspects of the runtime support. Clearly not all the language parsing aspects, which GCC handles regardless of what the target environment will be... ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] startup.tcl should be shipped as plaintext
On Monday 30 November 2009, Øyvind Harboe wrote: The error messages in embedded:startup.tcl refer to line numbers. It would be good to distribute startup.tcl for reference, even if it is not required. And install it where? And then how to cope with complaints of the I changed this, and it had no effect! variety? I'd rather not install it anywhere other than in the source tree. It might make sense to have a command to display the contents, though ... ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] Flashing DM355 bootloader
Hello All: I'm playing with a DM355 based board, and I'm trying to flash the bootloader into its NAND flash. NAND flash is a 256MB with 2048 blocks, each block 64 pages and each page 2048+64bytes. Those chips provide an internal ROM bootloader which, among other things, should start the next stage bootloader, in this case stored into flash. I've known from the Texas Instruments documentation that the ROM bootloader embedded into chip doesn't work the way NAND manufacturers suggest. So instead of reading the OOB information from the end of the page, that information is interleaved by each 512bytes. I think this is the reason why hwecc4_infix layout for davinci nand flash driver was developed. But there's also another parameter that can be used for writing to nand: oob_softecc (and oob_softecc_kw) My question is which one of those should be used to flash the first bootloader on that cards? · Use hwecc4_infix driver mode for davinci · Use oob_softecc flag when writing to nand · Use oob_softecc_kw flag when writing to nand · A combination of any of them Thanks and regards, -- Raúl Sánchez Siles Departamento de Montaje INFOGLOBAL, S. A. * C/ Virgilio, 2. Ciudad de la Imagen. 28223 Pozuelo de Alarcón (Madrid), España * T: +34 91 506 40 00 * F: +34 91 506 40 01 ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] Flashing DM355 bootloader
On Monday 30 November 2009, Raúl Sánchez Siles wrote: My question is which one of those should be used to flash the first bootloader on that cards? · Use hwecc4_infix driver mode for davinci · Use oob_softecc flag when writing to nand · Use oob_softecc_kw flag when writing to nand · A combination of any of them The hwecc4_infix is -- as you deduced -- intended to support the ROM boot loader (RBL) as it loads the second stage loader into the on-chip SRAM. Once that code is in SRAM, it'll set up the PLLs, DRAM, etc ... and then read the main bootloader (e.g. U-Boot) into DRAM. The second stage bootloader I've seen from TI expects to use that same hwecc4_infix for that code too. Which is rude, since it means you won't for example be able to use U-Boot to replace itself. Don't use the oob_softecc with DaVinci unless you're not ever going to use the hardware ECC; the ECC is different. Don't use the oob_softecc_kw with anything except the specific Marvell Kirkwood chips which need it. - Dave ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PATCH] arm: dcc_downloads and fast_memory_access are now enabled by default
I think David has explained why this is not a good idea for a default. It is not always safe and presents an option that would need to be disabled when bringing up new boards. Bring-up is hard enough without having to fight the tools from trying to be smarter than they are. On Mon, 2009-11-30 at 16:06 +0100, Øyvind Harboe wrote: Those few targets that have problems with fast_memory_access or dcc_downloads must add event handlers to the reset sequence to deal with this. The typical example are CPUs that run at kHz clocks. Signed-off-by: Øyvind Harboe oyvind.har...@zylin.com --- doc/openocd.texi | 15 ++- src/target/arm7_9_common.c |8 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index ea30092..43ea0d8 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -5642,18 +5642,23 @@ including ARM9TDMI, ARM920T, and ARM926EJ-S. @deffn Command {arm7_9 dcc_downloads} (@option{enable}|@option{disable}) @cindex DCC -Control the use of the debug communications channel (DCC) to write larger (128 byte) +Enabled by default. Control the use of the debug communications channel (DCC) to write larger (128 byte) amounts of memory. DCC downloads offer a huge speed increase, but might be -unsafe, especially with targets running at very low speeds. This command was introduced -with OpenOCD rev. 60, and requires a few bytes of working area. +unsafe, especially with targets running at very low speeds. This command requires +a few bytes of working area. This is implemented as an open loop where +OpenOCD pours data into the target. If the target is not able to keep +up, then OpenOCD will print an error message after the transfer +from OpenOCD is complete. @end deffn @anchor{arm7_9 fast_memory_access} @deffn Command {arm7_9 fast_memory_access} (@option{enable}|@option{disable}) -Enable or disable memory writes and reads that don't check completion of +Enabled by default. Enable or disable memory writes and reads that don't check completion of the operation. This provides a huge speed increase, especially with USB JTAG cables (FT2232), but might be unsafe if used with targets running at very low -speeds, like the 32kHz startup clock of an AT91RM9200. +speeds, like the 32kHz startup clock of an AT91RM9200. Targets that +require such low speeds during reset, will have to add reset event +handlers to turn this option off temporarily. @end deffn @subsection ARM720T specific commands diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index b5553cd..5438855 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -2828,8 +2828,8 @@ int arm7_9_init_arch_info(struct target *target, struct arm7_9_common *arm7_9) arm7_9-wp_available_max = 2; - arm7_9-fast_memory_access = false; - arm7_9-dcc_downloads = false; + arm7_9-fast_memory_access = true; + arm7_9-dcc_downloads = true; armv4_5-arch_info = arm7_9; armv4_5-read_core_reg = arm7_9_read_core_reg; @@ -2858,14 +2858,14 @@ static const struct command_registration arm7_9_any_command_handlers[] = { .mode = COMMAND_ANY, .usage = enable|disable, .help = use fast memory accesses instead of slower - but potentially safer accesses, + but potentially safer accesses. Enabled by default., }, { dcc_downloads, .handler = handle_arm7_9_dcc_downloads_command, .mode = COMMAND_ANY, .usage = enable | disable, - .help = use DCC downloads for larger memory writes, + .help = use DCC downloads for larger memory writes. Enabled by default., }, COMMAND_REGISTRATION_DONE }; ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] startup.tcl should be shipped as plaintext
On Mon, Nov 30, 2009 at 11:23 AM, Zach Welch z...@superlucidity.net wrote: On Mon, 2009-11-30 at 10:21 +0100, Øyvind Harboe wrote: The error messages in embedded:startup.tcl refer to line numbers. It would be good to distribute startup.tcl for reference, even if it is not required. If the user can't look in the source code, then they need to report the bug to someone. Why should it be treated differently than other built-in source code that displays line numbers? I had some false positives for trouble in this script today, and when I think back I never previously had any errors in this script, except during development where the complete startup.tcl *is* available in the build folder. I'm leaning towards just leaving it the way it is. -- Øyvind Harboe US toll free 1-866-980-3434 / International +47 51 63 25 00 http://www.zylin.com/zy1000.html ARM7 ARM9 ARM11 XScale Cortex JTAG debugger and flash programmer ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PATCH] Revert improve alloc_vprintf
On Mon, Nov 30, 2009 at 6:04 PM, David Brownell davi...@pacbell.net wrote: On Monday 30 November 2009, Ųyvind Harboe wrote: eCos does not have C99 support, which is kinda annoying, but not totally unexpected for deeply embedded systems. Could you elaborate on what's missing? I'm guessing some aspects of the runtime support. Clearly not all the language parsing aspects, which GCC handles regardless of what the target environment will be... eCos is just a bit backwards and missing defines / types for C99. I don't really know in any detail what C99 defines in terms of types, #defines and runtime fn's, I just find that it's missing in eCos oftentimes. Usually tiny quirks that can be worked around. -- Øyvind Harboe US toll free 1-866-980-3434 / International +47 51 63 25 00 http://www.zylin.com/zy1000.html ARM7 ARM9 ARM11 XScale Cortex JTAG debugger and flash programmer ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PATCH] arm: dcc_downloads and fast_memory_access are now enabled by default
How about a different attack on this problem: add a defualt post reset handler that checks that all the good options are enabled and prints out a warning otherwise. This could serve as a todo list for things missing from a well formed reset init script. If DCC fast_memory_access is not enabled for an arm target that works flawlessly with those options and the user just thinks that OpenOCD is slow, then something is very wrong. Attacking e.g. JTAG protocol performance when we really just have a usability problem is barking up the wrong tree. -- Øyvind Harboe US toll free 1-866-980-3434 / International +47 51 63 25 00 http://www.zylin.com/zy1000.html ARM7 ARM9 ARM11 XScale Cortex JTAG debugger and flash programmer ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] FT4232H support
Hello, I've built a JTAG adapter (Very similar to oocdlink-h) using the FT4232H instead of the FT2232H. Due to the lack of ACBUS on the 4232, I've routed the reset lines to the same pins on BDBUS. CDBUS and DDBUS both go to serial ports. What would be the best way to support that? Should I manually open the 2nd port on jtag_init in bit-bang mode and use it for reset events, or is there a better way to do that? Thanks, - Alex ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [PATCH] Supply 11-bit BYPASS instruction for PXA3xx
Hi, patch is attached, please consider applying. The pxa3xx uses different BYPASS instruction (0x7ff) than pxa2xx and ixp4xx, which use 0x7f. Signed-off-by: Marek Vasut marek.va...@gmail.com From 9c99c68059b213db828bcba73b512a980dc782d4 Mon Sep 17 00:00:00 2001 From: Marek Vasut marek.va...@gmail.com Date: Tue, 1 Dec 2009 01:15:21 +0100 Subject: [PATCH] Supply 11-bit BYPASS instruction for PXA3xx --- src/target/xscale.c |6 +- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/src/target/xscale.c b/src/target/xscale.c index fdc269a..636e208 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -1500,7 +1500,11 @@ static int xscale_assert_reset(struct target *target) xscale_write_dcsr(target, 1, 0); /* select BYPASS, because having DCSR selected caused problems on the PXA27x */ - xscale_jtag_set_instr(target-tap, 0x7f); + if (xscale-xscale_variant == XSCALE_IXP4XX_PXA2XX) + xscale_jtag_set_instr(target-tap, 0x7f); + else /* pxa3xx has 11-bit bypass instruction */ + xscale_jtag_set_instr(target-tap, 0x7ff); + jtag_execute_queue(); /* assert reset */ -- 1.6.5 ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PATCH] Supply 11-bit BYPASS instruction for PXA3xx
Dne Út 1. prosince 2009 01:17:57 Marek Vasut napsal(a): Hi, patch is attached, please consider applying. The pxa3xx uses different BYPASS instruction (0x7ff) than pxa2xx and ixp4xx, which use 0x7f. Signed-off-by: Marek Vasut marek.va...@gmail.com Argh, the following patch doesn't have a stupid formating issue. From cb7d451c8874c35f328b230ecaefd0454b40efcf Mon Sep 17 00:00:00 2001 From: Marek Vasut marek.va...@gmail.com Date: Tue, 1 Dec 2009 01:15:21 +0100 Subject: [PATCH] Supply 11-bit BYPASS instruction for PXA3xx --- src/target/xscale.c |6 +- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/src/target/xscale.c b/src/target/xscale.c index fdc269a..35039fb 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -1500,7 +1500,11 @@ static int xscale_assert_reset(struct target *target) xscale_write_dcsr(target, 1, 0); /* select BYPASS, because having DCSR selected caused problems on the PXA27x */ - xscale_jtag_set_instr(target-tap, 0x7f); + if (xscale-xscale_variant == XSCALE_IXP4XX_PXA2XX) + xscale_jtag_set_instr(target-tap, 0x7f); + else /* pxa3xx has 11-bit bypass instruction */ + xscale_jtag_set_instr(target-tap, 0x7ff); + jtag_execute_queue(); /* assert reset */ -- 1.6.5 ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PATCH 0/3] deferred 'init' and leaner 'help'
On Sun, 2009-11-29 at 14:33 -0800, Zachary T Welch wrote: 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. Pushed. You can now run 'openocd -c noinit' to start in configuration mode. It should now be possible to set up everything interactively over a telnet session and run init yourself. :) Unfortunately, there are still bugs with this mode of operation. Running 'init' immediately causes a failure, because no interface is defined; however, the command mode has changed and you can no longer define one. I will fix this shortcoming soon enough. --Z ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PUSHED 0/4] minor cleaning and audit
On Sun, 2009-11-29 at 19:00 -0800, Zachary T Welch wrote: Hi all, This series includes only minor changes. Applies on top of the last series to allow deferred 'init'. Share and Enjoy, --Z ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PUSHED 0/5] remove interp global variable
On Sun, 2009-11-29 at 19:03 -0800, Zachary T Welch wrote: Hi all, This series removes the 'interp' global variable from the system, bringing us a step closer to supporting several active command contexts. Share and Enjoy, --Z ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [patch 1/2] XScale: context restore, cleanup/bugfix
This loop over all registers routine shared the same mess as full_context() in terms of dozens of needless number_to_mode() calls. Fix that, and comments, with related cleanup. The misnamed xscale_restore_context() had a related bug. It was restoring the *WRONG REGISTERS* ... always from whatever the current mode was, instead of using the copy from whichever register bank it was trying to restore. (But it marked the intended register as having been restored...) Fixed that. --- I'd say that's a bad cut'n'paste that's been around for a long time, hidden partly by the previous obfuscated syntax (featuring absurdly long lines) but also by few folk dirtying registers for other modes. src/target/xscale.c | 44 +--- 1 file changed, 29 insertions(+), 15 deletions(-) --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -1768,37 +1768,45 @@ static int xscale_restore_context(struct } /* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS) - * we can't enter User mode on an XScale (unpredictable), - * but User shares registers with SYS - */ +* and check if any banked registers need to be written. Ignore +* USR mode (number 0) in favor of SYS; we can't enter User mode on +* an XScale (unpredictable), but they share all registers. +*/ for (i = 1; i 7; i++) { int dirty = 0; + enum armv4_5_mode mode = armv4_5_number_to_mode(i); - /* check if there are invalid registers in the current mode - */ + if (mode == ARMV4_5_MODE_USR) + continue; + + /* check if there are dirty registers in this mode */ for (j = 8; j = 14; j++) { - if (ARMV4_5_CORE_REG_MODE(armv4_5-core_cache, armv4_5_number_to_mode(i), j).dirty == 1) + if (ARMV4_5_CORE_REG_MODE(armv4_5-core_cache, + mode, j).dirty) dirty = 1; } /* if not USR/SYS, check if the SPSR needs to be written */ - if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS)) + if (mode != ARMV4_5_MODE_SYS) { - if (ARMV4_5_CORE_REG_MODE(armv4_5-core_cache, armv4_5_number_to_mode(i), 16).dirty == 1) + if (ARMV4_5_CORE_REG_MODE(armv4_5-core_cache, + mode, 16).dirty) dirty = 1; } + /* is there anything to flush for this mode? */ if (dirty) { uint32_t tmp_cpsr; + struct reg *r; - /* send banked registers */ + /* command 0x1: send banked registers */ xscale_send_u32(target, 0x1); tmp_cpsr = 0x0; - tmp_cpsr |= armv4_5_number_to_mode(i); + tmp_cpsr |= mode; tmp_cpsr |= 0xc0; /* I/F bits */ /* send CPSR for desired mode */ @@ -1807,14 +1815,20 @@ static int xscale_restore_context(struct /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */ for (j = 8; j = 14; j++) { - xscale_send_u32(target, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5-core_cache, armv4_5-core_mode, j).value, 0, 32)); - ARMV4_5_CORE_REG_MODE(armv4_5-core_cache, armv4_5_number_to_mode(i), j).dirty = 0; + r = ARMV4_5_CORE_REG_MODE(armv4_5-core_cache, + mode, j); + xscale_send_u32(target, + buf_get_u32(r-value, 0, 32)); + r-dirty = false; } - if ((armv4_5_number_to_mode(i) != ARMV4_5_MODE_USR) (armv4_5_number_to_mode(i) != ARMV4_5_MODE_SYS)) + if (mode != ARMV4_5_MODE_SYS) { - xscale_send_u32(target, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5-core_cache, armv4_5-core_mode, 16).value, 0, 32)); - ARMV4_5_CORE_REG_MODE(armv4_5-core_cache, armv4_5_number_to_mode(i), 16).dirty = 0; + r = ARMV4_5_CORE_REG_MODE(armv4_5-core_cache, + mode, 16); + xscale_send_u32(target, + buf_get_u32(r-value, 0, 32)); + r-dirty = false; }
Re: [Openocd-development] [PATCH 2/4] produce stack traces on segfaults
On Monday 30 November 2009, Zachary T Welch wrote: Registers a signal handler to catch SIGSEGV in order to display the stack where the program crashed. Is this for inside OpenOCD? If so, I'd rather just expect folk to run inside GDB. Either they're running natively and should never see SEGV ... or they should be able to fire up GDB to get this data (and likely more). ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PATCH 1/4] add 'module' helper module
On Monday 30 November 2009, Zachary T Welch wrote: Adds a fully-documented API for dynamically loading libraries and looking up symbols or addresses in them. Seems to me I've seen one or two or three or four of these before ... must there be another?? I know that portability of such things to non-UNIXey environments has been painful. I'm used to seeing systems either stick to the libdl stuff, or use some multiplatform beast which tracks all of the platform-specific annoyances. Also, I'm a bit uneasy at the notion of adding this, so I hope this doesn't merge unless it gets a lot better understood. What's the intended change which will have us loading modules? What modules would be loaded? Plus: +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); As noted, not very portable ... + 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; This looks wrong/dangerous. Surely better to just fail? + } + + if (NULL == sym-so_name) + sym-so_name = unknown; + if (NULL == sym-sym_name) + sym-sym_name = unknown; ... and this even more so; those names aren't valid. + return sym; +} + +struct module_symbol *module_symbol_by_name(struct module_instance *module, + const char *name) +{ + void *addr = dlsym(module-dlhandle, name); But dlsym can fail... + return module_symbol_by_addr(addr); +} ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [patch 2/2] XScale: restore_context() cleanup
Clean up two aspects to this routine: bad naming, since it doesn't restore the context, just the banked registers; and excess indentation for the bulk of the code. Also make some of its call sites stash the function's return code; someday they should use it for error checking. --- src/target/xscale.c | 68 ++ 1 file changed, 30 insertions(+), 38 deletions(-) --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -62,7 +62,7 @@ static int xscale_resume(struct target *, int current, uint32_t address, int handle_breakpoints, int debug_execution); static int xscale_debug_entry(struct target *); -static int xscale_restore_context(struct target *); +static int xscale_restore_banked(struct target *); static int xscale_get_reg(struct reg *reg); static int xscale_set_reg(struct reg *reg, uint8_t *buf); static int xscale_set_breakpoint(struct target *, struct breakpoint *); @@ -1251,7 +1251,7 @@ static int xscale_resume(struct target * xscale_enable_single_step(target, next_pc); /* restore banked registers */ - xscale_restore_context(target); + retval = xscale_restore_banked(target); /* send resume request (command 0x30 or 0x31) * clean the trace buffer if it is to be enabled (0x62) */ @@ -1296,7 +1296,7 @@ static int xscale_resume(struct target * xscale_enable_watchpoints(target); /* restore banked registers */ - xscale_restore_context(target); + retval = xscale_restore_banked(target); /* send resume request (command 0x30 or 0x31) * clean the trace buffer if it is to be enabled (0x62) */ @@ -1371,7 +1371,7 @@ static int xscale_step_inner(struct targ return retval; /* restore banked registers */ - if ((retval = xscale_restore_context(target)) != ERROR_OK) + if ((retval = xscale_restore_banked(target)) != ERROR_OK) return retval; /* send resume request (command 0x30 or 0x31) @@ -1755,7 +1755,7 @@ static int xscale_full_context(struct ta return ERROR_OK; } -static int xscale_restore_context(struct target *target) +static int xscale_restore_banked(struct target *target) { struct arm *armv4_5 = target_to_armv4_5(target); @@ -1774,8 +1774,8 @@ static int xscale_restore_context(struct */ for (i = 1; i 7; i++) { - int dirty = 0; enum armv4_5_mode mode = armv4_5_number_to_mode(i); + struct reg *r; if (mode == ARMV4_5_MODE_USR) continue; @@ -1785,7 +1785,7 @@ static int xscale_restore_context(struct { if (ARMV4_5_CORE_REG_MODE(armv4_5-core_cache, mode, j).dirty) - dirty = 1; + goto dirty; } /* if not USR/SYS, check if the SPSR needs to be written */ @@ -1793,43 +1793,35 @@ static int xscale_restore_context(struct { if (ARMV4_5_CORE_REG_MODE(armv4_5-core_cache, mode, 16).dirty) - dirty = 1; + goto dirty; } - /* is there anything to flush for this mode? */ - if (dirty) - { - uint32_t tmp_cpsr; - struct reg *r; - - /* command 0x1: send banked registers */ - xscale_send_u32(target, 0x1); + /* there's nothing to flush for this mode */ + continue; - tmp_cpsr = 0x0; - tmp_cpsr |= mode; - tmp_cpsr |= 0xc0; /* I/F bits */ +dirty: + /* command 0x1: send banked registers */ + xscale_send_u32(target, 0x1); - /* send CPSR for desired mode */ - xscale_send_u32(target, tmp_cpsr); + /* send CPSR for desired mode */ + xscale_send_u32(target, mode | 0xc0 /* I/F bits */); - /* send banked registers, r8 to r14, and spsr if not in USR/SYS mode */ - for (j = 8; j = 14; j++) - { - r = ARMV4_5_CORE_REG_MODE(armv4_5-core_cache, - mode, j); - xscale_send_u32(target, - buf_get_u32(r-value, 0, 32)); - r-dirty = false; - } + /* send r8 to r14/lr ... only FIQ needs more than r13..r14, +* but this protocol doesn't understand that nuance. +*/
Re: [Openocd-development] [PATCH] Supply 11-bit BYPASS instruction for PXA3xx
On Monday 30 November 2009, Marek Vasut wrote: Hi, patch is attached, please consider applying. The pxa3xx uses different BYPASS instruction (0x7ff) than pxa2xx and ixp4xx, which use 0x7f. Can you try a simpler patch, and just pass ~0 (all ones) instead of the constant 0x7f? I'd expect that would work, since the current code already handles two different IR lengths. Or if it doesn't, that's a lurking bug... Needing an if/else/... branch for each IR length is ugly and error prone. ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [patch 0/5] arm11/cortex-a8 coprocessor cleanup
Now that we have this DPM component, it can (and IMO should!) handle more of the cases where the ARMv6 and ARMv7 code have needlessly unique implementations. This patch addresses coprocessor stuff: - stop using read_cp15/write_cp15 methods in * armv7a.c * cortex_a8.c - add and use DPM support for coprocessors * dpm.c ... makes other implementations become dead * arm11.c ... remove * cortex_a8.c ... remove It's basically cleanup (see diffstat) but also there's a bit of speedup since the DPM ops let code be removed: instead of N * { prepare, access, finish } it's now prepare, N * access, finish which clearly wins whenever more than one coprocessor register needs to be read or written (like cacheflush). - Dave src/target/arm11.c | 68 src/target/arm_dpm.c | 55 src/target/armv7a.c| 39 ++- src/target/armv7a.h|7 -- src/target/cortex_a8.c | 166 +++-- 5 files changed, 144 insertions(+), 191 deletions(-) ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [patch 4/5] ARM11: remove previous mcr()/mrc() methods
We don't need this code, now that the DPM code handles it. --- src/target/arm11.c | 68 --- 1 file changed, 68 deletions(-) --- a/src/target/arm11.c +++ b/src/target/arm11.c @@ -1510,71 +1510,6 @@ COMMAND_HANDLER(arm11_handle_vcr) return ERROR_OK; } -static const uint32_t arm11_coproc_instruction_limits[] = -{ - 15, /* coprocessor */ - 7, /* opcode 1 */ - 15, /* CRn */ - 15, /* CRm */ - 7, /* opcode 2 */ - 0x, /* value */ -}; - -static int arm11_mrc_inner(struct target *target, int cpnum, - uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, - uint32_t *value, bool read) -{ - int retval; - struct arm11_common *arm11 = target_to_arm11(target); - - if (target-state != TARGET_HALTED) - { - LOG_ERROR(Target not halted); - return ERROR_FAIL; - } - - uint32_t instr = 0xEE10 | - (cpnum 8) | - (op1 21) | - (CRn 16) | - (CRm 0) | - (op2 5); - - if (read) - instr |= 0x0010; - - retval = arm11_run_instr_data_prepare(arm11); - if (retval != ERROR_OK) - return retval; - - if (read) - { - retval = arm11_run_instr_data_from_core_via_r0(arm11, instr, value); - if (retval != ERROR_OK) - return retval; - } - else - { - retval = arm11_run_instr_data_to_core_via_r0(arm11, instr, *value); - if (retval != ERROR_OK) - return retval; - } - - return arm11_run_instr_data_finish(arm11); -} - -static int arm11_mrc(struct target *target, int cpnum, - uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value) -{ - return arm11_mrc_inner(target, cpnum, op1, op2, CRn, CRm, value, true); -} - -static int arm11_mcr(struct target *target, int cpnum, - uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value) -{ - return arm11_mrc_inner(target, cpnum, op1, op2, CRn, CRm, value, false); -} - static const struct command_registration arm11_mw_command_handlers[] = { { .name = burst, @@ -1679,7 +1614,4 @@ struct target_type arm11_target = { .target_create =arm11_target_create, .init_target = arm11_init_target, .examine = arm11_examine, - - .mrc = arm11_mrc, - .mcr = arm11_mcr, }; ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [patch 3/5] ARM: implement mrc()/mcr() as DPM ops
Instead of having separate ARM11 and Cortex-A8 implementations of this code, have one shared implementation which just builds on the existing run instruction via R0 support. This enables followup patches to remove that now-unused code from those two drivers. (Patches to move the mrc and mcr code into struct arm are due too ... MIPS and other cores do not support those ARM-specific concepts.) --- src/target/arm_dpm.c | 55 + 1 file changed, 55 insertions(+) --- a/src/target/arm_dpm.c +++ b/src/target/arm_dpm.c @@ -34,6 +34,57 @@ * implementation differences between cores like ARM1136 and Cortex-A8. */ +/* + * Coprocessor support + */ + +/* Read coprocessor */ +static int dpm_mrc(struct target *target, int cpnum, + uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, + uint32_t *value) +{ + struct arm *arm = target_to_arm(target); + struct arm_dpm *dpm = arm-dpm; + int retval; + + retval = dpm-prepare(dpm); + if (retval != ERROR_OK) + return retval; + + /* read coprocessor register into R0; return via DCC */ + retval = dpm-instr_read_data_r0(dpm, + ARMV4_5_MRC(cpnum, op1, 0, CRn, CRm, op2), + value); + + /* (void) */ dpm-finish(dpm); + return retval; +} + +static int dpm_mcr(struct target *target, int cpnum, + uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, + uint32_t value) +{ + struct arm *arm = target_to_arm(target); + struct arm_dpm *dpm = arm-dpm; + int retval; + + retval = dpm-prepare(dpm); + if (retval != ERROR_OK) + return retval; + + /* read DCC into r0; then write coprocessor register from R0 */ + retval = dpm-instr_write_data_r0(dpm, + ARMV4_5_MCR(cpnum, op1, 0, CRn, CRm, op2), + value); + + /* (void) */ dpm-finish(dpm); + return retval; +} + +/* + * Register access utilities + */ + /* Toggles between recorded core mode (USR, SVC, etc) and a temporary one. * Routines *must* restore the original mode before returning!! */ @@ -510,6 +561,10 @@ int arm_dpm_setup(struct arm_dpm *dpm) return ERROR_FAIL; *register_get_last_cache_p(target-reg_cache) = cache; + + target-type-mrc = dpm_mrc; + target-type-mcr = dpm_mcr; + return ERROR_OK; } ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [patch 2/5] ARMv7-A: stop using CP15 ops
The ARMv7-A code uses read_cp15() to access fault registers. Instead, use DPM operations directly, passing in the relevant MRC instructions. This eliminates some per-operation overhead (though it'll be hard to observe, this is uncommon) and helps eliminate read_cp15(). --- src/target/armv7a.c | 39 +++ 1 file changed, 35 insertions(+), 4 deletions(-) --- a/src/target/armv7a.c +++ b/src/target/armv7a.c @@ -38,17 +38,48 @@ static void armv7a_show_fault_registers( { uint32_t dfsr, ifsr, dfar, ifar; struct armv7a_common *armv7a = target_to_armv7a(target); + struct arm_dpm *dpm = armv7a-armv4_5_common.dpm; + int retval; - armv7a-read_cp15(target, 0, 0, 5, 0, dfsr); - armv7a-read_cp15(target, 0, 1, 5, 0, ifsr); - armv7a-read_cp15(target, 0, 0, 6, 0, dfar); - armv7a-read_cp15(target, 0, 2, 6, 0, ifar); + retval = dpm-prepare(dpm); + if (retval != ERROR_OK) + return; + + /* ARMV4_5_MRC(cpnum, op1, r0, CRn, CRm, op2) */ + + /* c5/c0 - {data, instruction} fault status registers */ + retval = dpm-instr_read_data_r0(dpm, + ARMV4_5_MRC(15, 0, 0, 5, 0, 0), + dfsr); + if (retval != ERROR_OK) + goto done; + + retval = dpm-instr_read_data_r0(dpm, + ARMV4_5_MRC(15, 0, 0, 5, 0, 1), + ifsr); + if (retval != ERROR_OK) + goto done; + + /* c6/c0 - {data, instruction} fault address registers */ + retval = dpm-instr_read_data_r0(dpm, + ARMV4_5_MRC(15, 0, 0, 6, 0, 0), + dfar); + if (retval != ERROR_OK) + goto done; + + retval = dpm-instr_read_data_r0(dpm, + ARMV4_5_MRC(15, 0, 0, 6, 0, 2), + ifar); + if (retval != ERROR_OK) + goto done; LOG_USER(Data fault registersDFSR: %8.8 PRIx32 , DFAR: %8.8 PRIx32, dfsr, dfar); LOG_USER(Instruction fault registers IFSR: %8.8 PRIx32 , IFAR: %8.8 PRIx32, ifsr, ifar); +done: + /* (void) */ dpm-finish(dpm); } int armv7a_arch_state(struct target *target) ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [patch 5/5] Cortex-A8: remove previous mcr()/mrc() methods
We don't need this code, now that the DPM code handles it. Neither do we need the ARMv7-A CP15 operations; remove their remnants too. And disable a mostly-needless diagnostic. --- src/target/armv7a.h|7 --- src/target/cortex_a8.c | 97 --- 2 files changed, 1 insertion(+), 103 deletions(-) --- a/src/target/armv7a.h +++ b/src/target/armv7a.h @@ -62,13 +62,6 @@ struct armv7a_common /* Cache and Memory Management Unit */ struct armv4_5_mmu_common armv4_5_mmu; - int (*read_cp15)(struct target *target, - uint32_t op1, uint32_t op2, - uint32_t CRn, uint32_t CRm, uint32_t *value); - int (*write_cp15)(struct target *target, - uint32_t op1, uint32_t op2, - uint32_t CRn, uint32_t CRm, uint32_t value); - int (*examine_debug_reason)(struct target *target); void (*post_debug_entry)(struct target *target); --- a/src/target/cortex_a8.c +++ b/src/target/cortex_a8.c @@ -159,97 +159,6 @@ static int cortex_a8_read_regs_through_m return retval; } -static int cortex_a8_read_cp(struct target *target, uint32_t *value, uint8_t CP, - uint8_t op1, uint8_t CRn, uint8_t CRm, uint8_t op2) -{ - int retval; - struct armv7a_common *armv7a = target_to_armv7a(target); - struct swjdp_common *swjdp = armv7a-swjdp_info; - uint32_t dscr = 0; - - /* MRC(...) to read coprocessor register into r0 */ - cortex_a8_exec_opcode(target, ARMV4_5_MRC(CP, op1, 0, CRn, CRm, op2), - dscr); - - /* Move R0 to DTRTX */ - cortex_a8_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0), - dscr); - - /* Read DCCTX */ - retval = mem_ap_read_atomic_u32(swjdp, - armv7a-debug_base + CPUDBG_DTRTX, value); - - return retval; -} - -static int cortex_a8_write_cp(struct target *target, uint32_t value, - uint8_t CP, uint8_t op1, uint8_t CRn, uint8_t CRm, uint8_t op2) -{ - int retval; - uint32_t dscr; - struct armv7a_common *armv7a = target_to_armv7a(target); - struct swjdp_common *swjdp = armv7a-swjdp_info; - - LOG_DEBUG(CP%i, CRn %i, value 0x%08 PRIx32, CP, CRn, value); - - /* Check that DCCRX is not full */ - retval = mem_ap_read_atomic_u32(swjdp, - armv7a-debug_base + CPUDBG_DSCR, dscr); - if (dscr (1 DSCR_DTR_RX_FULL)) - { - LOG_ERROR(DSCR_DTR_RX_FULL, dscr 0x%08 PRIx32, dscr); - /* Clear DCCRX with MCR(p14, 0, Rd, c0, c5, 0), opcode 0xEE000E15 */ - cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), - dscr); - } - - /* Write DTRRX ... sets DSCR.DTRRXfull but exec_opcode() won't care */ - retval = mem_ap_write_u32(swjdp, - armv7a-debug_base + CPUDBG_DTRRX, value); - - /* Move DTRRX to r0 */ - cortex_a8_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), dscr); - - /* MCR(...) to write r0 to coprocessor */ - return cortex_a8_exec_opcode(target, - ARMV4_5_MCR(CP, op1, 0, CRn, CRm, op2), - dscr); -} - -static int cortex_a8_read_cp15(struct target *target, uint32_t op1, uint32_t op2, - uint32_t CRn, uint32_t CRm, uint32_t *value) -{ - return cortex_a8_read_cp(target, value, 15, op1, CRn, CRm, op2); -} - -static int cortex_a8_write_cp15(struct target *target, uint32_t op1, uint32_t op2, - uint32_t CRn, uint32_t CRm, uint32_t value) -{ - return cortex_a8_write_cp(target, value, 15, op1, CRn, CRm, op2); -} - -static int cortex_a8_mrc(struct target *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value) -{ - if (cpnum!=15) - { - LOG_ERROR(Only cp15 is supported); - return ERROR_FAIL; - } - return cortex_a8_read_cp15(target, op1, op2, CRn, CRm, value); -} - -static int cortex_a8_mcr(struct target *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value) -{ - if (cpnum!=15) - { - LOG_ERROR(Only cp15 is supported); - return ERROR_FAIL; - } - return cortex_a8_write_cp15(target, op1, op2, CRn, CRm, value); -} - - - static int cortex_a8_dap_read_coreregister_u32(struct target *target, uint32_t *value, int regnum) { @@ -421,7 +330,7 @@ static int cortex_a8_read_dcc(struct cor retval = mem_ap_read_atomic_u32(swjdp, a8-armv7a_common.debug_base + CPUDBG_DTRTX, data); - LOG_DEBUG(read DCC 0x%08 PRIx32, *data); + //LOG_DEBUG(read DCC 0x%08 PRIx32, *data); if (dscr_p) *dscr_p = dscr; @@ -1642,8 +1551,6 @@ static int cortex_a8_init_arch_info(stru //
[Openocd-development] [patch 1/5] Cortex-A8: stop using CP15 ops
There were two chunks of Cortex-A8 code which called the ARMv7-A CP15 operations; get rid of them, helping prepare to remove those methods completely: - post_debug_entry() can use the mrc() method to read its two registers. - write_memory() can use dpm-instr_write_data_r0() to flush the ICache and DCache ... doing it this way is actually faster since it reduces per-write overhead. Note that the mrc() method parameters are re-ordered with respect to the ARM instruction documentation, so that part can be confusing. Cleaned up the layout and comments in those areas a bit. --- src/target/cortex_a8.c | 69 --- 1 file changed, 53 insertions(+), 16 deletions(-) --- a/src/target/cortex_a8.c +++ b/src/target/cortex_a8.c @@ -933,19 +933,26 @@ static void cortex_a8_post_debug_entry(s { struct cortex_a8_common *cortex_a8 = target_to_cortex_a8(target); struct armv7a_common *armv7a = cortex_a8-armv7a_common; + int retval; -// cortex_a8_read_cp(target, cp15_control_register, 15, 0, 1, 0, 0); - /* examine cp15 control reg */ - armv7a-read_cp15(target, 0, 0, 1, 0, cortex_a8-cp15_control_reg); - jtag_execute_queue(); + /* MRC p15,0,Rt,c1,c0,0 ; Read CP15 System Control Register */ + retval = target-type-mrc(target, 15, + 0, 0, /* op1, op2 */ + 1, 0, /* CRn, CRm */ + cortex_a8-cp15_control_reg); LOG_DEBUG(cp15_control_reg: %8.8 PRIx32, cortex_a8-cp15_control_reg); if (armv7a-armv4_5_mmu.armv4_5_cache.ctype == -1) { uint32_t cache_type_reg; - /* identify caches */ - armv7a-read_cp15(target, 0, 1, 0, 0, cache_type_reg); - jtag_execute_queue(); + + /* MRC p15,0,Rt,c0,c0,1 ; Read CP15 Cache Type Register */ + retval = target-type-mrc(target, 15, + 0, 1, /* op1, op2 */ + 0, 0, /* CRn, CRm */ + cache_type_reg); + LOG_DEBUG(cp15 cache type: %8.8x, (unsigned) cache_type_reg); + /* FIXME the armv4_4 cache info DOES NOT APPLY to Cortex-A8 */ armv4_5_identify_cache(cache_type_reg, armv7a-armv4_5_mmu.armv4_5_cache); @@ -1350,25 +1357,55 @@ static int cortex_a8_write_memory(struct } } + /* REVISIT this op is generic ARMv7-A/R stuff */ if (retval == ERROR_OK target-state == TARGET_HALTED) { - /* The Cache handling will NOT work with MMU active, the wrong addresses will be invalidated */ + struct arm_dpm *dpm = armv7a-armv4_5_common.dpm; + + retval = dpm-prepare(dpm); + if (retval != ERROR_OK) + return retval; + + /* The Cache handling will NOT work with MMU active, the +* wrong addresses will be invalidated! +* +* For both ICache and DCache, walk all cache lines in the +* address range. Cortex-A8 has fixed 64 byte line length. +*/ + /* invalidate I-Cache */ if (armv7a-armv4_5_mmu.armv4_5_cache.i_cache_enabled) { - /* Invalidate ICache single entry with MVA, repeat this for all cache - lines in the address range, Cortex-A8 has fixed 64 byte line length */ - /* Invalidate Cache single entry with MVA to PoU */ - for (uint32_t cacheline=address; cachelineaddress+size*count; cacheline+=64) - armv7a-write_cp15(target, 0, 1, 7, 5, cacheline); /* I-Cache to PoU */ + /* ICIMVAU - Invalidate Cache single entry +* with MVA to PoU +* MCR p15, 0, r0, c7, c5, 1 +*/ + for (uint32_t cacheline = address; + cacheline address + size * count; + cacheline += 64) { + retval = dpm-instr_write_data_r0(dpm, + ARMV4_5_MCR(15, 0, 0, 7, 5, 1), + cacheline); + } } + /* invalidate D-Cache */ if (armv7a-armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) { - /* Invalidate Cache single entry with MVA to PoC */ - for (uint32_t cacheline=address; cachelineaddress+size*count; cacheline+=64) - armv7a-write_cp15(target, 0, 1, 7, 6, cacheline); /* U/D cache to PoC */ + /* DCIMVAC - Invalidate data Cache line +* with MVA to
Re: [Openocd-development] [PATCH 1/4] add 'module' helper module
On Mon, 2009-11-30 at 14:38 -0800, David Brownell wrote: On Monday 30 November 2009, Zachary T Welch wrote: Adds a fully-documented API for dynamically loading libraries and looking up symbols or addresses in them. Seems to me I've seen one or two or three or four of these before ... must there be another?? I know that portability of such things to non-UNIXey environments has been painful. I was avoiding adding any new external dependencies. I bet that's why you've seen N of them. I added it now to improve the stack tracing, but I think we are getting to the point where loadable modules could be possible. This is definitely part of that strategic plan. I'm used to seeing systems either stick to the libdl stuff, or use some multiplatform beast which tracks all of the platform-specific annoyances. Ummm... this is libdl, isn't it? That's what the man page for these APIs tell me to link against. That library is already included in most of our use cases, though I admit that I haven't tried these patches without any drivers enabled (i.e. a minimal build). Also, I'm a bit uneasy at the notion of adding this, so I hope this doesn't merge unless it gets a lot better understood. I am not in any hurry to push it. I wanted it for my own use. It's nicely encapsulated, si I will see virtually no merge conflicts while I maintain this in my tree. What's the intended change which will have us loading modules? What modules would be loaded? JTAG interfaces, flash devices, targets Any of those things could be turned into loadable modules, so only the features used are resident. Plus: +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); As noted, not very portable ... Yes. I can trivially split the non-portable portions of the API into a module_imp.c file, only one of which would be included. This allows for libdl, Win32/LoadLibrary, or any other implementation required. + 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; This looks wrong/dangerous. Surely better to just fail? It works and produces reasonable traces. + } + + if (NULL == sym-so_name) + sym-so_name = unknown; + if (NULL == sym-sym_name) + sym-sym_name = unknown; ... and this even more so; those names aren't valid. True. Better alternatives? + return sym; +} + +struct module_symbol *module_symbol_by_name(struct module_instance *module, + const char *name) +{ + void *addr = dlsym(module-dlhandle, name); But dlsym can fail... And returns NULL, which is an address that will be looked up (below)... That function will fail safely, excepting the issues you note above. I am not defending this API... just saying that it works + return module_symbol_by_addr(addr); +} ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PATCH 2/4] produce stack traces on segfaults
On Mon, 2009-11-30 at 14:42 -0800, David Brownell wrote: On Monday 30 November 2009, Zachary T Welch wrote: Registers a signal handler to catch SIGSEGV in order to display the stack where the program crashed. Is this for inside OpenOCD? If so, I'd rather just expect folk to run inside GDB. Either they're running natively and should never see SEGV ... or they should be able to fire up GDB to get this data (and likely more). Not everyone wants to run GDB, and not all segfaults can be predicted. If you get one, it's better to have usable data than be required to reproduce what might be a Heisenbug. I have found this feature to be highly useful in the past, to the extent that I am not joking about wanting to implement a libbfd version of the module symbol lookup. This feature ensures that we can get reasonable stack traces from users, without them having to do any extra work. Less steps for crash reports is a Good Thing, I imagine Martha would say. Good built-in debugging facilities can be far superior to a debugger, and the Jim scripting language adds the fun twist where OpenOCD can expose these debug features directly to the user. You laugh now. The first time you use one of the stack dumps that it can produce, you will come to thank me for adding this feature. ;) Right now, I seem to find new ways to create segfaults on a regular basis, and this makes it much faster for me to see what has happened -- without ever running GDB. In summary, printf remains among the best debugging aids. This simply aims to offer some critical introspective intelligence in that vein, which benefits users and developers. Cheers, Zach ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [patch 5/5] Cortex-A8: remove previous mcr()/mrc() methods
On Tue, Dec 1, 2009 at 3:59 AM, David Brownell davi...@pacbell.net wrote: We don't need this code, now that the DPM code handles it. Neither do we need the ARMv7-A CP15 operations; remove their remnants too. And disable a mostly-needless diagnostic. What about reset init scripts. Will they *never* need the mrc/mcr commands? -- Øyvind Harboe US toll free 1-866-980-3434 / International +47 51 63 25 00 http://www.zylin.com/zy1000.html ARM7 ARM9 ARM11 XScale Cortex JTAG debugger and flash programmer ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [patch 5/5] Cortex-A8: remove previous mcr()/mrc() methods
On Tue, Dec 1, 2009 at 7:55 AM, Øyvind Harboe oyvind.har...@zylin.com wrote: On Tue, Dec 1, 2009 at 3:59 AM, David Brownell davi...@pacbell.net wrote: We don't need this code, now that the DPM code handles it. Neither do we need the ARMv7-A CP15 operations; remove their remnants too. And disable a mostly-needless diagnostic. What about reset init scripts. Will they *never* need the mrc/mcr commands? Right... better read the entire series... I see that you added something via a much more general mechanism to cover this case. You're obviously way ahead of me on this one. -- Øyvind Harboe US toll free 1-866-980-3434 / International +47 51 63 25 00 http://www.zylin.com/zy1000.html ARM7 ARM9 ARM11 XScale Cortex JTAG debugger and flash programmer ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PATCH] arm: dcc_downloads and fast_memory_access are now enabled by default
On Mon, Nov 30, 2009 at 10:19 PM, Zach Welch z...@superlucidity.net wrote: I think David has explained why this is not a good idea for a default. It is not always safe and presents an option that would need to be disabled when bringing up new boards. Bring-up is hard enough without having to fight the tools from trying to be smarter than they are. The solution today makes performance suck in most cases as users do not get urged to flip two silly switches. The most effective thing we could do to improve performance for normal users today is to get dcc + fast_memory_access enabled when it works. -- Øyvind Harboe US toll free 1-866-980-3434 / International +47 51 63 25 00 http://www.zylin.com/zy1000.html ARM7 ARM9 ARM11 XScale Cortex JTAG debugger and flash programmer ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [patch 3/5] ARM: implement mrc()/mcr() as DPM ops
On Monday 30 November 2009, David Brownell wrote: (Patches to move the mrc and mcr code into struct arm are due too ... MIPS and other cores do not support those ARM-specific concepts.) Needed for testing, even ... here it is. Goes before slightly tweaked versions of the last few patches. These behave in light testing on Cortex-A8; didn't make time to do so with ARM1136. I'm going to merge the series anyway. = CUT HERE From: David Brownell dbrown...@users.sourceforge.net Subject: target: mcr and mrc are ARM-specific Switch mrc and mcr commands to be toplevel ARM operations, as they should initially have been. Correct the usage message for both commands: it matches ARM documentation (as one wants!) instead of reordering them to match the funky mrc() and mcr() method usage (sigh). For Cortex-A8: restore a line that got accidentally dropped, so the secure monitor mode shadow registers will show again. --- src/target/arm11.c | 13 ++ src/target/arm720t.c | 15 ++- src/target/arm920t.c | 15 ++- src/target/arm926ejs.c |5 - src/target/armv4_5.c | 168 + src/target/armv4_5.h | 15 +++ src/target/cortex_a8.c | 11 +- src/target/target.c | 199 - src/target/target_type.h |5 - 9 files changed, 228 insertions(+), 218 deletions(-) --- a/src/target/arm11.c +++ b/src/target/arm11.c @@ -1219,6 +1219,13 @@ static int arm11_remove_watchpoint(struc return ERROR_FAIL; } +static int arm11_mrc(struct target *target, int cpnum, + uint32_t op1, uint32_t op2, + uint32_t CRn, uint32_t CRm, uint32_t *value); +static int arm11_mcr(struct target *target, int cpnum, + uint32_t op1, uint32_t op2, uint32_t CRn, + uint32_t CRm, uint32_t value); + static int arm11_target_create(struct target *target, Jim_Interp *interp) { struct arm11_common *arm11; @@ -1238,6 +1245,9 @@ static int arm11_target_create(struct ta armv4_5_init_arch_info(target, arm11-arm); + arm11-arm.mrc = arm11_mrc; + arm11-arm.mcr = arm11_mcr; + arm11-target = target; arm11-jtag_info.tap = target-tap; @@ -1679,7 +1689,4 @@ struct target_type arm11_target = { .target_create =arm11_target_create, .init_target = arm11_init_target, .examine = arm11_examine, - - .mrc = arm11_mrc, - .mcr = arm11_mcr, }; --- a/src/target/arm720t.c +++ b/src/target/arm720t.c @@ -378,11 +378,24 @@ static int arm720t_init_target(struct co return arm7tdmi_init_target(cmd_ctx, target); } +/* FIXME remove forward decls */ +static int arm720t_mrc(struct target *target, int cpnum, + uint32_t op1, uint32_t op2, + uint32_t CRn, uint32_t CRm, + uint32_t *value); +static int arm720t_mcr(struct target *target, int cpnum, + uint32_t op1, uint32_t op2, + uint32_t CRn, uint32_t CRm, + uint32_t value); + static int arm720t_init_arch_info(struct target *target, struct arm720t_common *arm720t, struct jtag_tap *tap) { struct arm7_9_common *arm7_9 = arm720t-arm7_9_common; + arm7_9-armv4_5_common.mrc = arm720t_mrc; + arm7_9-armv4_5_common.mcr = arm720t_mcr; + arm7tdmi_init_arch_info(target, arm7_9, tap); arm720t-common_magic = ARM720T_COMMON_MAGIC; @@ -556,6 +569,4 @@ struct target_type arm720t_target = .target_create = arm720t_target_create, .init_target = arm720t_init_target, .examine = arm7_9_examine, - .mrc = arm720t_mrc, - .mcr = arm720t_mcr, }; --- a/src/target/arm920t.c +++ b/src/target/arm920t.c @@ -624,10 +624,23 @@ int arm920t_soft_reset_halt(struct targe return ERROR_OK; } +/* FIXME remove forward decls */ +static int arm920t_mrc(struct target *target, int cpnum, + uint32_t op1, uint32_t op2, + uint32_t CRn, uint32_t CRm, + uint32_t *value); +static int arm920t_mcr(struct target *target, int cpnum, + uint32_t op1, uint32_t op2, + uint32_t CRn, uint32_t CRm, + uint32_t value); + int arm920t_init_arch_info(struct target *target, struct arm920t_common *arm920t, struct jtag_tap *tap) { struct arm7_9_common *arm7_9 = arm920t-arm7_9_common; + arm7_9-armv4_5_common.mrc = arm920t_mrc; + arm7_9-armv4_5_common.mcr = arm920t_mcr; + /* initialize arm7/arm9 specific info (including armv4_5) */ arm9tdmi_init_arch_info(target, arm7_9, tap); @@ -1452,6 +1465,4 @@ struct target_type arm920t_target = .target_create = arm920t_target_create, .init_target = arm9tdmi_init_target, .examine = arm7_9_examine, - .mrc = arm920t_mrc, - .mcr = arm920t_mcr, }; --- a/src/target/arm926ejs.c +++
Re: [Openocd-development] [PATCH] arm: dcc_downloads and fast_memory_access are now enabled by default
On Tue, 2009-12-01 at 08:08 +0100, Øyvind Harboe wrote: On Mon, Nov 30, 2009 at 10:19 PM, Zach Welch z...@superlucidity.net wrote: I think David has explained why this is not a good idea for a default. It is not always safe and presents an option that would need to be disabled when bringing up new boards. Bring-up is hard enough without having to fight the tools from trying to be smarter than they are. The solution today makes performance suck in most cases as users do not get urged to flip two silly switches. The most effective thing we could do to improve performance for normal users today is to get dcc + fast_memory_access enabled when it works. How about a warning when it's _not_ explicitly enabled or disabled by the user? Specifically, tell the users to try enabling those features or to add explicit commands to stop the warnings. Scripts for boards where that feature will be safe by default could add the required commands, and users for others will be able to read the documentation for those commands decide for themselves. This keeps the default safe while giving users the nudge in the direction that you feel they will want to be headed -- eventually. --Z ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [PATCH 1/3] command: the Jim interpreter can now be provided rather than created
In embedded hosts, the Jim interpreter can come from the existing context rather than be created by OpenOCD. Signed-off-by: Øyvind Harboe oyvind.har...@zylin.com --- src/helper/command.c | 18 +++--- src/helper/command.h |6 -- src/openocd.c|6 +++--- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/helper/command.c b/src/helper/command.c index dcad6a1..d657668 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -1272,7 +1272,7 @@ static const struct command_registration command_builtin_handlers[] = { COMMAND_REGISTRATION_DONE }; -struct command_context* command_init(const char *startup_tcl) +struct command_context* command_init(const char *startup_tcl, Jim_Interp *interp) { struct command_context* context = malloc(sizeof(struct command_context)); const char *HostOs; @@ -1284,14 +1284,18 @@ struct command_context* command_init(const char *startup_tcl) context-output_handler_priv = NULL; #if !BUILD_ECOSBOARD - Jim_InitEmbedded(); - /* Create an interpreter */ - context-interp = Jim_CreateInterp(); - /* Add all the Jim core commands */ - Jim_RegisterCoreCommands(context-interp); + /* Create a jim interpreter if we were not handed one */ + if (interp == NULL) + { + Jim_InitEmbedded(); + /* Create an interpreter */ + interp = Jim_CreateInterp(); + /* Add all the Jim core commands */ + Jim_RegisterCoreCommands(interp); + } #endif + context-interp = interp; - Jim_Interp *interp = context-interp; #if defined(_MSC_VER) /* WinXX - is generic, the forward * looking problem is this: diff --git a/src/helper/command.h b/src/helper/command.h index 611db87..8d68c18 100644 --- a/src/helper/command.h +++ b/src/helper/command.h @@ -323,9 +323,11 @@ void command_set_output_handler(struct command_context* context, int command_context_mode(struct command_context *context, enum command_mode mode); /** - * Creates a new command context using the startup TCL provided. + * Creates a new command context using the startup TCL provided and + * the existing Jim interpreter, if any. If interp == NULL, then command_init + * creates a command interpreter. */ -struct command_context* command_init(const char *startup_tcl); +struct command_context* command_init(const char *startup_tcl, Jim_Interp *interp); /** * 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 diff --git a/src/openocd.c b/src/openocd.c index 22d4582..44e0292 100644 --- a/src/openocd.c +++ b/src/openocd.c @@ -188,14 +188,14 @@ static const struct command_registration openocd_command_handlers[] = { struct command_context *global_cmd_ctx; /* NB! this fn can be invoked outside this file for non PC hosted builds */ -struct command_context *setup_command_handler(void) +struct command_context *setup_command_handler(Jim_Interp *interp) { log_init(); LOG_DEBUG(log_init: complete); struct command_context *cmd_ctx; - global_cmd_ctx = cmd_ctx = command_init(openocd_startup_tcl); + global_cmd_ctx = cmd_ctx = command_init(openocd_startup_tcl, interp); register_commands(cmd_ctx, NULL, openocd_command_handlers); /* register subsystem commands */ @@ -242,7 +242,7 @@ int openocd_main(int argc, char *argv[]) /* initialize commandline interface */ struct command_context *cmd_ctx; - cmd_ctx = setup_command_handler(); + cmd_ctx = setup_command_handler(NULL); #if BUILD_IOUTIL if (ioutil_init(cmd_ctx) != ERROR_OK) -- 1.6.3.3 ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
[Openocd-development] [PATCH 2/3] zy1000: keep up with latest changes to command handling
Keep up with Jim Tcl interpreter creation cleanup. Signed-off-by: Øyvind Harboe oyvind.har...@zylin.com --- src/ecosboard.c | 10 -- src/jtag/zy1000/zy1000.c |2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/ecosboard.c b/src/ecosboard.c index 5588934..36e807e 100644 --- a/src/ecosboard.c +++ b/src/ecosboard.c @@ -80,6 +80,7 @@ #include unistd.h #include stdio.h +#include openocd.h #ifdef CYGPKG_HAL_NIOS2 #define ZY1000_SER_DEV /dev/uart_0 @@ -505,8 +506,6 @@ static void zylinjtag_startNetwork(void) cyg_httpd_init_tcl_interpreter(); - interp = httpstate.jim_interp; - Jim_CreateCommand(httpstate.jim_interp, log, zylinjtag_Jim_Command_log, NULL, NULL); Jim_CreateCommand(httpstate.jim_interp, zy1000_reboot, @@ -933,8 +932,6 @@ bool logAllToSerial = false; int boolParam(char *var); -struct command_context *setup_command_handler(void); - static const char *zylin_config_dir=/config/settings; static int add_default_dirs(void) @@ -1078,7 +1075,8 @@ int main(int argc, char *argv[]) /* initialize commandline interface */ struct command_context * cmd_ctx; - cmd_ctx = setup_command_handler(); + struct command_context *setup_command_handler(Jim_Interp *interp); + cmd_ctx = setup_command_handler(httpstate.jim_interp); command_set_output_handler(cmd_ctx, configuration_output_handler, NULL); command_context_mode(cmd_ctx, COMMAND_CONFIG); @@ -1095,7 +1093,7 @@ int main(int argc, char *argv[]) COMMAND_ANY, NULL); #endif - Jim_CreateCommand(interp, uart, zylinjtag_Jim_Command_uart, NULL, NULL); + Jim_CreateCommand(httpstate.jim_interp, uart, zylinjtag_Jim_Command_uart, NULL, NULL); log_init(); diff --git a/src/jtag/zy1000/zy1000.c b/src/jtag/zy1000/zy1000.c index 115b3be..07d840f 100644 --- a/src/jtag/zy1000/zy1000.c +++ b/src/jtag/zy1000/zy1000.c @@ -1,5 +1,5 @@ /*** - * Copyright (C) 2007-2008 by Øyvind Harboe * + * Copyright (C) 2007-2009 by Øyvind Harboe * * * * 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 * -- 1.6.3.3 ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PATCH] arm: dcc_downloads and fast_memory_access are now enabled by default
How about a warning when it's _not_ explicitly enabled or disabled by the user? Specifically, tell the users to try enabling those features or to add explicit commands to stop the warnings. Scripts for boards where that feature will be safe by default could add the required commands, and users for others will be able to read the documentation for those commands decide for themselves. This keeps the default safe while giving users the nudge in the direction that you feel they will want to be headed -- eventually. I think this is a good way to go forward. Here is a though on implementation: each target defines a default post-reset script, there is some suitable event that exists currently I'm sure. This post reset script does checks and prints out hints and warnings. -- Øyvind Harboe US toll free 1-866-980-3434 / International +47 51 63 25 00 http://www.zylin.com/zy1000.html ARM7 ARM9 ARM11 XScale Cortex JTAG debugger and flash programmer ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [PATCH 1/3] command: the Jim interpreter can now be provided rather than created
There is no third patch for this series, I just left out an unsuitable patch and I guess I should have used different args to git format patch to make it a series of two patches. -- Øyvind Harboe US toll free 1-866-980-3434 / International +47 51 63 25 00 http://www.zylin.com/zy1000.html ARM7 ARM9 ARM11 XScale Cortex JTAG debugger and flash programmer ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development
Re: [Openocd-development] [patch 3/5] ARM: implement mrc()/mcr() as DPM ops
On Mon, 2009-11-30 at 23:42 -0800, David Brownell wrote: On Monday 30 November 2009, David Brownell wrote: (Patches to move the mrc and mcr code into struct arm are due too ... MIPS and other cores do not support those ARM-specific concepts.) Needed for testing, even ... here it is. Goes before slightly tweaked versions of the last few patches. Sweet! I am very glad to see this moved. These behave in light testing on Cortex-A8; didn't make time to do so with ARM1136. I'm going to merge the series anyway. I'll trust you to fix any reported regressions. ;) --Z ___ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development