- renamed M5960 USB JTAG to "flyswatter"

- make ep93xx and at91rm9200 bitbang JTAG interfaces dependant on ARM host (thanks to Vincent Palatin)
- various whitespace fixes
- removed various warnings
- add support for Debian GNU/kFreeBSD (thanks to Uwe Hermann)
- fix OpenOCD compilation for various platforms (thanks to Uwe Hermann and Vincent Palatin)
- switched order of JTAG chain examination and validation (examine first, then multiple validation tries even if examination failed)
- added target_request subsystem to handle requests from the target (debug messages and tracepoints implemented, future enhancements might include
semihosting, all ARM7/9 only for now)
- added support for GDB vFlashXXX packets (thanks to Pavel Chromy)
- added support for receiving data via ARM7/9 DCC
- reworked flash writing. the 'flash write' command is now deprecated and replaced by 'flash write_binary' (old syntax and behaviour) and 'flash
write_image' (write image files (bin, hex, elf, s19) to a target).
- added support for AMD/ST/SST 29F400B non-cfi flashes



git-svn-id: svn://svn.berlios.de/openocd/trunk@190 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
drath
2007-08-10 19:44:06 +00:00
parent 835e6440b8
commit 20e4e77cdf
58 changed files with 1618 additions and 636 deletions

View File

@@ -11,8 +11,8 @@ noinst_LIBRARIES = libtarget.a
libtarget_a_SOURCES = target.c register.c breakpoints.c armv4_5.c embeddedice.c etm.c arm7tdmi.c arm9tdmi.c \
arm_jtag.c arm7_9_common.c algorithm.c arm920t.c arm720t.c armv4_5_mmu.c armv4_5_cache.c arm_disassembler.c \
arm966e.c arm926ejs.c etb.c xscale.c arm_simulator.c image.c armv7m.c cortex_m3.c cortex_swjdp.c \
etm_dummy.c $(OOCD_TRACE_FILES)
etm_dummy.c $(OOCD_TRACE_FILES) target_request.c trace.c
noinst_HEADERS = target.h register.h armv4_5.h embeddedice.h etm.h arm7tdmi.h arm9tdmi.h \
arm_jtag.h arm7_9_common.h arm920t.h arm720t.h armv4_5_mmu.h armv4_5_cache.h breakpoints.h algorithm.h \
arm_disassembler.h arm966e.h arm926ejs.h etb.h xscale.h arm_simulator.h image.h armv7m.h cortex_m3.h cortex_swjdp.h \
etm_dummy.h oocd_trace.h
etm_dummy.h oocd_trace.h target_request.h trace.h

View File

@@ -25,6 +25,7 @@
#include "embeddedice.h"
#include "target.h"
#include "target_request.h"
#include "armv4_5.h"
#include "arm_jtag.h"
#include "jtag.h"
@@ -589,6 +590,55 @@ int arm7_9_execute_fast_sys_speed(struct target_s *target)
return ERROR_OK;
}
int arm7_9_target_request_data(target_t *target, u32 size, u8 *buffer)
{
armv4_5_common_t *armv4_5 = target->arch_info;
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
arm_jtag_t *jtag_info = &arm7_9->jtag_info;
u32 *data;
int i;
data = malloc(size * (sizeof(u32)));
embeddedice_receive(jtag_info, data, size);
for (i = 0; i < size; i++)
{
h_u32_to_le(buffer + (i * 4), data[i]);
}
free(data);
return ERROR_OK;
}
int arm7_9_handle_target_request(void *priv)
{
target_t *target = priv;
armv4_5_common_t *armv4_5 = target->arch_info;
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
arm_jtag_t *jtag_info = &arm7_9->jtag_info;
reg_t *dcc_control = &arm7_9->eice_cache->reg_list[EICE_COMMS_CTRL];
if (target->state == TARGET_RUNNING)
{
/* read DCC control register */
embeddedice_read_reg(dcc_control);
jtag_execute_queue();
/* check W bit */
if (buf_get_u32(dcc_control->value, 1, 1) == 1)
{
u32 request;
embeddedice_receive(jtag_info, &request, 1);
target_request(target, request);
}
}
return ERROR_OK;
}
enum target_state arm7_9_poll(target_t *target)
{
int retval;
@@ -2467,5 +2517,7 @@ int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9)
armv4_5_init_arch_info(target, armv4_5);
target_register_timer_callback(arm7_9_handle_target_request, 1, 1, target);
return ERROR_OK;
}

View File

@@ -103,6 +103,8 @@ int arm7_9_register_commands(struct command_context_s *cmd_ctx);
enum target_state arm7_9_poll(target_t *target);
int arm7_9_target_request_data(target_t *target, u32 size, u8 *buffer);
int arm7_9_assert_reset(target_t *target);
int arm7_9_deassert_reset(target_t *target);
int arm7_9_reset_request_halt(target_t *target);

View File

@@ -59,6 +59,8 @@ target_type_t arm7tdmi_target =
.poll = arm7_9_poll,
.arch_state = armv4_5_arch_state,
.target_request_data = arm7_9_target_request_data,
.halt = arm7_9_halt,
.resume = arm7_9_resume,
.step = arm7_9_step,

View File

@@ -63,6 +63,8 @@ target_type_t arm920t_target =
.poll = arm7_9_poll,
.arch_state = arm920t_arch_state,
.target_request_data = arm7_9_target_request_data,
.halt = arm7_9_halt,
.resume = arm7_9_resume,
.step = arm7_9_step,

View File

@@ -63,6 +63,8 @@ target_type_t arm926ejs_target =
.poll = arm7_9_poll,
.arch_state = arm926ejs_arch_state,
.target_request_data = arm7_9_target_request_data,
.halt = arm7_9_halt,
.resume = arm7_9_resume,
.step = arm7_9_step,

View File

@@ -54,6 +54,8 @@ target_type_t arm966e_target =
.poll = arm7_9_poll,
.arch_state = armv4_5_arch_state,
.target_request_data = arm7_9_target_request_data,
.halt = arm7_9_halt,
.resume = arm7_9_resume,
.step = arm7_9_step,

View File

@@ -57,6 +57,8 @@ target_type_t arm9tdmi_target =
.poll = arm7_9_poll,
.arch_state = armv4_5_arch_state,
.target_request_data = arm7_9_target_request_data,
.halt = arm7_9_halt,
.resume = arm7_9_resume,
.step = arm7_9_step,

View File

@@ -60,6 +60,8 @@ target_type_t cortexm3_target =
.poll = cortex_m3_poll,
.arch_state = armv7m_arch_state,
.target_request_data = NULL,
.halt = cortex_m3_halt,
.resume = cortex_m3_resume,
.step = cortex_m3_step,

View File

@@ -274,6 +274,75 @@ int embeddedice_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_mask)
return ERROR_OK;
}
/* receive <size> words of 32 bit from the DCC
* we pretend the target is always going to be fast enough
* (relative to the JTAG clock), so we don't need to handshake
*/
int embeddedice_receive(arm_jtag_t *jtag_info, u32 *data, u32 size)
{
u8 reg_addr = 0x5;
scan_field_t fields[3];
jtag_add_end_state(TAP_RTI);
arm_jtag_scann(jtag_info, 0x2);
arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
fields[0].device = jtag_info->chain_pos;
fields[0].num_bits = 32;
fields[0].out_value = NULL;
fields[0].out_mask = NULL;
fields[0].in_value = NULL;
fields[0].in_check_value = NULL;
fields[0].in_check_mask = NULL;
fields[0].in_handler = NULL;
fields[0].in_handler_priv = NULL;
fields[1].device = jtag_info->chain_pos;
fields[1].num_bits = 5;
fields[1].out_value = malloc(1);
buf_set_u32(fields[1].out_value, 0, 5, reg_addr);
fields[1].out_mask = NULL;
fields[1].in_value = NULL;
fields[1].in_check_value = NULL;
fields[1].in_check_mask = NULL;
fields[1].in_handler = NULL;
fields[1].in_handler_priv = NULL;
fields[2].device = jtag_info->chain_pos;
fields[2].num_bits = 1;
fields[2].out_value = malloc(1);
buf_set_u32(fields[2].out_value, 0, 1, 0);
fields[2].out_mask = NULL;
fields[2].in_value = NULL;
fields[2].in_check_value = NULL;
fields[2].in_check_mask = NULL;
fields[2].in_handler = NULL;
fields[2].in_handler_priv = NULL;
jtag_add_dr_scan(3, fields, -1, NULL);
while (size > 0)
{
/* when reading the last item, set the register address to the DCC control reg,
* to avoid reading additional data from the DCC data reg
*/
if (size == 1)
buf_set_u32(fields[1].out_value, 0, 5, embeddedice_reg_arch_info[EICE_COMMS_CTRL]);
fields[0].in_handler = arm_jtag_buf_to_u32;
fields[0].in_handler_priv = data;
jtag_add_dr_scan(3, fields, -1, NULL);
data++;
size--;
}
free(fields[1].out_value);
free(fields[2].out_value);
return jtag_execute_queue();
}
int embeddedice_read_reg(reg_t *reg)
{
return embeddedice_read_reg_w_check(reg, NULL, NULL);

View File

@@ -97,5 +97,6 @@ extern int embeddedice_read_reg_w_check(reg_t *reg, u8* check_value, u8* check_m
extern int embeddedice_store_reg(reg_t *reg);
extern int embeddedice_set_reg(reg_t *reg, u32 value);
extern int embeddedice_set_reg_w_exec(reg_t *reg, u8 *buf);
extern int embeddedice_receive(arm_jtag_t *jtag_info, u32 *data, u32 size);
#endif /* EMBEDDED_ICE_H */

View File

@@ -133,6 +133,10 @@ int identify_image_type(image_t *image, char *type_string, char *url)
{
image->type = IMAGE_SRECORD;
}
else if (!strcmp(type_string, "build"))
{
image->type = IMAGE_BUILDER;
}
else
{
return ERROR_IMAGE_TYPE_UNKNOWN;
@@ -395,7 +399,7 @@ int image_elf_read_headers(image_t *image)
if ((field32(elf, elf->segments[i].p_type) == PT_LOAD) && (field32(elf, elf->segments[i].p_filesz) != 0))
{
image->sections[j].size = field32(elf,elf->segments[i].p_memsz);
image->sections[j].base_address = field32(elf,elf->segments[i].p_vaddr);
image->sections[j].base_address = field32(elf,elf->segments[i].p_paddr);
image->sections[j].private = &elf->segments[i];
image->sections[j].flags = field32(elf,elf->segments[i].p_flags);
j++;
@@ -758,6 +762,12 @@ int image_open(image_t *image, char *url, char *type_string)
return retval;
}
}
else if (image->type == IMAGE_BUILDER)
{
image->num_sections = 0;
image->sections = NULL;
image->type_private = NULL;
}
return retval;
};
@@ -765,7 +775,15 @@ int image_open(image_t *image, char *url, char *type_string)
int image_read_section(image_t *image, int section, u32 offset, u32 size, u8 *buffer, u32 *size_read)
{
int retval;
/* don't read past the end of a section */
if (offset + size > image->sections[section].size)
{
DEBUG("read past end of section: 0x%8.8x + 0x%8.8x > 0x%8.8x",
offset, size, image->sections[section].size);
return ERROR_INVALID_ARGUMENTS;
}
if (image->type == IMAGE_BINARY)
{
image_binary_t *image_binary = image->type_private;
@@ -774,9 +792,6 @@ int image_read_section(image_t *image, int section, u32 offset, u32 size, u8 *bu
if (section != 0)
return ERROR_INVALID_ARGUMENTS;
if ((offset > image->sections[0].size) || (offset + size > image->sections[0].size))
return ERROR_INVALID_ARGUMENTS;
/* seek to offset */
if ((retval = fileio_seek(&image_binary->fileio, offset)) != ERROR_OK)
{
@@ -849,6 +864,44 @@ int image_read_section(image_t *image, int section, u32 offset, u32 size, u8 *bu
return ERROR_OK;
}
else if (image->type == IMAGE_BUILDER)
{
memcpy(buffer, (u8*)image->sections[section].private + offset, size);
*size_read = size;
image->error_str[0] = '\0';
return ERROR_OK;
}
return ERROR_OK;
}
int image_add_section(image_t *image, u32 base, u32 size, int flags, u8 *data)
{
/* only image builder supports adding sections */
if (image->type != IMAGE_BUILDER)
return ERROR_INVALID_ARGUMENTS;
/* see if it's enough to extend an existing section */
if (((image->sections[image->num_sections - 1].base_address + image->sections[image->num_sections - 1].size) == base)
&& (image->sections[image->num_sections - 1].flags == flags))
{
u32 old_size = image->sections[image->num_sections - 1].size;
image->sections[image->num_sections - 1].size += size;
image->sections[image->num_sections - 1].private = realloc(image->sections[image->num_sections - 1].private, image->sections[image->num_sections - 1].size);
memcpy((u8*)image->sections[image->num_sections - 1].private + old_size, data, size);
return ERROR_OK;
}
/* allocate new section */
image->num_sections++;
image->sections = realloc(image->sections, sizeof(image_section_t) * image->num_sections);
image->sections[image->num_sections - 1].base_address = base;
image->sections[image->num_sections - 1].size = size;
image->sections[image->num_sections - 1].flags = flags;
image->sections[image->num_sections - 1].private = malloc(sizeof(u8) * size);
memcpy((u8*)image->sections[image->num_sections - 1].private, data, size);
return ERROR_OK;
}
@@ -898,6 +951,15 @@ int image_close(image_t *image)
if (image_mot->buffer)
free(image_mot->buffer);
}
else if (image->type == IMAGE_BUILDER)
{
int i;
for (i = 0; i < image->num_sections; i++)
{
free(image->sections[i].private);
}
}
if (image->type_private)
free(image->type_private);

View File

@@ -42,7 +42,8 @@ typedef enum image_type
IMAGE_IHEX, /* intel hex-record format */
IMAGE_MEMORY, /* target-memory pseudo-image */
IMAGE_ELF, /* ELF binary */
IMAGE_SRECORD /* motorola s19 */
IMAGE_SRECORD, /* motorola s19 */
IMAGE_BUILDER, /* when building a new image */
} image_type_t;
typedef struct image_section_s
@@ -102,6 +103,7 @@ typedef struct image_mot_s
extern int image_open(image_t *image, char *url, char *type_string);
extern int image_read_section(image_t *image, int section, u32 offset, u32 size, u8 *buffer, u32 *size_read);
extern int image_close(image_t *image);
extern int image_add_section(image_t *image, u32 base, u32 size, int flags, u8 *data);
#define ERROR_IMAGE_FORMAT_ERROR (-1400)
#define ERROR_IMAGE_TYPE_UNKNOWN (-1401)

View File

@@ -21,6 +21,7 @@
#include "config.h"
#endif
#define _GNU_SOURCE
#include <string.h>
#include <errno.h>
@@ -34,6 +35,7 @@
#include "register.h"
#include "jtag.h"
#include "arm7_9_common.h"
#include "replacements.h"
#include <stdlib.h>
@@ -78,7 +80,6 @@ int oocd_trace_read_memory(oocd_trace_t *oocd_trace, u8 *data, u32 address, u32
{
size_t bytes_written, bytes_read, bytes_to_read;
u8 cmd;
int i;
oocd_trace_write_reg(oocd_trace, OOCD_TRACE_ADDRESS, address);
oocd_trace_write_reg(oocd_trace, OOCD_TRACE_SDRAM_COUNTER, size);
@@ -105,7 +106,7 @@ int oocd_trace_init(etm_context_t *etm_ctx)
{
u8 trash[256];
oocd_trace_t *oocd_trace = etm_ctx->capture_driver_priv;
size_t bytes_written, bytes_read, bytes_to_read;
size_t bytes_read;
oocd_trace->tty_fd = open(oocd_trace->tty, O_RDWR | O_NOCTTY | O_NONBLOCK);
@@ -378,7 +379,6 @@ int handle_oocd_trace_resync_command(struct command_context_s *cmd_ctx, char *cm
armv4_5_common_t *armv4_5;
arm7_9_common_t *arm7_9;
oocd_trace_t *oocd_trace;
u32 status;
size_t bytes_written;
u8 cmd_array[1];

View File

@@ -23,6 +23,7 @@
#include "replacements.h"
#include "target.h"
#include "target_request.h"
#include "log.h"
#include "configuration.h"
@@ -883,6 +884,8 @@ int target_register_user_commands(struct command_context_s *cmd_ctx)
register_command(cmd_ctx, NULL, "load_binary", handle_load_image_command, COMMAND_EXEC, "[DEPRECATED] load_binary <file> <address>");
register_command(cmd_ctx, NULL, "dump_binary", handle_dump_image_command, COMMAND_EXEC, "[DEPRECATED] dump_binary <file> <address> <size>");
target_request_register_commands(cmd_ctx);
return ERROR_OK;
}
@@ -1000,6 +1003,13 @@ int handle_target_command(struct command_context_s *cmd_ctx, char *cmd, char **a
(*last_target_p)->next = NULL;
(*last_target_p)->arch_info = NULL;
/* initialize trace information */
(*last_target_p)->trace_info = malloc(sizeof(trace_t));
(*last_target_p)->trace_info->num_trace_points = 0;
(*last_target_p)->trace_info->trace_points = NULL;
(*last_target_p)->trace_info->trace_history_size = 0;
(*last_target_p)->trace_info->trace_history = NULL;
(*last_target_p)->type->target_command(cmd_ctx, cmd, args, argc, *last_target_p);
found = 1;

View File

@@ -23,6 +23,7 @@
#include "register.h"
#include "breakpoints.h"
#include "algorithm.h"
#include "trace.h"
#include "command.h"
#include "types.h"
@@ -101,6 +102,9 @@ typedef struct target_type_s
/* architecture specific status reply */
int (*arch_state)(struct target_s *target, char *buf, int buf_size);
/* target request support */
int (*target_request_data)(struct target_s *target, u32 size, u8 *buffer);
/* target execution control */
int (*halt)(struct target_s *target);
int (*resume)(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution);
@@ -155,12 +159,14 @@ typedef struct target_s
u32 working_area_size; /* size in bytes */
u32 backup_working_area; /* whether the content of the working area has to be preserved */
struct working_area_s *working_areas;/* list of allocated working areas */
enum target_debug_reason debug_reason; /* reason why the target entered debug state */
enum target_debug_reason debug_reason;/* reason why the target entered debug state */
enum target_endianess endianness; /* target endianess */
enum target_state state; /* the current backend-state (running, halted, ...) */
struct reg_cache_s *reg_cache; /* the first register cache of the target (core regs) */
struct breakpoint_s *breakpoints; /* list of breakpoints */
struct watchpoint_s *watchpoints; /* list of watchpoints */
struct trace_s *trace_info; /* generic trace information */
struct debug_msg_receiver_s *dbgmsg;/* list of debug message receivers */
void *arch_info; /* architecture specific information */
struct target_s *next; /* next target in list */
} target_t;

270
src/target/target_request.c Normal file
View File

@@ -0,0 +1,270 @@
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "replacements.h"
#include "log.h"
#include "target.h"
#include "target_request.h"
#include "binarybuffer.h"
#include "command.h"
#include <stdlib.h>
#include <string.h>
command_t *target_request_cmd = NULL;
int target_asciimsg(target_t *target, u32 length)
{
char *msg = malloc(CEIL(length + 1, 4) * 4);
debug_msg_receiver_t *c = target->dbgmsg;
target->type->target_request_data(target, CEIL(length, 4), (u8*)msg);
msg[length] = 0;
DEBUG("%s", msg);
while (c)
{
command_print(c->cmd_ctx, "%s", msg);
c = c->next;
}
return ERROR_OK;
}
int target_hexmsg(target_t *target, int size, u32 length)
{
if (size == 1)
{
u8 *data = malloc(CEIL(length * sizeof(u8), 4) * 4);
target->type->target_request_data(target, CEIL(length * sizeof(u8), 4), (u8*)data);
free(data);
}
else if (size == 2)
{
u16 *data = malloc(CEIL(length * sizeof(u16), 4) * 4);
target->type->target_request_data(target, CEIL(length * sizeof(u16), 4), (u8*)data);
free(data);
}
else if (size == 4)
{
u32 *data = malloc(CEIL(length * sizeof(u32), 4) * 4);
target->type->target_request_data(target, CEIL(length * sizeof(u32), 4), (u8*)data);
free(data);
}
else
{
ERROR("invalid debug message type");
}
return ERROR_OK;
}
/* handle requests from the target received by a target specific
* side-band channel (e.g. ARM7/9 DCC)
*/
int target_request(target_t *target, u32 request)
{
target_req_cmd_t target_req_cmd = request & 0xff;
switch (target_req_cmd)
{
case TARGET_REQ_TRACEMSG:
DEBUG("tracepoint: %i", (request & 0xffffff00) >> 8);
break;
case TARGET_REQ_DEBUGMSG:
if (((request & 0xff00) >> 8) == 0)
{
target_asciimsg(target, (request & 0xffff0000) >> 16);
}
else
{
target_hexmsg(target, (request & 0xff00) >> 8, (request & 0xffff0000) >> 16);
}
break;
/* case TARGET_REQ_SEMIHOSTING:
* break;
*/
default:
ERROR("unknown target request: %2.2x", target_req_cmd);
break;
}
return ERROR_OK;
}
int add_debug_msg_receiver(struct command_context_s *cmd_ctx, target_t *target)
{
debug_msg_receiver_t **p = &target->dbgmsg;
if (target == NULL)
return ERROR_INVALID_ARGUMENTS;
/* see if there's already a list */
if (*p)
{
/* find end of linked list */
p = &target->dbgmsg;
while ((*p)->next)
p = &((*p)->next);
p = &((*p)->next);
}
/* add new debug message receiver */
(*p) = malloc(sizeof(debug_msg_receiver_t));
(*p)->cmd_ctx = cmd_ctx;
(*p)->next = NULL;
return ERROR_OK;
}
debug_msg_receiver_t* find_debug_msg_receiver(struct command_context_s *cmd_ctx, target_t *target)
{
int all_targets = 0;
debug_msg_receiver_t **p = &target->dbgmsg;
/* if no target has been specified search all of them */
if (target == NULL)
{
/* if no targets haven been specified */
if (targets == NULL)
return NULL;
target = targets;
all_targets = 1;
}
do
{
while (*p)
{
if ((*p)->cmd_ctx == cmd_ctx)
{
return *p;
}
p = &((*p)->next);
}
target = target->next;
} while (target && all_targets);
return NULL;
}
int delete_debug_msg_receiver(struct command_context_s *cmd_ctx, target_t *target)
{
debug_msg_receiver_t **p;
debug_msg_receiver_t *c;
int all_targets = 0;
/* if no target has been specified search all of them */
if (target == NULL)
{
/* if no targets haven been specified */
if (targets == NULL)
return ERROR_OK;
target = targets;
all_targets = 1;
}
do
{
while (c)
{
debug_msg_receiver_t *next = c->next;
if (c->cmd_ctx == cmd_ctx)
{
*p = next;
free(c);
return ERROR_OK;
}
else
p = &(c->next);
c = next;
}
target = target->next;
} while (target && all_targets);
return ERROR_OK;
}
int handle_target_request_debugmsgs_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
target_t *target = get_current_target(cmd_ctx);
int receiving = 0;
/* see if reciever is already registered */
if (find_debug_msg_receiver(cmd_ctx, target) != NULL)
receiving = 1;
if (argc > 0)
{
if (!strcmp(args[0], "enable"))
{
/* don't register if this command context is already receiving */
if (!receiving)
{
receiving = 1;
add_debug_msg_receiver(cmd_ctx, target);
}
}
else if (!strcmp(args[0], "disable"))
{
/* no need to delete a receiver if none is registered */
if (receiving)
{
receiving = 0;
delete_debug_msg_receiver(cmd_ctx, target);
}
}
else
{
command_print(cmd_ctx, "usage: target_request debugmsgs ['enable'|'disable']");
}
}
command_print(cmd_ctx, "receiving debug messages from current target %s",
(receiving) ? "enabled" : "disabled");
return ERROR_OK;
}
int target_request_register_commands(struct command_context_s *cmd_ctx)
{
target_request_cmd =
register_command(cmd_ctx, NULL, "target_request", NULL, COMMAND_ANY, "target_request commands");
register_command(cmd_ctx, target_request_cmd, "debugmsgs", handle_target_request_debugmsgs_command,
COMMAND_EXEC, "enable/disable reception of debug messgages from target");
return ERROR_OK;
}

View File

@@ -0,0 +1,42 @@
/***************************************************************************
* Copyright (C) 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef TARGET_REQUEST_H
#define TARGET_REQUEST_H
#include "command.h"
typedef enum target_req_cmd
{
TARGET_REQ_TRACEMSG,
TARGET_REQ_DEBUGMSG,
/* TARGET_REQ_SEMIHOSTING, */
} target_req_cmd_t;
typedef struct debug_msg_receiver_s
{
command_context_t *cmd_ctx;
struct debug_msg_receiver_s *next;
} debug_msg_receiver_t;
extern int target_request(target_t *target, u32 request);
extern int delete_debug_msg_receiver(struct command_context_s *cmd_ctx, target_t *target);
extern int target_request_register_commands(struct command_context_s *cmd_ctx);
#endif /* TARGET_REQUEST_H */

69
src/target/trace.c Normal file
View File

@@ -0,0 +1,69 @@
/***************************************************************************
* Copyright (C) 2005, 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "replacements.h"
#include "log.h"
#include "trace.h"
#include "target.h"
#include <stdlib.h>
int handle_trace_history_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
{
target_t *target = get_current_target(cmd_ctx);
trace_t *trace = target->trace_info;
if (argc > 0)
{
if (trace->trace_history)
free(trace->trace_history);
trace->trace_history_size = strtoul(args[0], NULL, 0);
trace->trace_history = malloc(sizeof(u32) * trace->trace_history_size);
command_print(cmd_ctx, "new trace history size: %i", trace->trace_history_size);
}
else
{
int i;
for (i = 0; i < trace->trace_history_size; i++)
{
if (trace->trace_history[i] < trace->num_trace_points)
{
u32 address;
address = trace->trace_points[trace->trace_history[i]].address;
command_print(cmd_ctx, "trace point %i: 0x%8.8x",
trace->trace_history[i],
address);
}
else
{
command_print(cmd_ctx, "trace point %i: -not defined-", trace->trace_history[i]);
}
}
}
return ERROR_OK;
}

View File

@@ -22,6 +22,20 @@
#include "target.h"
typedef struct trace_point_s
{
u32 address;
u64 hit_counter;
} trace_point_t;
typedef struct trace_s
{
int num_trace_points;
trace_point_t *trace_points;
int trace_history_size;
u32 *trace_history;
} trace_t;
typedef enum trace_status
{
TRACE_IDLE = 0x0,

View File

@@ -84,6 +84,8 @@ int xscale_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint);
void xscale_enable_watchpoints(struct target_s *target);
void xscale_enable_breakpoints(struct target_s *target);
int xscale_read_trace(target_t *target);
target_type_t xscale_target =
{
.name = "xscale",
@@ -91,6 +93,8 @@ target_type_t xscale_target =
.poll = xscale_poll,
.arch_state = xscale_arch_state,
.target_request_data = NULL,
.halt = xscale_halt,
.resume = xscale_resume,
.step = xscale_step,