~arcachofo/simulide/1.1.0

« back to all changes in this revision

Viewing changes to src/simavr/sim/sim_gdb.c

  • Committer: arcachofo
  • Date: 2021-01-01 14:23:42 UTC
  • Revision ID: arcachofo@simulide.com-20210101142342-ozfljnll44g5lbl3
Initial Commit 0.5.15-RC3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 "sim_network.h"
 
23
#include <sys/time.h>
 
24
#include <stdlib.h>
 
25
#include <stdio.h>
 
26
#include <unistd.h>
 
27
#include <string.h>
 
28
#include <errno.h>
 
29
#include <pthread.h>
 
30
#include "sim_avr.h"
 
31
#include "sim_core.h" // for SET_SREG_FROM, READ_SREG_INTO
 
32
#include "sim_hex.h"
 
33
#include "avr_eeprom.h"
 
34
#include "sim_gdb.h"
 
35
 
 
36
#define DBG(w)
 
37
 
 
38
#define WATCH_LIMIT (32)
 
39
 
 
40
typedef struct {
 
41
        uint32_t len; /**< How many points are taken (points[0] .. points[len - 1]). */
 
42
        struct {
 
43
                uint32_t addr; /**< Which address is watched. */
 
44
                uint32_t size; /**< How large is the watched segment. */
 
45
                uint32_t kind; /**< Bitmask of enum avr_gdb_watch_type values. */
 
46
        } points[WATCH_LIMIT];
 
47
} avr_gdb_watchpoints_t;
 
48
 
 
49
typedef struct avr_gdb_t {
 
50
        avr_t * avr;
 
51
        int             listen; // listen socket
 
52
        int             s;              // current gdb connection
 
53
 
 
54
        avr_gdb_watchpoints_t breakpoints;
 
55
        avr_gdb_watchpoints_t watchpoints;
 
56
} avr_gdb_t;
 
57
 
 
58
 
 
59
/**
 
60
 * Returns the index of the watchpoint if found, -1 otherwise.
 
61
 */
 
62
static int
 
63
gdb_watch_find(
 
64
                const avr_gdb_watchpoints_t * w,
 
65
                uint32_t addr )
 
66
{
 
67
//#ifndef _WIN32
 
68
        for (int i = 0; i < w->len; i++) {
 
69
                if (w->points[i].addr > addr) {
 
70
                        return -1;
 
71
                } else if (w->points[i].addr == addr) {
 
72
                        return i;
 
73
                }
 
74
        }
 
75
//#endif
 
76
        return -1;
 
77
}
 
78
 
 
79
/**
 
80
 * Contrary to gdb_watch_find, this actually checks the address against
 
81
 * a watched memory _range_.
 
82
 */
 
83
static int
 
84
gdb_watch_find_range(
 
85
                const avr_gdb_watchpoints_t * w,
 
86
                uint32_t addr )
 
87
{
 
88
//#ifndef _WIN32
 
89
        for (int i = 0; i < w->len; i++) {
 
90
                if (w->points[i].addr > addr) {
 
91
                        return -1;
 
92
                } else if (w->points[i].addr <= addr && addr < w->points[i].addr + w->points[i].size) {
 
93
                        return i;
 
94
                }
 
95
        }
 
96
//#endif
 
97
        return -1;
 
98
}
 
99
 
 
100
/**
 
101
 * Returns -1 on error, 0 otherwise.
 
102
 */
 
103
static int
 
104
gdb_watch_add_or_update(
 
105
                avr_gdb_watchpoints_t * w,
 
106
                enum avr_gdb_watch_type kind,
 
107
                uint32_t addr,
 
108
                uint32_t size )
 
109
{
 
110
//#ifndef _WIN32
 
111
        /* If the watchpoint exists, update it. */
 
112
        int i = gdb_watch_find(w, addr);
 
113
        if (i != -1) {
 
114
                w->points[i].size = size;
 
115
                w->points[i].kind |= kind;
 
116
                return 0;
 
117
        }
 
118
 
 
119
        /* Otherwise add it. */
 
120
        if (w->len == WATCH_LIMIT) {
 
121
                return -1;
 
122
        }
 
123
 
 
124
        /* Find the insertion point. */
 
125
        for (i = 0; i < w->len; i++) {
 
126
                if (w->points[i].addr > addr) {
 
127
                        break;
 
128
                }
 
129
        }
 
130
 
 
131
        w->len++;
 
132
 
 
133
        /* Make space for new element, moving old ones from the end. */
 
134
        for (int j = w->len; j > i; j--) {
 
135
                w->points[j] = w->points[j - 1];
 
136
        }
 
137
 
 
138
        /* Insert it. */
 
139
        w->points[i].kind = kind;
 
140
        w->points[i].addr = addr;
 
141
        w->points[i].size = size;
 
142
//#endif
 
143
        return 0;
 
144
}
 
145
 
 
146
/**
 
147
 * Returns -1 on error or if the specified point does not exist, 0 otherwise.
 
148
 */
 
149
static int
 
150
gdb_watch_rm(
 
151
                avr_gdb_watchpoints_t * w,
 
152
                enum avr_gdb_watch_type kind,
 
153
                uint32_t addr )
 
154
{
 
155
//#ifndef _WIN32
 
156
        int i = gdb_watch_find(w, addr);
 
157
        if (i == -1) {
 
158
                return -1;
 
159
        }
 
160
 
 
161
        w->points[i].kind &= ~kind;
 
162
        if (w->points[i].kind) {
 
163
                return 0;
 
164
        }
 
165
 
 
166
        for (i = i + 1; i < w->len; i++) {
 
167
                w->points[i - 1] = w->points[i];
 
168
        }
 
169
 
 
170
        w->len--;
 
171
//#endif
 
172
        return 0;
 
173
}
 
174
 
 
175
static void
 
176
gdb_watch_clear(
 
177
                avr_gdb_watchpoints_t * w )
 
178
{
 
179
        w->len = 0;
 
180
}
 
181
 
 
182
static void
 
183
gdb_send_reply(
 
184
                avr_gdb_t * g,
 
185
                char * cmd )
 
186
{
 
187
//#ifndef _WIN32
 
188
        uint8_t reply[1024];
 
189
        uint8_t * dst = reply;
 
190
        uint8_t check = 0;
 
191
        *dst++ = '$';
 
192
        while (*cmd) {
 
193
                check += *cmd;
 
194
                *dst++ = *cmd++;
 
195
        }
 
196
        sprintf((char*)dst, "#%02x", check);
 
197
        DBG(printf("%s '%s'\n", __FUNCTION__, reply);)
 
198
        send(g->s, reply, dst - reply + 3, 0);
 
199
//#endif
 
200
}
 
201
 
 
202
static void
 
203
gdb_send_quick_status(
 
204
                avr_gdb_t * g,
 
205
                uint8_t signal )
 
206
{
 
207
//#ifndef _WIN32
 
208
        char cmd[64];
 
209
 
 
210
        sprintf(cmd, "T%02x20:%02x;21:%02x%02x;22:%02x%02x%02x00;",
 
211
                signal ? signal : 5, g->avr->data[R_SREG],
 
212
                g->avr->data[R_SPL], g->avr->data[R_SPH],
 
213
                g->avr->pc & 0xff, (g->avr->pc>>8)&0xff, (g->avr->pc>>16)&0xff);
 
214
        gdb_send_reply(g, cmd);
 
215
//#endif
 
216
}
 
217
 
 
218
static int
 
219
gdb_change_breakpoint(
 
220
                avr_gdb_watchpoints_t * w,
 
221
                int set,
 
222
                enum avr_gdb_watch_type kind,
 
223
                uint32_t addr,
 
224
                uint32_t size )
 
225
{
 
226
//#ifndef _WIN32
 
227
        DBG(printf("set %d kind %d addr %08x len %d\n", set, kind, addr, len);)
 
228
 
 
229
        if (set) {
 
230
                return gdb_watch_add_or_update(w, kind, addr, size);
 
231
        } else {
 
232
                return gdb_watch_rm(w, kind, addr);
 
233
        }
 
234
//#endif
 
235
        return -1;
 
236
}
 
237
 
 
238
static int
 
239
gdb_write_register(
 
240
                avr_gdb_t * g,
 
241
                int regi,
 
242
                uint8_t * src )
 
243
{
 
244
//#ifndef _WIN32
 
245
        switch (regi) {
 
246
                case 0 ... 31:
 
247
                        g->avr->data[regi] = *src;
 
248
                        return 1;
 
249
                case 32:
 
250
                        g->avr->data[R_SREG] = *src;
 
251
                        SET_SREG_FROM(g->avr, *src);
 
252
                        return 1;
 
253
                case 33:
 
254
                        g->avr->data[R_SPL] = src[0];
 
255
                        g->avr->data[R_SPH] = src[1];
 
256
                        return 2;
 
257
                case 34:
 
258
                        g->avr->pc = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
 
259
                        return 4;
 
260
        }
 
261
//#endif
 
262
        return 1;
 
263
}
 
264
 
 
265
static int
 
266
gdb_read_register(
 
267
                avr_gdb_t * g,
 
268
                int regi,
 
269
                char * rep )
 
270
{
 
271
//#ifndef _WIN32
 
272
        switch (regi) {
 
273
                case 0 ... 31:
 
274
                        sprintf(rep, "%02x", g->avr->data[regi]);
 
275
                        break;
 
276
                case 32: {
 
277
                                uint8_t sreg;
 
278
                                READ_SREG_INTO(g->avr, sreg);
 
279
                                sprintf(rep, "%02x", sreg);
 
280
                        }
 
281
                        break;
 
282
                case 33:
 
283
                        sprintf(rep, "%02x%02x", g->avr->data[R_SPL], g->avr->data[R_SPH]);
 
284
                        break;
 
285
                case 34:
 
286
                        sprintf(rep, "%02x%02x%02x00",
 
287
                                g->avr->pc & 0xff, (g->avr->pc>>8)&0xff, (g->avr->pc>>16)&0xff);
 
288
                        break;
 
289
        }
 
290
        return strlen(rep);
 
291
//#endif
 
292
return 0;
 
293
}
 
294
 
 
295
static void
 
296
gdb_handle_command(
 
297
                avr_gdb_t * g,
 
298
                char * cmd )
 
299
{
 
300
//#ifndef _WIN32
 
301
        avr_t * avr = g->avr;
 
302
        char rep[1024];
 
303
        uint8_t command = *cmd++;
 
304
        switch (command) {
 
305
                case 'q':
 
306
                        if (strncmp(cmd, "Supported", 9) == 0) {
 
307
                                /* If GDB asked what features we support, report back
 
308
                                 * the features we support, which is just memory layout
 
309
                                 * information for now.
 
310
                                 */
 
311
                                gdb_send_reply(g, "qXfer:memory-map:read+");
 
312
                                break;
 
313
                        } else if (strncmp(cmd, "Attached", 8) == 0) {
 
314
                                /* Respond that we are attached to an existing process..
 
315
                                 * ourselves!
 
316
                                 */
 
317
                                gdb_send_reply(g, "1");
 
318
                                break;
 
319
                        // Rmoving the following 3 lines fixes #150 issue:
 
320
                        // } else if (strncmp(cmd, "Offsets", 7) == 0) {
 
321
                        //      gdb_send_reply(g, "Text=0;Data=800000;Bss=800000");
 
322
                        //      break;
 
323
                        } else if (strncmp(cmd, "Xfer:memory-map:read", 20) == 0) {
 
324
                                snprintf(rep, sizeof(rep),
 
325
                                                "l<memory-map>\n"
 
326
                                                " <memory type='ram' start='0x800000' length='%#x'/>\n"
 
327
                                                " <memory type='flash' start='0' length='%#x'>\n"
 
328
                                                "  <property name='blocksize'>0x80</property>\n"
 
329
                                                " </memory>\n"
 
330
                                                "</memory-map>",
 
331
                                                g->avr->ramend + 1, g->avr->flashend + 1);
 
332
 
 
333
                                gdb_send_reply(g, rep);
 
334
                                break;
 
335
            }
 
336
                        gdb_send_reply(g, "");
 
337
                        break;
 
338
                case '?':
 
339
                        gdb_send_quick_status(g, 0);
 
340
                        break;
 
341
                case 'G': {     // set all general purpose registers
 
342
                        // get their binary form
 
343
                        read_hex_string(cmd, (uint8_t*)rep, strlen(cmd));
 
344
                        uint8_t *src = (uint8_t*)rep;
 
345
                        for (int i = 0; i < 35; i++)
 
346
                                src += gdb_write_register(g, i, src);
 
347
                        gdb_send_reply(g, "OK");
 
348
                }       break;
 
349
                case 'g': {     // read all general purpose registers
 
350
                        char * dst = rep;
 
351
                        for (int i = 0; i < 35; i++)
 
352
                                dst += gdb_read_register(g, i, dst);
 
353
                        gdb_send_reply(g, rep);
 
354
                }       break;
 
355
                case 'p': {     // read register
 
356
                        unsigned int regi = 0;
 
357
                        sscanf(cmd, "%x", &regi);
 
358
                        gdb_read_register(g, regi, rep);
 
359
                        gdb_send_reply(g, rep);
 
360
                }       break;
 
361
                case 'P': {     // write register
 
362
                        unsigned int regi = 0;
 
363
                        char * val = strchr(cmd, '=');
 
364
                        if (!val)
 
365
                                break;
 
366
                        *val++ = 0;
 
367
                        sscanf(cmd, "%x", &regi);
 
368
                        read_hex_string(val, (uint8_t*)rep, strlen(val));
 
369
                        gdb_write_register(g, regi, (uint8_t*)rep);
 
370
                        gdb_send_reply(g, "OK");
 
371
                }       break;
 
372
                case 'm': {     // read memory
 
373
                        avr_flashaddr_t addr;
 
374
                        uint32_t len;
 
375
                        sscanf(cmd, "%x,%x", &addr, &len);
 
376
                        uint8_t * src = NULL;
 
377
                        /* GDB seems to also use 0x1800000 for sram ?!?! */
 
378
                        addr &= 0xffffff;
 
379
                        if (addr < avr->flashend) {
 
380
                                src = avr->flash + addr;
 
381
                        } else if (addr >= 0x800000 && (addr - 0x800000) <= avr->ramend) {
 
382
                                src = avr->data + addr - 0x800000;
 
383
                        } else if (addr == (0x800000 + avr->ramend + 1) && len == 2) {
 
384
                                // Allow GDB to read a value just after end of stack.
 
385
                                // This is necessary to make instruction stepping work when stack is empty
 
386
                                AVR_LOG(avr, LOG_TRACE,
 
387
                                                "GDB: read just past end of stack %08x, %08x; returning zero\n", addr, len);
 
388
                                gdb_send_reply(g, "0000");
 
389
                                break;
 
390
                        } else if (addr >= 0x810000 && (addr - 0x810000) <= avr->e2end) {
 
391
                                avr_eeprom_desc_t ee = {.offset = (addr - 0x810000)};
 
392
                                avr_ioctl(avr, AVR_IOCTL_EEPROM_GET, &ee);
 
393
                                if (ee.ee)
 
394
                                        src = ee.ee;
 
395
                                else {
 
396
                                        gdb_send_reply(g, "E01");
 
397
                                        break;
 
398
                                }
 
399
                        } else {
 
400
                                AVR_LOG(avr, LOG_ERROR,
 
401
                                                "GDB: read memory error %08x, %08x (ramend %04x)\n",
 
402
                                                addr, len, avr->ramend+1);
 
403
                                gdb_send_reply(g, "E01");
 
404
                                break;
 
405
                        }
 
406
                        char * dst = rep;
 
407
                        while (len--) {
 
408
                                sprintf(dst, "%02x", *src++);
 
409
                                dst += 2;
 
410
                        }
 
411
                        *dst = 0;
 
412
                        gdb_send_reply(g, rep);
 
413
                }       break;
 
414
                case 'M': {     // write memory
 
415
                        uint32_t addr, len;
 
416
                        sscanf(cmd, "%x,%x", &addr, &len);
 
417
                        char * start = strchr(cmd, ':');
 
418
                        if (!start) {
 
419
                                gdb_send_reply(g, "E01");
 
420
                                break;
 
421
                        }
 
422
                        if (addr < 0xffff) {
 
423
                                read_hex_string(start + 1, avr->flash + addr, strlen(start+1));
 
424
                                gdb_send_reply(g, "OK");
 
425
                        } else if (addr >= 0x800000 && (addr - 0x800000) <= avr->ramend) {
 
426
                                read_hex_string(start + 1, avr->data + addr - 0x800000, strlen(start+1));
 
427
                                gdb_send_reply(g, "OK");
 
428
                        } else if (addr >= 0x810000 && (addr - 0x810000) <= avr->e2end) {
 
429
                                read_hex_string(start + 1, (uint8_t*)rep, strlen(start+1));
 
430
                                avr_eeprom_desc_t ee = {.offset = (addr - 0x810000), .size = len, .ee = (uint8_t*)rep };
 
431
                                avr_ioctl(avr, AVR_IOCTL_EEPROM_SET, &ee);
 
432
                                gdb_send_reply(g, "OK");
 
433
                        } else {
 
434
                                AVR_LOG(avr, LOG_ERROR, "GDB: write memory error %08x, %08x\n", addr, len);
 
435
                                gdb_send_reply(g, "E01");
 
436
                        }
 
437
                }       break;
 
438
                case 'c': {     // continue
 
439
                        avr->state = cpu_Running;
 
440
                }       break;
 
441
                case 's': {     // step
 
442
                        avr->state = cpu_Step;
 
443
                }       break;
 
444
                case 'r': {     // deprecated, suggested for AVRStudio compatibility
 
445
                        avr->state = cpu_StepDone;
 
446
                        avr_reset(avr);
 
447
                }       break;
 
448
                case 'Z':       // set clear break/watchpoint
 
449
                case 'z': {
 
450
                        uint32_t kind, addr, len;
 
451
                        int set = (command == 'Z');
 
452
                        sscanf(cmd, "%d,%x,%x", &kind, &addr, &len);
 
453
//                      printf("breakpoint %d, %08x, %08x\n", kind, addr, len);
 
454
                        switch (kind) {
 
455
                                case 0: // software breakpoint
 
456
                                case 1: // hardware breakpoint
 
457
                                        if (addr > avr->flashend ||
 
458
                                                        gdb_change_breakpoint(&g->breakpoints, set, 1 << kind, addr, len) == -1) {
 
459
                                                gdb_send_reply(g, "E01");
 
460
                                                break;
 
461
                                        }
 
462
 
 
463
                                        gdb_send_reply(g, "OK");
 
464
                                        break;
 
465
                                case 2: // write watchpoint
 
466
                                case 3: // read watchpoint
 
467
                                case 4: // access watchpoint
 
468
                                        /* Mask out the offset applied to SRAM addresses. */
 
469
                                        addr &= ~0x800000;
 
470
                                        if (addr > avr->ramend ||
 
471
                                                        gdb_change_breakpoint(&g->watchpoints, set, 1 << kind, addr, len) == -1) {
 
472
                                                gdb_send_reply(g, "E01");
 
473
                                                break;
 
474
                                        }
 
475
 
 
476
                                        gdb_send_reply(g, "OK");
 
477
                                        break;
 
478
                                default:
 
479
                                        gdb_send_reply(g, "");
 
480
                                        break;
 
481
                        }
 
482
                }       break;
 
483
                default:
 
484
                        gdb_send_reply(g, "");
 
485
                        break;
 
486
        }
 
487
//#endif
 
488
}
 
489
 
 
490
static int
 
491
gdb_network_handler(
 
492
                avr_gdb_t * g,
 
493
                uint32_t dosleep )
 
494
{
 
495
//#ifndef _WIN32
 
496
        fd_set read_set;
 
497
        int max;
 
498
        FD_ZERO(&read_set);
 
499
 
 
500
        if (g->s != -1) {
 
501
                FD_SET(g->s, &read_set);
 
502
                max = g->s + 1;
 
503
        } else {
 
504
                FD_SET(g->listen, &read_set);
 
505
                max = g->listen + 1;
 
506
        }
 
507
        struct timeval timo = { dosleep / 1000000, dosleep % 1000000 };
 
508
        int ret = select(max, &read_set, NULL, NULL, &timo);
 
509
 
 
510
        if (ret == 0)
 
511
                return 0;
 
512
 
 
513
        if (FD_ISSET(g->listen, &read_set)) {
 
514
                g->s = accept(g->listen, NULL, NULL);
 
515
 
 
516
                if (g->s == -1) {
 
517
                        perror("gdb_network_handler accept");
 
518
                        sleep(5);
 
519
                        return 1;
 
520
                }
 
521
        int i = 1;
 
522
        setsockopt (g->s, IPPROTO_TCP, TCP_NODELAY, &i, sizeof (i));
 
523
                g->avr->state = cpu_Stopped;
 
524
                printf("%s connection opened\n", __FUNCTION__);
 
525
        }
 
526
 
 
527
        if (g->s != -1 && FD_ISSET(g->s, &read_set)) {
 
528
                uint8_t buffer[1024];
 
529
 
 
530
                ssize_t r = recv(g->s, buffer, sizeof(buffer)-1, 0);
 
531
 
 
532
                if (r == 0) {
 
533
                        printf("%s connection closed\n", __FUNCTION__);
 
534
                        close(g->s);
 
535
                        gdb_watch_clear(&g->breakpoints);
 
536
                        gdb_watch_clear(&g->watchpoints);
 
537
                        g->avr->state = cpu_Running;    // resume
 
538
                        g->s = -1;
 
539
                        return 1;
 
540
                }
 
541
                if (r == -1) {
 
542
                        perror("gdb_network_handler recv");
 
543
                        sleep(1);
 
544
                        return 1;
 
545
                }
 
546
                buffer[r] = 0;
 
547
        //      printf("%s: received %d bytes\n'%s'\n", __FUNCTION__, r, buffer);
 
548
        //      hdump("gdb", buffer, r);
 
549
 
 
550
                uint8_t * src = buffer;
 
551
                while (*src == '+' || *src == '-')
 
552
                        src++;
 
553
                // control C -- lets send the guy a nice status packet
 
554
                if (*src == 3) {
 
555
                        src++;
 
556
                        g->avr->state = cpu_StepDone;
 
557
                        printf("GDB hit control-c\n");
 
558
                }
 
559
                if (*src  == '$') {
 
560
                        // strip checksum
 
561
                        uint8_t * end = buffer + r - 1;
 
562
                        while (end > src && *end != '#')
 
563
                                *end-- = 0;
 
564
                        *end = 0;
 
565
                        src++;
 
566
                        DBG(printf("GDB command = '%s'\n", src);)
 
567
 
 
568
                        send(g->s, "+", 1, 0);
 
569
 
 
570
                        gdb_handle_command(g, (char*)src);
 
571
                }
 
572
        }
 
573
//#endif
 
574
        return 1;
 
575
}
 
576
 
 
577
/**
 
578
 * If an applicable watchpoint exists for addr, stop the cpu and send a status report.
 
579
 * type is one of AVR_GDB_WATCH_READ, AVR_GDB_WATCH_WRITE depending on the type of access.
 
580
 */
 
581
void
 
582
avr_gdb_handle_watchpoints(
 
583
                avr_t * avr,
 
584
                uint16_t addr,
 
585
                enum avr_gdb_watch_type type )
 
586
{
 
587
//#ifndef _WIN32
 
588
        avr_gdb_t *g = avr->gdb;
 
589
 
 
590
        int i = gdb_watch_find_range(&g->watchpoints, addr);
 
591
        if (i == -1) {
 
592
                return;
 
593
        }
 
594
 
 
595
        int kind = g->watchpoints.points[i].kind;
 
596
        if (kind & type) {
 
597
                /* Send gdb reply (see GDB user manual appendix E.3). */
 
598
                char cmd[78];
 
599
                sprintf(cmd, "T%02x20:%02x;21:%02x%02x;22:%02x%02x%02x00;%s:%06x;",
 
600
                                5, g->avr->data[R_SREG],
 
601
                                g->avr->data[R_SPL], g->avr->data[R_SPH],
 
602
                                g->avr->pc & 0xff, (g->avr->pc>>8)&0xff, (g->avr->pc>>16)&0xff,
 
603
                                kind & AVR_GDB_WATCH_ACCESS ? "awatch" :
 
604
                                        kind & AVR_GDB_WATCH_WRITE ? "watch" : "rwatch",
 
605
                                addr | 0x800000);
 
606
                gdb_send_reply(g, cmd);
 
607
 
 
608
                avr->state = cpu_Stopped;
 
609
        }
 
610
//#endif
 
611
}
 
612
 
 
613
int
 
614
avr_gdb_processor(
 
615
                avr_t * avr,
 
616
                int sleep )
 
617
{
 
618
//#ifndef _WIN32
 
619
        if (!avr || !avr->gdb)
 
620
                return 0;
 
621
        avr_gdb_t * g = avr->gdb;
 
622
 
 
623
        if (avr->state == cpu_Running &&
 
624
                        gdb_watch_find(&g->breakpoints, avr->pc) != -1) {
 
625
                DBG(printf("avr_gdb_processor hit breakpoint at %08x\n", avr->pc);)
 
626
                gdb_send_quick_status(g, 0);
 
627
                avr->state = cpu_Stopped;
 
628
        } else if (avr->state == cpu_StepDone) {
 
629
                gdb_send_quick_status(g, 0);
 
630
                avr->state = cpu_Stopped;
 
631
        }
 
632
        // this also sleeps for a bit
 
633
        return gdb_network_handler(g, sleep);
 
634
//#endif
 
635
return 0;
 
636
}
 
637
 
 
638
 
 
639
int
 
640
avr_gdb_init(
 
641
                avr_t * avr )
 
642
{
 
643
//#ifndef _WIN32
 
644
        if (avr->gdb)
 
645
                return 0; // GDB server already is active
 
646
 
 
647
        avr_gdb_t * g = malloc(sizeof(avr_gdb_t));
 
648
        memset(g, 0, sizeof(avr_gdb_t));
 
649
 
 
650
        avr->gdb = NULL;
 
651
 
 
652
        if ( network_init() ) {
 
653
                AVR_LOG(avr, LOG_ERROR, "GDB: Can't initialize network");
 
654
                goto error;
 
655
        }
 
656
 
 
657
        if ((g->listen = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
 
658
                AVR_LOG(avr, LOG_ERROR, "GDB: Can't create socket: %s", strerror(errno));
 
659
                goto error;
 
660
        }
 
661
 
 
662
        int optval = 1;
 
663
        setsockopt(g->listen, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
 
664
 
 
665
        struct sockaddr_in address = { 0 };
 
666
        address.sin_family = AF_INET;
 
667
        address.sin_port = htons (avr->gdb_port);
 
668
 
 
669
        if (bind(g->listen, (struct sockaddr *) &address, sizeof(address))) {
 
670
                AVR_LOG(avr, LOG_ERROR, "GDB: Can not bind socket: %s", strerror(errno));
 
671
                goto error;
 
672
        }
 
673
        if (listen(g->listen, 1)) {
 
674
                perror("listen");
 
675
                goto error;
 
676
        }
 
677
        printf("avr_gdb_init listening on port %d\n", avr->gdb_port);
 
678
        g->avr = avr;
 
679
        g->s = -1;
 
680
        avr->gdb = g;
 
681
        // change default run behaviour to use the slightly slower versions
 
682
        avr->run = avr_callback_run_gdb;
 
683
        avr->sleep = avr_callback_sleep_gdb;
 
684
 
 
685
        return 0;
 
686
 
 
687
error:
 
688
        if (g->listen >= 0)
 
689
                close(g->listen);
 
690
        free(g);
 
691
//#endif
 
692
        return -1;
 
693
}
 
694
 
 
695
void
 
696
avr_deinit_gdb(
 
697
                avr_t * avr )
 
698
{
 
699
//#ifndef _WIN32
 
700
        if (!avr->gdb)
 
701
                return;
 
702
        avr->run = avr_callback_run_raw; // restore normal callbacks
 
703
        avr->sleep = avr_callback_sleep_raw;
 
704
        if (avr->gdb->listen != -1)
 
705
                close(avr->gdb->listen);
 
706
        avr->gdb->listen = -1;
 
707
        if (avr->gdb->s != -1)
 
708
                close(avr->gdb->s);
 
709
        avr->gdb->s = -1;
 
710
        free(avr->gdb);
 
711
        avr->gdb = NULL;
 
712
 
 
713
        network_release();
 
714
//#endif
 
715
}