Merge pull request #1 from schuay/master
[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 "sim_hex.h"
36 #include "avr_eeprom.h"
37 #include "sim_gdb.h"
38
39 #define DBG(w)
40
41 typedef struct avr_gdb_t {
42         avr_t * avr;
43         int             listen; // listen socket
44         int             s;              // current gdb connection
45
46         uint32_t        watchmap;
47         struct {
48                 avr_flashaddr_t pc;
49                 uint32_t        len;
50                 int kind;
51         } watch[32];
52 } avr_gdb_t;
53
54
55 static void gdb_send_reply(avr_gdb_t * g, char * cmd)
56 {
57         uint8_t reply[1024];
58         uint8_t * dst = reply;
59         uint8_t check = 0;
60         *dst++ = '$';
61         while (*cmd) {
62                 check += *cmd;
63                 *dst++ = *cmd++;
64         }
65         sprintf((char*)dst, "#%02x", check);
66         DBG(printf("%s '%s'\n", __FUNCTION__, reply);)
67         send(g->s, reply, dst - reply + 3, 0);
68 }
69
70 static void gdb_send_quick_status(avr_gdb_t * g, uint8_t signal)
71 {
72         char cmd[64];
73
74         sprintf(cmd, "T%02x20:%02x;21:%02x%02x;22:%02x%02x%02x00;",
75                 signal ? signal : 5, g->avr->data[R_SREG], 
76                 g->avr->data[R_SPL], g->avr->data[R_SPH],
77                 g->avr->pc & 0xff, (g->avr->pc>>8)&0xff, (g->avr->pc>>16)&0xff);
78         gdb_send_reply(g, cmd);
79 }
80
81 static int gdb_change_breakpoint(avr_gdb_t * g, int set, int kind, avr_flashaddr_t addr, uint32_t len)
82 {
83         DBG(printf("set %d kind %d addr %08x len %d (map %08x)\n", set, kind, addr, len, g->watchmap);)
84         if (set) {
85                 if (g->watchmap == 0xffffffff)
86                         return -1;      // map full
87
88                 // check to see if it exists
89                 for (int i = 0; i < 32; i++)
90                         if ((g->watchmap & (1 << i)) && g->watch[i].pc == addr) {
91                                 g->watch[i].len = len;
92                                 return 0;
93                         }
94                 for (int i = 0; i < 32; i++)
95                         if (!(g->watchmap & (1 << i))) {
96                                 g->watchmap |= (1 << i);
97                                 g->watch[i].len = len;
98                                 g->watch[i].pc = addr;
99                                 g->watch[i].kind = kind;
100                                 return 0;
101                         }
102         } else {
103                 for (int i = 0; i < 32; i++)
104                         if ((g->watchmap & (1 << i)) && g->watch[i].pc == addr) {
105                                 g->watchmap &= ~(1 << i);
106                                 g->watch[i].len = 0;
107                                 g->watch[i].pc = 0;
108                                 g->watch[i].kind = 0;
109                                 return 0;
110                         }
111         }
112         return -1;
113 }
114
115 static int gdb_write_register(avr_gdb_t * g, int regi, uint8_t * src)
116 {
117         switch (regi) {
118                 case 0 ... 31:
119                         g->avr->data[regi] = *src;
120                         return 1;
121                 case 32:
122                         g->avr->data[R_SREG] = *src;
123                         return 1;
124                 case 33:
125                         g->avr->data[R_SPL] = src[0];
126                         g->avr->data[R_SPH] = src[1];
127                         return 2;
128                 case 34:
129                         g->avr->pc = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
130                         return 4;
131         }
132         return 1;
133 }
134
135 static int gdb_read_register(avr_gdb_t * g, int regi, char * rep)
136 {
137         switch (regi) {
138                 case 0 ... 31:
139                         sprintf(rep, "%02x", g->avr->data[regi]);
140                         break;
141                 case 32:
142                         sprintf(rep, "%02x", g->avr->data[R_SREG]);
143                         break;
144                 case 33:
145                         sprintf(rep, "%02x%02x", g->avr->data[R_SPL], g->avr->data[R_SPH]);
146                         break;
147                 case 34:
148                         sprintf(rep, "%02x%02x%02x00", 
149                                 g->avr->pc & 0xff, (g->avr->pc>>8)&0xff, (g->avr->pc>>16)&0xff);
150                         break;
151         }
152         return strlen(rep);
153 }
154
155 static void gdb_handle_command(avr_gdb_t * g, char * cmd)
156 {
157         avr_t * avr = g->avr;
158         char rep[1024];
159         uint8_t command = *cmd++;
160         switch (command) {
161                 case '?':
162                         gdb_send_quick_status(g, 0);
163                         break;
164                 case 'G': {     // set all general purpose registers
165                         // get their binary form
166                         read_hex_string(cmd, (uint8_t*)rep, strlen(cmd));
167                         uint8_t *src = (uint8_t*)rep;
168                         for (int i = 0; i < 35; i++)
169                                 src += gdb_write_register(g, i, src);
170                         gdb_send_reply(g, "OK");                                                                                
171                 }       break;
172                 case 'g': {     // read all general purpose registers
173                         char * dst = rep;
174                         for (int i = 0; i < 35; i++)
175                                 dst += gdb_read_register(g, i, dst);
176                         gdb_send_reply(g, rep);                                         
177                 }       break;
178                 case 'p': {     // read register
179                         unsigned int regi = 0;
180                         sscanf(cmd, "%x", &regi);
181                         gdb_read_register(g, regi, rep);
182                         gdb_send_reply(g, rep);                 
183                 }       break;
184                 case 'P': {     // write register
185                         unsigned int regi = 0;
186                         char * val = strchr(cmd, '=');
187                         if (!val)
188                                 break;
189                         *val++ = 0;
190                         sscanf(cmd, "%x", &regi);
191                         read_hex_string(val, (uint8_t*)rep, strlen(val));
192                         gdb_write_register(g, regi, (uint8_t*)rep);
193                         gdb_send_reply(g, "OK");                                                                                
194                 }       break;
195                 case 'm': {     // read memory
196                         avr_flashaddr_t addr;
197                         uint32_t len;
198                         sscanf(cmd, "%x,%x", &addr, &len);
199                         uint8_t * src = NULL;
200                         if (addr < avr->flashend) {
201                                 src = avr->flash + addr;
202                         } else if (addr >= 0x800000 && (addr - 0x800000) <= avr->ramend) {
203                                 src = avr->data + addr - 0x800000;
204                         } else if (addr >= 0x810000 && (addr - 0x810000) <= avr->e2end) {
205                                 avr_eeprom_desc_t ee = {.offset = (addr - 0x810000)};
206                                 avr_ioctl(avr, AVR_IOCTL_EEPROM_GET, &ee);
207                                 if (ee.ee)
208                                         src = ee.ee;
209                                 else {
210                                         gdb_send_reply(g, "E01");
211                                         break;
212                                 }
213                         } else if (addr >= 0x800000 && (addr - 0x800000) == avr->ramend+1 && len == 2) {
214                                 // Allow GDB to read a value just after end of stack.
215                                 // This is necessary to make instruction stepping work when stack is empty
216                                 printf("GDB read just past end of stack %08x, %08x; returning zero\n", addr, len);
217                                 gdb_send_reply(g, "0000");
218                                 break;
219                         } else {
220                                 printf("read memory error %08x, %08x (ramend %04x)\n", addr, len, avr->ramend+1);
221                                 gdb_send_reply(g, "E01");
222                                 break;
223                         }
224                         char * dst = rep;
225                         while (len--) {
226                                 sprintf(dst, "%02x", *src++);
227                                 dst += 2;
228                         }
229                         *dst = 0;
230                         gdb_send_reply(g, rep);
231                 }       break;
232                 case 'M': {     // write memory
233                         uint32_t addr, len;
234                         sscanf(cmd, "%x,%x", &addr, &len);
235                         char * start = strchr(cmd, ':');
236                         if (!start) {
237                                 gdb_send_reply(g, "E01");
238                                 break;
239                         }
240                         if (addr < 0xffff) {
241                                 read_hex_string(start + 1, avr->flash + addr, strlen(start+1));
242                                 gdb_send_reply(g, "OK");                        
243                         } else if (addr >= 0x800000 && (addr - 0x800000) <= avr->ramend) {
244                                 read_hex_string(start + 1, avr->data + addr - 0x800000, strlen(start+1));
245                                 gdb_send_reply(g, "OK");                                                        
246                         } else if (addr >= 0x810000 && (addr - 0x810000) <= avr->e2end) {
247                                 read_hex_string(start + 1, (uint8_t*)rep, strlen(start+1));
248                                 avr_eeprom_desc_t ee = {.offset = (addr - 0x810000), .size = len, .ee = (uint8_t*)rep };
249                                 avr_ioctl(avr, AVR_IOCTL_EEPROM_SET, &ee);
250                                 gdb_send_reply(g, "OK");                                                        
251                         } else {
252                                 printf("write memory error %08x, %08x\n", addr, len);
253                                 gdb_send_reply(g, "E01");
254                         }               
255                 }       break;
256                 case 'c': {     // continue
257                         avr->state = cpu_Running;
258                 }       break;
259                 case 's': {     // step
260                         avr->state = cpu_Step;
261                 }       break;
262                 case 'r': {     // deprecated, suggested for AVRStudio compatibility
263                         avr->state = cpu_StepDone;
264                         avr_reset(avr);
265                 }       break;
266                 case 'Z':       // set clear break/watchpoint
267                 case 'z': {
268                         uint32_t kind, addr, len;
269                         sscanf(cmd, "%d,%x,%x", &kind, &addr, &len);
270 //                      printf("breakpoint %d, %08x, %08x\n", kind, addr, len);
271                         switch (kind) {
272                                 case 0: // software breakpoint
273                                 case 1: // hardware breakpoint
274                                         if (addr <= avr->flashend) {
275                                                 if (gdb_change_breakpoint(g, command == 'Z', kind, addr, len))
276                                                         gdb_send_reply(g, "E01");
277                                                 else
278                                                         gdb_send_reply(g, "OK");
279                                         } else
280                                                 gdb_send_reply(g, "E01");               // out of flash address
281                                         break;
282                                 // TODO
283                                 case 2: // write watchpoint
284                                 case 3: // read watchpoint
285                                 case 4: // access watchpoint
286                                 default:
287                                         gdb_send_reply(g, "");
288                         }       
289                 }       break;
290                 default:
291                         gdb_send_reply(g, "");
292                         break;
293         }
294 }
295
296 static int gdb_network_handler(avr_gdb_t * g, uint32_t dosleep)
297 {
298         fd_set read_set;
299         int max;
300         FD_ZERO(&read_set);
301
302         if (g->s != -1) {
303                 FD_SET(g->s, &read_set);
304                 max = g->s + 1;
305         } else {
306                 FD_SET(g->listen, &read_set);
307                 max = g->listen + 1;
308         }
309         struct timeval timo = { 0, dosleep };   // short, but not too short interval
310         int ret = select(max, &read_set, NULL, NULL, &timo);
311
312         if (ret == 0)
313                 return 0;
314         
315         if (FD_ISSET(g->listen, &read_set)) {
316                 g->s = accept(g->listen, NULL, NULL);
317
318                 if (g->s == -1) {
319                         perror("gdb_network_handler accept");
320                         sleep(5);
321                         return 1;
322                 }
323         int i = 1;
324         setsockopt (g->s, IPPROTO_TCP, TCP_NODELAY, &i, sizeof (i));
325                 g->avr->state = cpu_Stopped;
326                 printf("%s connection opened\n", __FUNCTION__);         
327         }
328                 
329         if (g->s != -1 && FD_ISSET(g->s, &read_set)) {
330                 uint8_t buffer[1024];
331                 
332                 ssize_t r = recv(g->s, buffer, sizeof(buffer)-1, 0);
333
334                 if (r == 0) {
335                         printf("%s connection closed\n", __FUNCTION__);
336                         close(g->s);
337                         g->watchmap = 0;                                // clear breakpoints
338                         g->avr->state = cpu_Running;    // resume
339                         g->s = -1;
340                         return 1;
341                 }
342                 if (r == -1) {
343                         perror("gdb_network_handler recv");
344                         sleep(1);
345                         return 1;
346                 }
347                 buffer[r] = 0;
348         //      printf("%s: received %d bytes\n'%s'\n", __FUNCTION__, r, buffer);
349         //      hdump("gdb", buffer, r);
350
351                 uint8_t * src = buffer;
352                 while (*src == '+' || *src == '-')
353                         src++;
354                 // control C -- lets send the guy a nice status packet
355                 if (*src == 3) {
356                         src++;
357                         g->avr->state = cpu_StepDone;
358                         printf("GDB hit control-c\n");
359                 }
360                 if (*src  == '$') {
361                         // strip checksum
362                         uint8_t * end = buffer + r - 1;
363                         while (end > src && *end != '#')
364                                 *end-- = 0;
365                         *end = 0;
366                         src++;
367                         DBG(printf("GDB command = '%s'\n", src);)
368
369                         send(g->s, "+", 1, 0);
370
371                         gdb_handle_command(g, (char*)src);
372                 }
373         }
374         return 1;
375 }
376
377 int avr_gdb_processor(avr_t * avr, int sleep)
378 {
379         if (!avr || !avr->gdb)
380                 return 0;       
381         avr_gdb_t * g = avr->gdb;
382
383         if (g->watchmap && avr->state == cpu_Running) {
384                 for (int i = 0; i < 32; i++)
385                         if ((g->watchmap & (1 << i)) && g->watch[i].pc == avr->pc) {
386                                 DBG(printf("avr_gdb_processor hit breakpoint at %08x\n", avr->pc);)
387                                 gdb_send_quick_status(g, 0);
388                                 avr->state = cpu_Stopped;
389                         }               
390         }
391         if (avr->state == cpu_StepDone) {
392                 gdb_send_quick_status(g, 0);
393                 avr->state = cpu_Stopped;
394         }
395         // this also sleeps for a bit
396         return gdb_network_handler(g, sleep);
397 }
398
399
400 int avr_gdb_init(avr_t * avr)
401 {
402         avr_gdb_t * g = malloc(sizeof(avr_gdb_t));
403         memset(g, 0, sizeof(avr_gdb_t));
404
405         avr->gdb = NULL;
406
407         if ((g->listen = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
408                 fprintf(stderr, "Can't create socket: %s", strerror(errno));
409                 return -1;
410         }
411
412         int i = 1;
413         setsockopt(g->listen, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
414
415         struct sockaddr_in address = { 0 };
416         address.sin_family = AF_INET;
417         address.sin_port = htons (avr->gdb_port);
418
419         if (bind(g->listen, (struct sockaddr *) &address, sizeof(address))) {
420                 fprintf(stderr, "Can not bind socket: %s", strerror(errno));
421                 return -1;
422         }
423         if (listen(g->listen, 1)) {
424                 perror("listen");
425                 return -1;
426         }
427         printf("avr_gdb_init listening on port %d\n", avr->gdb_port);
428         g->avr = avr;
429         g->s = -1;
430         avr->gdb = g;
431         // change default run behaviour to use the slightly slower versions
432         avr->run = avr_callback_run_gdb;
433         avr->sleep = avr_callback_sleep_gdb;
434         
435         return 0;
436 }