fast_load profiling tool moved to target.c

git-svn-id: svn://svn.berlios.de/openocd/trunk@1241 b42882b7-edfa-0310-969c-e2dbd0fdcd60
__archive__
oharboe 2008-12-15 09:05:16 +00:00
parent 508ed7a7c6
commit 459d03e3bb
2 changed files with 205 additions and 197 deletions

View File

@ -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");

View File

@ -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;
}