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, ®_list,
>> ®_list_size,
>> - reg_class);
>> + retval = target_get_gdb_reg_list(target, ®_list,
>> ®_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