X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=gdbserver%2Fgdb-server.c;h=65297bc0c3dcf56b1c1c40d27bf7ec1e897a662d;hb=e8bae670d226061d567869d24fe3cbc175dff364;hp=c06ea9717aa0eddd7e150418e5a2561ce8416645;hpb=ea11de2d8b1e12f689ae50ed36829c6be6f5929c;p=fw%2Fstlink diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index c06ea97..65297bc 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -6,6 +6,7 @@ license that can be found in the LICENSE file. */ +#include #include #include #include @@ -14,11 +15,18 @@ #include #include #include +#include #include #include "gdb-remote.h" +#define DEFAULT_LOGGING_LEVEL 100 +#define DEFAULT_GDB_LISTEN_PORT 4242 + +#define STRINGIFY_inner(name) #name +#define STRINGIFY(name) STRINGIFY_inner(name) + #define FLASH_BASE 0x08000000 #define FLASH_PAGE (sl->flash_pgsz) #define FLASH_PAGE_MASK (~((1 << 10) - 1)) @@ -32,6 +40,11 @@ static const char* current_memory_map = NULL; * Chip IDs are explained in the appropriate programming manual for the * DBGMCU_IDCODE register (0xE0042000) */ + +#define CORE_M3_R1 0x1BA00477 +#define CORE_M3_R2 0x4BA00477 +#define CORE_M4_R0 0x2BA01477 + struct chip_params { uint32_t chip_id; char* description; @@ -43,11 +56,11 @@ struct chip_params { { 0x410, "F1 Medium-density device", 0x1ffff7e0, 0x20000, 0x400, 0x5000, 0x1ffff000, 0x800 }, // table 2, pm0063 { 0x411, "F2 device", 0, /* No flash size register found in the docs*/ - 0x100000, 0x20000, 0x20000, 0x1ff00000, 0x7800 }, // table 1, pm0059 + 0x100000, 0x20000, 0x20000, 0x1fff0000, 0x7800 }, // table 1, pm0059 { 0x412, "F1 Low-density device", 0x1ffff7e0, 0x8000, 0x400, 0x2800, 0x1ffff000, 0x800 }, // table 1, pm0063 { 0x413, "F4 device", 0x1FFF7A10, - 0x100000, 0x20000, 0x20000, 0x1ff00000, 0x7800 }, // table 1, pm0081 + 0x100000, 0x20000, 0x30000, 0x1fff0000, 0x7800 }, // table 1, pm0081 { 0x414, "F1 High-density device", 0x1ffff7e0, 0x80000, 0x800, 0x10000, 0x1ffff000, 0x800 }, // table 3 pm0063 // This ignores the EEPROM! (and uses the page erase size, @@ -65,84 +78,181 @@ struct chip_params { { 0 } }; -int serve(stlink_t *sl, int port); -char* make_memory_map(const struct chip_params *params, uint32_t flash_size); +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; +} st_state_t; -int main(int argc, char** argv) { - stlink_t *sl = NULL; +int serve(stlink_t *sl, int port); +char* make_memory_map(const struct chip_params *params, uint32_t flash_size); - const char * HelpStr = "Usage:\n" - "\t st-util port [/dev/sgX]\n" - "\t st-util [port]\n" - "\t st-util --help\n"; - switch(argc) { +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'}, + {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" + " -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" + " -p 4242, --listen_port=1234\n" + "\t\t\tSet the gdb server listen port. " + "(default port: " STRINGIFY(DEFAULT_GDB_LISTEN_PORT) ")\n" + ; + + + int option_index = 0; + int c; + int q; + while ((c = getopt_long(argc, argv, "hv::d:s:1p:", 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"); + printf("option %s", long_options[option_index].name); + if (optarg) { + printf(" with arg %s", optarg); + } + printf("\n"); + break; + case 'h': + printf(help_str, argv[0]); + exit(EXIT_SUCCESS); + break; + case 'v': + if (optarg) { + st->logging_level = atoi(optarg); + } 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; + break; + case 's': + sscanf(optarg, "%i", &q); + if (q < 0 || q > 2) { + fprintf(stderr, "stlink version %d unknown!\n", q); + exit(EXIT_FAILURE); + } + st->stlink_version = q; + break; + case 'p': + sscanf(optarg, "%i", &q); + if (q < 0) { + fprintf(stderr, "Can't use a negative port to listen on: %d\n", q); + exit(EXIT_FAILURE); + } + st->listen_port = q; + break; + } + } + + if (optind < argc) { + printf("non-option ARGV-elements: "); + while (optind < argc) + printf("%s ", argv[optind++]); + printf("\n"); + } + return 0; +} - default: { - fprintf(stderr, HelpStr, NULL); - return 1; - } - case 3 : { - //sl = stlink_quirk_open(argv[2], 0); - // FIXME - hardcoded to usb.... - sl = stlink_open_usb(argv[2], 10); - if(sl == NULL) return 1; - break; - } +int main(int argc, char** argv) { - case 2 : { - if (strcmp(argv[1], "--help") == 0) { - fprintf(stdout, HelpStr, NULL); - return 1; - } - } + stlink_t *sl = NULL; - case 1 : { // Search ST-LINK (from /dev/sg0 to /dev/sg99) + st_state_t state; + memset(&state, 0, sizeof(state)); + // set defaults... + state.stlink_version = 2; + state.logging_level = DEFAULT_LOGGING_LEVEL; + state.listen_port = DEFAULT_GDB_LISTEN_PORT; + parse_options(argc, argv, &state); + switch (state.stlink_version) { + case 2: + sl = stlink_open_usb(state.logging_level); + if(sl == NULL) return 1; + break; + case 1: + if (strlen(state.devicename) == 0) { const int DevNumMax = 99; int ExistDevCount = 0; - for(int DevNum = 0; DevNum <= DevNumMax; DevNum++) - { - if(DevNum < 10) { + for (int DevNum = 0; DevNum <= DevNumMax; DevNum++) { + if (DevNum < 10) { char DevName[] = "/dev/sgX"; const int X_index = 7; DevName[X_index] = DevNum + '0'; - if ( !access(DevName, F_OK) ) { - sl = stlink_quirk_open(DevName, 0); + if (!access(DevName, F_OK)) { + sl = stlink_v1_open(DevName, 0); ExistDevCount++; } - } - else if(DevNum < 100) { + } else if (DevNum < 100) { char DevName[] = "/dev/sgXY"; const int X_index = 7; const int Y_index = 8; - DevName[X_index] = DevNum/10 + '0'; - DevName[Y_index] = DevNum%10 + '0'; - if ( !access(DevName, F_OK) ) { - sl = stlink_quirk_open(DevName, 0); + DevName[X_index] = DevNum / 10 + '0'; + DevName[Y_index] = DevNum % 10 + '0'; + if (!access(DevName, F_OK)) { + sl = stlink_v1_open(DevName, 0); ExistDevCount++; } } - if(sl != NULL) break; + if (sl != NULL) break; } - if(sl == NULL) { + if (sl == NULL) { fprintf(stdout, "\nNumber of /dev/sgX devices found: %i \n", - ExistDevCount); + ExistDevCount); fprintf(stderr, "ST-LINK not found\n"); return 1; } - break; + } else { + sl = stlink_v1_open(state.devicename, state.logging_level); } - } + break; + } - if(stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) - stlink_enter_swd_mode(sl); + if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { + if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { + stlink_exit_dfu_mode(sl); + } + stlink_enter_swd_mode(sl); + } uint32_t chip_id = stlink_chip_id(sl); - printf("Chip ID is %08x.\n", chip_id); + uint32_t core_id = stlink_core_id(sl); + + /* Fix chip_id for F4 */ + if (((chip_id & 0xFFF) == 0x411) && (core_id == CORE_M4_R0)) { + printf("Fixing wrong chip_id for STM32F4 Rev A errata\n"); + chip_id = 0x413; + } + + printf("Chip ID is %08x, Core ID is %08x.\n", chip_id, core_id); const struct chip_params* params = NULL; @@ -173,17 +283,11 @@ int main(int argc, char** argv) { // memory map is in 1k blocks. current_memory_map = make_memory_map(params, flash_size * 0x400); - int port; - - if(argc == 1) { - port = rand() & 0xffff; - } - else { - port = atoi(argv[1]); - } - - while(serve(sl, port) == 0); + while(serve(sl, state.listen_port) == 0); + /* Switch back to mass storage mode before closing. */ + stlink_run(sl); + stlink_exit_debug_mode(sl); stlink_close(sl); return 0; @@ -581,6 +685,7 @@ int serve(stlink_t *sl, int port) { printf("Listening at *:%d...\n", port); int client = accept(sock, NULL, NULL); + signal (SIGINT, SIG_DFL); if(client < 0) { perror("accept"); return 1;