From a92d27afb0733f6280088bd79b048cbd87a2a0c4 Mon Sep 17 00:00:00 2001 From: ntfreak Date: Mon, 18 Feb 2008 14:32:43 +0000 Subject: - Added a "User:" debug level. These are messages that are intended for the user and are part of normal operation. - Faster DEBUG/INFO() when they are disabled - target_read/write_buffer() now uses 16 and 32 bit access for single word aligned requests. Other requests are serviced as quickly as possible. - *much* faster read/write GDB packets, removing timeout problems. - GDB read/write packets w/single word aligned 32/16 bit access now use 32/16 bit word access. - working area can now be changed on the fly. Provides a way to move working area about as MMU is enabled/disabled. - cleaned up error messages for verify_image. Thanks Øyvind Harboe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: svn://svn.berlios.de/openocd/trunk@302 b42882b7-edfa-0310-969c-e2dbd0fdcd60 --- src/helper/log.c | 7 ++-- src/helper/log.h | 17 ++++++++-- src/server/gdb_server.c | 87 +++++-------------------------------------------- src/target/target.c | 50 +++++++++++++++++++--------- 4 files changed, 62 insertions(+), 99 deletions(-) diff --git a/src/helper/log.c b/src/helper/log.c index 4cdcfc87..fe475130 100644 --- a/src/helper/log.c +++ b/src/helper/log.c @@ -43,12 +43,13 @@ void log_setCallback(logCallback c, void *p) privData = p; } -static char *log_strings[4] = +static char *log_strings[5] = { + "User: ", "Error: ", "Warning:", "Info: ", - "Debug: ", + "Debug: " }; void log_printf(enum log_levels level, const char *file, int line, const char *function, const char *format, ...) @@ -68,7 +69,7 @@ void log_printf(enum log_levels level, const char *file, int line, const char *f if (f != NULL) file = f + 1; - fprintf(log_output, "%s %d %ld %s:%d %s(): %s\n", log_strings[level], count, time(NULL), file, line, function, buffer); + fprintf(log_output, "%s %d %ld %s:%d %s(): %s\n", log_strings[level+1], count, time(NULL), file, line, function, buffer); fflush(log_output); va_end(args); diff --git a/src/helper/log.h b/src/helper/log.h index 09bc3a17..ab32760a 100644 --- a/src/helper/log.h +++ b/src/helper/log.h @@ -26,6 +26,9 @@ #include /* logging priorities + * LOG_USER - user messages. Could be anything from information + * to progress messags. These messages do not represent + * incorrect or unexpected behaviour, just normal execution. * LOG_ERROR - fatal errors, that are likely to cause program abort * LOG_WARNING - non-fatal errors, that may be resolved later * LOG_INFO - state information, etc. @@ -33,6 +36,7 @@ */ enum log_levels { + LOG_USER = -1, LOG_ERROR = 0, LOG_WARNING = 1, LOG_INFO = 2, @@ -53,13 +57,16 @@ extern void log_setCallback(logCallback callback, void *priv); extern int debug_level; +/* Avoid fn call and building parameter list if we're not outputting the information. + * Matters on feeble CPUs for DEBUG/INFO statements that are involved frequently */ + #define DEBUG(expr ...) \ - do { \ + do { if (debug_level >= LOG_DEBUG) \ log_printf (LOG_DEBUG, __FILE__, __LINE__, __FUNCTION__, expr); \ } while(0) #define INFO(expr ...) \ - do { \ + do { if (debug_level >= LOG_INFO) \ log_printf (LOG_INFO, __FILE__, __LINE__, __FUNCTION__, expr); \ } while(0) @@ -73,6 +80,12 @@ extern int debug_level; log_printf (LOG_ERROR, __FILE__, __LINE__, __FUNCTION__, expr); \ } while(0) +#define USER(expr ...) \ + do { \ + log_printf (LOG_USER, __FILE__, __LINE__, __FUNCTION__, expr); \ + } while(0) + + /* general failures * error codes < 100 */ diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 99c9376d..d940bc1a 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -524,7 +524,7 @@ int gdb_output_con(connection_t *connection, char* line) int gdb_output(struct command_context_s *context, char* line) { /* this will be dumped to the log and also sent as an O packet if possible */ - ERROR(line); + USER(line); return ERROR_OK; } @@ -1056,35 +1056,18 @@ int gdb_read_memory_packet(connection_t *connection, target_t *target, char *pac DEBUG("addr: 0x%8.8x, len: 0x%8.8x", addr, len); - switch (len) - { - case 4: - if ((addr % 4) == 0) - retval = target->type->read_memory(target, addr, 4, 1, buffer); - else - retval = target->type->read_memory(target, addr, 1, len, buffer); - break; - case 2: - if ((addr % 2) == 0) - retval = target->type->read_memory(target, addr, 2, 1, buffer); - else - retval = target->type->read_memory(target, addr, 1, len, buffer); - break; - case 3: - case 1: - retval = target->type->read_memory(target, addr, 1, len, buffer); - break; - /* handle bulk reads */ - default: - retval = target_read_buffer(target, addr, len, buffer); - break; - } + retval = target_read_buffer(target, addr, len, buffer); #if 0 if (retval == ERROR_TARGET_DATA_ABORT) { /* TODO : Here we have to lie and send back all zero's lest stack traces won't work. * At some point this might be fixed in GDB, in which case this code can be removed. + * + * OpenOCD developers are acutely aware of this problem, but there is nothing + * gained by involving the user in this problem that hopefully will get resolved + * eventually + * * http://sourceware.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gdb&pr=2395 */ memset(buffer, 0, len); @@ -1159,31 +1142,7 @@ int gdb_write_memory_packet(connection_t *connection, target_t *target, char *pa buffer[i] = tmp; } - retval = ERROR_OK; - switch (len) - { - /* handle sized writes */ - case 4: - if ((addr % 4) == 0) - retval = target->type->write_memory(target, addr, 4, 1, buffer); - else - retval = target->type->write_memory(target, addr, 1, len, buffer); - break; - case 2: - if ((addr % 2) == 0) - retval = target->type->write_memory(target, addr, 2, 1, buffer); - else - retval = target->type->write_memory(target, addr, 1, len, buffer); - break; - case 3: - case 1: - retval = target->type->write_memory(target, addr, 1, len, buffer); - break; - /* handle bulk writes */ - default: - retval = target_write_buffer(target, addr, len, buffer); - break; - } + retval = target_write_buffer(target, addr, len, buffer); if (retval == ERROR_OK) { @@ -1206,7 +1165,6 @@ int gdb_write_memory_binary_packet(connection_t *connection, target_t *target, c u32 addr = 0; u32 len = 0; - u8 *buffer; int retval; /* skip command character */ @@ -1231,36 +1189,9 @@ int gdb_write_memory_binary_packet(connection_t *connection, target_t *target, c retval = ERROR_OK; if( len ) { - buffer = malloc(len); - DEBUG("addr: 0x%8.8x, len: 0x%8.8x", addr, len); - memcpy( buffer, separator, len ); - - switch (len) - { - case 4: - if ((addr % 4) == 0) - retval = target->type->write_memory(target, addr, 4, 1, buffer); - else - retval = target->type->write_memory(target, addr, 1, len, buffer); - break; - case 2: - if ((addr % 2) == 0) - retval = target->type->write_memory(target, addr, 2, 1, buffer); - else - retval = target->type->write_memory(target, addr, 1, len, buffer); - break; - case 3: - case 1: - retval = target->type->write_memory(target, addr, 1, len, buffer); - break; - default: - retval = target_write_buffer(target, addr, len, buffer); - break; - } - - free(buffer); + retval = target_write_buffer(target, addr, len, separator); } if (retval == ERROR_OK) diff --git a/src/target/target.c b/src/target/target.c index bafbfb0f..a6063764 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -700,23 +700,24 @@ int target_register_commands(struct command_context_s *cmd_ctx) register_command(cmd_ctx, NULL, "daemon_startup", handle_daemon_startup_command, COMMAND_CONFIG, NULL); register_command(cmd_ctx, NULL, "target_script", handle_target_script_command, COMMAND_CONFIG, NULL); register_command(cmd_ctx, NULL, "run_and_halt_time", handle_run_and_halt_time_command, COMMAND_CONFIG, NULL); - register_command(cmd_ctx, NULL, "working_area", handle_working_area_command, COMMAND_CONFIG, NULL); + register_command(cmd_ctx, NULL, "working_area", handle_working_area_command, COMMAND_ANY, NULL); return ERROR_OK; } +/* Single aligned words are guaranteed to use 16 or 32 bit access + * mode respectively, otherwise data is handled as quickly as + * possible + */ int target_write_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer) { int retval; DEBUG("writing buffer of %i byte at 0x%8.8x", size, address); - /* handle writes of less than 4 byte */ - if (size < 4) + if (((address % 2) == 0) && (size == 2)) { - if ((retval = target->type->write_memory(target, address, 1, size, buffer)) != ERROR_OK) - return retval; - return ERROR_OK; + return target->type->write_memory(target, address, 2, 1, buffer); } /* handle unaligned head bytes */ @@ -764,18 +765,20 @@ int target_write_buffer(struct target_s *target, u32 address, u32 size, u8 *buff return ERROR_OK; } + +/* Single aligned words are guaranteed to use 16 or 32 bit access + * mode respectively, otherwise data is handled as quickly as + * possible + */ int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer) { int retval; DEBUG("reading buffer of %i byte at 0x%8.8x", size, address); - /* handle reads of less than 4 byte */ - if (size < 4) + if (((address % 2) == 0) && (size == 2)) { - if ((retval = target->type->read_memory(target, address, 1, size, buffer)) != ERROR_OK) - return retval; - return ERROR_OK; + return target->type->read_memory(target, address, 2, 1, buffer); } /* handle unaligned head bytes */ @@ -828,9 +831,14 @@ int target_checksum_memory(struct target_s *target, u32 address, u32 size, u32* if (buffer == NULL) { ERROR("error allocating buffer for section (%d bytes)", size); - return ERROR_OK; + return ERROR_INVALID_ARGUMENTS; + } + retval = target_read_buffer(target, address, size, buffer); + if (retval != ERROR_OK) + { + free(buffer); + return retval; } - target_read_buffer(target, address, size, buffer); /* convert to target endianess */ for (i = 0; i < (size/sizeof(u32)); i++) @@ -1226,6 +1234,7 @@ int handle_working_area_command(struct command_context_s *cmd_ctx, char *cmd, ch ERROR("target number '%s' not defined", args[0]); exit(-1); } + target_free_all_working_areas(target); target->working_area = strtoul(args[1], NULL, 0); target->working_area_size = strtoul(args[2], NULL, 0); @@ -1450,6 +1459,13 @@ int handle_wait_halt_command(struct command_context_s *cmd_ctx, char *cmd, char return wait_state(cmd_ctx, cmd, TARGET_HALTED, ms); } +static void target_process_events(struct command_context_s *cmd_ctx) +{ + target_t *target = get_current_target(cmd_ctx); + target->type->poll(target); + target_call_timer_callbacks(); +} + static int wait_state(struct command_context_s *cmd_ctx, char *cmd, enum target_state state, int ms) { struct timeval timeout, now; @@ -1634,7 +1650,9 @@ int handle_resume_command(struct command_context_s *cmd_ctx, char *cmd, char **a } } - return wait_state(cmd_ctx, cmd, TARGET_RUNNING, 5000); + target_process_events(cmd_ctx); + + return ERROR_OK; } int handle_step_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) @@ -2017,7 +2035,7 @@ int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, ch if( retval != ERROR_OK ) { - command_print(cmd_ctx, "image verify failed, verify aborted"); + command_print(cmd_ctx, "could not calculate checksum, verify aborted"); free(buffer); image_close(&image); return ERROR_OK; @@ -2028,7 +2046,7 @@ int handle_verify_image_command(struct command_context_s *cmd_ctx, char *cmd, ch /* failed crc checksum, fall back to a binary compare */ u8 *data; - command_print(cmd_ctx, "image verify checksum failed - attempting binary compare"); + command_print(cmd_ctx, "checksum mismatch - attempting binary compare"); data = (u8*)malloc(buf_cnt); -- cgit v1.2.3