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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_61/] [or1ksim/] [debug/] [gdbcomm.c] - Blame information for rev 1308

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

powered by: WebSVN 2.1.0

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