4
Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
6
This file is part of simavr.
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.
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.
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/>.
22
#include "sim_network.h"
31
#include "sim_core.h" // for SET_SREG_FROM, READ_SREG_INTO
33
#include "avr_eeprom.h"
38
#define WATCH_LIMIT (32)
41
uint32_t len; /**< How many points are taken (points[0] .. points[len - 1]). */
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;
49
typedef struct avr_gdb_t {
51
int listen; // listen socket
52
int s; // current gdb connection
54
avr_gdb_watchpoints_t breakpoints;
55
avr_gdb_watchpoints_t watchpoints;
60
* Returns the index of the watchpoint if found, -1 otherwise.
64
const avr_gdb_watchpoints_t * w,
68
for (int i = 0; i < w->len; i++) {
69
if (w->points[i].addr > addr) {
71
} else if (w->points[i].addr == addr) {
80
* Contrary to gdb_watch_find, this actually checks the address against
81
* a watched memory _range_.
85
const avr_gdb_watchpoints_t * w,
89
for (int i = 0; i < w->len; i++) {
90
if (w->points[i].addr > addr) {
92
} else if (w->points[i].addr <= addr && addr < w->points[i].addr + w->points[i].size) {
101
* Returns -1 on error, 0 otherwise.
104
gdb_watch_add_or_update(
105
avr_gdb_watchpoints_t * w,
106
enum avr_gdb_watch_type kind,
111
/* If the watchpoint exists, update it. */
112
int i = gdb_watch_find(w, addr);
114
w->points[i].size = size;
115
w->points[i].kind |= kind;
119
/* Otherwise add it. */
120
if (w->len == WATCH_LIMIT) {
124
/* Find the insertion point. */
125
for (i = 0; i < w->len; i++) {
126
if (w->points[i].addr > addr) {
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];
139
w->points[i].kind = kind;
140
w->points[i].addr = addr;
141
w->points[i].size = size;
147
* Returns -1 on error or if the specified point does not exist, 0 otherwise.
151
avr_gdb_watchpoints_t * w,
152
enum avr_gdb_watch_type kind,
156
int i = gdb_watch_find(w, addr);
161
w->points[i].kind &= ~kind;
162
if (w->points[i].kind) {
166
for (i = i + 1; i < w->len; i++) {
167
w->points[i - 1] = w->points[i];
177
avr_gdb_watchpoints_t * w )
189
uint8_t * dst = reply;
196
sprintf((char*)dst, "#%02x", check);
197
DBG(printf("%s '%s'\n", __FUNCTION__, reply);)
198
send(g->s, reply, dst - reply + 3, 0);
203
gdb_send_quick_status(
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);
219
gdb_change_breakpoint(
220
avr_gdb_watchpoints_t * w,
222
enum avr_gdb_watch_type kind,
227
DBG(printf("set %d kind %d addr %08x len %d\n", set, kind, addr, len);)
230
return gdb_watch_add_or_update(w, kind, addr, size);
232
return gdb_watch_rm(w, kind, addr);
247
g->avr->data[regi] = *src;
250
g->avr->data[R_SREG] = *src;
251
SET_SREG_FROM(g->avr, *src);
254
g->avr->data[R_SPL] = src[0];
255
g->avr->data[R_SPH] = src[1];
258
g->avr->pc = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
274
sprintf(rep, "%02x", g->avr->data[regi]);
278
READ_SREG_INTO(g->avr, sreg);
279
sprintf(rep, "%02x", sreg);
283
sprintf(rep, "%02x%02x", g->avr->data[R_SPL], g->avr->data[R_SPH]);
286
sprintf(rep, "%02x%02x%02x00",
287
g->avr->pc & 0xff, (g->avr->pc>>8)&0xff, (g->avr->pc>>16)&0xff);
301
avr_t * avr = g->avr;
303
uint8_t command = *cmd++;
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.
311
gdb_send_reply(g, "qXfer:memory-map:read+");
313
} else if (strncmp(cmd, "Attached", 8) == 0) {
314
/* Respond that we are attached to an existing process..
317
gdb_send_reply(g, "1");
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");
323
} else if (strncmp(cmd, "Xfer:memory-map:read", 20) == 0) {
324
snprintf(rep, sizeof(rep),
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"
331
g->avr->ramend + 1, g->avr->flashend + 1);
333
gdb_send_reply(g, rep);
336
gdb_send_reply(g, "");
339
gdb_send_quick_status(g, 0);
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");
349
case 'g': { // read all general purpose registers
351
for (int i = 0; i < 35; i++)
352
dst += gdb_read_register(g, i, dst);
353
gdb_send_reply(g, rep);
355
case 'p': { // read register
356
unsigned int regi = 0;
357
sscanf(cmd, "%x", ®i);
358
gdb_read_register(g, regi, rep);
359
gdb_send_reply(g, rep);
361
case 'P': { // write register
362
unsigned int regi = 0;
363
char * val = strchr(cmd, '=');
367
sscanf(cmd, "%x", ®i);
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");
372
case 'm': { // read memory
373
avr_flashaddr_t addr;
375
sscanf(cmd, "%x,%x", &addr, &len);
376
uint8_t * src = NULL;
377
/* GDB seems to also use 0x1800000 for sram ?!?! */
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");
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);
396
gdb_send_reply(g, "E01");
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");
408
sprintf(dst, "%02x", *src++);
412
gdb_send_reply(g, rep);
414
case 'M': { // write memory
416
sscanf(cmd, "%x,%x", &addr, &len);
417
char * start = strchr(cmd, ':');
419
gdb_send_reply(g, "E01");
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");
434
AVR_LOG(avr, LOG_ERROR, "GDB: write memory error %08x, %08x\n", addr, len);
435
gdb_send_reply(g, "E01");
438
case 'c': { // continue
439
avr->state = cpu_Running;
442
avr->state = cpu_Step;
444
case 'r': { // deprecated, suggested for AVRStudio compatibility
445
avr->state = cpu_StepDone;
448
case 'Z': // set clear break/watchpoint
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);
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");
463
gdb_send_reply(g, "OK");
465
case 2: // write watchpoint
466
case 3: // read watchpoint
467
case 4: // access watchpoint
468
/* Mask out the offset applied to SRAM addresses. */
470
if (addr > avr->ramend ||
471
gdb_change_breakpoint(&g->watchpoints, set, 1 << kind, addr, len) == -1) {
472
gdb_send_reply(g, "E01");
476
gdb_send_reply(g, "OK");
479
gdb_send_reply(g, "");
484
gdb_send_reply(g, "");
501
FD_SET(g->s, &read_set);
504
FD_SET(g->listen, &read_set);
507
struct timeval timo = { dosleep / 1000000, dosleep % 1000000 };
508
int ret = select(max, &read_set, NULL, NULL, &timo);
513
if (FD_ISSET(g->listen, &read_set)) {
514
g->s = accept(g->listen, NULL, NULL);
517
perror("gdb_network_handler accept");
522
setsockopt (g->s, IPPROTO_TCP, TCP_NODELAY, &i, sizeof (i));
523
g->avr->state = cpu_Stopped;
524
printf("%s connection opened\n", __FUNCTION__);
527
if (g->s != -1 && FD_ISSET(g->s, &read_set)) {
528
uint8_t buffer[1024];
530
ssize_t r = recv(g->s, buffer, sizeof(buffer)-1, 0);
533
printf("%s connection closed\n", __FUNCTION__);
535
gdb_watch_clear(&g->breakpoints);
536
gdb_watch_clear(&g->watchpoints);
537
g->avr->state = cpu_Running; // resume
542
perror("gdb_network_handler recv");
547
// printf("%s: received %d bytes\n'%s'\n", __FUNCTION__, r, buffer);
548
// hdump("gdb", buffer, r);
550
uint8_t * src = buffer;
551
while (*src == '+' || *src == '-')
553
// control C -- lets send the guy a nice status packet
556
g->avr->state = cpu_StepDone;
557
printf("GDB hit control-c\n");
561
uint8_t * end = buffer + r - 1;
562
while (end > src && *end != '#')
566
DBG(printf("GDB command = '%s'\n", src);)
568
send(g->s, "+", 1, 0);
570
gdb_handle_command(g, (char*)src);
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.
582
avr_gdb_handle_watchpoints(
585
enum avr_gdb_watch_type type )
588
avr_gdb_t *g = avr->gdb;
590
int i = gdb_watch_find_range(&g->watchpoints, addr);
595
int kind = g->watchpoints.points[i].kind;
597
/* Send gdb reply (see GDB user manual appendix E.3). */
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",
606
gdb_send_reply(g, cmd);
608
avr->state = cpu_Stopped;
619
if (!avr || !avr->gdb)
621
avr_gdb_t * g = avr->gdb;
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;
632
// this also sleeps for a bit
633
return gdb_network_handler(g, sleep);
645
return 0; // GDB server already is active
647
avr_gdb_t * g = malloc(sizeof(avr_gdb_t));
648
memset(g, 0, sizeof(avr_gdb_t));
652
if ( network_init() ) {
653
AVR_LOG(avr, LOG_ERROR, "GDB: Can't initialize network");
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));
663
setsockopt(g->listen, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
665
struct sockaddr_in address = { 0 };
666
address.sin_family = AF_INET;
667
address.sin_port = htons (avr->gdb_port);
669
if (bind(g->listen, (struct sockaddr *) &address, sizeof(address))) {
670
AVR_LOG(avr, LOG_ERROR, "GDB: Can not bind socket: %s", strerror(errno));
673
if (listen(g->listen, 1)) {
677
printf("avr_gdb_init listening on port %d\n", avr->gdb_port);
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;
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)