fast_load profiling tool moved to target.c
git-svn-id: svn://svn.berlios.de/openocd/trunk@1241 b42882b7-edfa-0310-969c-e2dbd0fdcd60__archive__
parent
508ed7a7c6
commit
459d03e3bb
196
src/ecosboard.c
196
src/ecosboard.c
|
@ -121,196 +121,6 @@ static bool writeLog = true;
|
||||||
|
|
||||||
char hwaddr[512];
|
char hwaddr[512];
|
||||||
|
|
||||||
struct FastLoad
|
|
||||||
{
|
|
||||||
u32 address;
|
|
||||||
u8 *data;
|
|
||||||
int length;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
static int fastload_num;
|
|
||||||
static struct FastLoad *fastload;
|
|
||||||
|
|
||||||
static void free_fastload()
|
|
||||||
{
|
|
||||||
if (fastload!=NULL)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i=0; i<fastload_num; i++)
|
|
||||||
{
|
|
||||||
if (fastload[i].data)
|
|
||||||
free(fastload[i].data);
|
|
||||||
}
|
|
||||||
free(fastload);
|
|
||||||
fastload=NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int handle_fast_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
|
||||||
{
|
|
||||||
u8 *buffer;
|
|
||||||
u32 buf_cnt;
|
|
||||||
u32 image_size;
|
|
||||||
u32 min_address=0;
|
|
||||||
u32 max_address=0xffffffff;
|
|
||||||
int i;
|
|
||||||
int retval;
|
|
||||||
|
|
||||||
image_t image;
|
|
||||||
|
|
||||||
duration_t duration;
|
|
||||||
char *duration_text;
|
|
||||||
|
|
||||||
if ((argc < 1)||(argc > 5))
|
|
||||||
{
|
|
||||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
|
|
||||||
if (argc >= 2)
|
|
||||||
{
|
|
||||||
image.base_address_set = 1;
|
|
||||||
image.base_address = strtoul(args[1], NULL, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
image.base_address_set = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
image.start_address_set = 0;
|
|
||||||
|
|
||||||
if (argc>=4)
|
|
||||||
{
|
|
||||||
min_address=strtoul(args[3], NULL, 0);
|
|
||||||
}
|
|
||||||
if (argc>=5)
|
|
||||||
{
|
|
||||||
max_address=strtoul(args[4], NULL, 0)+min_address;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (min_address>max_address)
|
|
||||||
{
|
|
||||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
duration_start_measure(&duration);
|
|
||||||
|
|
||||||
if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
|
|
||||||
{
|
|
||||||
return ERROR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
image_size = 0x0;
|
|
||||||
retval = ERROR_OK;
|
|
||||||
fastload_num=image.num_sections;
|
|
||||||
fastload=(struct FastLoad *)malloc(sizeof(struct FastLoad)*image.num_sections);
|
|
||||||
if (fastload==NULL)
|
|
||||||
{
|
|
||||||
image_close(&image);
|
|
||||||
return ERROR_FAIL;
|
|
||||||
}
|
|
||||||
memset(fastload, 0, sizeof(struct FastLoad)*image.num_sections);
|
|
||||||
for (i = 0; i < image.num_sections; i++)
|
|
||||||
{
|
|
||||||
buffer = malloc(image.sections[i].size);
|
|
||||||
if (buffer == NULL)
|
|
||||||
{
|
|
||||||
command_print(cmd_ctx, "error allocating buffer for section (%d bytes)", image.sections[i].size);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
|
|
||||||
{
|
|
||||||
free(buffer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 offset=0;
|
|
||||||
u32 length=buf_cnt;
|
|
||||||
|
|
||||||
|
|
||||||
/* DANGER!!! beware of unsigned comparision here!!! */
|
|
||||||
|
|
||||||
if ((image.sections[i].base_address+buf_cnt>=min_address)&&
|
|
||||||
(image.sections[i].base_address<max_address))
|
|
||||||
{
|
|
||||||
if (image.sections[i].base_address<min_address)
|
|
||||||
{
|
|
||||||
/* clip addresses below */
|
|
||||||
offset+=min_address-image.sections[i].base_address;
|
|
||||||
length-=offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (image.sections[i].base_address+buf_cnt>max_address)
|
|
||||||
{
|
|
||||||
length-=(image.sections[i].base_address+buf_cnt)-max_address;
|
|
||||||
}
|
|
||||||
|
|
||||||
fastload[i].address=image.sections[i].base_address+offset;
|
|
||||||
fastload[i].data=malloc(length);
|
|
||||||
if (fastload[i].data==NULL)
|
|
||||||
{
|
|
||||||
free(buffer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
memcpy(fastload[i].data, buffer+offset, length);
|
|
||||||
fastload[i].length=length;
|
|
||||||
|
|
||||||
image_size += length;
|
|
||||||
command_print(cmd_ctx, "%u byte written at address 0x%8.8x", length, image.sections[i].base_address+offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
duration_stop_measure(&duration, &duration_text);
|
|
||||||
if (retval==ERROR_OK)
|
|
||||||
{
|
|
||||||
command_print(cmd_ctx, "Loaded %u bytes in %s", image_size, duration_text);
|
|
||||||
command_print(cmd_ctx, "NB!!! image has not been loaded to target, issue a subsequent 'fast_load' to do so.");
|
|
||||||
}
|
|
||||||
free(duration_text);
|
|
||||||
|
|
||||||
image_close(&image);
|
|
||||||
|
|
||||||
if (retval!=ERROR_OK)
|
|
||||||
{
|
|
||||||
free_fastload();
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
int handle_fast_load_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
|
||||||
{
|
|
||||||
if (argc>0)
|
|
||||||
return ERROR_COMMAND_SYNTAX_ERROR;
|
|
||||||
if (fastload==NULL)
|
|
||||||
{
|
|
||||||
LOG_ERROR("No image in memory");
|
|
||||||
return ERROR_FAIL;
|
|
||||||
}
|
|
||||||
int i;
|
|
||||||
int ms=timeval_ms();
|
|
||||||
int size=0;
|
|
||||||
for (i=0; i<fastload_num;i++)
|
|
||||||
{
|
|
||||||
int retval;
|
|
||||||
target_t *target = get_current_target(cmd_ctx);
|
|
||||||
if ((retval = target_write_buffer(target, fastload[i].address, fastload[i].length, fastload[i].data)) != ERROR_OK)
|
|
||||||
{
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
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));
|
|
||||||
return ERROR_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Give TELNET a way to find out what version this is */
|
/* Give TELNET a way to find out what version this is */
|
||||||
int handle_zy1000_version_command(struct command_context_s *cmd_ctx, char *cmd,
|
int handle_zy1000_version_command(struct command_context_s *cmd_ctx, char *cmd,
|
||||||
|
@ -1969,12 +1779,6 @@ int main(int argc, char *argv[])
|
||||||
register_command(cmd_ctx, NULL, "rm", handle_rm_command, COMMAND_ANY,
|
register_command(cmd_ctx, NULL, "rm", handle_rm_command, COMMAND_ANY,
|
||||||
"remove file");
|
"remove file");
|
||||||
|
|
||||||
register_command(cmd_ctx, NULL, "fast_load_image", handle_fast_load_image_command, COMMAND_ANY,
|
|
||||||
"same args as load_image, image stored in memory");
|
|
||||||
|
|
||||||
register_command(cmd_ctx, NULL, "fast_load", handle_fast_load_command, COMMAND_ANY,
|
|
||||||
"loads active fast load image to current target");
|
|
||||||
|
|
||||||
register_command(cmd_ctx, NULL, "cat", handle_cat_command, COMMAND_ANY,
|
register_command(cmd_ctx, NULL, "cat", handle_cat_command, COMMAND_ANY,
|
||||||
"display file content");
|
"display file content");
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,9 @@ int handle_wp_command(struct command_context_s *cmd_ctx, char *cmd, char **args,
|
||||||
int handle_rwp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
|
int handle_rwp_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
|
||||||
int handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc);
|
int handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc);
|
||||||
int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
|
int handle_profile_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
|
||||||
|
int handle_fast_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
|
||||||
|
int handle_fast_load_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
|
||||||
|
|
||||||
static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
|
static int jim_array2mem(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
|
||||||
static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
|
static int jim_mem2array(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
|
||||||
static int jim_target( Jim_Interp *interp, int argc, Jim_Obj *const *argv);
|
static int jim_target( Jim_Interp *interp, int argc, Jim_Obj *const *argv);
|
||||||
|
@ -929,6 +932,14 @@ int target_register_commands(struct command_context_s *cmd_ctx)
|
||||||
register_command(cmd_ctx, NULL, "virt2phys", handle_virt2phys_command, COMMAND_ANY, "translate a virtual address into a physical address");
|
register_command(cmd_ctx, NULL, "virt2phys", handle_virt2phys_command, COMMAND_ANY, "translate a virtual address into a physical address");
|
||||||
register_command(cmd_ctx, NULL, "profile", handle_profile_command, COMMAND_EXEC, "profiling samples the CPU PC");
|
register_command(cmd_ctx, NULL, "profile", handle_profile_command, COMMAND_EXEC, "profiling samples the CPU PC");
|
||||||
|
|
||||||
|
register_command(cmd_ctx, NULL, "fast_load_image", handle_fast_load_image_command, COMMAND_ANY,
|
||||||
|
"same args as load_image, image stored in memory - mainly for profiling purposes");
|
||||||
|
|
||||||
|
register_command(cmd_ctx, NULL, "fast_load", handle_fast_load_command, COMMAND_ANY,
|
||||||
|
"loads active fast load image to current target - mainly for profiling purposes");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
register_jim(cmd_ctx, "target", jim_target, "configure target" );
|
register_jim(cmd_ctx, "target", jim_target, "configure target" );
|
||||||
|
|
||||||
|
|
||||||
|
@ -3845,7 +3856,7 @@ static int target_create( Jim_GetOptInfo *goi )
|
||||||
/* incase variant is not set */
|
/* incase variant is not set */
|
||||||
if (!target->variant)
|
if (!target->variant)
|
||||||
target->variant = strdup("");
|
target->variant = strdup("");
|
||||||
|
|
||||||
/* create the target specific commands */
|
/* create the target specific commands */
|
||||||
if( target->type->register_commands ){
|
if( target->type->register_commands ){
|
||||||
(*(target->type->register_commands))( cmd_ctx );
|
(*(target->type->register_commands))( cmd_ctx );
|
||||||
|
@ -3993,3 +4004,196 @@ static int jim_target( Jim_Interp *interp, int argc, Jim_Obj *const *argv )
|
||||||
|
|
||||||
return JIM_ERR;
|
return JIM_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct FastLoad
|
||||||
|
{
|
||||||
|
u32 address;
|
||||||
|
u8 *data;
|
||||||
|
int length;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
static int fastload_num;
|
||||||
|
static struct FastLoad *fastload;
|
||||||
|
|
||||||
|
static void free_fastload()
|
||||||
|
{
|
||||||
|
if (fastload!=NULL)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i=0; i<fastload_num; i++)
|
||||||
|
{
|
||||||
|
if (fastload[i].data)
|
||||||
|
free(fastload[i].data);
|
||||||
|
}
|
||||||
|
free(fastload);
|
||||||
|
fastload=NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int handle_fast_load_image_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
||||||
|
{
|
||||||
|
u8 *buffer;
|
||||||
|
u32 buf_cnt;
|
||||||
|
u32 image_size;
|
||||||
|
u32 min_address=0;
|
||||||
|
u32 max_address=0xffffffff;
|
||||||
|
int i;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
image_t image;
|
||||||
|
|
||||||
|
duration_t duration;
|
||||||
|
char *duration_text;
|
||||||
|
|
||||||
|
if ((argc < 1)||(argc > 5))
|
||||||
|
{
|
||||||
|
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
|
||||||
|
if (argc >= 2)
|
||||||
|
{
|
||||||
|
image.base_address_set = 1;
|
||||||
|
image.base_address = strtoul(args[1], NULL, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
image.base_address_set = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
image.start_address_set = 0;
|
||||||
|
|
||||||
|
if (argc>=4)
|
||||||
|
{
|
||||||
|
min_address=strtoul(args[3], NULL, 0);
|
||||||
|
}
|
||||||
|
if (argc>=5)
|
||||||
|
{
|
||||||
|
max_address=strtoul(args[4], NULL, 0)+min_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (min_address>max_address)
|
||||||
|
{
|
||||||
|
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
duration_start_measure(&duration);
|
||||||
|
|
||||||
|
if (image_open(&image, args[0], (argc >= 3) ? args[2] : NULL) != ERROR_OK)
|
||||||
|
{
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
image_size = 0x0;
|
||||||
|
retval = ERROR_OK;
|
||||||
|
fastload_num=image.num_sections;
|
||||||
|
fastload=(struct FastLoad *)malloc(sizeof(struct FastLoad)*image.num_sections);
|
||||||
|
if (fastload==NULL)
|
||||||
|
{
|
||||||
|
image_close(&image);
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
memset(fastload, 0, sizeof(struct FastLoad)*image.num_sections);
|
||||||
|
for (i = 0; i < image.num_sections; i++)
|
||||||
|
{
|
||||||
|
buffer = malloc(image.sections[i].size);
|
||||||
|
if (buffer == NULL)
|
||||||
|
{
|
||||||
|
command_print(cmd_ctx, "error allocating buffer for section (%d bytes)", image.sections[i].size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((retval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt)) != ERROR_OK)
|
||||||
|
{
|
||||||
|
free(buffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 offset=0;
|
||||||
|
u32 length=buf_cnt;
|
||||||
|
|
||||||
|
|
||||||
|
/* DANGER!!! beware of unsigned comparision here!!! */
|
||||||
|
|
||||||
|
if ((image.sections[i].base_address+buf_cnt>=min_address)&&
|
||||||
|
(image.sections[i].base_address<max_address))
|
||||||
|
{
|
||||||
|
if (image.sections[i].base_address<min_address)
|
||||||
|
{
|
||||||
|
/* clip addresses below */
|
||||||
|
offset+=min_address-image.sections[i].base_address;
|
||||||
|
length-=offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (image.sections[i].base_address+buf_cnt>max_address)
|
||||||
|
{
|
||||||
|
length-=(image.sections[i].base_address+buf_cnt)-max_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
fastload[i].address=image.sections[i].base_address+offset;
|
||||||
|
fastload[i].data=malloc(length);
|
||||||
|
if (fastload[i].data==NULL)
|
||||||
|
{
|
||||||
|
free(buffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
memcpy(fastload[i].data, buffer+offset, length);
|
||||||
|
fastload[i].length=length;
|
||||||
|
|
||||||
|
image_size += length;
|
||||||
|
command_print(cmd_ctx, "%u byte written at address 0x%8.8x", length, image.sections[i].base_address+offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
duration_stop_measure(&duration, &duration_text);
|
||||||
|
if (retval==ERROR_OK)
|
||||||
|
{
|
||||||
|
command_print(cmd_ctx, "Loaded %u bytes in %s", image_size, duration_text);
|
||||||
|
command_print(cmd_ctx, "NB!!! image has not been loaded to target, issue a subsequent 'fast_load' to do so.");
|
||||||
|
}
|
||||||
|
free(duration_text);
|
||||||
|
|
||||||
|
image_close(&image);
|
||||||
|
|
||||||
|
if (retval!=ERROR_OK)
|
||||||
|
{
|
||||||
|
free_fastload();
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_fast_load_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
|
||||||
|
{
|
||||||
|
if (argc>0)
|
||||||
|
return ERROR_COMMAND_SYNTAX_ERROR;
|
||||||
|
if (fastload==NULL)
|
||||||
|
{
|
||||||
|
LOG_ERROR("No image in memory");
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
int i;
|
||||||
|
int ms=timeval_ms();
|
||||||
|
int size=0;
|
||||||
|
for (i=0; i<fastload_num;i++)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
target_t *target = get_current_target(cmd_ctx);
|
||||||
|
if ((retval = target_write_buffer(target, fastload[i].address, fastload[i].length, fastload[i].data)) != ERROR_OK)
|
||||||
|
{
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
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));
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue