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

Subversion Repositories vapi

[/] [vapi/] [tags/] [initial/] [vapi.c] - Blame information for rev 13

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 markom
/* vapi.c -- Verification API Interface test side
2
   Copyright (C) 2001, Marko Mlinar, markom@opencores.org
3
 
4
This file is part of OpenRISC 1000 Architectural Simulator.
5
 
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
 
20
#include <stdio.h>
21
#include <stdlib.h>
22
#include <string.h>
23
#include <sys/poll.h>
24
#include <sys/socket.h>
25
#include <netdb.h>
26
#include <netinet/in.h>
27
#include <netinet/tcp.h>
28
#include <sys/select.h>
29
#include <sys/time.h>
30
#include <unistd.h>
31
 
32
#include <signal.h>
33
#include <sys/types.h>
34
#include <sys/stat.h>
35
#include <sys/ioctl.h>
36
#include <fcntl.h>
37
#include <errno.h>
38
 
39
int vapi_fd;
40
unsigned long vapi_id;
41
 
42
static int vapi_write_stream(int fd, void* buf, int len)
43
{
44
  int n;
45
  char* w_buf = (char*)buf;
46
  struct pollfd block;
47
 
48
  while(len) {
49
    if((n = write(fd,w_buf,len)) < 0) {
50
      switch(errno) {
51
      case EWOULDBLOCK: /* or EAGAIN */
52
        /* We've been called on a descriptor marked
53
           for nonblocking I/O. We better simulate
54
           blocking behavior. */
55
        block.fd = fd;
56
        block.events = POLLOUT;
57
        block.revents = 0;
58
        poll(&block,1,-1);
59
        continue;
60
      case EINTR:
61
        continue;
62
      case EPIPE:
63
        close(fd);
64
        vapi_fd = 0;
65
        return -1;
66
      default:
67
        return -1;
68
      }
69
    } else {
70
      len -= n;
71
      w_buf += n;
72
    }
73
  }
74
  return 0;
75
}
76
 
77
static int vapi_read_stream(int fd, void* buf, int len)
78
{
79
  int n;
80
  char* r_buf = (char*)buf;
81
  struct pollfd block;
82
 
83
  while(len) {
84
    if((n = read(fd,r_buf,len)) < 0) {
85
      switch(errno) {
86
      case EWOULDBLOCK: /* or EAGAIN */
87
        /* We've been called on a descriptor marked
88
           for nonblocking I/O. We better simulate
89
           blocking behavior. */
90
        block.fd = fd;
91
        block.events = POLLIN;
92
        block.revents = 0;
93
        poll(&block,1,-1);
94
        continue;
95
      case EINTR:
96
        continue;
97
      default:
98
        return -1;
99
      }
100
    } else if(n == 0) {
101
      close(fd);
102
      fd = 0;
103
      return -1;
104
    } else {
105
      len -= n;
106
      r_buf += n;
107
    }
108
  }
109
  return 0;
110
}
111
 
112
static int write_packet (unsigned long id, unsigned long data) {
113
  id = htonl (id);
114
  if (vapi_write_stream(vapi_fd, &id, sizeof (id)) < 0)
115
    return 1;
116
  data = htonl (data);
117
  if (vapi_write_stream(vapi_fd, &data, sizeof (data)) < 0)
118
    return 1;
119
  return 0;
120
}
121
 
122
static int read_packet (unsigned long *id, unsigned long *data) {
123
  if (vapi_read_stream(vapi_fd, id, sizeof (unsigned long)) < 0)
124
    return 1;
125
  *id = htonl (*id);
126
  if (vapi_read_stream(vapi_fd, data, sizeof (unsigned long)) < 0)
127
    return 1;
128
  *data = htonl (*data);
129
  return 0;
130
}
131
 
132
/* Added by CZ 24/05/01 */
133
static int connect_to_server(char* hostname,char* name)
134
{
135
  struct hostent *host;
136
  struct sockaddr_in sin;
137
  struct servent *service;
138
  struct protoent *protocol;
139
  int sock,flags;
140
  char sTemp[256],sTemp2[256];
141
  char* proto_name = "tcp";
142
  int port = 0;
143
  int on_off = 0; /* Turn off Nagel's algorithm on the socket */
144
  char *s;
145
 
146
  if(!(protocol = getprotobyname(proto_name))) {
147
    sprintf(sTemp,"Protocol \"%s\" not available.\n",
148
      proto_name);
149
    error(sTemp);
150
    return 0;
151
  }
152
 
153
  /* Convert name to an integer only if it is well formatted.
154
     Otherwise, assume that it is a service name. */
155
 
156
  port = strtol(name, &s, 10);
157
  if(*s)
158
    port = 0;
159
 
160
  if(!port) {
161
    if(!(service = getservbyname(name, protocol->p_name))) {
162
          sprintf(sTemp,"Unknown service \"%s\".\n",name);
163
          error(sTemp);
164
          return 0;
165
        }
166
    port = ntohs(service->s_port);
167
  }
168
 
169
  if(!(host = gethostbyname(hostname))) {
170
    sprintf(sTemp,"Unknown host \"%s\"\n",hostname);
171
    error(sTemp);
172
    return 0;
173
  }
174
 
175
  if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
176
    sprintf(sTemp, "can't create socket errno = %d\n", errno);
177
    sprintf(sTemp2, "%s\n",strerror(errno));
178
    strcat(sTemp, sTemp2);
179
    error(sTemp);
180
    return 0;
181
  }
182
 
183
  if(fcntl(sock, F_GETFL, &flags) < 0) {
184
    sprintf(sTemp, "Unable to get flags for VAPI proxy socket %d", sock);
185
    error(sTemp);
186
    close(sock);
187
    return 0;
188
  }
189
 
190
  if(fcntl(sock,F_SETFL, flags & ~O_NONBLOCK) < 0) {
191
    sprintf(sTemp, "Unable to set flags for VAPI proxy socket %d to value 0x%08x", sock,flags | O_NONBLOCK);
192
    error(sTemp);
193
    close(sock);
194
    return 0;
195
  }
196
 
197
  memset(&sin,0,sizeof(sin));
198
  sin.sin_family = host->h_addrtype;
199
  memcpy(&sin.sin_addr, host->h_addr_list[0], host->h_length);
200
  sin.sin_port = htons(port);
201
 
202
  if((connect(sock, (struct sockaddr*)&sin, sizeof(sin)) < 0)
203
     && errno != EINPROGRESS) {
204
 
205
    sprintf(sTemp, "connect failed  errno = %d\n", errno);
206
    sprintf(sTemp2, "%s\n", strerror(errno));
207
    close(sock);
208
    strcat(sTemp, sTemp2);
209
    error(sTemp);
210
    return 0;
211
  }
212
 
213
  if(fcntl(sock,F_SETFL, flags | O_NONBLOCK) < 0) {
214
    sprintf(sTemp, "Unable to set flags for VAPI proxy socket %d to value 0x%08x", sock, flags | O_NONBLOCK);
215
    error(sTemp);
216
    close(sock);
217
    return 0;
218
  }
219
 
220
  if(setsockopt(sock,protocol->p_proto,TCP_NODELAY,&on_off,sizeof(int)) < 0) {
221
    sprintf(sTemp,"Unable to disable Nagel's algorithm for socket %d.\nsetsockopt", sock);
222
    error(sTemp);
223
    close(sock);
224
    return 0;
225
  }
226
 
227
  return sock;
228
}
229
 
230
/* Initialize a new connection to the or1k board, and make sure we are
231
   really connected.  */
232
 
233
int
234
vapi_init (char *port_name, unsigned long id)
235
{
236
  vapi_id = id;
237
  /* CZ 24/05/01 - Check to see if we have specified a remote
238
     VAPI interface or a local one. It is remote if it follows
239
     the URL naming convention vapi://<hostname>:<port> */
240
  if(!strncmp(port_name,"vapi://",7)) {
241
    char *port;
242
    char hostname[256];
243
 
244
    port = strchr(&port_name[7], ':');
245
    if(port) {
246
          int len = port - port_name - 7;
247
          strncpy(hostname,&port_name[7],len);
248
          hostname[len] = '\0';
249
          port++;
250
        } else
251
      strcpy(hostname,&port_name[7]);
252
 
253
    /* Interface is remote */
254
    if(!(vapi_fd = connect_to_server(hostname,port))) {
255
          char sTemp[256];
256
          sprintf(sTemp,"Can not access VAPI Proxy Server at \"%s\"",
257
                  &port_name[5]);
258
          error(sTemp);
259
        }
260
    printf("Remote or1k testing using %s, id 0x%x\n", port_name, id);
261
    if (vapi_write_stream (vapi_fd, &id, sizeof (id)))
262
      return 1;
263
  } else
264
    return 1;
265
  return 0;
266
}
267
 
268
void
269
vapi_done ()  /* CZ */
270
{
271
  int flags = 0;
272
  struct linger linger;
273
  char sTemp[256];
274
 
275
  linger.l_onoff = 0;
276
  linger.l_linger = 0;
277
 
278
  /* First, make sure we're non blocking */
279
  if(fcntl(vapi_fd, F_GETFL,&flags) < 0) {
280
    sprintf(sTemp,"Unable to get flags for VAPI proxy socket %d", vapi_fd);
281
    error(sTemp);
282
  }
283
  if(fcntl(vapi_fd, F_SETFL, flags & ~O_NONBLOCK) < 0) {
284
    sprintf(sTemp,"Unable to set flags for VAPI proxy socket %d to value 0x%08x", vapi_fd, flags | O_NONBLOCK);
285
    error(sTemp);
286
  }
287
 
288
  /* Now, make sure we don't linger around */
289
  if(setsockopt(vapi_fd,SOL_SOCKET,SO_LINGER,&linger,sizeof(linger)) < 0) {
290
    sprintf(sTemp,"Unable to disable SO_LINGER for VAPI proxy socket %d.", vapi_fd);
291
    error(sTemp);
292
  }
293
 
294
  close(vapi_fd);
295
}
296
 
297
/* Writes an unsigned long to server */
298
void vapi_write(unsigned long data) {
299
  printf ("WRITE [%08x, %08x]\n", vapi_id, data);
300
  if (write_packet (vapi_id, data))
301
    perror ("write packet");
302
}
303
 
304
/* Reads an unsigned long from server */
305
unsigned long vapi_read() {
306
  unsigned long id, data;
307
  if(read_packet (&id, &data)) {
308
    if(vapi_fd) {
309
      perror("vapi read");
310
      close(vapi_fd);
311
      vapi_fd = 0;
312
    }
313
    exit (2);
314
  }
315
  if (id != vapi_id) {
316
    fprintf (stderr, "ERROR: Invalid id %x, expected %x.", id, vapi_id);
317
    exit (1);
318
  }
319
  printf ("READ [%08x, %08x]\n", id, data);
320
  return data;
321
}
322
 
323
/* Polls the port if anything is available and if do_read is set something is read from port. */
324
int vapi_waiting ()
325
{
326
  struct pollfd fds[1];
327
 
328
  if(vapi_fd) {
329
    fds[0].fd = vapi_fd;
330
    fds[0].events = POLLIN;
331
    fds[0].revents = 0;
332
  } else
333
    return;
334
 
335
  while(1) {
336
    switch(poll(fds, 1, 0)) {
337
    case -1:
338
      if(errno == EINTR)
339
        continue;
340
      perror("poll");
341
      break;
342
    case 0: /* Nothing interesting going on */
343
      return 0;
344
    default:
345
      return 1;
346
    } /* End of switch statement */
347
  } /* End of while statement */
348
}
349
 
350
int main (int argc, char *argv[]) {
351
  unsigned long id, data;
352
  if (argc != 3) {
353
    printf ("Usage: vapit URL ID\n");
354
    printf ("vapit vapi://localhost:9998 0x12345678\n");
355
    return 2;
356
  }
357
  id = atol (argv[2]);
358
  if (sscanf (argv[2], "0x%x", &id)) {
359
    if (vapi_init(argv[1], id))
360
      return 1;
361
  } else {
362
    fprintf (stderr, "Invalid vapi_id\n", argv[2]);
363
    return 2;
364
  }
365
 
366
  if (vapi_main ()) {
367
    fprintf (stderr, "TEST FAILED.\n");
368
    return 1;
369
  }
370
  printf ("Test passed.\n");
371
 
372
  vapi_done();
373
  return 0;
374
}

powered by: WebSVN 2.1.0

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