Added code so gdbserver can fully support the STM32F4 variable page sizes
[fw/stlink] / gdbserver / gdb-server.c
1 /* -*- tab-width:8 -*- */
2 #define DEBUG 0
3 /*
4  Copyright (C)  2011 Peter Zotov <whitequark@whitequark.org>
5  Use of this source code is governed by a BSD-style
6  license that can be found in the LICENSE file.
7 */
8
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <sys/types.h>
14 #include <sys/socket.h>
15 #include <netinet/in.h>
16 #include <arpa/inet.h>
17 #include <signal.h>
18
19 #include <stlink-common.h>
20
21 #include "gdb-remote.h"
22
23 #define FLASH_BASE 0x08000000
24
25 //Allways update the FLASH_PAGE before each use, by calling stlink_calculate_pagesize
26 #define FLASH_PAGE (sl->flash_pgsz)
27
28 volatile int do_exit = 0;
29 void ctrl_c(int sig)
30 {
31   do_exit = 1;
32 }
33
34 static const char hex[] = "0123456789abcdef";
35
36 static const char* current_memory_map = NULL;
37
38 struct chip_params {
39         uint32_t chip_id;
40         char* description;
41         uint32_t flash_size_reg;
42         uint32_t max_flash_size, flash_pagesize;
43         uint32_t sram_size;
44         uint32_t bootrom_base, bootrom_size;
45 } const devices[] = {
46         { 0x410, "F1 Medium-density device", 0x1ffff7e0,
47           0x20000,  0x400, 0x5000,  0x1ffff000, 0x800  },               // table 2, pm0063
48         { 0x411, "F2 device", 0, /* No flash size register found in the docs*/
49           0x100000,   0x20000, 0x20000, 0x1fff0000, 0x7800  },  // table 1, pm0059
50         { 0x412, "F1 Low-density device", 0x1ffff7e0,
51           0x8000,   0x400, 0x2800,  0x1ffff000, 0x800  },               // table 1, pm0063
52           /*Page size is variable */
53         { 0x413, "F4 device", 0x1FFF7A10,                                               //RM0090 error same as unique ID
54           0x100000,   0x4000, 0x30000,  0x1fff0000, 0x7800  },  // table 1, pm0081
55         { 0x414, "F1 High-density device", 0x1ffff7e0,
56           0x80000,  0x800, 0x10000, 0x1ffff000, 0x800  },               // table 3 pm0063
57           // This ignores the EEPROM! (and uses the page erase size,
58           // not the sector write protection...)
59         { 0x416, "L1 Med-density device", 0x1FF8004C,                   // table 1, pm0062
60           0x20000, 0x100, 0x4000, 0x1ff00000, 0x1000 },
61         { 0x418, "F1 Connectivity line device", 0x1ffff7e0,
62           0x40000,  0x800, 0x10000, 0x1fffb000, 0x4800 },
63         { 0x420, "F1 Medium-density value line device", 0x1ffff7e0,
64           0x20000,  0x400, 0x2000,  0x1ffff000, 0x800  },
65         { 0x428, "F1 High-density value line device", 0x1ffff7e0,
66           0x80000,  0x800, 0x8000,  0x1ffff000, 0x800  },
67         { 0x430, "F1 XL-density device", 0x1ffff7e0,                    // pm0068
68           0x100000, 0x800, 0x18000, 0x1fffe000, 0x1800 },
69         { 0 }
70 };
71
72 int serve(stlink_t *sl, int port);
73 char* make_memory_map(stlink_t *sl, const struct chip_params *params, uint32_t flash_size);
74
75 int main(int argc, char** argv) {
76
77         stlink_t *sl = NULL;
78         int port = 0;
79         uint32_t flash_size;
80
81         const char * HelpStr =  "\nUsage:\n"
82                                  "\tst-util [Arguments]\n"
83                                  "\tArguments (no more than 2):\n"
84                                   "\t\t<Port>: Port. Default: 4242.\n"
85                                   "\t\t{usb|sgauto|/dev/sgX}: Transport, "
86                                    "where X = {0, 1, 2, ...}. Default: USB.\n"
87                                  "\tExamples:\n"
88                                   "\t\tst-util 1234\n"
89                                   "\t\tst-util sgauto\n"
90                                   "\t\tst-util 1234 usb\n"
91                                   "\t\tst-util /dev/sgX 1234\n"
92                                   "\t\tst-util 1234 /dev/sgX\n";
93         
94         
95         // Parsing the arguments of command line ...
96         
97         if (argc == 1 || argc > 3) {
98             fprintf(stderr, HelpStr, NULL);
99             return 1;
100         }
101                 
102         for(int a = 1; a < argc; a++) {
103             
104             // Port
105             int p = atoi(argv[a]);
106             if (p < 0 || p > 0xFFFF) {
107                 fprintf(stderr, "Invalid port\n");
108                 fprintf(stderr, HelpStr, NULL);
109                 return 1;
110             }
111             if (p > 0 && port == 0) {port = p; continue;}
112             
113             // if (p == 0) ...
114             
115             if (sl != NULL) {
116                 fprintf(stderr, "Invalid argumets\n");
117                 fprintf(stderr, HelpStr, NULL);
118                 return 1;
119             }
120             
121             // usb
122             if (!strcmp(argv[a], "usb")) {
123                 sl = stlink_open_usb(10);
124                 if(sl == NULL) return 1;
125                 continue;
126             }
127
128             // /dev/sgX
129             if (!strncmp(argv[a], "/dev/sgX", 7)) {
130                 if(!CONFIG_USE_LIBSG) {
131                     fprintf(stderr, "libsg not use\n");
132                     return 1;
133                 }
134                 sl = stlink_quirk_open(argv[a], 0);
135                 if(sl == NULL) return 1;
136                 continue;
137             }
138
139             // sg_auto
140             if (!strcmp(argv[a], "sgauto")) {
141                 if(!CONFIG_USE_LIBSG) {
142                     fprintf(stderr, "libsg not use\n");
143                     return 1;
144                 }
145
146                 // Search ST-LINK (from /dev/sg0 to /dev/sg99)
147                 for(int DevNum = 0; DevNum <= 99; DevNum++)
148                 {
149                     if(DevNum < 10) {
150                         char DevName[] = "/dev/sgX";
151                         DevName[7] = DevNum + '0';
152                         if ( !access(DevName, F_OK) )
153                             sl = stlink_quirk_open(DevName, 0);
154                     }
155                     else {
156                         char DevName[] = "/dev/sgXY";
157                         DevName[7] = DevNum/10 + '0';
158                         DevName[8] = DevNum%10 + '0';
159                         if ( !access(DevName, F_OK) )
160                             sl = stlink_quirk_open(DevName, 0);
161                     }
162                     if (sl != NULL) break;
163                 }
164
165                 if(sl == NULL) return 1;
166                 continue;
167             }
168             
169             // Invalid argumets
170             fprintf(stderr, "Invalid argumets\n");
171             fprintf(stderr, HelpStr, NULL);
172             return 1;
173         }
174          
175         // Default transport: USB
176         if (sl == NULL) sl = stlink_open_usb(10);
177         // Default port: 4242
178         if (port == 0) port = 4242;
179         
180         // End parsing
181         
182         
183         if (sl == NULL) return 1;
184
185         if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) {
186                 stlink_exit_dfu_mode(sl);
187         }
188
189         if(stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) {
190           stlink_enter_swd_mode(sl);
191         }
192
193         stlink_identify_device(sl);
194         printf("Chip ID is %08x, Core ID is  %08x.\n", sl->chip_id, sl->core_id);
195
196         sl->verbose=0;
197
198         const struct chip_params* params = NULL;
199
200         for(int i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) {
201                 if(devices[i].chip_id == (sl->chip_id & 0xFFF)) {
202                         params = &devices[i];
203                         break;
204                 }
205         }
206
207         if(params == NULL) {
208                 fprintf(stderr, "Cannot recognize the connected device!\n");
209                 return 0;
210         }
211
212         printf("Device connected: %s\n", params->description);
213
214         if(sl->chip_id==STM32F4_CHIP_ID) {
215                 flash_size=0x100000;                    //todo: RM0090 error; size register same address as unique ID
216                 printf("Device parameters: SRAM: 0x%x bytes, Flash: up to 0x%x bytes with variable page size\n",
217                         params->sram_size, flash_size);
218         }
219         else {
220                 printf("Device parameters: SRAM: 0x%x bytes, Flash: up to 0x%x bytes in pages of 0x%x bytes\n",
221                         params->sram_size, params->max_flash_size, params->flash_pagesize);
222                 stlink_read_mem32(sl, params->flash_size_reg, 4);
223                 flash_size = sl->q_buf[0] | (sl->q_buf[1] << 8);
224                 //flash_size_reg is in 1k blocks.
225                 flash_size *= 0x400;
226         }
227
228         /* Init PAGE_SIZE for fixed page size devices.
229          * stlink_calculate_pagesize will then return this value for them.
230          * variable pagesize devices must allways update FLASH_PAGE before use! */
231         FLASH_PAGE = params->flash_pagesize;
232         sl->flash_size=flash_size;
233
234         printf("Flash size is %d\n", flash_size);
235         current_memory_map = make_memory_map(sl, params, flash_size);
236
237         while(serve(sl, port) == 0);
238
239         /* Switch back to mass storage mode before closing. */
240         stlink_run(sl);
241         stlink_exit_debug_mode(sl);
242         stlink_close(sl);
243
244         return 0;
245 }
246
247 static const char* const memory_map_template_F4 =
248   "<?xml version=\"1.0\"?>"
249   "<!DOCTYPE memory-map PUBLIC \"+//IDN gnu.org//DTD GDB Memory Map V1.0//EN\""
250   "     \"http://sourceware.org/gdb/gdb-memory-map.dtd\">"
251   "<memory-map>"
252   "  <memory type=\"rom\" start=\"0x00000000\" length=\"0x100000\"/>"       // code = sram, bootrom or flash; flash is bigger
253   "  <memory type=\"ram\" start=\"0x20000000\" length=\"0x30000\"/>"        // sram
254   "  <memory type=\"flash\" start=\"0x08000000\" length=\"0x10000\">"           //Sectors 0..3
255   "    <property name=\"blocksize\">0x4000</property>"                                          //16kB
256   "  </memory>"
257   "  <memory type=\"flash\" start=\"0x08010000\" length=\"0x10000\">"           //Sector 4
258   "    <property name=\"blocksize\">0x10000</property>"                                         //64kB
259   "  </memory>"
260   "  <memory type=\"flash\" start=\"0x08020000\" length=\"0x70000\">"           //Sectors 5..11
261   "    <property name=\"blocksize\">0x20000</property>"                                         //128kB
262   "  </memory>"
263   "  <memory type=\"ram\" start=\"0x40000000\" length=\"0x1fffffff\"/>"         // peripheral regs
264   "  <memory type=\"ram\" start=\"0xe0000000\" length=\"0x1fffffff\"/>"         // cortex regs
265   "  <memory type=\"rom\" start=\"0x1fff0000\" length=\"0x7800\"/>"         // bootrom
266   "  <memory type=\"rom\" start=\"0x1fffc000\" length=\"0x10\"/>"               // option byte area
267   "</memory-map>";
268
269 static const char* const memory_map_template =
270   "<?xml version=\"1.0\"?>"
271   "<!DOCTYPE memory-map PUBLIC \"+//IDN gnu.org//DTD GDB Memory Map V1.0//EN\""
272   "     \"http://sourceware.org/gdb/gdb-memory-map.dtd\">"
273   "<memory-map>"
274   "  <memory type=\"rom\" start=\"0x00000000\" length=\"0x%x\"/>"       // code = sram, bootrom or flash; flash is bigger
275   "  <memory type=\"ram\" start=\"0x20000000\" length=\"0x%x\"/>"       // sram 8k
276   "  <memory type=\"flash\" start=\"0x08000000\" length=\"0x%x\">"
277   "    <property name=\"blocksize\">0x%x</property>"
278   "  </memory>"
279   "  <memory type=\"ram\" start=\"0x40000000\" length=\"0x1fffffff\"/>" // peripheral regs
280   "  <memory type=\"ram\" start=\"0xe0000000\" length=\"0x1fffffff\"/>" // cortex regs
281   "  <memory type=\"rom\" start=\"0x%08x\" length=\"0x%x\"/>"           // bootrom
282   "  <memory type=\"rom\" start=\"0x1ffff800\" length=\"0x8\"/>"        // option byte area
283   "</memory-map>";
284
285 char* make_memory_map(stlink_t *sl, const struct chip_params *params, uint32_t flash_size) {
286         /* This will be freed in serve() */
287         char* map = malloc(4096);
288         map[0] = '\0';
289
290         if(sl->chip_id==STM32F4_CHIP_ID) {
291         strcpy(map, memory_map_template_F4);
292     }
293
294     else {
295         snprintf(map, 4096, memory_map_template,
296                         flash_size,
297                         params->sram_size,
298                         flash_size, params->flash_pagesize,
299                         params->bootrom_base, params->bootrom_size);
300     }
301         return map;
302 }
303
304
305 /* 
306  * DWT_COMP0     0xE0001020
307  * DWT_MASK0     0xE0001024
308  * DWT_FUNCTION0 0xE0001028
309  * DWT_COMP1     0xE0001030
310  * DWT_MASK1     0xE0001034
311  * DWT_FUNCTION1 0xE0001038
312  * DWT_COMP2     0xE0001040
313  * DWT_MASK2     0xE0001044
314  * DWT_FUNCTION2 0xE0001048
315  * DWT_COMP3     0xE0001050
316  * DWT_MASK3     0xE0001054
317  * DWT_FUNCTION3 0xE0001058
318  */
319
320 #define DATA_WATCH_NUM 4
321
322 enum watchfun { WATCHDISABLED = 0, WATCHREAD = 5, WATCHWRITE = 6, WATCHACCESS = 7 };
323
324 struct code_hw_watchpoint {
325         stm32_addr_t addr;
326         uint8_t mask;
327         enum watchfun fun;
328 };
329
330 struct code_hw_watchpoint data_watches[DATA_WATCH_NUM];
331
332 static void init_data_watchpoints(stlink_t *sl) {
333         #ifdef DEBUG
334         printf("init watchpoints\n");
335         #endif
336
337         // set trcena in debug command to turn on dwt unit
338         stlink_read_mem32(sl, 0xE000EDFC, 4);
339         sl->q_buf[3] |= 1;
340         stlink_write_mem32(sl, 0xE000EDFC, 4);
341
342         // make sure all watchpoints are cleared
343         memset(sl->q_buf, 0, 4);
344         for(int i = 0; i < DATA_WATCH_NUM; i++) {
345                 data_watches[i].fun = WATCHDISABLED;
346                 stlink_write_mem32(sl, 0xe0001028 + i * 16, 4);
347         }
348 }
349
350 static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr, unsigned int len)
351 {
352         int i = 0;
353         uint32_t mask;
354
355         // computer mask
356         // find a free watchpoint
357         // configure
358
359         mask = -1;
360         i = len;
361         while(i) {
362                 i >>= 1;
363                 mask++;
364         }
365
366         if((mask != -1) && (mask < 16)) {
367                 for(i = 0; i < DATA_WATCH_NUM; i++) {
368                         // is this an empty slot ?
369                         if(data_watches[i].fun == WATCHDISABLED) {
370                                 #ifdef DEBUG
371                                 printf("insert watchpoint %d addr %x wf %u mask %u len %d\n", i, addr, wf, mask, len);
372                                 #endif
373
374                                 data_watches[i].fun = wf;
375                                 data_watches[i].addr = addr;
376                                 data_watches[i].mask = mask;
377
378                                 // insert comparator address
379                                 sl->q_buf[0] = (addr & 0xff);
380                                 sl->q_buf[1] = ((addr >> 8) & 0xff);
381                                 sl->q_buf[2] = ((addr >> 16) & 0xff);
382                                 sl->q_buf[3] = ((addr >> 24)  & 0xff);
383
384                                 stlink_write_mem32(sl, 0xE0001020 + i * 16, 4);
385
386                                 // insert mask
387                                 memset(sl->q_buf, 0, 4);
388                                 sl->q_buf[0] = mask;
389                                 stlink_write_mem32(sl, 0xE0001024 + i * 16, 4);
390
391                                 // insert function
392                                 memset(sl->q_buf, 0, 4);
393                                 sl->q_buf[0] = wf;
394                                 stlink_write_mem32(sl, 0xE0001028 + i * 16, 4);
395
396                                 // just to make sure the matched bit is clear !
397                                 stlink_read_mem32(sl,  0xE0001028 + i * 16, 4);
398                                 return 0;
399                         }
400                 }
401         }
402
403         #ifdef DEBUG
404         printf("failure: add watchpoints addr %x wf %u len %u\n", addr, wf, len);
405         #endif
406         return -1;
407 }
408
409 static int delete_data_watchpoint(stlink_t *sl, stm32_addr_t addr)
410 {
411         int i;
412
413         for(i = 0 ; i < DATA_WATCH_NUM; i++) {
414                 if((data_watches[i].addr == addr) && (data_watches[i].fun != WATCHDISABLED)) {
415                         #ifdef DEBUG
416                         printf("delete watchpoint %d addr %x\n", i, addr);
417                         #endif
418
419                         memset(sl->q_buf, 0, 4);
420                         data_watches[i].fun = WATCHDISABLED;
421                         stlink_write_mem32(sl, 0xe0001028 + i * 16, 4);
422
423                         return 0;
424                 }
425         }
426
427         #ifdef DEBUG
428         printf("failure: delete watchpoint addr %x\n", addr);
429         #endif
430
431         return -1;
432 }
433
434 #define CODE_BREAK_NUM  6
435 #define CODE_BREAK_LOW  0x01
436 #define CODE_BREAK_HIGH 0x02
437
438 struct code_hw_breakpoint {
439         stm32_addr_t addr;
440         int          type;
441 };
442
443 struct code_hw_breakpoint code_breaks[CODE_BREAK_NUM];
444
445 static void init_code_breakpoints(stlink_t *sl) {
446         memset(sl->q_buf, 0, 4);
447         sl->q_buf[0] = 0x03; // KEY | ENABLE
448         stlink_write_mem32(sl, CM3_REG_FP_CTRL, 4);
449         printf("KARL - should read back as 0x03, not 60 02 00 00\n");
450         stlink_read_mem32(sl, CM3_REG_FP_CTRL, 4);
451
452         memset(sl->q_buf, 0, 4);
453         for(int i = 0; i < CODE_BREAK_NUM; i++) {
454                 code_breaks[i].type = 0;
455                 stlink_write_mem32(sl, CM3_REG_FP_COMP0 + i * 4, 4);
456         }
457 }
458
459 static int update_code_breakpoint(stlink_t *sl, stm32_addr_t addr, int set) {
460         stm32_addr_t fpb_addr = addr & ~0x3;
461         int type = addr & 0x2 ? CODE_BREAK_HIGH : CODE_BREAK_LOW;
462
463         if(addr & 1) {
464                 fprintf(stderr, "update_code_breakpoint: unaligned address %08x\n", addr);
465                 return -1;
466         }
467
468         int id = -1;
469         for(int i = 0; i < CODE_BREAK_NUM; i++) {
470                 if(fpb_addr == code_breaks[i].addr ||
471                         (set && code_breaks[i].type == 0)) {
472                         id = i;
473                         break;
474                 }
475         }
476
477         if(id == -1) {
478                 if(set) return -1; // Free slot not found
479                 else    return 0;  // Breakpoint is already removed
480         }
481
482         struct code_hw_breakpoint* brk = &code_breaks[id];
483
484         brk->addr = fpb_addr;
485
486         if(set) brk->type |= type;
487         else    brk->type &= ~type;
488
489         memset(sl->q_buf, 0, 4);
490
491         if(brk->type == 0) {
492                 #ifdef DEBUG
493                 printf("clearing hw break %d\n", id);
494                 #endif
495
496                 stlink_write_mem32(sl, 0xe0002008 + id * 4, 4);
497         } else {
498                 sl->q_buf[0] = ( brk->addr        & 0xff) | 1;
499                 sl->q_buf[1] = ((brk->addr >> 8)  & 0xff);
500                 sl->q_buf[2] = ((brk->addr >> 16) & 0xff);
501                 sl->q_buf[3] = ((brk->addr >> 24) & 0xff) | (brk->type << 6);
502
503                 #ifdef DEBUG
504                 printf("setting hw break %d at %08x (%d)\n",
505                         id, brk->addr, brk->type);
506                 printf("reg %02x %02x %02x %02x\n",
507                         sl->q_buf[3], sl->q_buf[2], sl->q_buf[1], sl->q_buf[0]);
508                 #endif
509
510                 stlink_write_mem32(sl, 0xe0002008 + id * 4, 4);
511         }
512
513         return 0;
514 }
515
516
517 struct flash_block {
518         stm32_addr_t addr;
519         unsigned     length;
520         uint8_t*     data;
521
522         struct flash_block* next;
523 };
524
525 static struct flash_block* flash_root;
526
527 static int flash_add_block(stm32_addr_t addr, unsigned length, stlink_t *sl) {
528
529         if(addr < FLASH_BASE || addr + length > FLASH_BASE + sl->flash_size) {
530                 fprintf(stderr, "flash_add_block: incorrect bounds\n");
531                 return -1;
532         }
533
534         stlink_calculate_pagesize(sl, addr);
535         if(addr % FLASH_PAGE != 0 || length % FLASH_PAGE != 0) {
536                 fprintf(stderr, "flash_add_block: unaligned block\n");
537                 return -1;
538         }
539
540         struct flash_block* new = malloc(sizeof(struct flash_block));
541         new->next = flash_root;
542
543         new->addr   = addr;
544         new->length = length;
545         new->data   = calloc(length, 1);
546
547         flash_root = new;
548
549         return 0;
550 }
551
552 static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) {
553         int fit_blocks = 0, fit_length = 0;
554
555         for(struct flash_block* fb = flash_root; fb; fb = fb->next) {
556                 /* Block: ------X------Y--------
557                  * Data:            a-----b
558                  *                a--b
559                  *            a-----------b
560                  * Block intersects with data, if:
561                  *  a < Y && b > x
562                  */
563
564                 unsigned X = fb->addr, Y = fb->addr + fb->length;
565                 unsigned a = addr, b = addr + length;
566                 if(a < Y && b > X) {
567                         // from start of the block
568                         unsigned start = (a > X ? a : X) - X;
569                         unsigned end   = (b > Y ? Y : b) - X;
570
571                         memcpy(fb->data + start, data, end - start);
572
573                         fit_blocks++;
574                         fit_length += end - start;
575                 }
576         }
577
578         if(fit_blocks == 0) {
579                 fprintf(stderr, "Unfit data block %08x -> %04x\n", addr, length);
580                 return -1;
581         }
582
583         if(fit_length != length) {
584                 fprintf(stderr, "warning: data block %08x -> %04x truncated to %04x\n",
585                         addr, length, fit_length);
586                 fprintf(stderr, "(this is not an error, just a GDB glitch)\n");
587         }
588
589         return 0;
590 }
591
592 static int flash_go(stlink_t *sl) {
593         int error = -1;
594
595         // Some kinds of clock settings do not allow writing to flash.
596         stlink_reset(sl);
597
598         for(struct flash_block* fb = flash_root; fb; fb = fb->next) {
599                 #ifdef DEBUG
600                 printf("flash_do: block %08x -> %04x\n", fb->addr, fb->length);
601                 #endif
602
603                 unsigned length = fb->length;
604                 for(stm32_addr_t page = fb->addr; page < fb->addr + fb->length; page += FLASH_PAGE) {
605
606                         //Update FLASH_PAGE
607                         stlink_calculate_pagesize(sl, page);
608
609                         #ifdef DEBUG
610                         printf("flash_do: page %08x\n", page);
611                         #endif
612
613                         if(stlink_write_flash(sl, page, fb->data + (page - fb->addr),
614                                         length > FLASH_PAGE ? FLASH_PAGE : length) < 0)
615                                 goto error;
616                         }
617         }
618
619         stlink_reset(sl);
620
621         error = 0;
622
623 error:
624         for(struct flash_block* fb = flash_root, *next; fb; fb = next) {
625                 next = fb->next;
626                 free(fb->data);
627                 free(fb);
628         }
629
630         flash_root = NULL;
631
632         return error;
633 }
634
635 int serve(stlink_t *sl, int port) {
636         int sock = socket(AF_INET, SOCK_STREAM, 0);
637         if(sock < 0) {
638                 perror("socket");
639                 return 1;
640         }
641
642         unsigned int val = 1;
643         setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
644
645         struct sockaddr_in serv_addr = {0};
646         serv_addr.sin_family = AF_INET;
647         serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
648         serv_addr.sin_port = htons(port);
649
650         if(bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
651                 perror("bind");
652                 return 1;
653         }
654
655         if(listen(sock, 5) < 0) {
656                 perror("listen");
657                 return 1;
658         }
659
660         stlink_force_debug(sl);
661         stlink_reset(sl);
662         init_code_breakpoints(sl);
663         init_data_watchpoints(sl);
664
665         printf("Listening at *:%d...\n", port);
666
667         (void) signal (SIGINT, ctrl_c);
668         int client = accept(sock, NULL, NULL);
669         signal (SIGINT, SIG_DFL);
670         if(client < 0) {
671                 perror("accept");
672                 return 1;
673         }
674
675         close(sock);
676
677         printf("GDB connected.\n");
678
679         /*
680          * To allow resetting the chip from GDB it is required to
681          * emulate attaching and detaching to target.
682          */
683         unsigned int attached = 1;
684
685         while(1) {
686                 char* packet;
687
688                 int status = gdb_recv_packet(client, &packet);
689                 if(status < 0) {
690                         fprintf(stderr, "cannot recv: %d\n", status);
691                         return 1;
692                 }
693
694                 #ifdef DEBUG
695                 printf("recv: %s\n", packet);
696                 #endif
697
698                 char* reply = NULL;
699                 reg regp;
700
701                 switch(packet[0]) {
702                 case 'q': {
703                         if(packet[1] == 'P' || packet[1] == 'C' || packet[1] == 'L') {
704                                 reply = strdup("");
705                                 break;
706                         }
707
708                         char *separator = strstr(packet, ":"), *params = "";
709                         if(separator == NULL) {
710                                 separator = packet + strlen(packet);
711                         } else {
712                                 params = separator + 1;
713                         }
714
715                         unsigned queryNameLength = (separator - &packet[1]);
716                         char* queryName = calloc(queryNameLength + 1, 1);
717                         strncpy(queryName, &packet[1], queryNameLength);
718
719                         #ifdef DEBUG
720                         printf("query: %s;%s\n", queryName, params);
721                         #endif
722
723                         if(!strcmp(queryName, "Supported")) {
724                                 reply = strdup("PacketSize=3fff;qXfer:memory-map:read+");
725                         } else if(!strcmp(queryName, "Xfer")) {
726                                 char *type, *op, *s_addr, *s_length;
727                                 char *tok = params;
728                                 char *annex __attribute__((unused));
729
730                                 type     = strsep(&tok, ":");
731                                 op       = strsep(&tok, ":");
732                                 annex    = strsep(&tok, ":");
733                                 s_addr   = strsep(&tok, ",");
734                                 s_length = tok;
735
736                                 unsigned addr = strtoul(s_addr, NULL, 16),
737                                        length = strtoul(s_length, NULL, 16);
738
739                                 #ifdef DEBUG
740                                 printf("Xfer: type:%s;op:%s;annex:%s;addr:%d;length:%d\n",
741                                         type, op, annex, addr, length);
742                                 #endif
743
744                                 const char* data = NULL;
745
746                                 if(!strcmp(type, "memory-map") && !strcmp(op, "read"))
747                                         data = current_memory_map;
748
749                                 if(data) {
750                                         unsigned data_length = strlen(data);
751                                         if(addr + length > data_length)
752                                                 length = data_length - addr;
753
754                                         if(length == 0) {
755                                                 reply = strdup("l");
756                                         } else {
757                                                 reply = calloc(length + 2, 1);
758                                                 reply[0] = 'm';
759                                                 strncpy(&reply[1], data, length);
760                                         }
761                                 }
762                         }
763
764                         if(reply == NULL)
765                                 reply = strdup("");
766
767                         free(queryName);
768
769                         break;
770                 }
771
772                 case 'v': {
773                         char *params = NULL;
774                         char *cmdName = strtok_r(packet, ":;", &params);
775
776                         cmdName++; // vCommand -> Command
777
778                         if(!strcmp(cmdName, "FlashErase")) {
779                                 char *s_addr, *s_length;
780                                 char *tok = params;
781
782                                 s_addr   = strsep(&tok, ",");
783                                 s_length = tok;
784
785                                 unsigned addr = strtoul(s_addr, NULL, 16),
786                                        length = strtoul(s_length, NULL, 16);
787
788                                 #ifdef DEBUG
789                                 printf("FlashErase: addr:%08x,len:%04x\n",
790                                         addr, length);
791                                 #endif
792
793                                 if(flash_add_block(addr, length, sl) < 0) {
794                                         reply = strdup("E00");
795                                 } else {
796                                         reply = strdup("OK");
797                                 }
798                         } else if(!strcmp(cmdName, "FlashWrite")) {
799                                 char *s_addr, *data;
800                                 char *tok = params;
801
802                                 s_addr = strsep(&tok, ":");
803                                 data   = tok;
804
805                                 unsigned addr = strtoul(s_addr, NULL, 16);
806                                 unsigned data_length = status - (data - packet);
807
808                                 // Length of decoded data cannot be more than
809                                 // encoded, as escapes are removed.
810                                 // Additional byte is reserved for alignment fix.
811                                 uint8_t *decoded = calloc(data_length + 1, 1);
812                                 unsigned dec_index = 0;
813                                 for(int i = 0; i < data_length; i++) {
814                                         if(data[i] == 0x7d) {
815                                                 i++;
816                                                 decoded[dec_index++] = data[i] ^ 0x20;
817                                         } else {
818                                                 decoded[dec_index++] = data[i];
819                                         }
820                                 }
821
822                                 // Fix alignment
823                                 if(dec_index % 2 != 0)
824                                         dec_index++;
825
826                                 #ifdef DEBUG
827                                 printf("binary packet %d -> %d\n", data_length, dec_index);
828                                 #endif
829
830                                 if(flash_populate(addr, decoded, dec_index) < 0) {
831                                         reply = strdup("E00");
832                                 } else {
833                                         reply = strdup("OK");
834                                 }
835                         } else if(!strcmp(cmdName, "FlashDone")) {
836                                 if(flash_go(sl) < 0) {
837                                         reply = strdup("E00");
838                                 } else {
839                                         reply = strdup("OK");
840                                 }
841                         } else if(!strcmp(cmdName, "Kill")) {
842                                 attached = 0;
843
844                                 reply = strdup("OK");
845                         }
846
847                         if(reply == NULL)
848                                 reply = strdup("");
849
850                         break;
851                 }
852
853                 case 'c':
854                         stlink_run(sl);
855
856                         while(1) {
857                                 int status = gdb_check_for_interrupt(client);
858                                 if(status < 0) {
859                                         fprintf(stderr, "cannot check for int: %d\n", status);
860                                         return 1;
861                                 }
862
863                                 if(status == 1) {
864                                         stlink_force_debug(sl);
865                                         break;
866                                 }
867
868                                 stlink_status(sl);
869                                 if(sl->core_stat == STLINK_CORE_HALTED) {
870                                         break;
871                                 }
872
873                                 usleep(100000);
874                         }
875
876                         reply = strdup("S05"); // TRAP
877                         break;
878
879                 case 's':
880                         stlink_step(sl);
881
882                         reply = strdup("S05"); // TRAP
883                         break;
884
885                 case '?':
886                         if(attached) {
887                                 reply = strdup("S05"); // TRAP
888                         } else {
889                                 /* Stub shall reply OK if not attached. */
890                                 reply = strdup("OK");
891                         }
892                         break;
893
894                 case 'g':
895                         stlink_read_all_regs(sl, &regp);
896
897                         reply = calloc(8 * 16 + 1, 1);
898                         for(int i = 0; i < 16; i++)
899                                 sprintf(&reply[i * 8], "%08x", htonl(regp.r[i]));
900
901                         break;
902
903                 case 'p': {
904                         unsigned id = strtoul(&packet[1], NULL, 16);
905                         unsigned myreg = 0xDEADDEAD;
906
907                         if(id < 16) {
908                                 stlink_read_reg(sl, id, &regp);
909                                 myreg = htonl(regp.r[id]);
910                         } else if(id == 0x19) {
911                                 stlink_read_reg(sl, 16, &regp);
912                                 myreg = htonl(regp.xpsr);
913                         } else {
914                                 reply = strdup("E00");
915                         }
916
917                         reply = calloc(8 + 1, 1);
918                         sprintf(reply, "%08x", myreg);
919
920                         break;
921                 }
922
923                 case 'P': {
924                         char* s_reg = &packet[1];
925                         char* s_value = strstr(&packet[1], "=") + 1;
926
927                         unsigned reg   = strtoul(s_reg,   NULL, 16);
928                         unsigned value = strtoul(s_value, NULL, 16);
929
930                         if(reg < 16) {
931                                 stlink_write_reg(sl, ntohl(value), reg);
932                         } else if(reg == 0x19) {
933                                 stlink_write_reg(sl, ntohl(value), 16);
934                         } else {
935                                 reply = strdup("E00");
936                         }
937
938                         if(!reply) {
939                                 reply = strdup("OK");
940                         }
941
942                         break;
943                 }
944
945                 case 'G':
946                         for(int i = 0; i < 16; i++) {
947                                 char str[9] = {0};
948                                 strncpy(str, &packet[1 + i * 8], 8);
949                                 uint32_t reg = strtoul(str, NULL, 16);
950                                 stlink_write_reg(sl, ntohl(reg), i);
951                         }
952
953                         reply = strdup("OK");
954                         break;
955
956                 case 'm': {
957                         char* s_start = &packet[1];
958                         char* s_count = strstr(&packet[1], ",") + 1;
959
960                         stm32_addr_t start = strtoul(s_start, NULL, 16);
961                         unsigned     count = strtoul(s_count, NULL, 16);
962
963                         unsigned adj_start = start % 4;
964
965                         stlink_read_mem32(sl, start - adj_start, (count % 4 == 0) ?
966                                                 count : count + 4 - (count % 4));
967
968                         reply = calloc(count * 2 + 1, 1);
969                         for(int i = 0; i < count; i++) {
970                                 reply[i * 2 + 0] = hex[sl->q_buf[i + adj_start] >> 4];
971                                 reply[i * 2 + 1] = hex[sl->q_buf[i + adj_start] & 0xf];
972                         }
973
974                         break;
975                 }
976
977                 case 'M': {
978                         char* s_start = &packet[1];
979                         char* s_count = strstr(&packet[1], ",") + 1;
980                         char* hexdata = strstr(packet, ":") + 1;
981
982                         stm32_addr_t start = strtoul(s_start, NULL, 16);
983                         unsigned     count = strtoul(s_count, NULL, 16);
984
985                         for(int i = 0; i < count; i ++) {
986                                 char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 };
987                                 uint8_t byte = strtoul(hex, NULL, 16);
988                                 sl->q_buf[i] = byte;
989                         }
990
991                         if((count % 4) == 0 && (start % 4) == 0) {
992                                 stlink_write_mem32(sl, start, count);
993                         } else {
994                                 stlink_write_mem8(sl, start, count);
995                         }
996
997                         reply = strdup("OK");
998
999                         break;
1000                 }
1001
1002                 case 'Z': {
1003                         char *endptr;
1004                         stm32_addr_t addr = strtoul(&packet[3], &endptr, 16);
1005                         stm32_addr_t len  = strtoul(&endptr[1], NULL, 16);
1006
1007                         switch (packet[1]) {
1008                                 case '1':
1009                                 if(update_code_breakpoint(sl, addr, 1) < 0) {
1010                                         reply = strdup("E00");
1011                                 } else {
1012                                         reply = strdup("OK");
1013                                 }
1014                                 break;
1015
1016                                 case '2':   // insert write watchpoint
1017                                 case '3':   // insert read  watchpoint
1018                                 case '4':   // insert access watchpoint
1019                                 {
1020                                         enum watchfun wf;
1021                                         if(packet[1] == '2') {
1022                                                 wf = WATCHWRITE;
1023                                         } else if(packet[1] == '3') {
1024                                                 wf = WATCHREAD;
1025                                         } else {
1026                                                 wf = WATCHACCESS;
1027                                                 if(add_data_watchpoint(sl, wf, addr, len) < 0) {
1028                                                         reply = strdup("E00");
1029                                                 } else {
1030                                                         reply = strdup("OK");
1031                                                         break;
1032                                                 }
1033                                         }
1034                                 }
1035
1036                                 default:
1037                                 reply = strdup("");
1038                         }
1039                         break;
1040                 }
1041                 case 'z': {
1042                         char *endptr;
1043                         stm32_addr_t addr = strtoul(&packet[3], &endptr, 16);
1044                         //stm32_addr_t len  = strtoul(&endptr[1], NULL, 16);
1045
1046                         switch (packet[1]) {
1047                                 case '1': // remove breakpoint
1048                                 update_code_breakpoint(sl, addr, 0);
1049                                 reply = strdup("OK");
1050                                 break;
1051
1052                                 case '2' : // remove write watchpoint
1053                                 case '3' : // remove read watchpoint
1054                                 case '4' : // remove access watchpoint
1055                                 if(delete_data_watchpoint(sl, addr) < 0) {
1056                                         reply = strdup("E00");
1057                                 } else {
1058                                         reply = strdup("OK");
1059                                         break;
1060                                 }
1061
1062                                 default:
1063                                 reply = strdup("");
1064                         }
1065                         break;
1066                 }
1067
1068                 case '!': {
1069                         /*
1070                          * Enter extended mode which allows restarting.
1071                          * We do support that always.
1072                          */
1073
1074                         reply = strdup("OK");
1075
1076                         break;
1077                 }
1078
1079                 case 'R': {
1080                         /* Reset the core. */
1081
1082                         stlink_reset(sl);
1083                         init_code_breakpoints(sl);
1084                         init_data_watchpoints(sl);
1085
1086                         attached = 1;
1087
1088                         reply = strdup("OK");
1089
1090                         break;
1091                 }
1092
1093                 default:
1094                         reply = strdup("");
1095                 }
1096
1097                 if(reply) {
1098                         #ifdef DEBUG
1099                         printf("send: %s\n", reply);
1100                         #endif
1101
1102                         int result = gdb_send_packet(client, reply);
1103                         if(result != 0) {
1104                                 fprintf(stderr, "cannot send: %d\n", result);
1105                                 return 1;
1106                         }
1107
1108                         free(reply);
1109                 }
1110
1111                 free(packet);
1112         }
1113
1114         return 0;
1115 }