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