2012/12/27 Franck Jullien <[email protected]>:
> 2012/12/27  <[email protected]>:
>> This is an automated email from Gerrit.
>>
>> Hsiangkai Wang ([email protected]) just uploaded a new patch set to 
>> Gerrit, which you can find at http://openocd.zylin.com/1094
>>
>> -- gerrit
>>
>> commit 3197816865c195806517249bfa320f3709ab4d77
>> Author: Hsiangkai Wang <[email protected]>
>> Date:   Thu Dec 27 15:41:32 2012 +0800
>>
>>     gdb server: provide an implementation for gdb target description
>>
>>     If target supports gdb target description, users could use
>>     gdb_target_description [enable|disable] to config the feature.
>>     The default setting is disable. After the feature is enabled,
>>     gdb_server will response qXfer:features:read+ to "qSupported"
>>     packet. Target has the responsibility to provide correct
>>     target description as gdb_server received "qXfer:features:read:"
>>     In order to provide target descriptions, target needs to implement
>>     callback function, get_gdb_target_description.
>>
>>     The sample code extracted from nds32 implementation is as follow
>>     (nds32 implementation is ongoing)
>>
>>     int nds32_get_gdb_target_description(struct target *target, char **xml,
>>                 char *annex, int32_t offset, uint32_t length)
>>     {
>>         struct nds32 *nds32 = target_to_nds32(target);
>>         struct nds32_cpu_version *cpu_version = &(nds32->cpu_version);
>>         struct nds32_misc_config *misc_config = &(nds32->misc_config);
>>         int retval = ERROR_OK;
>>         int pos = 0;
>>         int size = 0;
>>         char *tdesc;
>>
>>         if (strcmp(annex, "target.xml") == 0) {
>>                 char *fpu_desc = "";
>>                 char *audio_desc = "";
>>
>>                 if (misc_config->audio_isa)
>>                         audio_desc = "<xi:include 
>> href=\"nds32-audio.xml\"/>";
>>
>>                 if (cpu_version->cop_fpu_extension)
>>                         fpu_desc = "<xi:include href=\"nds32-fpu.xml\"/>";
>>
>>                 const char *main_description = "l<?xml version=\"1.0\"?>" \
>>                                                    "<!DOCTYPE target SYSTEM 
>> \"gdb-target.dtd\">" \
>>                                                    
>> "<target><architecture>nds32</architecture>" \
>>                                                    "<xi:include 
>> href=\"nds32-core.xml\"/>" \
>>                                                    "<xi:include 
>> href=\"nds32-system.xml\"/>" \
>>                                                    "%s" \
>>                                                    "%s" \
>>                                                    "</target>";
>>                 nds32_xml_printf(&retval, xml, &pos, &size, 
>> main_description, audio_desc, fpu_desc);
>>
>>                 return retval;
>>         } else if (strcmp(annex, "nds32-core.xml") == 0) {
>>                 tdesc = nds32_tdesc[NDS32_CORE_TDESC];
>>                 if (tdesc == NULL)
>>                         return ERROR_FAIL;
>>         } else if (strcmp(annex, "nds32-system.xml") == 0) {
>>                 tdesc = nds32_tdesc[NDS32_SYSTEM_TDESC];
>>                 if (tdesc == NULL)
>>                         return ERROR_FAIL;
>>         } else if (strcmp(annex, "nds32-audio.xml") == 0) {
>>                 tdesc = nds32_tdesc[NDS32_AUDIO_TDESC];
>>                 if (tdesc == NULL)
>>                         return ERROR_FAIL;
>>         } else if (strcmp(annex, "nds32-fpu.xml") == 0) {
>>                 tdesc = nds32_tdesc[NDS32_FPU_TDESC];
>>                 if (tdesc == NULL)
>>                         return ERROR_FAIL;
>>         } else {
>>                 return ERROR_FAIL;
>>         }
>>
>>         char transfer_type;
>>         uint32_t tdesc_length = strlen(tdesc);
>>
>>         if (length < (tdesc_length - offset))
>>                 transfer_type = 'm';
>>         else
>>                 transfer_type = 'l';
>>
>>         *xml = malloc(length+2);
>>         (*xml)[0] = transfer_type;
>>         if (transfer_type == 'm')
>>         {
>>                 strncpy((*xml) + 1, tdesc + offset, length);
>>                 (*xml)[1 + length] = '\0';
>>         }
>>         else
>>         {
>>                 strncpy((*xml) + 1, tdesc + offset, tdesc_length - offset);
>>                 (*xml)[1 + (tdesc_length - offset)] = '\0';
>>         }
>>
>>         return ERROR_OK;
>>     }
>>
>>     Change-Id: I07b9907b1e773209c0efb15e79249d0fe855643b
>>     Signed-off-by: Hsiangkai Wang <[email protected]>
>>
>> diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c
>> index 3c125fe..299b102 100644
>> --- a/src/server/gdb_server.c
>> +++ b/src/server/gdb_server.c
>> @@ -115,6 +115,11 @@ static int gdb_flash_program = 1;
>>   */
>>  static int gdb_report_data_abort;
>>
>> +/* set if we are sending target descriptions to gdb
>> + * via qXfer:features:read packet */
>> +/* disabled by default */
>> +static int gdb_use_target_description;
>> +
>>  static int gdb_last_signal(struct target *target)
>>  {
>>         switch (target->debug_reason) {
>> @@ -1815,9 +1820,10 @@ static int gdb_query_packet(struct connection 
>> *connection,
>>                         &buffer,
>>                         &pos,
>>                         &size,
>> -                       
>> "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read-;QStartNoAckMode+",
>> +                       
>> "PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read%c;QStartNoAckMode+",
>>                         (GDB_BUFFER_SIZE - 1),
>> -                       ((gdb_use_memory_map == 1) && 
>> (flash_get_bank_count() > 0)) ? '+' : '-');
>> +                       ((gdb_use_memory_map == 1) && 
>> (flash_get_bank_count() > 0)) ? '+' : '-',
>> +                       (gdb_use_target_description == 1) ? '+' : '-');
>>
>>                 if (retval != ERROR_OK) {
>>                         gdb_send_error(connection, 01);
>> @@ -1833,8 +1839,6 @@ static int gdb_query_packet(struct connection 
>> *connection,
>>                 return gdb_memory_map(connection, packet, packet_size);
>>         else if (strncmp(packet, "qXfer:features:read:", 20) == 0) {
>>                 char *xml = NULL;
>> -               int size = 0;
>> -               int pos = 0;
>>                 int retval = ERROR_OK;
>>
>>                 int offset;
>> @@ -1849,24 +1853,25 @@ static int gdb_query_packet(struct connection 
>> *connection,
>>                         return ERROR_OK;
>>                 }
>>
>> -               if (strcmp(annex, "target.xml") != 0) {
>> -                       gdb_send_error(connection, 01);
>> -                       return ERROR_OK;
>> -               }
>> -
>> -               xml_printf(&retval,
>> -                       &xml,
>> -                       &pos,
>> -                       &size, \
>> -                       "l < target version=\"1.0\">\n < architecture > 
>> arm</architecture>\n</target>\n");
>> -
>> +               /* Target should prepare correct target description for 
>> annex.
>> +                * The first character of returned xml is 'm' or 'l'. 'm' for
>> +                * there are *more* chunks to transfer. 'l' for it is the 
>> *last*
>> +                * chunk of target description.
>> +                *
>> +                * example of xml (as annex == "target.xml"):
>> +                *
>> +                * "l<?xml version=\"1.0\"?>" \
>> +                * "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">" \
>> +                * "<target><architecture>arm</architecture>" \
>> +                * "</target>
>> +                */
>> +               retval = target_get_gdb_target_description(target, &xml, 
>> annex, offset, length);
>>                 if (retval != ERROR_OK) {
>>                         gdb_error(connection, retval);
>>                         return retval;
>>                 }
>>
>>                 gdb_put_packet(connection, xml, strlen(xml));
>> -
>>                 free(xml);
>>                 return ERROR_OK;
>>         } else if (strncmp(packet, "QStartNoAckMode", 15) == 0) {
>> @@ -2443,6 +2448,15 @@ 
>> COMMAND_HANDLER(handle_gdb_breakpoint_override_command)
>>         return ERROR_OK;
>>  }
>>
>> +COMMAND_HANDLER(handle_gdb_target_description_command)
>> +{
>> +       if (CMD_ARGC != 1)
>> +               return ERROR_COMMAND_SYNTAX_ERROR;
>> +
>> +       COMMAND_PARSE_ENABLE(CMD_ARGV[0], gdb_use_target_description);
>> +       return ERROR_OK;
>> +}
>> +
>>  static const struct command_registration gdb_command_handlers[] = {
>>         {
>>                 .name = "gdb_sync",
>> @@ -2495,6 +2509,13 @@ static const struct command_registration 
>> gdb_command_handlers[] = {
>>                         "to be used by gdb 'break' commands.",
>>                 .usage = "('hard'|'soft'|'disable')"
>>         },
>> +       {
>> +               .name = "gdb_target_description",
>> +               .handler = handle_gdb_target_description_command,
>> +               .mode = COMMAND_CONFIG,
>> +               .help = "enable or disable target description",
>> +               .usage = "('enable'|'disable')"
>> +       },
>>         COMMAND_REGISTRATION_DONE
>>  };
>>
>> diff --git a/src/target/target.c b/src/target/target.c
>> index d9d4362..c781955 100644
>> --- a/src/target/target.c
>> +++ b/src/target/target.c
>> @@ -60,6 +60,8 @@ static int target_read_buffer_default(struct target 
>> *target, uint32_t address,
>>                 uint32_t size, uint8_t *buffer);
>>  static int target_write_buffer_default(struct target *target, uint32_t 
>> address,
>>                 uint32_t size, const uint8_t *buffer);
>> +static int target_get_gdb_target_description_default(struct target *target, 
>> char **xml,
>> +               char *annex, int32_t offset, uint32_t length);
>>  static int target_array2mem(Jim_Interp *interp, struct target *target,
>>                 int argc, Jim_Obj * const *argv);
>>  static int target_mem2array(Jim_Interp *interp, struct target *target,
>> @@ -1062,6 +1064,16 @@ int target_get_gdb_general_reg_list(struct target 
>> *target,
>>         return target->type->get_gdb_general_reg_list(target, reg_list, 
>> reg_list_size);
>>  }
>>
>> +int target_get_gdb_target_description(struct target *target,
>> +               char **xml, char *annex, int32_t offset, uint32_t length)
>> +{
>> +       if (target->state != TARGET_HALTED) {
>> +               LOG_WARNING("target %s is not halted", target->cmd_name);
>> +               return ERROR_TARGET_NOT_HALTED;
>> +       }
>> +       return target->type->get_gdb_target_description(target, xml, annex, 
>> offset, length);
>> +}
>> +
>>  int target_step(struct target *target,
>>                 int current, uint32_t address, int handle_breakpoints)
>>  {
>> @@ -1168,6 +1180,9 @@ static int target_init_one(struct command_context 
>> *cmd_ctx,
>>         if (target->type->write_buffer == NULL)
>>                 target->type->write_buffer = target_write_buffer_default;
>>
>> +       if (target->type->get_gdb_target_description == NULL)
>> +               target->type->get_gdb_target_description = 
>> target_get_gdb_target_description_default;
>> +
>>         return ERROR_OK;
>>  }
>>
>> @@ -1798,6 +1813,27 @@ static int target_write_buffer_default(struct target 
>> *target, uint32_t address,
>>         return retval;
>>  }
>>
>> +static int target_get_gdb_target_description_default(struct target *target, 
>> char **xml,
>> +               char *annex, int32_t offset, uint32_t length)
>> +{
>> +       if (strcmp(annex, "target.xml") != 0)
>> +               return ERROR_FAIL;
>> +
>> +       const char *default_description = "l<?xml version=\"1.0\"?>" \
>> +                                          "<!DOCTYPE target SYSTEM 
>> \"gdb-target.dtd\">" \
>> +                                          
>> "<target><architecture>arm</architecture>" \
>> +                                          "</target>";
>> +       const int description_length = strlen(default_description);
>> +
>> +       *xml = realloc(*xml, description_length + 1);
>> +       if (*xml == NULL)
>> +               return ERROR_FAIL;
>> +
>> +       strcpy(*xml, default_description);
>> +
>> +       return ERROR_OK;
>> +}
>> +
>>  /* Single aligned words are guaranteed to use 16 or 32 bit access
>>   * mode respectively, otherwise data is handled as quickly as
>>   * possible
>> diff --git a/src/target/target.h b/src/target/target.h
>> index c6e6923..2e39e4d 100644
>> --- a/src/target/target.h
>> +++ b/src/target/target.h
>> @@ -412,6 +412,14 @@ int target_get_gdb_general_reg_list(struct target 
>> *target,
>>                 struct reg **reg_list[], int *reg_list_size);
>>
>>  /**
>> + * Obtain target description for GDB.
>> + *
>> + * This routine is a wrapper for target->type->get_gdb_target_description.
>> + */
>> +int target_get_gdb_target_description(struct target *target,
>> +               char **xml, char *annex, int32_t offset, uint32_t length);
>> +
>> +/**
>>   * Step the target.
>>   *
>>   * This routine is a wrapper for target->type->step.
>> diff --git a/src/target/target_type.h b/src/target/target_type.h
>> index 966c9e1..44521bb 100644
>> --- a/src/target/target_type.h
>> +++ b/src/target/target_type.h
>> @@ -122,6 +122,12 @@ struct target_type {
>>          */
>>         int (*get_gdb_general_reg_list)(struct target *target, struct reg 
>> **reg_list[], int *reg_list_size);
>>
>> +       /**
>> +        * Get target description for GDB.  Do @b not call this function
>> +        * directly, use target_get_gdb_target_description() instead.
>> +        */
>> +       int (*get_gdb_target_description)(struct target *target, char **xml, 
>> char *annex, int32_t offset, uint32_t length);
>> +
>>         /* target memory access
>>         * size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit)
>>         * count: number of items of <size>
>>
>> --
>>
>> ------------------------------------------------------------------------------
>> Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS,
>> MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current
>> with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft
>> MVPs and experts. ON SALE this month only -- learn more at:
>> http://p.sf.net/sfu/learnmore_122712
>> _______________________________________________
>> OpenOCD-devel mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/openocd-devel
>
> Hi,
>
> I just pushed something similar some days ago:
> http://openocd.zylin.com/#/c/1051/
> In case you want to take a look.
>
> Franck.

You could also use http://openocd.zylin.com/#/c/1090/ to generate your
tdesc file.

Franck.

------------------------------------------------------------------------------
Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS,
MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current
with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft
MVPs and experts. ON SALE this month only -- learn more at:
http://p.sf.net/sfu/learnmore_122712
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to