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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [jtag/] [jp-io-vpi.c] - Rev 1765

Compare with Previous | Blame | View Log

/* jp-io-vpi.c -- JTAG communications vpi plugin
   Copyright (C) 2004 György Jeney, nog@sdf.lonestar.org
 
This file is part of OpenRISC 1000 Architectural Simulator.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
/* This plugs into an rtl simulator via vpi */
 
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/un.h>
#include <errno.h>
 
#include <vpi_user.h>
 
/* The vpi<->jp connection is `mastered' by jp1.  Therefore we just sit doing
 * `nothing', waiting for jp1 to request or send us some data */
static uint8_t vpi_out; /* data that the sim gives to us */
 
static int jp_comm_m; /* The listening socket */
static int jp_comm; /* The socket for communitateing with jp1 */
 
static int jp_got_con; /* Have we got a connection ? */
 
static int count_comp; /* Has the predetermined cycle-count been reached ? */
static int jp_waiting; /* Is jp-waiting for count_comp ? */
 
int jp_check_con();
 
/*---------------------------------------------[ VPI interface to the sim ]---*/
/* Sends a byte from the sim */
int vpi_jp_out(char *xx)
{
  vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
  vpiHandle argv = vpi_iterate(vpiArgument, sys);
  s_vpi_value value;
 
  if(!argv) {
    vpi_printf("$jp_out: missing destination argument\n");
    vpi_free_object(argv);
    return 0;
  }
  vpiHandle dat_to = vpi_scan(argv);
  if(vpi_get(vpiType, dat_to) != vpiNet) {
    vpi_printf("$jp_out: Must have a net as argument!!\n");
    vpi_free_object(argv);
    return 0;
  }
 
  value.format = vpiVectorVal;
  vpi_get_value(dat_to, &value);
 
  if((value.value.vector->bval & 1)) {
    vpi_free_object(argv);
    return 0;
  }
  vpi_out = value.value.vector->aval & 1;
 
  vpi_free_object(argv);
 
  return 0;
}
 
/* Sends a byte to the sim */
int vpi_jp_in(char *xx)
{
  int ret;
  uint8_t dat;
  s_vpi_vecval vec;
 
  s_vpi_value value;
  vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
  vpiHandle argv;
  vpiHandle dat_to;
 
  vpiHandle dat_to_index;
 
  if(!jp_got_con) {
    if(!jp_check_con())
      return 0;
  }
 
  ret = read(jp_comm, &dat, 1);
  if(!ret)
    return 0;
  if((ret == -1) && (errno == EAGAIN))
    return 0;
 
  if(dat & 0x80) {
    switch(dat & 0x7f) {
    case 0:
      /* jp1 wants the TDO */
      write(jp_comm, &vpi_out, 1);
      return 0;
    case 1:
      /* jp wants a time-out */
      if(count_comp)
        write(jp_comm, &dat, 1); /* The value is irrelevent */
      else
        jp_waiting = 1;
      return 0;
    }
  }
 
  argv = vpi_iterate(vpiArgument, sys);
 
  /* We got the data, acknowledge it and send it on to the sim */
  if(!argv) {
    vpi_printf("$jp_in: missing destination argument\n");
    vpi_free_object(argv);
    return 0;
  }
  dat_to = vpi_scan(argv);
  if(vpi_get(vpiType, dat_to) != vpiMemory) {
    vpi_printf("$jp_in: Must have a memory as argument!!\n");
    vpi_free_object(argv);
    return 0;
  }
 
  value.format = vpiVectorVal;
 
  vec.aval = (dat & 0xf) | 0x10;
  vec.bval = 0;
  value.value.vector = &vec;
  dat_to_index = vpi_handle_by_index(dat_to, 0);
  vpi_put_value(dat_to_index, &value, 0, vpiNoDelay);
 
  vpi_free_object(argv);
 
  dat |= 0x10;
  write(jp_comm, &dat, 1);
 
  count_comp = 0;
 
  return 0;
}
 
/* tells us that we reached a predetermined cycle count */
int jp_wait_time(char *xx)
{
  uint8_t dat = 0;
  if(jp_waiting) {
    write(jp_comm, &dat, 1);
    jp_waiting = 0;
  }
  count_comp = 1;
  return 0;
}
 
/*---------------------------------------------------[ VPI<->jp functions ]---*/
int init_sock(char *xx)
{
  struct sockaddr_un addr;
  int ret;
  vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
  vpiHandle argv = vpi_iterate(vpiArgument, sys);
  s_vpi_value value;
 
  if(!argv) {
    vpi_printf("$jp_init: missing destination argument\n");
    return 0;
  }
  vpiHandle sock = vpi_scan(argv);
/*
  if(vpi_get(vpiConstType, sock) != vpiStringConst) {
    vpi_printf("$jp_init: Must have a string as argument!!\n");
    vpi_free_object(argv);
    return 0;
  }
*/
 
  value.format = vpiStringVal;
  vpi_get_value(sock, &value);
 
  addr.sun_family = AF_UNIX;
  strcpy(addr.sun_path, value.value.str);
 
  if((jp_comm_m = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
    fprintf(stderr, "Unable to create comm socket\n");
    return 0;
  }
 
  if(bind(jp_comm_m, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
    fprintf(stderr, "Unable to bind to the unix socket %s\n", addr.sun_path);
    return 0;
  }
 
  if(listen(jp_comm_m, 1) == -1) {
    fprintf(stderr, "Unable to listen on %s (%s)\n", addr.sun_path,
            strerror(errno));
    return 0;
  }
 
  ret = fcntl(jp_comm_m, F_GETFL);
  ret |= O_NONBLOCK;
  fcntl(jp_comm_m, F_SETFL, ret);
 
  jp_got_con = 0;
  jp_waiting = 0;
  printf("Just registered socket!!!\n");
  return 0;
}
 
/* Checks to see if we got a connection */
int jp_check_con()
{
  int ret;
 
  if((jp_comm = accept(jp_comm_m, NULL, NULL)) == -1) {
    if(errno == EAGAIN)
      return 0;
    fprintf(stderr, "Unable to accept connection (%s)\n", strerror(errno));
    return 0;
  }
 
  /* Set the comm socket to non-blocking */
  ret = fcntl(jp_comm, F_GETFL);
  ret |= O_NONBLOCK;
  fcntl(jp_comm, F_SETFL, ret);
 
  jp_got_con = 1;
  return 1;
}
 
/*------------------------------------------------------------[ VPI stuff ]---*/
static void jtag_register()
{
  s_vpi_systf_data tf_data;
 
  tf_data.type      = vpiSysTask;
  tf_data.tfname    = "$jp_in";
  tf_data.calltf    = vpi_jp_in;
  tf_data.compiletf = 0;
  tf_data.sizetf    = 0;
  vpi_register_systf(&tf_data);
 
  tf_data.type      = vpiSysTask;
  tf_data.tfname    = "$jp_out";
  tf_data.calltf    = vpi_jp_out;
  tf_data.compiletf = 0;
  tf_data.sizetf    = 0;
  vpi_register_systf(&tf_data);
 
  tf_data.type      = vpiSysTask;
  tf_data.tfname    = "$jp_init";
  tf_data.calltf    = init_sock;
  tf_data.compiletf = 0;
  tf_data.sizetf    = 0;
  vpi_register_systf(&tf_data);
 
  tf_data.type      = vpiSysTask;
  tf_data.tfname    = "$jp_wait_time";
  tf_data.calltf    = jp_wait_time;
  tf_data.compiletf = 0;
  tf_data.sizetf    = 0;
  vpi_register_systf(&tf_data);
}
 
void (*vlog_startup_routines[])() = {
      jtag_register,
      0
};
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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