X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=gdbserver%2Fgdb-server.c;h=f92fc05f06aa7c11f437c67ab252561fbccf85bc;hb=44445dd7b0f557bb9ff2fe22e0da17b03560c673;hp=f60aadcf414bf812e6e95d2118c39efaa994ffb1;hpb=5b6eb51bd22c44fa8d9e70519b561dc64c37f6c9;p=fw%2Fstlink diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index f60aadc..f92fc05 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -192,6 +192,71 @@ winsock_error: return 0; } +static const char* const target_description_F4 = + "" + "" + "" + " arm" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + static const char* const memory_map_template_F4 = "" "chip_id==STM32_CHIPID_F4) { + reply = strdup("PacketSize=3fff;qXfer:memory-map:read+;qXfer:features:read+"); + } + else { + reply = strdup("PacketSize=3fff;qXfer:memory-map:read+"); + } } else if(!strcmp(queryName, "Xfer")) { char *type, *op, *__s_addr, *s_length; char *tok = params; @@ -674,6 +745,9 @@ int serve(stlink_t *sl, int port) { if(!strcmp(type, "memory-map") && !strcmp(op, "read")) data = current_memory_map; + if(!strcmp(type, "features") && !strcmp(op, "read")) + data = target_description_F4; + if(data) { unsigned data_length = strlen(data); if(addr + length > data_length) @@ -711,6 +785,16 @@ int serve(stlink_t *sl, int port) { #ifdef DEBUG printf("Rcmd: halt\n"); +#endif + } else if (!strncmp(params,"6a7461675f7265736574",20)) { //jtag_reset + reply = strdup("OK"); + + stlink_jtag_reset(sl, 1); + stlink_jtag_reset(sl, 0); + stlink_force_debug(sl); + +#ifdef DEBUG + printf("Rcmd: jtag_reset\n"); #endif } else if (!strncmp(params,"7265736574",10)) { //reset reply = strdup("OK"); @@ -881,6 +965,30 @@ int serve(stlink_t *sl, int port) { } else if(id == 0x19) { stlink_read_reg(sl, 16, ®p); myreg = htonl(regp.xpsr); + } else if(id == 0x1A) { + stlink_read_reg(sl, 17, ®p); + myreg = htonl(regp.main_sp); + } else if(id == 0x1B) { + stlink_read_reg(sl, 18, ®p); + myreg = htonl(regp.process_sp); + } else if(id == 0x1C) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.control); + } else if(id == 0x1D) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.faultmask); + } else if(id == 0x1E) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.basepri); + } else if(id == 0x1F) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.primask); + } else if(id >= 0x20 && id < 0x40) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.s[id-0x20]); + } else if(id == 0x40) { + stlink_read_unsupported_reg(sl, id, ®p); + myreg = htonl(regp.fpscr); } else { reply = strdup("E00"); } @@ -902,6 +1010,22 @@ int serve(stlink_t *sl, int port) { stlink_write_reg(sl, ntohl(value), reg); } else if(reg == 0x19) { stlink_write_reg(sl, ntohl(value), 16); + } else if(reg == 0x1A) { + stlink_write_reg(sl, ntohl(value), 17); + } else if(reg == 0x1B) { + stlink_write_reg(sl, ntohl(value), 18); + } else if(reg == 0x1C) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if(reg == 0x1D) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if(reg == 0x1E) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if(reg == 0x1F) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if(reg >= 0x20 && reg < 0x40) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); + } else if(reg == 0x40) { + stlink_write_unsupported_reg(sl, ntohl(value), reg, ®p); } else { reply = strdup("E00"); } @@ -932,9 +1056,9 @@ int serve(stlink_t *sl, int port) { unsigned count = strtoul(s_count, NULL, 16); unsigned adj_start = start % 4; + unsigned count_rnd = (count + adj_start + 4 - 1) / 4 * 4; - stlink_read_mem32(sl, start - adj_start, (count % 4 == 0) ? - count : count + 4 - (count % 4)); + stlink_read_mem32(sl, start - adj_start, count_rnd); reply = calloc(count * 2 + 1, 1); for(unsigned int i = 0; i < count; i++) { @@ -953,20 +1077,43 @@ int serve(stlink_t *sl, int port) { stm32_addr_t start = strtoul(s_start, NULL, 16); unsigned count = strtoul(s_count, NULL, 16); - for(unsigned int i = 0; i < count; i ++) { + if(start % 4) { + unsigned align_count = 4 - start % 4; + if (align_count > count) align_count = count; + for(unsigned int i = 0; i < align_count; i ++) { char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; uint8_t byte = strtoul(hex, NULL, 16); sl->q_buf[i] = byte; + } + stlink_write_mem8(sl, start, align_count); + start += align_count; + count -= align_count; + hexdata += 2*align_count; } - if((count % 4) == 0 && (start % 4) == 0) { - stlink_write_mem32(sl, start, count); - } else { - stlink_write_mem8(sl, start, count); + if(count - count % 4) { + unsigned aligned_count = count - count % 4; + + for(unsigned int i = 0; i < aligned_count; i ++) { + char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; + uint8_t byte = strtoul(hex, NULL, 16); + sl->q_buf[i] = byte; + } + stlink_write_mem32(sl, start, aligned_count); + count -= aligned_count; + start += aligned_count; + hexdata += 2*aligned_count; } + if(count) { + for(unsigned int i = 0; i < count; i ++) { + char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; + uint8_t byte = strtoul(hex, NULL, 16); + sl->q_buf[i] = byte; + } + stlink_write_mem8(sl, start, count); + } reply = strdup("OK"); - break; } @@ -995,13 +1142,14 @@ int serve(stlink_t *sl, int port) { wf = WATCHREAD; } else { wf = WATCHACCESS; - if(add_data_watchpoint(sl, wf, addr, len) < 0) { - reply = strdup("E00"); - } else { - reply = strdup("OK"); - break; - } } + + if(add_data_watchpoint(sl, wf, addr, len) < 0) { + reply = strdup("E00"); + } else { + reply = strdup("OK"); + break; + } } default: @@ -1073,7 +1221,9 @@ int serve(stlink_t *sl, int port) { int result = gdb_send_packet(client, reply); if(result != 0) { fprintf(stderr, "cannot send: %d\n", result); - return 1; + free(reply); + free(packet); + goto start_again; } free(reply);