- 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 git-svn-id: svn://svn.berlios.de/openocd/trunk@302 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
parent
cf9646bda6
commit
a92d27afb0
|
@ -43,12 +43,13 @@ void log_setCallback(logCallback c, void *p)
|
||||||
privData = p;
|
privData = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *log_strings[4] =
|
static char *log_strings[5] =
|
||||||
{
|
{
|
||||||
|
"User: ",
|
||||||
"Error: ",
|
"Error: ",
|
||||||
"Warning:",
|
"Warning:",
|
||||||
"Info: ",
|
"Info: ",
|
||||||
"Debug: ",
|
"Debug: "
|
||||||
};
|
};
|
||||||
|
|
||||||
void log_printf(enum log_levels level, const char *file, int line, const char *function, const char *format, ...)
|
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)
|
if (f != NULL)
|
||||||
file = f + 1;
|
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);
|
fflush(log_output);
|
||||||
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
/* logging priorities
|
/* 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_ERROR - fatal errors, that are likely to cause program abort
|
||||||
* LOG_WARNING - non-fatal errors, that may be resolved later
|
* LOG_WARNING - non-fatal errors, that may be resolved later
|
||||||
* LOG_INFO - state information, etc.
|
* LOG_INFO - state information, etc.
|
||||||
|
@ -33,6 +36,7 @@
|
||||||
*/
|
*/
|
||||||
enum log_levels
|
enum log_levels
|
||||||
{
|
{
|
||||||
|
LOG_USER = -1,
|
||||||
LOG_ERROR = 0,
|
LOG_ERROR = 0,
|
||||||
LOG_WARNING = 1,
|
LOG_WARNING = 1,
|
||||||
LOG_INFO = 2,
|
LOG_INFO = 2,
|
||||||
|
@ -53,13 +57,16 @@ extern void log_setCallback(logCallback callback, void *priv);
|
||||||
|
|
||||||
extern int debug_level;
|
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 ...) \
|
#define DEBUG(expr ...) \
|
||||||
do { \
|
do { if (debug_level >= LOG_DEBUG) \
|
||||||
log_printf (LOG_DEBUG, __FILE__, __LINE__, __FUNCTION__, expr); \
|
log_printf (LOG_DEBUG, __FILE__, __LINE__, __FUNCTION__, expr); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define INFO(expr ...) \
|
#define INFO(expr ...) \
|
||||||
do { \
|
do { if (debug_level >= LOG_INFO) \
|
||||||
log_printf (LOG_INFO, __FILE__, __LINE__, __FUNCTION__, expr); \
|
log_printf (LOG_INFO, __FILE__, __LINE__, __FUNCTION__, expr); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
@ -73,6 +80,12 @@ extern int debug_level;
|
||||||
log_printf (LOG_ERROR, __FILE__, __LINE__, __FUNCTION__, expr); \
|
log_printf (LOG_ERROR, __FILE__, __LINE__, __FUNCTION__, expr); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
#define USER(expr ...) \
|
||||||
|
do { \
|
||||||
|
log_printf (LOG_USER, __FILE__, __LINE__, __FUNCTION__, expr); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
/* general failures
|
/* general failures
|
||||||
* error codes < 100
|
* error codes < 100
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -524,7 +524,7 @@ int gdb_output_con(connection_t *connection, char* line)
|
||||||
int gdb_output(struct command_context_s *context, 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 */
|
/* this will be dumped to the log and also sent as an O packet if possible */
|
||||||
ERROR(line);
|
USER(line);
|
||||||
return ERROR_OK;
|
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);
|
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);
|
retval = target_read_buffer(target, addr, len, buffer);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (retval == ERROR_TARGET_DATA_ABORT)
|
if (retval == ERROR_TARGET_DATA_ABORT)
|
||||||
{
|
{
|
||||||
/* TODO : Here we have to lie and send back all zero's lest stack traces won't work.
|
/* 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.
|
* 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
|
* http://sourceware.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gdb&pr=2395
|
||||||
*/
|
*/
|
||||||
memset(buffer, 0, len);
|
memset(buffer, 0, len);
|
||||||
|
@ -1159,31 +1142,7 @@ int gdb_write_memory_packet(connection_t *connection, target_t *target, char *pa
|
||||||
buffer[i] = tmp;
|
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);
|
retval = target_write_buffer(target, addr, len, buffer);
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retval == ERROR_OK)
|
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 addr = 0;
|
||||||
u32 len = 0;
|
u32 len = 0;
|
||||||
|
|
||||||
u8 *buffer;
|
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
/* skip command character */
|
/* skip command character */
|
||||||
|
@ -1231,36 +1189,9 @@ int gdb_write_memory_binary_packet(connection_t *connection, target_t *target, c
|
||||||
retval = ERROR_OK;
|
retval = ERROR_OK;
|
||||||
if( len ) {
|
if( len ) {
|
||||||
|
|
||||||
buffer = malloc(len);
|
|
||||||
|
|
||||||
DEBUG("addr: 0x%8.8x, len: 0x%8.8x", addr, len);
|
DEBUG("addr: 0x%8.8x, len: 0x%8.8x", addr, len);
|
||||||
|
|
||||||
memcpy( buffer, separator, len );
|
retval = target_write_buffer(target, addr, len, separator);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retval == ERROR_OK)
|
if (retval == ERROR_OK)
|
||||||
|
|
|
@ -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, "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, "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, "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;
|
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 target_write_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
DEBUG("writing buffer of %i byte at 0x%8.8x", size, address);
|
DEBUG("writing buffer of %i byte at 0x%8.8x", size, address);
|
||||||
|
|
||||||
/* handle writes of less than 4 byte */
|
if (((address % 2) == 0) && (size == 2))
|
||||||
if (size < 4)
|
|
||||||
{
|
{
|
||||||
if ((retval = target->type->write_memory(target, address, 1, size, buffer)) != ERROR_OK)
|
return target->type->write_memory(target, address, 2, 1, buffer);
|
||||||
return retval;
|
|
||||||
return ERROR_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle unaligned head bytes */
|
/* 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;
|
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 target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffer)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
DEBUG("reading buffer of %i byte at 0x%8.8x", size, address);
|
DEBUG("reading buffer of %i byte at 0x%8.8x", size, address);
|
||||||
|
|
||||||
/* handle reads of less than 4 byte */
|
if (((address % 2) == 0) && (size == 2))
|
||||||
if (size < 4)
|
|
||||||
{
|
{
|
||||||
if ((retval = target->type->read_memory(target, address, 1, size, buffer)) != ERROR_OK)
|
return target->type->read_memory(target, address, 2, 1, buffer);
|
||||||
return retval;
|
|
||||||
return ERROR_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle unaligned head bytes */
|
/* handle unaligned head bytes */
|
||||||
|
@ -828,9 +831,14 @@ int target_checksum_memory(struct target_s *target, u32 address, u32 size, u32*
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
{
|
{
|
||||||
ERROR("error allocating buffer for section (%d bytes)", size);
|
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 */
|
/* convert to target endianess */
|
||||||
for (i = 0; i < (size/sizeof(u32)); i++)
|
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]);
|
ERROR("target number '%s' not defined", args[0]);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
target_free_all_working_areas(target);
|
||||||
|
|
||||||
target->working_area = strtoul(args[1], NULL, 0);
|
target->working_area = strtoul(args[1], NULL, 0);
|
||||||
target->working_area_size = strtoul(args[2], 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);
|
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)
|
static int wait_state(struct command_context_s *cmd_ctx, char *cmd, enum target_state state, int ms)
|
||||||
{
|
{
|
||||||
struct timeval timeout, now;
|
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)
|
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 )
|
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);
|
free(buffer);
|
||||||
image_close(&image);
|
image_close(&image);
|
||||||
return ERROR_OK;
|
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 */
|
/* failed crc checksum, fall back to a binary compare */
|
||||||
u8 *data;
|
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);
|
data = (u8*)malloc(buf_cnt);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue