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

Subversion Repositories or1k

[/] [or1k/] [branches/] [stable_0_2_x/] [or1ksim/] [vapi/] [vapi.c] - Blame information for rev 1358

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

Line No. Rev Author Line
1 293 markom
/* vapi.c -- Verification API Interface
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 336 markom
#include "config.h"
21 293 markom
 
22
#include <stdio.h>
23
#include <ctype.h>
24
#include <string.h>
25
#include <stdlib.h>
26
#include <unistd.h>
27
#include <stdarg.h>
28
#include <signal.h>
29
#include <errno.h>
30
 
31
/* Added by CZ 24/05/01 */
32
#include <sys/stat.h>
33
#include <sys/types.h>
34
#include <sys/socket.h>
35
#include <netinet/in.h>
36
#include <sys/select.h>
37
#include <sys/poll.h>
38
#include <fcntl.h>
39
#include <netdb.h>
40
#include <netinet/tcp.h>
41
 
42 1358 nogj
#include "config.h"
43
 
44
#ifdef HAVE_INTTYPES_H
45
#include <inttypes.h>
46
#endif
47
 
48
#include "port.h"
49
#include "arch.h"
50 336 markom
#include "sim-config.h"
51 439 erez
#include "vapi.h"
52 1308 phoenix
#include "debug.h"
53 293 markom
 
54 304 markom
static unsigned int serverIP = 0;
55 293 markom
 
56 304 markom
static unsigned int server_fd = 0;
57
static unsigned int nhandlers = 0;
58
 
59 293 markom
static int tcp_level = 0;
60
 
61 304 markom
static struct vapi_handler {
62
  int fd;
63 477 erez
  unsigned long base_id, num_ids;
64 336 markom
  void (*read_func)(unsigned long, unsigned long);
65 293 markom
  struct vapi_handler *next;
66 304 markom
  int temp;
67 442 erez
} *vapi_handler = NULL;
68 293 markom
 
69 304 markom
/* Structure for polling, it is cached, that it doesn't have to be rebuilt each time */
70
static struct pollfd *fds = NULL;
71
static int nfds = 0;
72
 
73
/* Rebuilds the fds structures; see fds.  */
74
void rebuild_fds () {
75
  struct vapi_handler *t;
76
  if (fds)
77
    free (fds);
78
  fds = (struct pollfd *) malloc (sizeof (struct pollfd) * (nhandlers + 1));
79
  if (!fds) {
80
    fprintf (stderr, "FATAL: Out of memory.\n");
81
    exit (1);
82
  }
83
 
84
  nfds = 0;
85
  fds[nfds].fd = server_fd;
86
  fds[nfds].events = POLLIN;
87
  fds[nfds++].revents = 0;
88
 
89
  for (t = vapi_handler; t; t = t->next) {
90
    if (t->fd) {
91
      t->temp = nfds;
92
      fds[nfds].fd = t->fd;
93
      fds[nfds].events = POLLIN;
94
      fds[nfds++].revents = 0;
95
    } else
96
      t->temp = -1;
97
  }
98
}
99
 
100 477 erez
/* Determines whether a certain handler handles an ID */
101
static inline int handler_fits_id( const struct vapi_handler *t, unsigned long id ) {
102
  return ((id >= t->base_id) && (id < t->base_id + t->num_ids));
103
}
104
 
105 304 markom
/* Finds a handler with given ID, return it, NULL if not found.  */
106
static struct vapi_handler *find_handler (unsigned long id) {
107
  struct vapi_handler *t = vapi_handler;
108 477 erez
  while (t && !handler_fits_id (t, id))
109 304 markom
    t = t->next;
110
  return t;
111
}
112
 
113
/* Adds a handler with given id and returns it.  */
114 477 erez
static struct vapi_handler *add_handler (unsigned long base_id, unsigned long num_ids) {
115 304 markom
  struct vapi_handler **t = &vapi_handler;
116
  struct vapi_handler *tt;
117
  while ((*t))
118
    t = &(*t)->next;
119
  tt = (struct vapi_handler *)malloc (sizeof (struct vapi_handler));
120
  tt->next = NULL;
121 477 erez
  tt->base_id = base_id;
122
  tt->num_ids = num_ids;
123 304 markom
  tt->read_func = NULL;
124
  tt->fd = 0;
125
  (*t) = tt;
126
  free (fds);
127
  fds = NULL;
128
  nhandlers++;
129
  rebuild_fds ();
130
  return tt;
131
}
132
 
133 439 erez
void vapi_write_log_file(VAPI_COMMAND command, unsigned long devid, unsigned long data)
134 419 erez
{
135 439 erez
  if (!runtime.vapi.vapi_file)
136
    return;
137 477 erez
  if (!config.vapi.hide_device_id && devid <= VAPI_MAX_DEVID)
138 1308 phoenix
    fprintf (runtime.vapi.vapi_file, "%04lx", devid);
139
  fprintf (runtime.vapi.vapi_file, "%1x%08lx\n", command, data);
140 419 erez
}
141
 
142 304 markom
static int vapi_write_stream(int fd, void* buf, int len)
143
{
144
  int n;
145
  char* w_buf = (char*)buf;
146
  struct pollfd block;
147
 
148
  while(len) {
149
    if((n = write(fd, w_buf, len)) < 0) {
150
      switch(errno) {
151
      case EWOULDBLOCK: /* or EAGAIN */
152
        /* We've been called on a descriptor marked
153
           for nonblocking I/O. We better simulate
154
           blocking behavior. */
155
        block.fd = fd;
156
        block.events = POLLOUT;
157
        block.revents = 0;
158
        poll(&block,1,-1);
159
        continue;
160
      case EINTR:
161
        continue;
162
      case EPIPE:
163
        close(fd);
164
        fd = 0;
165
        return -1;
166
      default:
167
        return -1;
168
      }
169
    } else {
170
      len -= n;
171
      w_buf += n;
172
    }
173
  }
174
  return 0;
175
}
176
 
177
static int vapi_read_stream(int fd, void* buf, int len)
178
{
179
  int n;
180
  char* r_buf = (char*)buf;
181
  struct pollfd block;
182
 
183
  while(len) {
184
    if((n = read(fd,r_buf,len)) < 0) {
185
      switch(errno) {
186
      case EWOULDBLOCK: /* or EAGAIN */
187
        /* We've been called on a descriptor marked
188
           for nonblocking I/O. We better simulate
189
           blocking behavior. */
190
        block.fd = fd;
191
        block.events = POLLIN;
192
        block.revents = 0;
193
        poll(&block,1,-1);
194
        continue;
195
      case EINTR:
196
        continue;
197
      default:
198
        return -1;
199
      }
200
    } else if(n == 0) {
201
      close(fd);
202
      fd = 0;
203
      return -1;
204
    } else {
205
      len -= n;
206
      r_buf += n;
207
    }
208
  }
209
  return 0;
210
}
211
 
212 293 markom
/* Added by CZ 24/05/01 */
213
int get_server_socket(const char* name,const char* proto,int port)
214
{
215
  struct servent *service;
216
  struct protoent *protocol;
217
  struct sockaddr_in sa;
218
  struct hostent *hp;
219
  int sockfd;
220
  char myname[256];
221
  int flags;
222
  char sTemp[256];
223
 
224
  /* First, get the protocol number of TCP */
225
  if(!(protocol = getprotobyname(proto))) {
226
    sprintf(sTemp,"Unable to load protocol \"%s\"",proto);
227
    perror(sTemp);
228
    return 0;
229
  }
230
  tcp_level = protocol->p_proto; /* Save for later */
231
 
232
  /* If we weren't passed a non standard port, get the port
233
     from the services directory. */
234
  if(!port) {
235 1308 phoenix
    if((service = getservbyname(name,protocol->p_name)))
236 293 markom
      port = ntohs(service->s_port);
237
  }
238 336 markom
 
239 293 markom
  /* Create the socket using the TCP protocol */
240
  if((sockfd = socket(PF_INET,SOCK_STREAM,protocol->p_proto)) < 0) {
241
    perror("Unable to create socket");
242
    return 0;
243
  }
244 336 markom
 
245 293 markom
  flags = 1;
246
  if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(const char*)&flags,sizeof(int)) < 0) {
247
    sprintf(sTemp,"Can not set SO_REUSEADDR option on socket %d",sockfd);
248
    perror(sTemp);
249
    close(sockfd);
250
    return 0;
251
  }
252
 
253
  /* The server should also be non blocking. Get the current flags. */
254
  if(fcntl(sockfd,F_GETFL,&flags) < 0) {
255
    sprintf(sTemp,"Unable to get flags for socket %d",sockfd);
256
    perror(sTemp);
257
    close(sockfd);
258
    return 0;
259
  }
260
 
261
  /* Set the nonblocking flag */
262
  if(fcntl(sockfd,F_SETFL, flags | O_NONBLOCK) < 0) {
263
    sprintf(sTemp,"Unable to set flags for socket %d to value 0x%08x",
264
            sockfd,flags | O_NONBLOCK);
265
    perror(sTemp);
266
    close(sockfd);
267
    return 0;
268
  }
269
 
270
  /* Find out what our address is */
271
  memset(&sa,0,sizeof(struct sockaddr_in));
272
  gethostname(myname,sizeof(myname));
273
  if(!(hp = gethostbyname(myname))) {
274
    perror("Unable to read hostname");
275
    close(sockfd);
276
    return 0;
277
  }
278
 
279
  /* Bind our socket to the appropriate address */
280
  sa.sin_family = hp->h_addrtype;
281
  sa.sin_port = htons(port);
282
  if(bind(sockfd,(struct sockaddr*)&sa,sizeof(struct sockaddr_in)) < 0) {
283
    sprintf(sTemp,"Unable to bind socket %d to port %d",sockfd,port);
284
    perror(sTemp);
285
    close(sockfd);
286
    return 0;
287
  }
288
  serverIP = sa.sin_addr.s_addr;
289
  flags = sizeof(struct sockaddr_in);
290
  if(getsockname(sockfd,(struct sockaddr*)&sa,&flags) < 0) {
291
    sprintf(sTemp,"Unable to get socket information for socket %d",sockfd);
292
    perror(sTemp);
293
    close(sockfd);
294
    return 0;
295
  }
296 551 markom
  runtime.vapi.server_port = ntohs(sa.sin_port);
297 293 markom
 
298
  /* Set the backlog to 1 connections */
299
  if(listen(sockfd,1) < 0) {
300
    sprintf(sTemp,"Unable to set backlog on socket %d to %d",sockfd,1);
301
    perror(sTemp);
302
    close(sockfd);
303
    return 0;
304
  }
305
 
306
  return sockfd;
307
}
308
 
309 442 erez
static void server_request()
310 293 markom
{
311
  struct sockaddr_in sa;
312
  struct sockaddr* addr = (struct sockaddr*)&sa;
313
  int n = sizeof(struct sockaddr_in);
314 336 markom
  int fd = accept(server_fd, addr, &n);
315 293 markom
  int on_off = 0; /* Turn off Nagel's algorithm on the socket */
316
  int flags;
317
  char sTemp[256];
318
 
319
  if(fd < 0) {
320
    /* This is valid, because a connection could have started,
321
       and then terminated due to a protocol error or user
322
       initiation before the accept could take place. */
323
    if(errno != EWOULDBLOCK && errno != EAGAIN) {
324
      perror("accept");
325
      close(server_fd);
326
      server_fd = 0;
327 551 markom
      runtime.vapi.enabled = 0;
328 293 markom
      serverIP = 0;
329 336 markom
    }
330 293 markom
    return;
331
  }
332
 
333
  if(fcntl(fd,F_GETFL,&flags) < 0) {
334
    sprintf(sTemp,"Unable to get flags for vapi socket %d",fd);
335
    perror(sTemp);
336
    close(fd);
337
    return;
338
  }
339
 
340
  if(fcntl(fd,F_SETFL, flags | O_NONBLOCK) < 0) {
341
    sprintf(sTemp,"Unable to set flags for vapi socket %d to value 0x%08x",
342
            fd,flags | O_NONBLOCK);
343
    perror(sTemp);
344
    close(fd);
345
    return;
346
  }
347
 
348
  if(setsockopt(fd,tcp_level,TCP_NODELAY,&on_off,sizeof(int)) < 0) {
349
    sprintf(sTemp,"Unable to disable Nagel's algorithm for socket %d.\nsetsockopt",fd);
350
    perror(sTemp);
351
    close(fd);
352
    return;
353
  }
354 304 markom
 
355
  /* Install new handler */
356
  {
357
    unsigned long id;
358
    struct vapi_handler *t;
359
    if (vapi_read_stream (fd, &id, sizeof (id))) {
360
      perror ("Cannot get id");
361
      close (fd);
362
      return;
363 293 markom
    }
364 304 markom
    t = find_handler (id);
365 355 markom
    if (t) {
366 304 markom
      if (t->fd) {
367 1308 phoenix
        fprintf (stderr, "WARNING: Test with id %lx already connected. Ignoring.\n", id);
368 304 markom
        close (fd);
369
        return;
370 355 markom
      } else {
371
        t->fd = fd;
372
        rebuild_fds ();
373
      }
374
    } else {
375 1308 phoenix
      fprintf (stderr, "WARNING: Test with id %lx not registered. Ignoring.\n", id);
376 355 markom
      close(fd); /* kill the connection */
377
      return;
378 293 markom
    }
379 304 markom
    if(config.sim.verbose)
380 1308 phoenix
      PRINTF ("\nConnection with test (id %lx) established.\n", id);
381 293 markom
  }
382
}
383
 
384
static int write_packet (unsigned long id, unsigned long data) {
385 304 markom
  struct vapi_handler *t = find_handler (id);
386
  if (!t || !t->fd)
387
    return 1;
388 293 markom
  id = htonl (id);
389 304 markom
  if (vapi_write_stream(t->fd, &id, sizeof (id)) < 0)
390 293 markom
    return 1;
391
  data = htonl (data);
392 304 markom
  if (vapi_write_stream(t->fd, &data, sizeof (data)) < 0)
393 293 markom
    return 1;
394
  return 0;
395 442 erez
}
396 293 markom
 
397 442 erez
static int read_packet (int fd, unsigned long *id, unsigned long *data)
398
{
399 477 erez
  if (fd <= 0)
400 293 markom
    return 1;
401 477 erez
  if (vapi_read_stream(fd, id, sizeof(unsigned long)) < 0)
402 293 markom
    return 1;
403 442 erez
  *id = ntohl (*id);
404 477 erez
  if (vapi_read_stream(fd, data, sizeof(unsigned long)) < 0)
405 304 markom
    return 1;
406 442 erez
  *data = ntohl (*data);
407 293 markom
  return 0;
408 304 markom
}
409 293 markom
 
410 442 erez
static void vapi_request (struct vapi_handler *t)
411
{
412
  unsigned long id, data;
413
 
414
  if (read_packet(t->fd, &id, &data)) {
415 477 erez
    if (t->fd > 0) {
416 293 markom
      perror("vapi read");
417 304 markom
      close(t->fd);
418
      t->fd = 0;
419 361 markom
      rebuild_fds ();
420 293 markom
    }
421
    return;
422
  }
423
 
424 442 erez
  vapi_write_log_file (VAPI_COMMAND_REQUEST, id, data);
425 1350 nogj
  debug (4, "[%08lx, %08lx]\n", id, data);
426 442 erez
 
427
  /* This packet may be for another handler */
428 477 erez
  if (!handler_fits_id (t, id))
429 442 erez
    t = find_handler (id);
430
  if (!t || !t->read_func)
431 1308 phoenix
    fprintf (stderr, "WARNING: Received packet for undefined id %08lx, data %08lx\n", id, data);
432 293 markom
  else
433 442 erez
    t->read_func(id, data);
434 293 markom
}
435
 
436
void vapi_check ()
437
{
438 304 markom
  struct vapi_handler *t;
439 293 markom
 
440 304 markom
  if (!server_fd || !fds) {
441
    fprintf (stderr, "FATAL: Unable to maintain VAPI server.\n");
442
    exit (1);
443 293 markom
  }
444
 
445 361 markom
  debug(5, ".");
446 355 markom
 
447 304 markom
  /* Handle everything in queue. */
448 293 markom
  while(1) {
449 304 markom
    switch(poll(fds, nfds, 0)) {
450 293 markom
    case -1:
451
      if(errno == EINTR)
452
        continue;
453
      perror("poll");
454 304 markom
      if (server_fd)
455
        close(server_fd);
456 551 markom
      runtime.vapi.enabled = 0;
457 304 markom
      serverIP = 0;
458
      return;
459 293 markom
    case 0: /* Nothing interesting going on */
460
      return;
461
    default:
462 304 markom
      /* Handle the vapi ports first. */
463
      for (t = vapi_handler; t; t = t->next)
464
        if (t->temp >= 0 && fds[t->temp].revents)
465
          vapi_request (t);
466 293 markom
 
467 304 markom
      if(fds[0].revents) {
468 293 markom
        if(fds[0].revents & POLLIN)
469
          server_request();
470
        else { /* Error Occurred */
471 304 markom
          fprintf(stderr,"Received flags 0x%08x on server. Shutting down.\n", fds[0].revents);
472
          if (server_fd)
473
            close(server_fd);
474 293 markom
          server_fd = 0;
475 551 markom
          runtime.vapi.enabled = 0;
476 293 markom
          serverIP = 0;
477
        }
478
      }
479
      break;
480
    } /* End of switch statement */
481
  } /* End of while statement */
482
}
483
 
484 304 markom
/* Inits the VAPI, according to sim-config */
485
int vapi_init ()
486 293 markom
{
487 304 markom
  nhandlers = 0;
488
  vapi_handler = NULL;
489 551 markom
  if (!runtime.vapi.enabled)
490 304 markom
    return 0; /* Nothing to do */
491
 
492 551 markom
  runtime.vapi.server_port = config.vapi.server_port;
493
  if (!runtime.vapi.server_port) {
494 304 markom
    fprintf (stderr, "WARNING: server_port = 0, shutting down VAPI\n");
495 551 markom
    runtime.vapi.enabled = 0;
496 304 markom
    return 1;
497
  }
498 1308 phoenix
  if ((server_fd = get_server_socket("or1ksim", "tcp", runtime.vapi.server_port)))
499 997 markom
    PRINTF("VAPI Server started on port %d\n", runtime.vapi.server_port);
500 304 markom
  else {
501 293 markom
    perror ("Connection");
502 304 markom
    return 1;
503
  }
504
 
505
  rebuild_fds ();
506 355 markom
 
507 361 markom
  if ((runtime.vapi.vapi_file = fopen (config.vapi.vapi_fn, "wt+")) == NULL)
508 355 markom
    fprintf (stderr, "WARNING: cannot open VAPI log file\n");
509
 
510 304 markom
  return 0;
511
}
512
 
513
/* Closes the VAPI */
514
void vapi_done ()
515
{
516
  int i;
517
  struct vapi_handler *t = vapi_handler;
518 293 markom
 
519 304 markom
  for (i = 0; i < nfds; i++)
520
    if (fds[i].fd)
521 306 markom
      close (fds[i].fd);
522 304 markom
  server_fd = 0;
523 551 markom
  runtime.vapi.enabled = 0;
524 304 markom
  serverIP = 0;
525
  free (fds);
526
  fds = 0;
527 361 markom
  if (runtime.vapi.vapi_file) {
528
    /* Mark end of simulation */
529 442 erez
    vapi_write_log_file (VAPI_COMMAND_END, 0, 0);
530 361 markom
    fclose (runtime.vapi.vapi_file);
531
  }
532 355 markom
 
533 304 markom
  while (vapi_handler) {
534
    t = vapi_handler;
535
    vapi_handler = vapi_handler->next;
536
    free (t);
537
  }
538 293 markom
}
539
 
540 477 erez
/* Installs a vapi handler for one VAPI id */
541 336 markom
void vapi_install_handler (unsigned long id, void (*read_func) (unsigned long, unsigned long))
542 304 markom
{
543 477 erez
  vapi_install_multi_handler (id, 1, read_func);
544
}
545
 
546
/* Installs a vapi handler for many VAPI id */
547
void vapi_install_multi_handler (unsigned long base_id, unsigned long num_ids, void (*read_func) (unsigned long, unsigned long))
548
{
549 293 markom
  struct vapi_handler *tt;
550 355 markom
 
551 1350 nogj
  debug(4, "vapi_install_handler %08lx, %lu, %08p\n", base_id, num_ids, read_func);
552 304 markom
  if (read_func == NULL) {
553
    struct vapi_handler **t = &vapi_handler;
554 477 erez
    while ((*t) && !handler_fits_id (*t, base_id))
555 293 markom
      t = &(*t)->next;
556
    if (!t) {
557 1308 phoenix
      fprintf (stderr, "Cannot uninstall VAPI read handler from id %lx\n",
558
               base_id);
559 293 markom
      exit (1);
560
    }
561
    tt = *t;
562
    (*t) = (*t)->next;
563
    free (tt);
564 304 markom
    nhandlers--;
565 293 markom
  } else {
566 477 erez
    tt = find_handler (base_id);
567 355 markom
    if (!tt) {
568 477 erez
      tt = add_handler (base_id, num_ids);
569 355 markom
      tt->read_func = read_func;
570
    } else {
571
      tt->read_func = read_func;
572
      rebuild_fds ();
573
    }
574 293 markom
  }
575
}
576
 
577 304 markom
/* Returns number of unconnected handles.  */
578 336 markom
int vapi_num_unconnected (int printout)
579 304 markom
{
580
  struct vapi_handler *t = vapi_handler;
581
  int numu = 0;
582 336 markom
  for (; t; t = t->next) {
583
    if (!t->fd) {
584
      numu++;
585 477 erez
      if (printout) {
586
        if ( t->num_ids == 1 )
587 1308 phoenix
          PRINTF (" 0x%lx", t->base_id);
588 477 erez
        else
589 1308 phoenix
          PRINTF (" 0x%lx..0x%lx", t->base_id, t->base_id + t->num_ids - 1);
590 477 erez
      }
591 336 markom
    }
592
  }
593 304 markom
  return numu;
594
}
595
 
596 305 markom
/* Sends a packet to specified test */
597
int vapi_send (unsigned long id, unsigned long data)
598
{
599 1350 nogj
  debug (4, "vapi_send [%08lx %08lx]\n", id, data);
600 442 erez
  vapi_write_log_file (VAPI_COMMAND_SEND, id, data);
601 305 markom
  write_packet (id, data);
602
}
603
 
604
/*
605 304 markom
int main ()
606
{
607 551 markom
  runtime.vapi.enabled = 1;
608 304 markom
  config.vapi.server_port = 9999;
609 293 markom
  vapi_init ();
610
  while (1) {
611
    vapi_check();
612 304 markom
    usleep(1);
613 293 markom
  }
614
  vapi_done ();
615 335 markom
}*/
616 1358 nogj
 
617
/*---------------------------------------------------[ VAPI configuration ]---*/
618
void vapi_enabled(union param_val val, void *dat)
619
{
620
  config.vapi.enabled = val.int_val;
621
}
622
 
623
void vapi_server_port(union param_val val, void *dat)
624
{
625
  config.vapi.server_port = val.int_val;
626
}
627
 
628
void vapi_log_enabled(union param_val val, void *dat)
629
{
630
  config.vapi.log_enabled = val.int_val;
631
}
632
 
633
void vapi_hide_device_id(union param_val val, void *dat)
634
{
635
  config.vapi.hide_device_id = val.int_val;
636
}
637
 
638
void vapi_log_fn(union param_val val, void *dat)
639
{
640
  strcpy(config.vapi.vapi_fn, val.str_val);
641
}
642
 
643
void reg_vapi_sec(void)
644
{
645
  struct config_section *sec = reg_config_sec("VAPI", NULL, NULL);
646
 
647
  reg_config_param(sec, "enabled", paramt_int, vapi_enabled);
648
  reg_config_param(sec, "server_port", paramt_int, vapi_server_port);
649
  reg_config_param(sec, "log_enabled", paramt_int, vapi_log_enabled);
650
  reg_config_param(sec, "hide_device_id", paramt_int, vapi_hide_device_id);
651
  reg_config_param(sec, "vapi_log_fn", paramt_str, vapi_log_fn);
652
}

powered by: WebSVN 2.1.0

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