Hi, Franck,

I agree your enhancement.  I will do some modification and merge your patch
in commit 1382.
Thanks.

2013/6/10 Franck Jullien <[email protected]>

> H
> siangkai Wang,
>
> Could you try this patch on your target ? It implies only some minor
> changes in your target code.
> This way, the tdesc thing will be compatible with my openrisc port.
>
> Thanks.
>
>
> 2013/6/9 <[email protected]>
>
> From: Franck Jullien <[email protected]>
>>
>> This patch adds the possibility to create feature sections
>> from the feature name. The feature name can be anything.
>>
>> It also adds a command to save the tdesc file (for debug purpose).
>>
>> Change-Id: I47f51028c6a1a2a2bb41e61170438e576eb05890
>> Signed-off-by: Franck Jullien <[email protected]>
>> ---
>>  src/server/gdb_server.c |  223
>> +++++++++++++++++++++++++++++++++--------------
>>  src/target/register.h   |    8 +--
>>  2 files changed, 157 insertions(+), 74 deletions(-)
>>
>> diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
>> index bcd1a66..5f9552f 100644
>> --- a/src/server/gdb_server.c
>> +++ b/src/server/gdb_server.c
>> @@ -1717,20 +1717,6 @@ static const char *gdb_get_reg_type_name(enum
>> reg_type type)
>>         return "int"; /* "int" as default value */
>>  }
>>
>> -static const char *gdb_get_reg_group_name(enum reg_group group)
>> -{
>> -       switch (group) {
>> -               case REG_GROUP_GENERAL:
>> -                       return "general";
>> -               case REG_GROUP_FLOAT:
>> -                       return "float";
>> -               case REG_GROUP_VECTOR:
>> -                       return "vector";
>> -       }
>> -
>> -       return NULL;
>> -}
>> -
>>  static int gdb_generate_reg_type_description(struct target *target,
>>                 char **tdesc, int *pos, int *size, struct reg_data_type
>> *type)
>>  {
>> @@ -1828,10 +1814,46 @@ static int
>> gdb_generate_reg_type_description(struct target *target,
>>         return ERROR_OK;
>>  }
>>
>> +/* Get a list of available target registers features. feature_list must
>> + * be freed by caller.
>> + */
>> +int get_reg_features_list(struct target *target, char **feature_list[],
>> int *feature_list_size,
>> +                         struct reg **reg_list, int reg_list_size)
>> +{
>> +       int tbl_sz = 0;
>> +
>> +       /* Start with only one element */
>> +       *feature_list = calloc(1, sizeof(char *));
>> +
>> +       for (int i = 0; i < reg_list_size; i++) {
>> +               if (reg_list[i]->feature->name != NULL &&
>> strcmp(reg_list[i]->feature->name, "")) {
>> +                       /* We found a feature, check if the feature is
>> already in the
>> +                        * table. If not, allocate a new entry for the
>> table and
>> +                        * put the new feature in it.
>> +                        */
>> +                       for (int j = 0; j < (tbl_sz + 1); j++) {
>> +                               if (!((*feature_list)[j])) {
>> +                                       (*feature_list)[tbl_sz++] =
>> strdup(reg_list[i]->feature->name);
>> +                                       *feature_list =
>> realloc(*feature_list, sizeof(char *) * (tbl_sz + 1));
>> +                                       (*feature_list)[tbl_sz] = NULL;
>> +                                       break;
>> +                               } else {
>> +                                       if (!strcmp((*feature_list)[j],
>> reg_list[i]->feature->name))
>> +                                       break;
>> +                               }
>> +                       }
>> +               }
>> +       }
>> +
>> +       if (feature_list_size)
>> +               *feature_list_size = tbl_sz;
>> +
>> +       return ERROR_OK;
>> +}
>> +
>>  static int gdb_generate_target_description(struct target *target, char
>> **tdesc)
>>  {
>>         int retval = ERROR_OK;
>> -       enum target_register_class reg_class;
>>         struct reg **reg_list;
>>         int reg_list_size;
>>         int pos = 0;
>> @@ -1842,75 +1864,97 @@ static int gdb_generate_target_description(struct
>> target *target, char **tdesc)
>>                         "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">\n"
>>                         "<target version=\"1.0\">\n");
>>
>> -       for (reg_class = REG_CLASS_GENERAL; reg_class != REG_CLASS_END;
>> reg_class++) {
>> -               retval = target_get_gdb_reg_list(target, &reg_list,
>> &reg_list_size,
>> -                               reg_class);
>> +       retval = target_get_gdb_reg_list(target, &reg_list,
>> &reg_list_size,
>> +                       REG_CLASS_ALL);
>> +
>> +       if (retval != ERROR_OK) {
>> +               LOG_ERROR("get register list failed");
>> +               return ERROR_FAIL;
>> +       }
>>
>> -               if (retval != ERROR_OK) {
>> -                       LOG_ERROR("get register list %d failed",
>> reg_class);
>> -                       continue;
>> -               }
>> +       if (reg_list_size <= 0)
>> +               return ERROR_FAIL;
>>
>> -               if (reg_list_size <= 0)
>> -                       continue;
>> +       char **features = NULL;
>> +       /* Get a list of available target registers features */
>> +       retval = get_reg_features_list(target, &features, NULL, reg_list,
>> reg_list_size);
>> +       if (retval != ERROR_OK) {
>> +               LOG_ERROR("Can't get the registers feature list");
>> +               return ERROR_FAIL;
>> +       }
>>
>> -               /* generate target description according to register list
>> */
>> -               xml_printf(&retval, tdesc, &pos, &size,
>> -                               "<feature name=\"%s\">\n",
>> -                               reg_list[0]->feature->name);
>> +       /* If we found some features associated with registers, create
>> sections */
>> +       int current_feature = 0;
>>
>> -               int i;
>> -               for (i = 0; i < reg_list_size; i++) {
>> -                       const char *type_str;
>> -                       if (reg_list[i]->reg_data_type != NULL) {
>> -                               if (reg_list[i]->reg_data_type->type ==
>> REG_TYPE_ARCH_DEFINED) {
>> -                                       /* generate <type... first, if
>> there are architecture-defined types. */
>> -
>> gdb_generate_reg_type_description(target, tdesc, &pos, &size,
>> -
>> reg_list[i]->reg_data_type);
>> -
>> -                                       type_str =
>> reg_list[i]->reg_data_type->id;
>> +       /* generate target description according to register list */
>> +       if (features != NULL) {
>> +               while (features[current_feature]) {
>> +
>> +                       xml_printf(&retval, tdesc, &pos, &size,
>> +                                       "<feature name=\"%s\">\n",
>> +                                       features[current_feature]);
>> +
>> +                       int i;
>> +                       for (i = 0; i < reg_list_size; i++) {
>> +
>> +                               if (strcmp(reg_list[i]->feature->name,
>> features[current_feature]))
>> +                                       continue;
>> +
>> +                               const char *type_str;
>> +                               if (reg_list[i]->reg_data_type != NULL) {
>> +                                       if
>> (reg_list[i]->reg_data_type->type == REG_TYPE_ARCH_DEFINED) {
>> +                                               /* generate <type...
>> first, if there are architecture-defined types. */
>> +
>> gdb_generate_reg_type_description(target, tdesc, &pos, &size,
>> +
>> reg_list[i]->reg_data_type);
>> +
>> +                                               type_str =
>> reg_list[i]->reg_data_type->id;
>> +                                       } else {
>> +                                               /* predefined type */
>> +                                               type_str =
>> gdb_get_reg_type_name(
>> +
>> reg_list[i]->reg_data_type->type);
>> +                                       }
>>                                 } else {
>> -                                       /* predefined type */
>> -                                       type_str = gdb_get_reg_type_name(
>> -
>> reg_list[i]->reg_data_type->type);
>> +                                       /* Default type is "int" */
>> +                                       type_str = "int";
>>                                 }
>> -                       } else {
>> -                               /* Default type is "int" */
>> -                               type_str = "int";
>> -                       }
>>
>> -                       xml_printf(&retval, tdesc, &pos, &size,
>> -                                       "<reg name=\"%s\"",
>> reg_list[i]->name);
>> -                       xml_printf(&retval, tdesc, &pos, &size,
>> -                                       " bitsize=\"%d\"",
>> reg_list[i]->size);
>> -                       xml_printf(&retval, tdesc, &pos, &size,
>> -                                       " regnum=\"%d\"",
>> reg_list[i]->number);
>> -                       if (reg_list[i]->caller_save)
>>                                 xml_printf(&retval, tdesc, &pos, &size,
>> -                                               " save-restore=\"yes\"");
>> -                       else
>> +                                               "<reg name=\"%s\"",
>> reg_list[i]->name);
>> +
>>                                 xml_printf(&retval, tdesc, &pos, &size,
>> -                                               " save-restore=\"no\"");
>> +                                               " bitsize=\"%d\"",
>> reg_list[i]->size);
>>
>> -                       xml_printf(&retval, tdesc, &pos, &size,
>> -                                       " type=\"%s\"", type_str);
>> +                               xml_printf(&retval, tdesc, &pos, &size,
>> +                                               " regnum=\"%d\"",
>> reg_list[i]->number);
>> +
>> +                               if (reg_list[i]->caller_save)
>> +                                       xml_printf(&retval, tdesc, &pos,
>> &size,
>> +                                                       "
>> save-restore=\"yes\"");
>> +                               else
>> +                                       xml_printf(&retval, tdesc, &pos,
>> &size,
>> +                                                       "
>> save-restore=\"no\"");
>>
>> -                       const char *group_str;
>> -                       group_str =
>> gdb_get_reg_group_name(reg_list[i]->group);
>> -                       if (group_str != NULL)
>>                                 xml_printf(&retval, tdesc, &pos, &size,
>> -                                               " group=\"%s\"",
>> group_str);
>> +                                               " type=\"%s\"", type_str);
>>
>> -                       xml_printf(&retval, tdesc, &pos, &size,
>> -                                       "/>\n");
>> -               }
>> +                               if (reg_list[i]->group != NULL)
>> +                                       xml_printf(&retval, tdesc, &pos,
>> &size,
>> +                                                       " group=\"%s\"",
>> reg_list[i]->group);
>>
>> -               xml_printf(&retval, tdesc, &pos, &size,
>> -                               "</feature>\n");
>> +                               xml_printf(&retval, tdesc, &pos, &size,
>> +                                               "/>\n");
>> +                       }
>>
>> -               free(reg_list);
>> +                       xml_printf(&retval, tdesc, &pos, &size,
>> +                                       "</feature>\n");
>> +
>> +                       current_feature++;
>> +               }
>>         }
>>
>> +       free(reg_list);
>> +       free(features);
>> +
>>         xml_printf(&retval, tdesc, &pos, &size,
>>                         "</target>\n");
>>
>> @@ -2658,6 +2702,45 @@
>> COMMAND_HANDLER(handle_gdb_target_description_command)
>>         return ERROR_OK;
>>  }
>>
>> +COMMAND_HANDLER(handle_gdb_save_tdesc)
>> +{
>> +       static char *tdesc;
>> +       static uint32_t tdesc_length;
>> +       struct target *target = get_current_target(CMD_CTX);
>> +       char *tdesc_filename;
>> +
>> +       if (tdesc == NULL) {
>> +               gdb_generate_target_description(target, &tdesc);
>> +               tdesc_length = strlen(tdesc);
>> +       }
>> +
>> +       struct fileio fileio;
>> +       size_t size_written;
>> +
>> +       tdesc_filename = malloc(strlen(target_type_name(target)) + 5);
>> +       sprintf(tdesc_filename, "%s.xml", target_type_name(target));
>> +
>> +       int retval = fileio_open(&fileio, tdesc_filename, FILEIO_WRITE,
>> FILEIO_TEXT);
>> +
>> +       free(tdesc_filename);
>> +
>> +       if (retval != ERROR_OK) {
>> +               LOG_WARNING("Can't open %s for writing", tdesc_filename);
>> +               return ERROR_FAIL;
>> +       }
>> +
>> +       retval = fileio_write(&fileio, tdesc_length, tdesc,
>> &size_written);
>> +
>> +       fileio_close(&fileio);
>> +
>> +       if (retval != ERROR_OK) {
>> +               LOG_WARNING("Error while writing the tdesc file");
>> +               return ERROR_FAIL;
>> +       }
>> +
>> +       return ERROR_OK;
>> +}
>> +
>>  static const struct command_registration gdb_command_handlers[] = {
>>         {
>>                 .name = "gdb_sync",
>> @@ -2717,6 +2800,12 @@ static const struct command_registration
>> gdb_command_handlers[] = {
>>                 .help = "enable or disable target description",
>>                 .usage = "('enable'|'disable')"
>>         },
>> +       {
>> +               .name = "save_tdesc",
>> +               .handler = handle_gdb_save_tdesc,
>> +               .mode = COMMAND_ANY,
>> +               .help = "print the target description file",
>> +       },
>>         COMMAND_REGISTRATION_DONE
>>  };
>>
>> diff --git a/src/target/register.h b/src/target/register.h
>> index 25824bf..cffcf57 100644
>> --- a/src/target/register.h
>> +++ b/src/target/register.h
>> @@ -44,12 +44,6 @@ enum reg_type {
>>         REG_TYPE_ARCH_DEFINED,
>>  };
>>
>> -enum reg_group {
>> -       REG_GROUP_GENERAL,
>> -       REG_GROUP_FLOAT,
>> -       REG_GROUP_VECTOR,
>> -};
>> -
>>  struct reg_feature {
>>         const char *name;
>>  };
>> @@ -129,7 +123,7 @@ struct reg {
>>         bool valid;
>>         uint32_t size;
>>         struct reg_data_type *reg_data_type;
>> -       enum reg_group group;
>> +       const char *group;
>>         void *arch_info;
>>         const struct reg_arch_type *type;
>>  };
>> --
>> 1.7.1
>>
>>
>
------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to