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
