Many more changes, timed callbacks etc
[simavr] / simavr / sim / sim_gdb.c
1 /*
2         sim_gdb.c
3
4         Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
5
6         This file is part of simavr.
7
8         simavr is free software: you can redistribute it and/or modify
9         it under the terms of the GNU General Public License as published by
10         the Free Software Foundation, either version 3 of the License, or
11         (at your option) any later version.
12
13         simavr is distributed in the hope that it will be useful,
14         but WITHOUT ANY WARRANTY; without even the implied warranty of
15         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16         GNU General Public License for more details.
17
18         You should have received a copy of the GNU General Public License
19         along with simavr.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <netinet/in.h>
23 #include <netinet/tcp.h>
24 #include <arpa/inet.h>
25 #include <sys/socket.h>
26 #include <sys/time.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <unistd.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <poll.h>
33 #include <pthread.h>
34 #include "sim_avr.h"
35 #include "avr_eeprom.h"
36
37 #define DBG(w)
38
39 typedef struct avr_gdb_t {
40         avr_t * avr;
41         int             listen; // listen socket
42         int             s;              // current gdb connection
43
44         uint32_t        watchmap;
45         struct {
46                 uint32_t        pc;
47                 uint32_t        len;
48                 int kind;
49         } watch[32];
50 } avr_gdb_t;
51
52     // decode line text hex to binary
53 int read_hex_string(const char * src, uint8_t * buffer, int maxlen)
54 {
55     uint8_t * dst = buffer;
56     int ls = 0;
57     uint8_t b = 0;
58     while (*src && maxlen--) {
59         char c = *src++;
60         switch (c) {
61             case 'a' ... 'f':   b = (b << 4) | (c - 'a' + 0xa); break;
62             case 'A' ... 'F':   b = (b << 4) | (c - 'A' + 0xa); break;
63             case '0' ... '9':   b = (b << 4) | (c - '0'); break;
64             default:
65                 if (c > ' ') {
66                     fprintf(stderr, "%s: huh '%c' (%s)\n", __FUNCTION__, c, src);
67                     return -1;
68                 }
69                 continue;
70         }
71         if (ls & 1) {
72             *dst++ = b; b = 0;
73         }
74         ls++;
75     }
76
77     return dst - buffer;
78 }
79
80 static void gdb_send_reply(avr_gdb_t * g, char * cmd)
81 {
82         uint8_t reply[1024];
83         uint8_t * dst = reply;
84         uint8_t check = 0;
85         *dst++ = '$';
86         while (*cmd) {
87                 check += *cmd;
88                 *dst++ = *cmd++;
89         }
90         sprintf((char*)dst, "#%02x", check);
91         DBG(printf("%s '%s'\n", __FUNCTION__, reply);)
92         send(g->s, reply, dst - reply + 3, 0);
93 }
94
95 static void gdb_send_quick_status(avr_gdb_t * g, uint8_t signal)
96 {
97         char cmd[64];
98
99         sprintf(cmd, "T%02x20:%02x;21:%02x%02x;22:%02x%02x%02x00;",
100                 signal ? signal : 5, g->avr->data[R_SREG], 
101                 g->avr->data[R_SPL], g->avr->data[R_SPH],
102                 g->avr->pc & 0xff, (g->avr->pc>>8)&0xff, (g->avr->pc>>16)&0xff);
103         gdb_send_reply(g, cmd);
104 }
105
106 static int gdb_change_breakpoint(avr_gdb_t * g, int set, int kind, uint32_t addr, uint32_t len)
107 {
108         DBG(printf("set %d kind %d addr %08x len %d (map %08x)\n", set, kind, addr, len, g->watchmap);)
109         if (set) {
110                 if (g->watchmap == 0xffffffff)
111                         return -1;      // map full
112
113                 // check to see if it exists
114                 for (int i = 0; i < 32; i++)
115                         if ((g->watchmap & (1 << i)) && g->watch[i].pc == addr) {
116                                 g->watch[i].len = len;
117                                 return 0;
118                         }
119                 for (int i = 0; i < 32; i++)
120                         if (!(g->watchmap & (1 << i))) {
121                                 g->watchmap |= (1 << i);
122                                 g->watch[i].len = len;
123                                 g->watch[i].pc = addr;
124                                 g->watch[i].kind = kind;
125                                 return 0;
126                         }
127         } else {
128                 for (int i = 0; i < 32; i++)
129                         if ((g->watchmap & (1 << i)) && g->watch[i].pc == addr) {
130                                 g->watchmap &= ~(1 << i);
131                                 g->watch[i].len = 0;
132                                 g->watch[i].pc = 0;
133                                 g->watch[i].kind = 0;
134                                 return 0;
135                         }
136         }
137         return -1;
138 }
139
140 static int gdb_write_register(avr_gdb_t * g, int regi, uint8_t * src)
141 {
142         switch (regi) {
143                 case 0 ... 31:
144                         g->avr->data[regi] = *src;
145                         return 1;
146                 case 32:
147                         g->avr->data[R_SREG] = * src;
148                         return 1;
149                 case 33:
150                         g->avr->data[R_SPL] = *src++;
151                         g->avr->data[R_SPH] = *src++;
152                         return 2;
153                 case 34:
154                         g->avr->pc = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
155                         return 4;
156         }
157         return 1;
158 }
159
160 static int gdb_read_register(avr_gdb_t * g, int regi, char * rep)
161 {
162         switch (regi) {
163                 case 0 ... 31:
164                         sprintf(rep, "%02x", g->avr->data[regi]);
165                         break;
166                 case 32:
167                         sprintf(rep, "%02x", g->avr->data[R_SREG]);
168                         break;
169                 case 33:
170                         sprintf(rep, "%02x%02x", g->avr->data[R_SPL], g->avr->data[R_SPH]);
171                         break;
172                 case 34:
173                         sprintf(rep, "%02x%02x%02x00", 
174                                 g->avr->pc & 0xff, (g->avr->pc>>8)&0xff, (g->avr->pc>>16)&0xff);
175                         break;
176         }
177         return strlen(rep);
178 }
179
180 static void gdb_handle_command(avr_gdb_t * g, char * cmd)
181 {
182         avr_t * avr = g->avr;
183         char rep[1024];
184         uint8_t command = *cmd++;
185         switch (command) {
186                 case '?':
187                         gdb_send_quick_status(g, 0);
188                         break;
189                 case 'G': {     // set all general purpose registers
190                         // get their binary form
191                         read_hex_string(cmd, (uint8_t*)rep, strlen(cmd));
192                         uint8_t *src = (uint8_t*)rep;
193                         for (int i = 0; i < 35; i++)
194                                 src += gdb_write_register(g, i, src);
195                         gdb_send_reply(g, "OK");                                                                                
196                 }       break;
197                 case 'g': {     // read all general purpose registers
198                         char * dst = rep;
199                         for (int i = 0; i < 35; i++)
200                                 dst += gdb_read_register(g, i, dst);
201                         gdb_send_reply(g, rep);                                         
202                 }       break;
203                 case 'p': {     // read register
204                         unsigned int regi = 0;
205                         sscanf(cmd, "%x", &regi);
206                         gdb_read_register(g, regi, rep);
207                         gdb_send_reply(g, rep);                 
208                 }       break;
209                 case 'P': {     // write register
210                         unsigned int regi = 0;
211                         char * val = strchr(cmd, '=');
212                         if (!val)
213                                 break;
214                         *val++ = 0;
215                         sscanf(cmd, "%x", &regi);
216                         read_hex_string(val, (uint8_t*)rep, strlen(val));
217                         gdb_write_register(g, regi, (uint8_t*)rep);
218                         gdb_send_reply(g, "OK");                                                                                
219                 }       break;
220                 case 'm': {     // read memory
221                         uint32_t addr, len;
222                         sscanf(cmd, "%x,%x", &addr, &len);
223                         uint8_t * src = NULL;
224                         if (addr < 0xffff) {
225                                 src = avr->flash + addr;
226                         } else if (addr >= 0x800000 && (addr - 0x800000) <= avr->ramend) {
227                                 src = avr->data + addr - 0x800000;
228                         } else if (addr >= 0x810000 && (addr - 0x810000) <= avr->e2end) {
229                                 avr_eeprom_desc_t ee = {.offset = (addr - 0x810000)};
230                                 avr_ioctl(avr, AVR_IOCTL_EEPROM_GET, &ee);
231                                 if (ee.ee)
232                                         src = ee.ee;
233                                 else
234                                         gdb_send_reply(g, "E01");
235                         } else {
236                                 printf("read memory error %08x, %08x (ramend %04x)\n", addr, len, avr->ramend+1);
237                                 gdb_send_reply(g, "E01");
238                                 break;
239                         }
240                         char * dst = rep;
241                         while (len--) {
242                                 sprintf(dst, "%02x", *src++);
243                                 dst += 2;
244                         }
245                         *dst = 0;
246                         gdb_send_reply(g, rep);
247                 }       break;
248                 case 'M': {     // write memory
249                         uint32_t addr, len;
250                         sscanf(cmd, "%x,%x", &addr, &len);
251                         char * start = strchr(cmd, ':');
252                         if (!start) {
253                                 gdb_send_reply(g, "E01");
254                                 break;
255                         }
256                         if (addr < 0xffff) {
257                                 read_hex_string(start + 1, avr->flash + addr, strlen(start+1));
258                                 gdb_send_reply(g, "OK");                        
259                         } else if (addr >= 0x800000 && (addr - 0x800000) <= avr->ramend) {
260                                 read_hex_string(start + 1, avr->data + addr - 0x800000, strlen(start+1));
261                                 gdb_send_reply(g, "OK");                                                        
262                         } else if (addr >= 0x810000 && (addr - 0x810000) <= avr->e2end) {
263                                 read_hex_string(start + 1, (uint8_t*)rep, strlen(start+1));
264                                 avr_eeprom_desc_t ee = {.offset = (addr - 0x810000), .size = len, .ee = (uint8_t*)rep };
265                                 avr_ioctl(avr, AVR_IOCTL_EEPROM_SET, &ee);
266                                 gdb_send_reply(g, "OK");                                                        
267                         } else {
268                                 printf("write memory error %08x, %08x\n", addr, len);
269                                 gdb_send_reply(g, "E01");
270                         }               
271                 }       break;
272                 case 'c': {     // continue
273                         avr->state = cpu_Running;
274                 }       break;
275                 case 's': {     // step
276                         avr->state = cpu_Step;
277                 }       break;
278                 case 'Z':       // set clear break/watchpoint
279                 case 'z': {
280                         uint32_t kind, addr, len;
281                         sscanf(cmd, "%d,%x,%x", &kind, &addr, &len);
282 //                      printf("breakbpoint %d, %08x, %08x\n", kind, addr, len);
283                         switch (kind) {
284                                 case 0: // software breakpoint
285                                 case 1: // hardware breakpoint
286                                         if (addr <= avr->flashend) {
287                                                 if (gdb_change_breakpoint(g, command == 'Z', kind, addr, len))
288                                                         gdb_send_reply(g, "E01");
289                                                 else
290                                                         gdb_send_reply(g, "OK");
291                                         } else
292                                                 gdb_send_reply(g, "E01");               // out of flash address
293                                         break;
294                                 // TODO
295                                 case 2: // write watchpoint
296                                 case 3: // read watchpoint
297                                 case 4: // access watchpoint
298                                 default:
299                                         gdb_send_reply(g, "");
300                         }       
301                 }       break;
302                 default:
303                         gdb_send_reply(g, "");
304         }
305 }
306
307 static int gdb_network_handler(avr_gdb_t * g, uint32_t dosleep)
308 {
309         fd_set read_set;
310         int max;
311         FD_ZERO(&read_set);
312
313         if (g->s != -1) {
314                 FD_SET(g->s, &read_set);
315                 max = g->s + 1;
316         } else {
317                 FD_SET(g->listen, &read_set);
318                 max = g->listen + 1;
319         }
320         struct timeval timo = { 0, dosleep };   // short, but not too short interval
321         int ret = select(max, &read_set, NULL, NULL, &timo);
322
323         if (ret == 0)
324                 return 0;
325         
326         if (FD_ISSET(g->listen, &read_set)) {
327                 g->s = accept(g->listen, NULL, NULL);
328
329                 if (g->s == -1) {
330                         perror("gdb_network_handler accept");
331                         sleep(5);
332                         return 1;
333                 }
334         int i = 1;
335         setsockopt (g->s, IPPROTO_TCP, TCP_NODELAY, &i, sizeof (i));
336                 g->avr->state = cpu_Stopped;
337                 printf("%s connection opened\n", __FUNCTION__);         
338         }
339                 
340         if (FD_ISSET(g->s, &read_set)) {
341                 uint8_t buffer[1024];
342                 
343                 ssize_t r = recv(g->s, buffer, sizeof(buffer)-1, 0);
344
345                 if (r == 0) {
346                         printf("%s connection closed\n", __FUNCTION__);
347                         close(g->s);
348                         g->watchmap = 0;                                // clear breakpoints
349                         g->avr->state = cpu_Running;    // resume
350                         g->s = -1;
351                         return 1;
352                 }
353                 if (r == -1) {
354                         perror("gdb_network_handler recv");
355                         sleep(1);
356                         return 1;
357                 }
358                 buffer[r] = 0;
359         //      printf("%s: received %d bytes\n'%s'\n", __FUNCTION__, r, buffer);
360         //      hdump("gdb", buffer, r);
361
362                 uint8_t * src = buffer;
363                 while (*src == '+' || *src == '-')
364                         src++;
365                 // control C -- lets send the guy a nice status packet
366                 if (*src == 3) {
367                         src++;
368                         g->avr->state = cpu_StepDone;
369                         printf("GDB hit control-c\n");
370                 }
371                 if (*src  == '$') {
372                         // strip checksum
373                         uint8_t * end = buffer + r - 1;
374                         while (end > src && *end != '#')
375                                 *end-- = 0;
376                         *end = 0;
377                         src++;
378                         DBG(printf("GDB command = '%s'\n", src);)
379
380                         send(g->s, "+", 1, 0);
381
382                         gdb_handle_command(g, (char*)src);
383                 }
384         }
385         return 1;
386 }
387
388 int avr_gdb_processor(avr_t * avr, int sleep)
389 {
390         if (!avr || !avr->gdb)
391                 return 0;       
392         avr_gdb_t * g = avr->gdb;
393
394         if (g->watchmap && avr->state == cpu_Running) {
395                 for (int i = 0; i < 32; i++)
396                         if ((g->watchmap & (1 << i)) && g->watch[i].pc == avr->pc) {
397                                 DBG(printf("avr_gdb_processor hit breakpoint at %08x\n", avr->pc);)
398                                 gdb_send_quick_status(g, 0);
399                                 avr->state = cpu_Stopped;
400                         }               
401         }
402         if (avr->state == cpu_StepDone) {
403                 gdb_send_quick_status(g, 0);
404                 avr->state = cpu_Stopped;
405         }
406         // this also sleeps for a bit
407         return gdb_network_handler(g, sleep);
408 }
409
410
411 int avr_gdb_init(avr_t * avr)
412 {
413         avr_gdb_t * g = malloc(sizeof(avr_gdb_t));
414         memset(g, 0, sizeof(avr_gdb_t));
415
416         avr->gdb = NULL;
417
418         if ((g->listen = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
419                 fprintf(stderr, "Can't create socket: %s", strerror(errno));
420                 return -1;
421         }
422
423         int i = 1;
424         setsockopt(g->listen, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
425
426         struct sockaddr_in address = { 0 };
427         address.sin_family = AF_INET;
428         address.sin_port = htons (avr->gdb_port);
429
430         if (bind(g->listen, (struct sockaddr *) &address, sizeof(address))) {
431                 fprintf(stderr, "Can not bind socket: %s", strerror(errno));
432                 return -1;
433         }
434         if (listen(g->listen, 1)) {
435                 perror("listen");
436                 return -1;
437         }
438         printf("avr_gdb_init listening on port %d\n", avr->gdb_port);
439         g->avr = avr;
440         g->s = -1;
441         avr->gdb = g;
442         
443         return 0;
444 }