OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [debug/] [gdbcomm.c] - Blame information for rev 1782

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 321 markom
/* gdbcomm.c -- Communication routines for gdb
2 479 markom
         Copyright (C) 2001 by Marko Mlinar, markom@opencores.org
3
         Code copied from toplevel.c
4 321 markom
 
5 479 markom
         This file is part of OpenRISC 1000 Architectural Simulator.
6
 
7
         This program is free software; you can redistribute it and/or modify
8
         it under the terms of the GNU General Public License as published by
9
         the Free Software Foundation; either version 2 of the License, or
10
         (at your option) any later version.
11
 
12
         This program is distributed in the hope that it will be useful,
13
         but WITHOUT ANY WARRANTY; without even the implied warranty of
14
         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
15
         GNU General Public License for more details.
16 321 markom
 
17 479 markom
         You should have received a copy of the GNU General Public License
18
         along with this program; if not, write to the Free Software
19
         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 321 markom
*/
21
 
22
#include <stdlib.h>
23
#include <stdio.h>
24
#include <sys/stat.h>
25
#include <sys/types.h>
26
#include <sys/socket.h>
27
#include <netinet/in.h>
28
#include <sys/select.h>
29
#include <sys/poll.h>
30
#include <fcntl.h>
31
#include <netdb.h>
32
#include <netinet/tcp.h>
33 1308 phoenix
#include <unistd.h>
34
#include <string.h>
35 321 markom
 
36 1358 nogj
#include "config.h"
37
 
38
#ifdef HAVE_INTTYPES_H
39
#include <inttypes.h>
40
#endif
41
 
42
#include "port.h"
43
#include "arch.h"
44 321 markom
#include "gdb.h"
45
#include "gdbcomm.h"
46 439 erez
#include "vapi.h"
47 321 markom
#include "sim-config.h"
48 1308 phoenix
#include "debug_unit.h"
49 321 markom
 
50 1308 phoenix
static int gdb_read(void* buf,int len);
51
static int gdb_write(const void* buf,int len);
52
 
53 321 markom
static unsigned int serverIP = 0;
54
static unsigned int serverPort = 0;
55
static unsigned int server_fd = 0;
56
static unsigned int gdb_fd = 0;
57
 
58
static int tcp_level = 0;
59
 
60
/* Added by CZ 24/05/01 */
61
int GetServerSocket(const char* name,const char* proto,int port)
62
{
63
  struct servent *service;
64
  struct protoent *protocol;
65
  struct sockaddr_in sa;
66
  struct hostent *hp;
67
  int sockfd;
68
  char myname[256];
69
  int flags;
70
  char sTemp[256];
71
 
72
  /* First, get the protocol number of TCP */
73
  if(!(protocol = getprotobyname(proto)))
74
    {
75
      sprintf(sTemp,"Unable to load protocol \"%s\"",proto);
76
      perror(sTemp);
77
      return 0;
78
    }
79
  tcp_level = protocol->p_proto; /* Save for later */
80
 
81
  /* If we weren't passed a non standard port, get the port
82
     from the services directory. */
83
  if(!port)
84
    {
85 1308 phoenix
      if((service = getservbyname(name,protocol->p_name)))
86 479 markom
        port = ntohs(service->s_port);
87 321 markom
    }
88
 
89
  /* Create the socket using the TCP protocol */
90
  if((sockfd = socket(PF_INET,SOCK_STREAM,protocol->p_proto)) < 0)
91
    {
92
      perror("Unable to create socket");
93
      return 0;
94
    }
95
 
96
  flags = 1;
97
  if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(const char*)&flags,sizeof(int)) < 0)
98
    {
99
      sprintf(sTemp,"Can not set SO_REUSEADDR option on socket %d",sockfd);
100
      perror(sTemp);
101
      close(sockfd);
102
      return 0;
103
    }
104
 
105
  /* The server should also be non blocking. Get the current flags. */
106
  if(fcntl(sockfd,F_GETFL,&flags) < 0)
107
    {
108
      sprintf(sTemp,"Unable to get flags for socket %d",sockfd);
109
      perror(sTemp);
110
      close(sockfd);
111
      return 0;
112
    }
113
 
114
  /* Set the nonblocking flag */
115
  if(fcntl(sockfd,F_SETFL, flags | O_NONBLOCK) < 0)
116
    {
117
      sprintf(sTemp,"Unable to set flags for socket %d to value 0x%08x",
118 479 markom
              sockfd,flags | O_NONBLOCK);
119 321 markom
      perror(sTemp);
120
      close(sockfd);
121
      return 0;
122
    }
123
 
124
  /* Find out what our address is */
125
  memset(&sa,0,sizeof(struct sockaddr_in));
126
  gethostname(myname,sizeof(myname));
127
  if(!(hp = gethostbyname(myname)))
128
    {
129
      perror("Unable to read hostname");
130
      close(sockfd);
131
      return 0;
132
    }
133
 
134
  /* Bind our socket to the appropriate address */
135
  sa.sin_family = hp->h_addrtype;
136
  sa.sin_port = htons(port);
137
  if(bind(sockfd,(struct sockaddr*)&sa,sizeof(struct sockaddr_in)) < 0)
138
    {
139
      sprintf(sTemp,"Unable to bind socket %d to port %d",sockfd,port);
140
      perror(sTemp);
141
      close(sockfd);
142
      return 0;
143
    }
144
  serverIP = sa.sin_addr.s_addr;
145
  flags = sizeof(struct sockaddr_in);
146
  if(getsockname(sockfd,(struct sockaddr*)&sa,&flags) < 0)
147
    {
148
      sprintf(sTemp,"Unable to get socket information for socket %d",sockfd);
149
      perror(sTemp);
150
      close(sockfd);
151
      return 0;
152
    }
153
  serverPort = ntohs(sa.sin_port);
154
 
155
  /* Set the backlog to 1 connections */
156
  if(listen(sockfd,1) < 0)
157
    {
158
      sprintf(sTemp,"Unable to set backlog on socket %d to %d",sockfd,1);
159
      perror(sTemp);
160
      close(sockfd);
161
      return 0;
162
    }
163
 
164
  return sockfd;
165
}
166
 
167
void BlockJTAG()
168
{
169
  struct pollfd fds[2];
170
  int n = 0;
171
 
172
  fds[n].fd = server_fd;
173
  fds[n].events = POLLIN;
174
  fds[n++].revents = 0;
175
  if(gdb_fd)
176
    {
177
      fds[n].fd = gdb_fd;
178
      fds[n].events = POLLIN;
179
      fds[n++].revents = 0;
180
    }
181
  poll(fds,n,-1);
182
}
183
 
184
void HandleServerSocket(Boolean block)
185
{
186
  struct pollfd fds[3];
187
  int n = 0;
188
  int timeout = block ? -1 : 0;
189
  Boolean data_on_stdin = false;
190
  int o_serv_fd = server_fd;
191
 
192
  if(!o_serv_fd && !gdb_fd)
193
    return;
194
 
195
  if(o_serv_fd)
196
    {
197
      fds[n].fd = o_serv_fd;
198
      fds[n].events = POLLIN;
199
      fds[n++].revents = 0;
200
    }
201
  if(gdb_fd)
202
    {
203
      fds[n].fd = gdb_fd;
204
      fds[n].events = POLLIN;
205
      fds[n++].revents = 0;
206
    }
207
  if(block)
208
    {
209
      fds[n].fd = 0;
210
      fds[n].events = POLLIN;
211
      fds[n++].revents = 0;
212
    }
213
 
214
  while(!data_on_stdin)
215
    {
216
      switch(poll(fds,n,timeout))
217 479 markom
        {
218
        case -1:
219
          if(errno == EINTR)
220
            continue;
221
          perror("poll");
222
          server_fd = 0;
223
          break;
224
        case 0: /* Nothing interesting going on */
225
          data_on_stdin = true; /* Can only get here if nonblocking */
226
          break;
227
        default:
228
          /* Make sure to handle the gdb port first! */
229
          if((fds[0].revents && (gdb_fd && !o_serv_fd) ||
230
              fds[1].revents && (server_fd && gdb_fd)))
231
            {
232
              int revents = o_serv_fd ? fds[1].revents : fds[0].revents;
233 321 markom
 
234 479 markom
              if(revents & POLLIN)
235
                GDBRequest();
236
              else /* Error Occurred */
237
                {
238
                  fprintf(stderr,"Received flags 0x%08x on gdb socket. Shutting down.\n",revents);
239
                  close(gdb_fd);
240
                  gdb_fd = 0;
241
                }
242
            }
243
          if(fds[0].revents && o_serv_fd)
244
            {
245
              if(fds[0].revents & POLLIN)
246
                JTAGRequest();
247
              else /* Error Occurred */
248
                {
249
                  fprintf(stderr,"Received flags 0x%08x on server. Shutting down.\n",fds[0].revents);
250
                  close(o_serv_fd);
251
                  server_fd = 0;
252
                  serverPort = 0;
253
                  serverIP = 0;
254
                }
255
            }
256
          if(fds[2].revents || (fds[1].revents && !gdb_fd))
257
            data_on_stdin = true;
258
          break;
259
        } /* End of switch statement */
260 321 markom
    } /* End of while statement */
261
}
262
 
263
void JTAGRequest()
264
{
265
  struct sockaddr_in sa;
266
  struct sockaddr* addr = (struct sockaddr*)&sa;
267
  int n = sizeof(struct sockaddr_in);
268
  int fd = accept(server_fd,addr,&n);
269
  int on_off = 0; /* Turn off Nagel's algorithm on the socket */
270
  int flags;
271
  char sTemp[256];
272
 
273
  if(fd < 0)
274
    {
275
      /* This is valid, because a connection could have started,
276 479 markom
         and then terminated due to a protocol error or user
277
         initiation before the accept could take place. */
278 321 markom
      if(errno != EWOULDBLOCK && errno != EAGAIN)
279 479 markom
        {
280
          perror("accept");
281
          close(server_fd);
282
          server_fd = 0;
283
          serverPort = 0;
284
          serverIP = 0;
285
        }
286 321 markom
      return;
287
    }
288
 
289
  if(gdb_fd)
290
    {
291
      close(fd);
292
      return;
293
    }
294
 
295
  if(fcntl(fd,F_GETFL,&flags) < 0)
296
    {
297
      sprintf(sTemp,"Unable to get flags for gdb socket %d",fd);
298
      perror(sTemp);
299
      close(fd);
300
      return;
301
    }
302
 
303
  if(fcntl(fd,F_SETFL, flags | O_NONBLOCK) < 0)
304
    {
305
      sprintf(sTemp,"Unable to set flags for gdb socket %d to value 0x%08x",
306 479 markom
              fd,flags | O_NONBLOCK);
307 321 markom
      perror(sTemp);
308
      close(fd);
309
      return;
310
    }
311
 
312
  if(setsockopt(fd,tcp_level,TCP_NODELAY,&on_off,sizeof(int)) < 0)
313
    {
314
      sprintf(sTemp,"Unable to disable Nagel's algorithm for socket %d.\nsetsockopt",fd);
315
      perror(sTemp);
316
      close(fd);
317
      return;
318
    }
319
 
320
  gdb_fd = fd;
321
}
322
 
323
void GDBRequest()
324
{
325
  JTAGProxyWriteMessage msg_write;
326
  JTAGProxyReadMessage msg_read;
327
  JTAGProxyChainMessage msg_chain;
328
  JTAGProxyWriteResponse resp_write;
329
  JTAGProxyReadResponse resp_read;
330
  JTAGProxyChainResponse resp_chain;
331
  JTAGProxyBlockWriteMessage *msg_bwrite;
332
  JTAGProxyBlockReadMessage msg_bread;
333
  JTAGProxyBlockWriteResponse resp_bwrite;
334
  JTAGProxyBlockReadResponse *resp_bread;
335
  char *buf;
336
  int err = 0;
337
  uint32_t command,length;
338
  int len,i;
339
 
340
  /* First, we must read the incomming command */
341
  if(gdb_read(&command,sizeof(uint32_t)) < 0)
342
    {
343
      if(gdb_fd)
344 479 markom
        {
345
          perror("gdb socket - 1");
346
          close(gdb_fd);
347
          gdb_fd = 0;
348
        }
349 321 markom
      return;
350
    }
351
  if(gdb_read(&length,sizeof(uint32_t)) < 0)
352
    {
353
      if(gdb_fd)
354 479 markom
        {
355
          perror("gdb socket - 2");
356
          close(gdb_fd);
357
          gdb_fd = 0;
358
        }
359 321 markom
      return;
360
    }
361
  length = ntohl(length);
362
 
363
  /* Now, verify the protocol and implement the command */
364
  switch(ntohl(command))
365
    {
366
    case JTAG_COMMAND_WRITE:
367
      if(length != sizeof(msg_write) - 8)
368 479 markom
        {
369
          ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
370
          return;
371
        }
372 321 markom
      buf = (char*)&msg_write;
373
      if(gdb_read(&buf[8],length) < 0)
374 479 markom
        {
375
          if(gdb_fd)
376
            {
377
              perror("gdb socket - 3");
378
              close(gdb_fd);
379
              gdb_fd = 0;
380
            }
381
          return;
382
        }
383 321 markom
      msg_write.address = ntohl(msg_write.address);
384
      msg_write.data_H = ntohl(msg_write.data_H);
385
      msg_write.data_L = ntohl(msg_write.data_L);
386
      err = DebugSetRegister(msg_write.address,msg_write.data_L);
387
      resp_write.status = htonl(err);
388
      if(gdb_write(&resp_write,sizeof(resp_write)) < 0)
389 479 markom
        {
390
          if(gdb_fd)
391
            {
392
              perror("gdb socket - 4");
393
              close(gdb_fd);
394
              gdb_fd = 0;
395
            }
396
          return;
397
        }
398 321 markom
      break;
399
    case JTAG_COMMAND_READ:
400
      if(length != sizeof(msg_read) - 8)
401 479 markom
        {
402
          ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
403
          return;
404
        }
405 321 markom
      buf = (char*)&msg_read;
406
      if(gdb_read(&buf[8],length) < 0)
407 479 markom
        {
408
          if(gdb_fd)
409
            {
410
              perror("gdb socket - 5");
411
              close(gdb_fd);
412
              gdb_fd = 0;
413
            }
414
          return;
415
        }
416 321 markom
      msg_read.address = ntohl(msg_read.address);
417
      err = DebugGetRegister(msg_read.address,&resp_read.data_L);
418
      resp_read.status = htonl(err);
419
      resp_read.data_H = 0;
420
      resp_read.data_L = htonl(resp_read.data_L);
421
      if(gdb_write(&resp_read,sizeof(resp_read)) < 0)
422 479 markom
        {
423
          if(gdb_fd)
424
            {
425
              perror("gdb socket - 6");
426
              close(gdb_fd);
427
              gdb_fd = 0;
428
            }
429
          return;
430
        }
431 321 markom
      break;
432
    case JTAG_COMMAND_BLOCK_WRITE:
433
      if(length < sizeof(JTAGProxyBlockWriteMessage)-8)
434 479 markom
        {
435
          ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
436
          return;
437
        }
438 321 markom
      if(!(buf = (char*)malloc(8+length)))
439 479 markom
        {
440
          ProtocolClean(length,JTAG_PROXY_OUT_OF_MEMORY);
441
          return;
442
        }
443 321 markom
      msg_bwrite = (JTAGProxyBlockWriteMessage*)buf;
444
      if(gdb_read(&buf[8],length) < 0)
445 479 markom
        {
446
          if(gdb_fd)
447
            {
448
              perror("gdb socket - 5");
449
              close(gdb_fd);
450
              gdb_fd = 0;
451
            }
452
          free(buf);
453
          return;
454
        }
455 321 markom
      msg_bwrite->address = ntohl(msg_bwrite->address);
456
      msg_bwrite->nRegisters = ntohl(msg_bwrite->nRegisters);
457
      for(i=0;i<msg_bwrite->nRegisters;i++)
458 479 markom
        {
459
          int t_err = 0;
460 321 markom
 
461 479 markom
          msg_bwrite->data[i] = ntohl(msg_bwrite->data[i]);
462
          t_err = DebugSetRegister(msg_bwrite->address + 4 * i,msg_bwrite->data[i]);
463
          err = err ? err : t_err;
464
        }
465 321 markom
      resp_bwrite.status = htonl(err);
466
      free(buf);
467
      buf = NULL;
468
      msg_bwrite = NULL;
469
      if(gdb_write(&resp_bwrite,sizeof(resp_bwrite)) < 0)
470 479 markom
        {
471
          if(gdb_fd)
472
            {
473
              perror("gdb socket - 4");
474
              close(gdb_fd);
475
              gdb_fd = 0;
476
            }
477
          return;
478
        }
479 321 markom
      break;
480
    case JTAG_COMMAND_BLOCK_READ:
481
      if(length != sizeof(msg_bread) - 8)
482 479 markom
        {
483
          ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
484
          return;
485
        }
486 321 markom
      buf = (char*)&msg_bread;
487
      if(gdb_read(&buf[8],length) < 0)
488 479 markom
        {
489
          if(gdb_fd)
490
            {
491
              perror("gdb socket - 5");
492
              close(gdb_fd);
493
              gdb_fd = 0;
494
            }
495
          return;
496
        }
497 321 markom
      msg_bread.address = ntohl(msg_bread.address);
498
      msg_bread.nRegisters = ntohl(msg_bread.nRegisters);
499
      len = sizeof(JTAGProxyBlockReadResponse) + 4*(msg_bread.nRegisters-1);
500
      if(!(buf = (char*)malloc(len)))
501 479 markom
        {
502
          ProtocolClean(0,JTAG_PROXY_OUT_OF_MEMORY);
503
          return;
504
        }
505 321 markom
      resp_bread = (JTAGProxyBlockReadResponse*)buf;
506
      for(i=0;i<msg_bread.nRegisters;i++)
507 479 markom
        {
508
          int t_err;
509 321 markom
 
510 479 markom
          t_err = DebugGetRegister(msg_bread.address + 4 * i,&resp_bread->data[i]);
511
          resp_bread->data[i] = htonl(resp_bread->data[i]);
512
          err = err ? err : t_err;
513
        }
514 321 markom
      resp_bread->status = htonl(err);
515
      resp_bread->nRegisters = htonl(msg_bread.nRegisters);
516
      if(gdb_write(resp_bread,len) < 0)
517 479 markom
        {
518
          if(gdb_fd)
519
            {
520
              perror("gdb socket - 6");
521
              close(gdb_fd);
522
              gdb_fd = 0;
523
            }
524
          free(buf);
525
          return;
526
        }
527 321 markom
      free(buf);
528
      buf = NULL;
529
      resp_bread = NULL;
530
      break;
531
    case JTAG_COMMAND_CHAIN:
532
      if(length != sizeof(msg_chain) - 8)
533 479 markom
        {
534
          ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
535
          return;
536
        }
537 321 markom
      buf = (char*)&msg_chain;
538
      if(gdb_read(&buf[8],sizeof(msg_chain)-8) < 0)
539 479 markom
        {
540
          if(gdb_fd)
541
            {
542
              perror("gdb socket - 7");
543
              close(gdb_fd);
544
              gdb_fd = 0;
545
            }
546
          return;
547
        }
548 321 markom
      msg_chain.chain = htonl(msg_chain.chain);
549
      err = DebugSetChain(msg_chain.chain);
550
      resp_chain.status = htonl(err);
551
      if(gdb_write(&resp_chain,sizeof(resp_chain)) < 0)
552 479 markom
        {
553
          if(gdb_fd)
554
            {
555
              perror("gdb socket - 8");
556
              close(gdb_fd);
557
              gdb_fd = 0;
558
            }
559
          return;
560
        }
561 321 markom
      break;
562
    default:
563
      ProtocolClean(length,JTAG_PROXY_COMMAND_NOT_IMPLEMENTED);
564
      break;
565
    }
566
}
567
 
568
void ProtocolClean(int length,int32_t err)
569
{
570
  char buf[4096];
571
 
572
  err = htonl(err);
573
  if((gdb_read(buf,length) < 0) ||
574
      (gdb_write(&err,sizeof(err)) < 0) && gdb_fd)
575
    {
576
      perror("gdb socket - 9");
577
      close(gdb_fd);
578
      gdb_fd = 0;
579
    }
580
}
581
 
582 439 erez
static int gdb_write(const void* buf,int len)
583 321 markom
{
584 439 erez
  int n, log_n = 0;
585
  const char* w_buf = (const char*)buf;
586
  const uint32_t* log_buf = (const uint32_t*)buf;
587 321 markom
  struct pollfd block;
588
 
589 439 erez
  while(len) {
590
    if((n = write(gdb_fd,w_buf,len)) < 0) {
591
      switch(errno) {
592
      case EWOULDBLOCK: /* or EAGAIN */
593 479 markom
        /* We've been called on a descriptor marked
594
           for nonblocking I/O. We better simulate
595
           blocking behavior. */
596
        block.fd = gdb_fd;
597
        block.events = POLLOUT;
598
        block.revents = 0;
599
        poll(&block,1,-1);
600
        continue;
601 439 erez
      case EINTR:
602 479 markom
        continue;
603 439 erez
      case EPIPE:
604 479 markom
        close(gdb_fd);
605
        gdb_fd = 0;
606
        return -1;
607 439 erez
      default:
608 479 markom
        return -1;
609 439 erez
      }
610 321 markom
    }
611 439 erez
    else {
612
      len -= n;
613
      w_buf += n;
614
      if ( config.debug.vapi_id )
615 479 markom
        for ( log_n += n; log_n >= 4; log_n -= 4, ++ log_buf )
616
          vapi_write_log_file( VAPI_COMMAND_SEND, config.debug.vapi_id, ntohl(*log_buf) );
617 439 erez
    }
618
  }
619 321 markom
  return 0;
620
}
621
 
622
static int gdb_read(void* buf,int len)
623
{
624 439 erez
  int n, log_n = 0;
625 321 markom
  char* r_buf = (char*)buf;
626 439 erez
  uint32_t* log_buf = (uint32_t*)buf;
627 321 markom
  struct pollfd block;
628
 
629 439 erez
  while(len) {
630
    if((n = read(gdb_fd,r_buf,len)) < 0) {
631
      switch(errno) {
632
      case EWOULDBLOCK: /* or EAGAIN */
633 479 markom
        /* We've been called on a descriptor marked
634
           for nonblocking I/O. We better simulate
635
           blocking behavior. */
636
        block.fd = gdb_fd;
637
        block.events = POLLIN;
638
        block.revents = 0;
639
        poll(&block,1,-1);
640
        continue;
641 439 erez
      case EINTR:
642 479 markom
        continue;
643 439 erez
      default:
644 479 markom
        return -1;
645 439 erez
      }
646 321 markom
    }
647 439 erez
    else if(n == 0) {
648
      close(gdb_fd);
649
      gdb_fd = 0;
650
      return -1;
651
    }
652
    else {
653
      len -= n;
654
      r_buf += n;
655
      if ( config.debug.vapi_id )
656 479 markom
        for ( log_n += n; log_n >= 4; log_n -= 4, ++ log_buf )
657
          vapi_write_log_file( VAPI_COMMAND_REQUEST, config.debug.vapi_id, ntohl(*log_buf) );
658 439 erez
    }
659
  }
660 321 markom
  return 0;
661
}
662
 
663
int gdbcomm_init ()
664
{
665
  serverPort = config.debug.server_port;
666 1308 phoenix
  if((server_fd = GetServerSocket("or1ksim","tcp",serverPort)))
667 997 markom
    PRINTF("JTAG Proxy server started on port %d\n",serverPort);
668 479 markom
  else
669 997 markom
    PRINTF("Cannot start JTAG proxy server on port %d\n", serverPort);
670 321 markom
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.