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 <netinet/in.h>
23 #include <netinet/tcp.h>
24 #include <arpa/inet.h>
25 #include <sys/socket.h>
35 #include "sim_core.h" // for SET_SREG_FROM, READ_SREG_INTO
37 #include "avr_eeprom.h"
42 #define WATCH_LIMIT (32)
45 uint32_t len; /**< How many points are taken (points[0] .. points[len - 1]). */
47 uint32_t addr; /**< Which address is watched. */
48 uint32_t size; /**< How large is the watched segment. */
49 uint32_t kind; /**< Bitmask of enum avr_gdb_watch_type values. */
50 } points[WATCH_LIMIT];
51 } avr_gdb_watchpoints_t;
53 typedef struct avr_gdb_t {
55 int listen; // listen socket
56 int s; // current gdb connection
58 avr_gdb_watchpoints_t breakpoints;
59 avr_gdb_watchpoints_t watchpoints;
64 * Returns the index of the watchpoint if found, -1 otherwise.
66 static int gdb_watch_find(const avr_gdb_watchpoints_t * w, uint32_t addr)
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_.
83 static int gdb_watch_find_range(const avr_gdb_watchpoints_t * w, uint32_t addr)
85 for (int i = 0; i < w->len; i++) {
86 if (w->points[i].addr > addr) {
88 } else if (w->points[i].addr <= addr && addr < w->points[i].addr + w->points[i].size) {
97 * Returns -1 on error, 0 otherwise.
99 static int gdb_watch_add_or_update(avr_gdb_watchpoints_t * w, enum avr_gdb_watch_type kind, uint32_t addr,
102 /* If the watchpoint exists, update it. */
103 int i = gdb_watch_find(w, addr);
105 w->points[i].size = size;
106 w->points[i].kind |= kind;
110 /* Otherwise add it. */
111 if (w->len == WATCH_LIMIT) {
115 /* Find the insertion point. */
116 for (i = 0; i < w->len; i++) {
117 if (w->points[i].addr > addr) {
124 /* Make space for new element. */
125 for (int j = i + 1; j < w->len; j++) {
126 w->points[j] = w->points[j - 1];
130 w->points[i].kind = kind;
131 w->points[i].addr = addr;
132 w->points[i].size = size;
138 * Returns -1 on error or if the specified point does not exist, 0 otherwise.
140 static int gdb_watch_rm(avr_gdb_watchpoints_t * w, enum avr_gdb_watch_type kind, uint32_t addr)
142 int i = gdb_watch_find(w, addr);
147 w->points[i].kind &= ~kind;
148 if (w->points[i].kind) {
152 for (i = i + 1; i < w->len; i++) {
153 w->points[i - 1] = w->points[i];
161 static void gdb_watch_clear(avr_gdb_watchpoints_t * w)
166 static void gdb_send_reply(avr_gdb_t * g, char * cmd)
169 uint8_t * dst = reply;
176 sprintf((char*)dst, "#%02x", check);
177 DBG(printf("%s '%s'\n", __FUNCTION__, reply);)
178 send(g->s, reply, dst - reply + 3, 0);
181 static void gdb_send_quick_status(avr_gdb_t * g, uint8_t signal)
185 sprintf(cmd, "T%02x20:%02x;21:%02x%02x;22:%02x%02x%02x00;",
186 signal ? signal : 5, g->avr->data[R_SREG],
187 g->avr->data[R_SPL], g->avr->data[R_SPH],
188 g->avr->pc & 0xff, (g->avr->pc>>8)&0xff, (g->avr->pc>>16)&0xff);
189 gdb_send_reply(g, cmd);
192 static int gdb_change_breakpoint(avr_gdb_watchpoints_t * w, int set, enum avr_gdb_watch_type kind,
193 uint32_t addr, uint32_t size)
195 DBG(printf("set %d kind %d addr %08x len %d\n", set, kind, addr, len);)
198 return gdb_watch_add_or_update(w, kind, addr, size);
200 return gdb_watch_rm(w, kind, addr);
206 static int gdb_write_register(avr_gdb_t * g, int regi, uint8_t * src)
210 g->avr->data[regi] = *src;
213 g->avr->data[R_SREG] = *src;
214 SET_SREG_FROM(g->avr, *src);
217 g->avr->data[R_SPL] = src[0];
218 g->avr->data[R_SPH] = src[1];
221 g->avr->pc = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
227 static int gdb_read_register(avr_gdb_t * g, int regi, char * rep)
231 sprintf(rep, "%02x", g->avr->data[regi]);
235 READ_SREG_INTO(g->avr, sreg);
236 sprintf(rep, "%02x", sreg);
240 sprintf(rep, "%02x%02x", g->avr->data[R_SPL], g->avr->data[R_SPH]);
243 sprintf(rep, "%02x%02x%02x00",
244 g->avr->pc & 0xff, (g->avr->pc>>8)&0xff, (g->avr->pc>>16)&0xff);
250 static void gdb_handle_command(avr_gdb_t * g, char * cmd)
252 avr_t * avr = g->avr;
254 uint8_t command = *cmd++;
257 gdb_send_quick_status(g, 0);
259 case 'G': { // set all general purpose registers
260 // get their binary form
261 read_hex_string(cmd, (uint8_t*)rep, strlen(cmd));
262 uint8_t *src = (uint8_t*)rep;
263 for (int i = 0; i < 35; i++)
264 src += gdb_write_register(g, i, src);
265 gdb_send_reply(g, "OK");
267 case 'g': { // read all general purpose registers
269 for (int i = 0; i < 35; i++)
270 dst += gdb_read_register(g, i, dst);
271 gdb_send_reply(g, rep);
273 case 'p': { // read register
274 unsigned int regi = 0;
275 sscanf(cmd, "%x", ®i);
276 gdb_read_register(g, regi, rep);
277 gdb_send_reply(g, rep);
279 case 'P': { // write register
280 unsigned int regi = 0;
281 char * val = strchr(cmd, '=');
285 sscanf(cmd, "%x", ®i);
286 read_hex_string(val, (uint8_t*)rep, strlen(val));
287 gdb_write_register(g, regi, (uint8_t*)rep);
288 gdb_send_reply(g, "OK");
290 case 'm': { // read memory
291 avr_flashaddr_t addr;
293 sscanf(cmd, "%x,%x", &addr, &len);
294 uint8_t * src = NULL;
295 if (addr < avr->flashend) {
296 src = avr->flash + addr;
297 } else if (addr >= 0x800000 && (addr - 0x800000) <= avr->ramend) {
298 src = avr->data + addr - 0x800000;
299 } else if (addr >= 0x810000 && (addr - 0x810000) <= avr->e2end) {
300 avr_eeprom_desc_t ee = {.offset = (addr - 0x810000)};
301 avr_ioctl(avr, AVR_IOCTL_EEPROM_GET, &ee);
305 gdb_send_reply(g, "E01");
308 } else if (addr >= 0x800000 && (addr - 0x800000) == avr->ramend+1 && len == 2) {
309 // Allow GDB to read a value just after end of stack.
310 // This is necessary to make instruction stepping work when stack is empty
311 AVR_LOG(avr, LOG_TRACE, "GDB: read just past end of stack %08x, %08x; returning zero\n", addr, len);
312 gdb_send_reply(g, "0000");
315 AVR_LOG(avr, LOG_ERROR, "GDB: read memory error %08x, %08x (ramend %04x)\n", addr, len, avr->ramend+1);
316 gdb_send_reply(g, "E01");
321 sprintf(dst, "%02x", *src++);
325 gdb_send_reply(g, rep);
327 case 'M': { // write memory
329 sscanf(cmd, "%x,%x", &addr, &len);
330 char * start = strchr(cmd, ':');
332 gdb_send_reply(g, "E01");
336 read_hex_string(start + 1, avr->flash + addr, strlen(start+1));
337 gdb_send_reply(g, "OK");
338 } else if (addr >= 0x800000 && (addr - 0x800000) <= avr->ramend) {
339 read_hex_string(start + 1, avr->data + addr - 0x800000, strlen(start+1));
340 gdb_send_reply(g, "OK");
341 } else if (addr >= 0x810000 && (addr - 0x810000) <= avr->e2end) {
342 read_hex_string(start + 1, (uint8_t*)rep, strlen(start+1));
343 avr_eeprom_desc_t ee = {.offset = (addr - 0x810000), .size = len, .ee = (uint8_t*)rep };
344 avr_ioctl(avr, AVR_IOCTL_EEPROM_SET, &ee);
345 gdb_send_reply(g, "OK");
347 AVR_LOG(avr, LOG_ERROR, "GDB: write memory error %08x, %08x\n", addr, len);
348 gdb_send_reply(g, "E01");
351 case 'c': { // continue
352 avr->state = cpu_Running;
355 avr->state = cpu_Step;
357 case 'r': { // deprecated, suggested for AVRStudio compatibility
358 avr->state = cpu_StepDone;
361 case 'Z': // set clear break/watchpoint
363 uint32_t kind, addr, len;
364 int set = (command == 'Z');
365 sscanf(cmd, "%d,%x,%x", &kind, &addr, &len);
366 // printf("breakpoint %d, %08x, %08x\n", kind, addr, len);
368 case 0: // software breakpoint
369 case 1: // hardware breakpoint
370 if (addr > avr->flashend ||
371 gdb_change_breakpoint(&g->breakpoints, set, 1 << kind, addr, len) == -1) {
372 gdb_send_reply(g, "E01");
376 gdb_send_reply(g, "OK");
378 case 2: // write watchpoint
379 case 3: // read watchpoint
380 case 4: // access watchpoint
381 /* Mask out the offset applied to SRAM addresses. */
383 if (addr > avr->ramend ||
384 gdb_change_breakpoint(&g->watchpoints, set, 1 << kind, addr, len) == -1) {
385 gdb_send_reply(g, "E01");
389 gdb_send_reply(g, "OK");
392 gdb_send_reply(g, "");
397 gdb_send_reply(g, "");
402 static int gdb_network_handler(avr_gdb_t * g, uint32_t dosleep)
409 FD_SET(g->s, &read_set);
412 FD_SET(g->listen, &read_set);
415 struct timeval timo = { 0, dosleep }; // short, but not too short interval
416 int ret = select(max, &read_set, NULL, NULL, &timo);
421 if (FD_ISSET(g->listen, &read_set)) {
422 g->s = accept(g->listen, NULL, NULL);
425 perror("gdb_network_handler accept");
430 setsockopt (g->s, IPPROTO_TCP, TCP_NODELAY, &i, sizeof (i));
431 g->avr->state = cpu_Stopped;
432 printf("%s connection opened\n", __FUNCTION__);
435 if (g->s != -1 && FD_ISSET(g->s, &read_set)) {
436 uint8_t buffer[1024];
438 ssize_t r = recv(g->s, buffer, sizeof(buffer)-1, 0);
441 printf("%s connection closed\n", __FUNCTION__);
443 gdb_watch_clear(&g->breakpoints);
444 gdb_watch_clear(&g->watchpoints);
445 g->avr->state = cpu_Running; // resume
450 perror("gdb_network_handler recv");
455 // printf("%s: received %d bytes\n'%s'\n", __FUNCTION__, r, buffer);
456 // hdump("gdb", buffer, r);
458 uint8_t * src = buffer;
459 while (*src == '+' || *src == '-')
461 // control C -- lets send the guy a nice status packet
464 g->avr->state = cpu_StepDone;
465 printf("GDB hit control-c\n");
469 uint8_t * end = buffer + r - 1;
470 while (end > src && *end != '#')
474 DBG(printf("GDB command = '%s'\n", src);)
476 send(g->s, "+", 1, 0);
478 gdb_handle_command(g, (char*)src);
485 * If an applicable watchpoint exists for addr, stop the cpu and send a status report.
486 * type is one of AVR_GDB_WATCH_READ, AVR_GDB_WATCH_WRITE depending on the type of access.
488 void avr_gdb_handle_watchpoints(avr_t * avr, uint16_t addr, enum avr_gdb_watch_type type)
490 avr_gdb_t *g = avr->gdb;
492 int i = gdb_watch_find_range(&g->watchpoints, addr);
497 int kind = g->watchpoints.points[i].kind;
499 /* Send gdb reply (see GDB user manual appendix E.3). */
501 sprintf(cmd, "T%02x20:%02x;21:%02x%02x;22:%02x%02x%02x00;%s:%06x;",
502 5, g->avr->data[R_SREG],
503 g->avr->data[R_SPL], g->avr->data[R_SPH],
504 g->avr->pc & 0xff, (g->avr->pc>>8)&0xff, (g->avr->pc>>16)&0xff,
505 kind & AVR_GDB_WATCH_ACCESS ? "awatch" : kind & AVR_GDB_WATCH_WRITE ? "watch" : "rwatch",
507 gdb_send_reply(g, cmd);
509 avr->state = cpu_Stopped;
513 int avr_gdb_processor(avr_t * avr, int sleep)
515 if (!avr || !avr->gdb)
517 avr_gdb_t * g = avr->gdb;
519 if (avr->state == cpu_Running && gdb_watch_find(&g->breakpoints, avr->pc) != -1) {
520 DBG(printf("avr_gdb_processor hit breakpoint at %08x\n", avr->pc);)
521 gdb_send_quick_status(g, 0);
522 avr->state = cpu_Stopped;
523 } else if (avr->state == cpu_StepDone) {
524 gdb_send_quick_status(g, 0);
525 avr->state = cpu_Stopped;
527 // this also sleeps for a bit
528 return gdb_network_handler(g, sleep);
532 int avr_gdb_init(avr_t * avr)
534 avr_gdb_t * g = malloc(sizeof(avr_gdb_t));
535 memset(g, 0, sizeof(avr_gdb_t));
539 if ((g->listen = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
540 AVR_LOG(avr, LOG_ERROR, "GDB: Can't create socket: %s", strerror(errno));
545 setsockopt(g->listen, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
547 struct sockaddr_in address = { 0 };
548 address.sin_family = AF_INET;
549 address.sin_port = htons (avr->gdb_port);
551 if (bind(g->listen, (struct sockaddr *) &address, sizeof(address))) {
552 AVR_LOG(avr, LOG_ERROR, "GDB: Can not bind socket: %s", strerror(errno));
555 if (listen(g->listen, 1)) {
559 printf("avr_gdb_init listening on port %d\n", avr->gdb_port);
563 // change default run behaviour to use the slightly slower versions
564 avr->run = avr_callback_run_gdb;
565 avr->sleep = avr_callback_sleep_gdb;
570 void avr_deinit_gdb(avr_t * avr)
572 if (avr->gdb->listen != -1)
573 close(avr->gdb->listen);
574 if (avr->gdb->s != -1)