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, ...)
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);
#include <stdarg.h>
/* 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.
*/
enum log_levels
{
+ LOG_USER = -1,
LOG_ERROR = 0,
LOG_WARNING = 1,
LOG_INFO = 2,
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)
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
*/
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;
}
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);
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)
{
u32 addr = 0;
u32 len = 0;
- u8 *buffer;
int retval;
/* skip command character */
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)
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 */
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 */
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++)
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);
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;
}
}
- 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)
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;
/* 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);