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

Reply via email to