X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Ftarget.c;h=b71d839367e414658856d23101c56906da371e38;hp=5cff9d081ad27cecb6c0069780553ab8fbeb80b9;hb=28f088dc661d4c0e50c60876a5d6eec13d144c0c;hpb=778b789c8ed44faadfb572c9a0eebb4e4a76a3aa diff --git a/src/target/target.c b/src/target/target.c index 5cff9d081a..b71d839367 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -14,6 +14,12 @@ * 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 * @@ -44,8 +50,13 @@ #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, @@ -70,6 +81,7 @@ extern struct target_type arm11_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; @@ -92,6 +104,7 @@ static struct target_type *target_types[] = &mips_m4k_target, &avr_target, &dsp563xx_target, + &dsp5680xx_target, &testee_target, &avr32_ap7k_target, NULL, @@ -278,6 +291,15 @@ uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer) 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) { @@ -302,6 +324,15 @@ void target_buffer_set_u32(struct target *target, uint8_t *buffer, uint32_t valu 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) { @@ -317,6 +348,38 @@ static void target_buffer_set_u8(struct target *target, uint8_t *buffer, uint8_t *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) { @@ -593,7 +656,7 @@ const char *target_type_name(struct target *target) 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)) { @@ -683,19 +746,19 @@ static int target_read_phys_memory(struct target *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); } @@ -703,7 +766,7 @@ int target_bulk_write_memory(struct target *target, 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; } @@ -761,7 +824,7 @@ err_read_phys_memory(struct target *target, uint32_t address, 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; @@ -845,6 +908,13 @@ static int target_init_one(struct command_context *cmd_ctx, 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; } @@ -1213,7 +1283,7 @@ int target_alloc_working_area_try(struct target *target, uint32_t size, struct w } /* mark as used, and return the new (reused) area */ - new_wa->free = 0; + new_wa->free = false; *area = new_wa; /* user pointer */ @@ -1247,7 +1317,7 @@ static int target_free_working_area_restore(struct target *target, struct workin return retval; } - area->free = 1; + area->free = true; /* mark user pointer invalid */ *area->user = NULL; @@ -1311,9 +1381,8 @@ int target_arch_state(struct target *target) * 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); @@ -1336,6 +1405,13 @@ int target_write_buffer(struct target *target, uint32_t address, uint32_t size, 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); @@ -1386,7 +1462,7 @@ int target_write_buffer(struct target *target, uint32_t address, uint32_t size, return retval; } - return ERROR_OK; + return retval; } /* Single aligned words are guaranteed to use 16 or 32 bit access @@ -1395,7 +1471,6 @@ int target_write_buffer(struct target *target, uint32_t address, uint32_t size, */ 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); @@ -1418,6 +1493,13 @@ int target_read_buffer(struct target *target, uint32_t address, uint32_t size, u 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); @@ -1502,7 +1584,7 @@ int target_checksum_memory(struct target *target, uint32_t address, uint32_t siz return retval; } - /* convert to target endianess */ + /* convert to target endianness */ for (i = 0; i < (size/sizeof(uint32_t)); i++) { uint32_t target_data; @@ -2314,7 +2396,7 @@ COMMAND_HANDLER(handle_md_command) 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--; @@ -2349,10 +2431,10 @@ COMMAND_HANDLER(handle_md_command) } 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); } @@ -3660,7 +3742,10 @@ enum target_cfg_param { TCFG_WORK_AREA_BACKUP, TCFG_ENDIAN, TCFG_VARIANT, + TCFG_COREID, TCFG_CHAIN_POSITION, + TCFG_DBGBASE, + TCFG_RTOS, }; static Jim_Nvp nvp_config_opts[] = { @@ -3672,8 +3757,10 @@ 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 } }; @@ -3881,6 +3968,7 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target) /* loop for more e*/ break; + case TCFG_ENDIAN: if (goi->isconfigure) { e = Jim_GetOpt_Nvp(goi, nvp_target_endian, &n); @@ -3924,6 +4012,23 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target) 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; @@ -3947,6 +4052,34 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target) 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) */ @@ -4221,9 +4354,6 @@ static int jim_target_examine(Jim_Interp *interp, int argc, Jim_Obj *const *argv 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; @@ -4263,9 +4393,6 @@ static int jim_target_poll(Jim_Interp *interp, int argc, Jim_Obj *const *argv) } 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; @@ -4640,6 +4767,9 @@ static int target_create(Jim_GetOptInfo *goi) /* 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; @@ -4672,6 +4802,9 @@ static int target_create(Jim_GetOptInfo *goi) 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); @@ -4798,6 +4931,61 @@ static int jim_target_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) 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;itarget = 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; @@ -4913,6 +5101,14 @@ static const struct command_registration target_subcommand_handlers[] = { .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 };