* Copyright (C) 2008 by Rick Altherr *
* kc8apf@kc8apf.net> *
* *
+ * Copyright (C) 2011 by Broadcom Corporation *
+ * Evan Hunter - ehunter@broadcom.com *
+ * *
+ * Copyright (C) ST-Ericsson SA 2011 *
+ * michel.jaouen@stericsson.com : smp minimum support *
+ * *
* 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 *
#include "register.h"
#include "trace.h"
#include "image.h"
+#include "rtos/rtos.h"
+static int target_read_buffer_default(struct target *target, uint32_t address,
+ uint32_t size, uint8_t *buffer);
+static int target_write_buffer_default(struct target *target, uint32_t address,
+ uint32_t size, const uint8_t *buffer);
static int target_array2mem(Jim_Interp *interp, struct target *target,
int argc, Jim_Obj *const *argv);
static int target_mem2array(Jim_Interp *interp, struct target *target,
extern struct target_type mips_m4k_target;
extern struct target_type avr_target;
extern struct target_type dsp563xx_target;
+extern struct target_type dsp5680xx_target;
extern struct target_type testee_target;
extern struct target_type avr32_ap7k_target;
&mips_m4k_target,
&avr_target,
&dsp563xx_target,
+ &dsp5680xx_target,
&testee_target,
&avr32_ap7k_target,
NULL,
return be_to_h_u32(buffer);
}
+/* read a uint24_t from a buffer in target memory endianness */
+uint32_t target_buffer_get_u24(struct target *target, const uint8_t *buffer)
+{
+ if (target->endianness == TARGET_LITTLE_ENDIAN)
+ return le_to_h_u24(buffer);
+ else
+ return be_to_h_u24(buffer);
+}
+
/* read a uint16_t from a buffer in target memory endianness */
uint16_t target_buffer_get_u16(struct target *target, const uint8_t *buffer)
{
h_u32_to_be(buffer, value);
}
+/* write a uint24_t to a buffer in target memory endianness */
+void target_buffer_set_u24(struct target *target, uint8_t *buffer, uint32_t value)
+{
+ if (target->endianness == TARGET_LITTLE_ENDIAN)
+ h_u24_to_le(buffer, value);
+ else
+ h_u24_to_be(buffer, value);
+}
+
/* write a uint16_t to a buffer in target memory endianness */
void target_buffer_set_u16(struct target *target, uint8_t *buffer, uint16_t value)
{
*buffer = value;
}
+/* write a uint32_t array to a buffer in target memory endianness */
+void target_buffer_get_u32_array(struct target *target, const uint8_t *buffer, uint32_t count, uint32_t *dstbuf)
+{
+ uint32_t i;
+ for(i = 0; i < count; i ++)
+ dstbuf[i] = target_buffer_get_u32(target,&buffer[i*4]);
+}
+
+/* write a uint16_t array to a buffer in target memory endianness */
+void target_buffer_get_u16_array(struct target *target, const uint8_t *buffer, uint32_t count, uint16_t *dstbuf)
+{
+ uint32_t i;
+ for(i = 0; i < count; i ++)
+ dstbuf[i] = target_buffer_get_u16(target,&buffer[i*2]);
+}
+
+/* write a uint32_t array to a buffer in target memory endianness */
+void target_buffer_set_u32_array(struct target *target, uint8_t *buffer, uint32_t count, uint32_t *srcbuf)
+{
+ uint32_t i;
+ for(i = 0; i < count; i ++)
+ target_buffer_set_u32(target,&buffer[i*4],srcbuf[i]);
+}
+
+/* write a uint16_t array to a buffer in target memory endianness */
+void target_buffer_set_u16_array(struct target *target, uint8_t *buffer, uint32_t count, uint16_t *srcbuf)
+{
+ uint32_t i;
+ for(i = 0; i < count; i ++)
+ target_buffer_set_u16(target,&buffer[i*2],srcbuf[i]);
+}
+
/* return a pointer to a configured target; id is name or number */
struct target *get_target(const char *id)
{
return target->type->name;
}
-static int target_write_memory_imp(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+static int target_write_memory_imp(struct target *target, uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
{
if (!target_was_examined(target))
{
}
int target_write_memory(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+ uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
{
return target->type->write_memory(target, address, size, count, buffer);
}
static int target_write_phys_memory(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+ uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
{
return target->type->write_phys_memory(target, address, size, count, buffer);
}
int target_bulk_write_memory(struct target *target,
- uint32_t address, uint32_t count, uint8_t *buffer)
+ uint32_t address, uint32_t count, const uint8_t *buffer)
{
return target->type->bulk_write_memory(target, address, count, buffer);
}
int target_add_breakpoint(struct target *target,
struct breakpoint *breakpoint)
{
- if (target->state != TARGET_HALTED) {
+ if ((target->state != TARGET_HALTED)&&(breakpoint->type!=BKPT_HARD)) {
LOG_WARNING("target %s is not halted", target->cmd_name);
return ERROR_TARGET_NOT_HALTED;
}
static int
err_write_phys_memory(struct target *target, uint32_t address,
- uint32_t size, uint32_t count, uint8_t *buffer)
+ uint32_t size, uint32_t count, const uint8_t *buffer)
{
LOG_ERROR("Not implemented: %s", __func__);
return ERROR_FAIL;
type->read_phys_memory = type->read_memory;
type->virt2phys = identity_virt2phys;
}
+
+ if (target->type->read_buffer == NULL)
+ target->type->read_buffer = target_read_buffer_default;
+
+ if (target->type->write_buffer == NULL)
+ target->type->write_buffer = target_write_buffer_default;
+
return ERROR_OK;
}
}
/* mark as used, and return the new (reused) area */
- new_wa->free = 0;
+ new_wa->free = false;
*area = new_wa;
/* user pointer */
return retval;
}
- area->free = 1;
+ area->free = true;
/* mark user pointer invalid */
*area->user = NULL;
* mode respectively, otherwise data is handled as quickly as
* possible
*/
-int target_write_buffer(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer)
+int target_write_buffer(struct target *target, uint32_t address, uint32_t size, const uint8_t *buffer)
{
- int retval;
LOG_DEBUG("writing buffer of %i byte at 0x%8.8x",
(int)size, (unsigned)address);
return ERROR_FAIL;
}
+ return target->type->write_buffer(target, address, size, buffer);
+}
+
+static int target_write_buffer_default(struct target *target, uint32_t address, uint32_t size, const uint8_t *buffer)
+{
+ int retval = ERROR_OK;
+
if (((address % 2) == 0) && (size == 2))
{
return target_write_memory(target, address, 2, 1, buffer);
return retval;
}
- return ERROR_OK;
+ return retval;
}
/* Single aligned words are guaranteed to use 16 or 32 bit access
*/
int target_read_buffer(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer)
{
- int retval;
LOG_DEBUG("reading buffer of %i byte at 0x%8.8x",
(int)size, (unsigned)address);
return ERROR_FAIL;
}
+ return target->type->read_buffer(target, address, size, buffer);
+}
+
+static int target_read_buffer_default(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer)
+{
+ int retval = ERROR_OK;
+
if (((address % 2) == 0) && (size == 2))
{
return target_read_memory(target, address, 2, 1, buffer);
return retval;
}
- /* convert to target endianess */
+ /* convert to target endianness */
for (i = 0; i < (size/sizeof(uint32_t)); i++)
{
uint32_t target_data;
bool physical=strcmp(CMD_ARGV[0], "phys")==0;
int (*fn)(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
+ uint32_t address, uint32_t size_value, uint32_t count, uint8_t *buffer);
if (physical)
{
CMD_ARGC--;
}
typedef int (*target_write_fn)(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
+ uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer);
static int target_write_memory_fast(struct target *target,
- uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+ uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer)
{
return target_write_buffer(target, address, size * count, buffer);
}
TCFG_WORK_AREA_BACKUP,
TCFG_ENDIAN,
TCFG_VARIANT,
+ TCFG_COREID,
TCFG_CHAIN_POSITION,
+ TCFG_DBGBASE,
+ TCFG_RTOS,
};
static Jim_Nvp nvp_config_opts[] = {
{ .name = "-work-area-backup", .value = TCFG_WORK_AREA_BACKUP },
{ .name = "-endian" , .value = TCFG_ENDIAN },
{ .name = "-variant", .value = TCFG_VARIANT },
+ { .name = "-coreid", .value = TCFG_COREID },
{ .name = "-chain-position", .value = TCFG_CHAIN_POSITION },
-
+ { .name = "-dbgbase", .value = TCFG_DBGBASE },
+ { .name = "-rtos", .value = TCFG_RTOS },
{ .name = NULL, .value = -1 }
};
/* loop for more e*/
break;
+
case TCFG_ENDIAN:
if (goi->isconfigure) {
e = Jim_GetOpt_Nvp(goi, nvp_target_endian, &n);
Jim_SetResultString(goi->interp, target->variant,-1);
/* loop for more */
break;
+
+ case TCFG_COREID:
+ if (goi->isconfigure) {
+ e = Jim_GetOpt_Wide(goi, &w);
+ if (e != JIM_OK) {
+ return e;
+ }
+ target->coreid = (int32_t)w;
+ } else {
+ if (goi->argc != 0) {
+ goto no_params;
+ }
+ }
+ Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_size));
+ /* loop for more */
+ break;
+
case TCFG_CHAIN_POSITION:
if (goi->isconfigure) {
Jim_Obj *o_t;
Jim_SetResultString(goi->interp, target->tap->dotted_name, -1);
/* loop for more e*/
break;
+ case TCFG_DBGBASE:
+ if (goi->isconfigure) {
+ e = Jim_GetOpt_Wide(goi, &w);
+ if (e != JIM_OK) {
+ return e;
+ }
+ target->dbgbase = (uint32_t)w;
+ target->dbgbase_set = true;
+ } else {
+ if (goi->argc != 0) {
+ goto no_params;
+ }
+ }
+ Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->dbgbase));
+ /* loop for more */
+ break;
+
+ case TCFG_RTOS:
+ /* RTOS */
+ {
+ int result = rtos_create( goi, target );
+ if ( result != JIM_OK )
+ {
+ return result;
+ }
+ }
+ /* loop for more */
+ break;
}
} /* while (goi->argc) */
int e = target->type->examine(target);
if (e != ERROR_OK)
{
- Jim_Obj *eObj = Jim_NewIntObj(interp, e);
- Jim_SetResultFormatted(interp, "examine-fails: %#s", eObj);
- Jim_FreeNewObj(interp, eObj);
return JIM_ERR;
}
return JIM_OK;
}
if (e != ERROR_OK)
{
- Jim_Obj *eObj = Jim_NewIntObj(interp, e);
- Jim_SetResultFormatted(interp, "poll-fails: %#s", eObj);
- Jim_FreeNewObj(interp, eObj);
return JIM_ERR;
}
return JIM_OK;
/* will be set by "-endian" */
target->endianness = TARGET_ENDIAN_UNKNOWN;
+ /* default to first core, override with -coreid */
+ target->coreid = 0;
+
target->working_area = 0x0;
target->working_area_size = 0x0;
target->working_areas = NULL;
target->endianness = TARGET_ENDIAN_UNKNOWN;
+ target->rtos = NULL;
+ target->rtos_auto_detect = false;
+
/* Do the rest as "configure" options */
goi->isconfigure = 1;
e = target_configure(goi, target);
return JIM_OK;
}
+static int jim_target_smp(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+{
+ int i;
+ const char *targetname;
+ int retval,len;
+ struct target *target;
+ struct target_list *head, *curr, *new;
+ curr = (struct target_list*) NULL;
+ head = (struct target_list*) NULL;
+ new = (struct target_list*) NULL;
+
+ retval = 0;
+ LOG_DEBUG("%d",argc);
+ /* argv[1] = target to associate in smp
+ * argv[2] = target to assoicate in smp
+ * argv[3] ...
+ */
+
+ for(i=1;i<argc;i++)
+ {
+
+ targetname = Jim_GetString(argv[i], &len);
+ target = get_target(targetname);
+ LOG_DEBUG("%s ",targetname);
+ if (target)
+ {
+ new=malloc(sizeof(struct target_list));
+ new->target = target;
+ new->next = (struct target_list*)NULL;
+ if (head == (struct target_list*)NULL)
+ {
+ head = new;
+ curr = head;
+ }
+ else
+ {
+ curr->next = new;
+ curr = new;
+ }
+ }
+ }
+ /* now parse the list of cpu and put the target in smp mode*/
+ curr=head;
+
+ while(curr!=(struct target_list *)NULL)
+ {
+ target=curr->target;
+ target->smp = 1;
+ target->head = head;
+ curr=curr->next;
+ }
+ return retval;
+}
+
+
static int jim_target_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
Jim_GetOptInfo goi;
.help = "Returns the number of targets as an integer "
"(DEPRECATED)",
},
+ {
+ .name = "smp",
+ .mode = COMMAND_ANY,
+ .jim_handler = jim_target_smp,
+ .usage = "targetname1 targetname2 ...",
+ .help = "gather several target in a smp list"
+ },
+
COMMAND_REGISTRATION_DONE
};