Don't exit after kill gdb command; re-listen instead.
[fw/stlink] / src / 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 "gdb-remote.h"
17 #include "stlink-hw.h"
18
19 static const char hex[] = "0123456789abcdef";
20
21 int serve(struct stlink* sl, int port);
22
23 int main(int argc, char** argv) {
24         if(argc != 3) {
25                 fprintf(stderr, "Usage: %s <port> /dev/sgX\n", argv[0]);
26                 return 1;
27         }
28
29         struct stlink *sl = stlink_quirk_open(argv[2], 0);
30         if (sl == NULL)
31                 return 1;
32
33         if(stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE)
34                 stlink_enter_swd_mode(sl);
35
36         stlink_core_id(sl);
37         printf("Debugging ARM core %08x.\n", sl->core_id);
38
39         int port = atoi(argv[1]);
40
41         while(serve(sl, port) == 0);
42
43         stlink_close(sl);
44
45         return 0;
46 }
47
48 int serve(struct stlink* sl, int port) {
49         int sock = socket(AF_INET, SOCK_STREAM, 0);
50         if(sock < 0) {
51                 perror("socket");
52                 return 1;
53         }
54
55         struct sockaddr_in serv_addr = {0};
56         serv_addr.sin_family = AF_INET;
57         serv_addr.sin_addr.s_addr = INADDR_ANY;
58         serv_addr.sin_port = htons(port);
59
60         if(bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
61                 perror("bind");
62                 return 1;
63         }
64
65         if(listen(sock, 5) < 0) {
66                 perror("listen");
67                 return 1;
68         }
69
70         stlink_force_debug(sl);
71         stlink_reset(sl);
72
73         printf("Listening at *:%d...\n", port);
74
75         int client = accept(sock, NULL, NULL);
76         if(client < 0) {
77                 perror("accept");
78                 return 1;
79         }
80
81         close(sock);
82
83         printf("GDB connected.\n");
84
85         while(1) {
86                 char* packet;
87
88                 int status = gdb_recv_packet(client, &packet);
89                 if(status < 0) {
90                         fprintf(stderr, "cannot recv: %d\n", status);
91                         return 1;
92                 }
93
94                 //printf("recv: %s\n", packet);
95
96                 char* reply = NULL;
97
98                 switch(packet[0]) {
99                 case 'c':
100                         stlink_run(sl);
101
102                         printf("Core running, waiting for interrupt.\n");
103
104                         int status = gdb_wait_for_interrupt(client);
105                         if(status < 0) {
106                                 fprintf(stderr, "cannot wait for int: %d\n", status);
107                                 return 1;
108                         }
109
110                         stlink_force_debug(sl);
111
112                         reply = strdup("S05"); // TRAP
113                         break;
114
115                 case 's':
116                         stlink_step(sl);
117
118                         reply = strdup("S05"); // TRAP
119                         break;
120
121                 case '?':
122                         reply = strdup("S05"); // TRAP
123                         break;
124
125                 case 'g':
126                         stlink_read_all_regs(sl);
127
128                         reply = calloc(8 * 16 + 1, 1);
129                         for(int i = 0; i < 16; i++)
130                                 sprintf(&reply[i * 8], "%08x", htonl(sl->reg.r[i]));
131
132                         break;
133
134                 case 'p': {
135                         unsigned id = strtoul(&packet[1], NULL, 16), reg = 0xDEADDEAD;
136
137                         if(id < 16) {
138                                 stlink_read_reg(sl, id);
139                                 reg = htonl(sl->reg.r[id]);
140                         } else if(id == 0x19) {
141                                 stlink_read_reg(sl, 16);
142                                 reg = htonl(sl->reg.xpsr);
143                         } else {
144                                 reply = strdup("E00");
145                         }
146
147                         reply = calloc(8 + 1, 1);
148                         sprintf(reply, "%08x", reg);
149
150                         break;
151                 }
152
153                 case 'P': {
154                         char* s_reg = &packet[1];
155                         char* s_value = strstr(&packet[1], "=") + 1;
156
157                         unsigned reg   = strtoul(s_reg,   NULL, 16);
158                         unsigned value = strtoul(s_value, NULL, 16);
159
160                         if(reg < 16) {
161                                 stlink_write_reg(sl, ntohl(value), reg);
162                         } else if(reg == 0x19) {
163                                 stlink_write_reg(sl, ntohl(value), 16);
164                         } else {
165                                 reply = strdup("E00");
166                         }
167
168                         if(!reply) {
169                                 reply = strdup("OK");
170                         }
171
172                         break;
173                 }
174
175                 case 'G':
176                         for(int i = 0; i < 16; i++) {
177                                 char str[9] = {0};
178                                 strncpy(str, &packet[1 + i * 8], 8);
179                                 uint32_t reg = strtoul(str, NULL, 16);
180                                 stlink_write_reg(sl, ntohl(reg), i);
181                         }
182
183                         reply = strdup("OK");
184                         break;
185
186                 case 'm': {
187                         char* s_start = &packet[1];
188                         char* s_count = strstr(&packet[1], ",") + 1;
189
190                         stm32_addr_t start = strtoul(s_start, NULL, 16);
191                         unsigned     count = strtoul(s_count, NULL, 16);
192
193                         unsigned adj_start = start % 4;
194
195                         stlink_read_mem32(sl, start - adj_start, (count % 4 == 0) ?
196                                                 count : count + 4 - (count % 4));
197
198                         reply = calloc(count * 2 + 1, 1);
199                         for(int i = 0; i < count; i++) {
200                                 reply[i * 2 + 0] = hex[sl->q_buf[i + adj_start] >> 4];
201                                 reply[i * 2 + 1] = hex[sl->q_buf[i + adj_start] & 0xf];
202                         }
203
204                         break;
205                 }
206
207                 case 'M': {
208                         char* s_start = &packet[1];
209                         char* s_count = strstr(&packet[1], ",") + 1;
210                         char* hexdata = strstr(packet, ":") + 1;
211
212                         stm32_addr_t start = strtoul(s_start, NULL, 16);
213                         unsigned     count = strtoul(s_count, NULL, 16);
214
215                         for(int i = 0; i < count; i ++) {
216                                 char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 };
217                                 uint8_t byte = strtoul(hex, NULL, 16);
218                                 sl->q_buf[i] = byte;
219                         }
220
221                         if((count % 4) == 0 && (start % 4) == 0) {
222                                 stlink_write_mem32(sl, start, count);
223                         } else {
224                                 stlink_write_mem8(sl, start, count);
225                         }
226
227                         reply = strdup("OK");
228
229                         break;
230                 }
231
232                 case 'k': {
233                         // After this function will be entered afterwards, the
234                         // chip will be reset anyway. So this is a no-op.
235
236                         close(client);
237                         return 0;
238                 }
239
240                 default:
241                         reply = strdup("");
242                 }
243
244                 if(reply) {
245                         //printf("send: %s\n", reply);
246
247                         int result = gdb_send_packet(client, reply);
248                         if(result != 0) {
249                                 fprintf(stderr, "cannot send: %d\n", result);
250                                 return 1;
251                         }
252
253                         free(reply);
254                 }
255
256                 free(packet);
257         }
258
259         return 0;
260 }