Merge remote branch 'origin/master' into HEAD
[fw/openocd] / src / target / target.c
index a282aab6ad908919c9307b981022267aa616d176..026ca13b9c41875b43bac347893d7b42b3b50bd3 100644 (file)
 #include "image.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,
@@ -278,6 +282,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 +315,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)
 {
@@ -593,7 +615,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 +705,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);
 }
@@ -761,7 +783,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 +867,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 +1242,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 +1276,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 +1340,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 +1364,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 +1421,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 +1430,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 +1452,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 +1543,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 +2355,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 +2390,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);
 }
@@ -3077,7 +3118,7 @@ static void writeGmon(uint32_t *samples, uint32_t sampleNum, const char *filenam
 
        int addressSpace = (max-min + 1);
 
-       static const uint32_t maxBuckets = 256 * 1024; /* maximum buckets. */
+       static const uint32_t maxBuckets = 16 * 1024; /* maximum buckets. */
        uint32_t length = addressSpace;
        if (length > maxBuckets)
        {
@@ -3104,7 +3145,7 @@ static void writeGmon(uint32_t *samples, uint32_t sampleNum, const char *filenam
        writeLong(f, min);                      /* low_pc */
        writeLong(f, max);                      /* high_pc */
        writeLong(f, length);           /* # of samples */
-       writeLong(f, 64000000);         /* 64MHz */
+       writeLong(f, 100);                      /* KLUDGE! We lie, ca. 100Hz best case. */
        writeString(f, "seconds");
        for (i = 0; i < (15-strlen("seconds")); i++)
                writeData(f, &zero, 1);
@@ -3660,7 +3701,9 @@ enum target_cfg_param {
        TCFG_WORK_AREA_BACKUP,
        TCFG_ENDIAN,
        TCFG_VARIANT,
+       TCFG_COREID,
        TCFG_CHAIN_POSITION,
+       TCFG_DBGBASE,
 };
 
 static Jim_Nvp nvp_config_opts[] = {
@@ -3672,8 +3715,9 @@ 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 = NULL, .value = -1 }
 };
 
@@ -3924,6 +3968,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 = (int)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 +4008,22 @@ 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;
                }
        } /* while (goi->argc) */
 
@@ -4221,9 +4298,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 +4337,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 +4711,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;
@@ -4964,9 +5038,10 @@ COMMAND_HANDLER(handle_fast_load_image_command)
        struct duration bench;
        duration_start(&bench);
 
-       if (image_open(&image, CMD_ARGV[0], (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL) != ERROR_OK)
+       retval = image_open(&image, CMD_ARGV[0], (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL);
+       if (retval != ERROR_OK)
        {
-               return ERROR_OK;
+               return retval;
        }
 
        image_size = 0x0;
@@ -4975,6 +5050,7 @@ COMMAND_HANDLER(handle_fast_load_image_command)
        fastload = (struct FastLoad *)malloc(sizeof(struct FastLoad)*image.num_sections);
        if (fastload == NULL)
        {
+               command_print(CMD_CTX, "out of memory");
                image_close(&image);
                return ERROR_FAIL;
        }
@@ -4986,6 +5062,7 @@ COMMAND_HANDLER(handle_fast_load_image_command)
                {
                        command_print(CMD_CTX, "error allocating buffer for section (%d bytes)",
                                                  (int)(image.sections[i].size));
+                       retval = ERROR_FAIL;
                        break;
                }
 
@@ -5021,6 +5098,9 @@ COMMAND_HANDLER(handle_fast_load_image_command)
                        if (fastload[i].data == NULL)
                        {
                                free(buffer);
+                               command_print(CMD_CTX, "error allocating buffer for section (%d bytes)",
+                                                         length);
+                               retval = ERROR_FAIL;
                                break;
                        }
                        memcpy(fastload[i].data, buffer + offset, length);
@@ -5075,14 +5155,18 @@ COMMAND_HANDLER(handle_fast_load_command)
                command_print(CMD_CTX, "Write to 0x%08x, length 0x%08x",
                                          (unsigned int)(fastload[i].address),
                                          (unsigned int)(fastload[i].length));
-               if (retval == ERROR_OK)
+               retval = target_write_buffer(target, fastload[i].address, fastload[i].length, fastload[i].data);
+               if (retval != ERROR_OK)
                {
-                       retval = target_write_buffer(target, fastload[i].address, fastload[i].length, fastload[i].data);
+                       break;
                }
                size += fastload[i].length;
        }
-       int after = timeval_ms();
-       command_print(CMD_CTX, "Loaded image %f kBytes/s", (float)(size/1024.0)/((float)(after-ms)/1000.0));
+       if (retval == ERROR_OK)
+       {
+               int after = timeval_ms();
+               command_print(CMD_CTX, "Loaded image %f kBytes/s", (float)(size/1024.0)/((float)(after-ms)/1000.0));
+       }
        return retval;
 }