X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=gdbserver%2Fgdb-server.c;h=a3ed335ad1d42a161bdf9dd9b9ec3b3d976822d7;hb=788d2df7723e9da3a0369365f56830ab9541e9c7;hp=32f0d8bafa6197ad14f2da2162fef58d7aae01d1;hpb=5be889e3feb75fc7f594012c4855b4dc16940050;p=fw%2Fstlink diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 32f0d8b..a3ed335 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -7,9 +7,11 @@ */ #include +#include #include #include #include +#include #include #include #ifdef __MINGW32__ @@ -18,7 +20,6 @@ #include #include #include -#include #endif #include @@ -45,11 +46,10 @@ static const char* current_memory_map = NULL; typedef struct _st_state_t { // things from command line, bleh int stlink_version; - // "/dev/serial/by-id/usb-FTDI_TTL232R-3V3_FTE531X6-if00-port0" is only 58 chars - char devicename[100]; int logging_level; - int listen_port; + int listen_port; int persistent; + int reset; } st_state_t; @@ -67,23 +67,23 @@ static void cleanup(int signal __attribute__((unused))) { exit(1); } + + int parse_options(int argc, char** argv, st_state_t *st) { static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"verbose", optional_argument, NULL, 'v'}, - {"device", required_argument, NULL, 'd'}, {"stlink_version", required_argument, NULL, 's'}, {"stlinkv1", no_argument, NULL, '1'}, {"listen_port", required_argument, NULL, 'p'}, {"multi", optional_argument, NULL, 'm'}, + {"no-reset", optional_argument, NULL, 'n'}, {0, 0, 0, 0}, }; const char * help_str = "%s - usage:\n\n" " -h, --help\t\tPrint this help\n" - " -vXX, --verbose=XX\tspecify a specific verbosity level (0..99)\n" - " -v, --verbose\tspecify generally verbose logging\n" - " -d , --device=/dev/stlink2_1\n" - "\t\t\tWhere is your stlink device connected?\n" + " -vXX, --verbose=XX\tSpecify a specific verbosity level (0..99)\n" + " -v, --verbose\t\tSpecify generally verbose logging\n" " -s X, --stlink_version=X\n" "\t\t\tChoose what version of stlink to use, (defaults to 2)\n" " -1, --stlinkv1\tForce stlink version 1\n" @@ -93,13 +93,19 @@ int parse_options(int argc, char** argv, st_state_t *st) { " -m, --multi\n" "\t\t\tSet gdb server to extended mode.\n" "\t\t\tst-util will continue listening for connections after disconnect.\n" + " -n, --no-reset\n" + "\t\t\tDo not reset board on connection.\n" + "\n" + "The STLINKv2 device to use can be specified in the environment\n" + "variable STLINK_DEVICE on the format :.\n" + "\n" ; int option_index = 0; int c; int q; - while ((c = getopt_long(argc, argv, "hv::d:s:1p:m", long_options, &option_index)) != -1) { + while ((c = getopt_long(argc, argv, "hv::s:1p:mn", long_options, &option_index)) != -1) { switch (c) { case 0: printf("XXXXX Shouldn't really normally come here, only if there's no corresponding option\n"); @@ -119,13 +125,6 @@ int parse_options(int argc, char** argv, st_state_t *st) { } else { st->logging_level = DEFAULT_LOGGING_LEVEL; } - break; - case 'd': - if (strlen(optarg) > sizeof (st->devicename)) { - fprintf(stderr, "device name too long: %zd\n", strlen(optarg)); - } else { - strcpy(st->devicename, optarg); - } break; case '1': st->stlink_version = 1; @@ -149,6 +148,9 @@ int parse_options(int argc, char** argv, st_state_t *st) { case 'm': st->persistent = 1; break; + case 'n': + st->reset = 0; + break; } } @@ -163,6 +165,7 @@ int parse_options(int argc, char** argv, st_state_t *st) { int main(int argc, char** argv) { + int32_t voltage; stlink_t *sl = NULL; @@ -172,23 +175,34 @@ int main(int argc, char** argv) { state.stlink_version = 2; state.logging_level = DEFAULT_LOGGING_LEVEL; state.listen_port = DEFAULT_GDB_LISTEN_PORT; + state.reset = 1; /* By default, reset board */ parse_options(argc, argv, &state); switch (state.stlink_version) { case 2: - sl = stlink_open_usb(state.logging_level); + sl = stlink_open_usb(state.logging_level, 0); if(sl == NULL) return 1; break; case 1: - sl = stlink_v1_open(state.logging_level); + sl = stlink_v1_open(state.logging_level, 0); if(sl == NULL) return 1; break; } connected_stlink = sl; signal(SIGINT, &cleanup); + signal(SIGTERM, &cleanup); + + if (state.reset) { + stlink_reset(sl); + } printf("Chip ID is %08x, Core ID is %08x.\n", sl->chip_id, sl->core_id); + voltage = stlink_target_voltage(sl); + if (voltage != -1) { + printf("Target voltage is %d mV.\n", voltage); + } + sl->verbose=0; current_memory_map = make_memory_map(sl); @@ -202,6 +216,9 @@ int main(int argc, char** argv) { do { serve(sl, &state); + + /* Continue */ + stlink_run(sl); } while (state.persistent); #ifdef __MINGW32__ @@ -210,7 +227,6 @@ winsock_error: #endif /* Switch back to mass storage mode before closing. */ - stlink_run(sl); stlink_exit_debug_mode(sl); stlink_close(sl); @@ -367,7 +383,7 @@ struct code_hw_watchpoint { struct code_hw_watchpoint data_watches[DATA_WATCH_NUM]; static void init_data_watchpoints(stlink_t *sl) { - #ifdef DEBUG + #if DEBUG printf("init watchpoints\n"); #endif @@ -402,7 +418,7 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr for(i = 0; i < DATA_WATCH_NUM; i++) { // is this an empty slot ? if(data_watches[i].fun == WATCHDISABLED) { - #ifdef DEBUG + #if DEBUG printf("insert watchpoint %d addr %x wf %u mask %u len %d\n", i, addr, wf, mask, len); #endif @@ -426,7 +442,7 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr } } - #ifdef DEBUG + #if DEBUG printf("failure: add watchpoints addr %x wf %u len %u\n", addr, wf, len); #endif return -1; @@ -438,7 +454,7 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) for(i = 0 ; i < DATA_WATCH_NUM; i++) { if((data_watches[i].addr == addr) && (data_watches[i].fun != WATCHDISABLED)) { - #ifdef DEBUG + #if DEBUG printf("delete watchpoint %d addr %x\n", i, addr); #endif @@ -449,7 +465,7 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) } } - #ifdef DEBUG + #if DEBUG printf("failure: delete watchpoint addr %x\n", addr); #endif @@ -457,6 +473,7 @@ static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr) } #define CODE_BREAK_NUM 6 +#define CODE_LIT_NUM 2 #define CODE_BREAK_LOW 0x01 #define CODE_BREAK_HIGH 0x02 @@ -470,8 +487,14 @@ struct code_hw_breakpoint code_breaks[CODE_BREAK_NUM]; static void init_code_breakpoints(stlink_t *sl) { memset(sl->q_buf, 0, 4); stlink_write_debug32(sl, CM3_REG_FP_CTRL, 0x03 /*KEY | ENABLE4*/); - printf("KARL - should read back as 0x03, not 60 02 00 00\n"); - stlink_read_debug32(sl, CM3_REG_FP_CTRL); + unsigned int val = stlink_read_debug32(sl, CM3_REG_FP_CTRL); + if (((val & 3) != 1) || + ((((val >> 8) & 0x70) | ((val >> 4) & 0xf)) != CODE_BREAK_NUM) || + (((val >> 8) & 0xf) != CODE_LIT_NUM)){ + fprintf(stderr, "[FP_CTRL] = 0x%08x expecting 0x%08x\n", val, + ((CODE_BREAK_NUM & 0x70) << 8) | (CODE_LIT_NUM << 8) | ((CODE_BREAK_NUM & 0xf) << 4) | 1); + } + for(int i = 0; i < CODE_BREAK_NUM; i++) { code_breaks[i].type = 0; @@ -510,7 +533,7 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { else brk->type &= ~type; if(brk->type == 0) { - #ifdef DEBUG + #if DEBUG printf("clearing hw break %d\n", id); #endif @@ -518,7 +541,7 @@ static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) { } else { uint32_t mask = (brk->addr) | 1 | (brk->type << 30); - #ifdef DEBUG + #if DEBUG printf("setting hw break %d at %08x (%d)\n", id, brk->addr, brk->type); printf("reg %08x \n", @@ -614,7 +637,7 @@ static int flash_go(stlink_t *sl) { stlink_reset(sl); for(struct flash_block* fb = flash_root; fb; fb = fb->next) { - #ifdef DEBUG + #if DEBUG printf("flash_do: block %08x -> %04x\n", fb->addr, fb->length); #endif @@ -624,7 +647,7 @@ static int flash_go(stlink_t *sl) { //Update FLASH_PAGE stlink_calculate_pagesize(sl, page); - #ifdef DEBUG + #if DEBUG printf("flash_do: page %08x\n", page); #endif @@ -663,7 +686,7 @@ int serve(stlink_t *sl, st_state_t *st) { struct sockaddr_in serv_addr; memset(&serv_addr,0,sizeof(struct sockaddr_in)); serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); + serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(st->listen_port); if(bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { @@ -676,11 +699,6 @@ int serve(stlink_t *sl, st_state_t *st) { return 1; } - stlink_force_debug(sl); - stlink_reset(sl); - init_code_breakpoints(sl); - init_data_watchpoints(sl); - printf("Listening at *:%d...\n", st->listen_port); int client = accept(sock, NULL, NULL); @@ -692,6 +710,13 @@ int serve(stlink_t *sl, st_state_t *st) { close(sock); + stlink_force_debug(sl); + if (st->reset) { + stlink_reset(sl); + } + init_code_breakpoints(sl); + init_data_watchpoints(sl); + printf("GDB connected.\n"); /* @@ -709,7 +734,7 @@ int serve(stlink_t *sl, st_state_t *st) { return 1; } - #ifdef DEBUG + #if DEBUG printf("recv: %s\n", packet); #endif @@ -734,7 +759,7 @@ int serve(stlink_t *sl, st_state_t *st) { char* queryName = calloc(queryNameLength + 1, 1); strncpy(queryName, &packet[1], queryNameLength); - #ifdef DEBUG + #if DEBUG printf("query: %s;%s\n", queryName, params); #endif @@ -759,7 +784,7 @@ int serve(stlink_t *sl, st_state_t *st) { unsigned addr = strtoul(__s_addr, NULL, 16), length = strtoul(s_length, NULL, 16); - #ifdef DEBUG + #if DEBUG printf("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n", type, op, annex, addr, length); #endif @@ -796,7 +821,7 @@ int serve(stlink_t *sl, st_state_t *st) { if (!strncmp(params,"726573756d65",12)) {// resume -#ifdef DEBUG +#if DEBUG printf("Rcmd: resume\n"); #endif stlink_run(sl); @@ -807,7 +832,7 @@ int serve(stlink_t *sl, st_state_t *st) { stlink_force_debug(sl); -#ifdef DEBUG +#if DEBUG printf("Rcmd: halt\n"); #endif } else if (!strncmp(params,"6a7461675f7265736574",20)) { //jtag_reset @@ -817,7 +842,7 @@ int serve(stlink_t *sl, st_state_t *st) { stlink_jtag_reset(sl, 0); stlink_force_debug(sl); -#ifdef DEBUG +#if DEBUG printf("Rcmd: jtag_reset\n"); #endif } else if (!strncmp(params,"7265736574",10)) { //reset @@ -828,11 +853,11 @@ int serve(stlink_t *sl, st_state_t *st) { init_code_breakpoints(sl); init_data_watchpoints(sl); -#ifdef DEBUG +#if DEBUG printf("Rcmd: reset\n"); #endif } else { -#ifdef DEBUG +#if DEBUG printf("Rcmd: %s\n", params); #endif @@ -864,7 +889,7 @@ int serve(stlink_t *sl, st_state_t *st) { unsigned addr = strtoul(__s_addr, NULL, 16), length = strtoul(s_length, NULL, 16); - #ifdef DEBUG + #if DEBUG printf("FlashErase: addr:%08x,len:%04x\n", addr, length); #endif @@ -902,7 +927,7 @@ int serve(stlink_t *sl, st_state_t *st) { if(dec_index % 2 != 0) dec_index++; - #ifdef DEBUG + #if DEBUG printf("binary packet %d -> %d\n", data_length, dec_index); #endif @@ -1244,7 +1269,7 @@ int serve(stlink_t *sl, st_state_t *st) { } if(reply) { - #ifdef DEBUG + #if DEBUG printf("send: %s\n", reply); #endif