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
