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
>
>
------------------------------------------------------------------------------
How ServiceNow helps IT people transform IT departments:
1. A cloud service to automate IT design, transition and operations
2. Dashboards that offer high-level views of enterprise services
3. A single system of record for all IT processes
http://p.sf.net/sfu/servicenow-d2d-j
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to