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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [jtag/] [jp-io-vpi.c] - Blame information for rev 1780

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

Line No. Rev Author Line
1 1380 phoenix
/* jp-io-vpi.c -- JTAG communications vpi plugin
2
   Copyright (C) 2004 György Jeney, nog@sdf.lonestar.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
/* This plugs into an rtl simulator via vpi */
21
 
22
#include <stdio.h>
23
#include <sys/types.h>
24
#include <sys/socket.h>
25
#include <unistd.h>
26
#include <stdint.h>
27
#include <fcntl.h>
28
#include <sys/un.h>
29
#include <errno.h>
30
 
31
#include <vpi_user.h>
32
 
33
/* The vpi<->jp connection is `mastered' by jp1.  Therefore we just sit doing
34
 * `nothing', waiting for jp1 to request or send us some data */
35
static uint8_t vpi_out; /* data that the sim gives to us */
36
 
37
static int jp_comm_m; /* The listening socket */
38
static int jp_comm; /* The socket for communitateing with jp1 */
39
 
40
static int jp_got_con; /* Have we got a connection ? */
41
 
42
static int count_comp; /* Has the predetermined cycle-count been reached ? */
43
static int jp_waiting; /* Is jp-waiting for count_comp ? */
44
 
45
int jp_check_con();
46
 
47
/*---------------------------------------------[ VPI interface to the sim ]---*/
48
/* Sends a byte from the sim */
49
int vpi_jp_out(char *xx)
50
{
51
  vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
52
  vpiHandle argv = vpi_iterate(vpiArgument, sys);
53
  s_vpi_value value;
54
 
55
  if(!argv) {
56
    vpi_printf("$jp_out: missing destination argument\n");
57
    vpi_free_object(argv);
58
    return 0;
59
  }
60
  vpiHandle dat_to = vpi_scan(argv);
61
  if(vpi_get(vpiType, dat_to) != vpiNet) {
62
    vpi_printf("$jp_out: Must have a net as argument!!\n");
63
    vpi_free_object(argv);
64
    return 0;
65
  }
66
 
67
  value.format = vpiVectorVal;
68
  vpi_get_value(dat_to, &value);
69
 
70
  if((value.value.vector->bval & 1)) {
71
    vpi_free_object(argv);
72
    return 0;
73
  }
74
  vpi_out = value.value.vector->aval & 1;
75
 
76
  vpi_free_object(argv);
77
 
78
  return 0;
79
}
80
 
81
/* Sends a byte to the sim */
82
int vpi_jp_in(char *xx)
83
{
84
  int ret;
85
  uint8_t dat;
86
  s_vpi_vecval vec;
87
 
88
  s_vpi_value value;
89
  vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
90
  vpiHandle argv;
91
  vpiHandle dat_to;
92
 
93
  vpiHandle dat_to_index;
94
 
95
  if(!jp_got_con) {
96
    if(!jp_check_con())
97
      return 0;
98
  }
99
 
100
  ret = read(jp_comm, &dat, 1);
101
  if(!ret)
102
    return 0;
103
  if((ret == -1) && (errno == EAGAIN))
104
    return 0;
105
 
106
  if(dat & 0x80) {
107
    switch(dat & 0x7f) {
108
    case 0:
109
      /* jp1 wants the TDO */
110
      write(jp_comm, &vpi_out, 1);
111
      return 0;
112
    case 1:
113
      /* jp wants a time-out */
114
      if(count_comp)
115
        write(jp_comm, &dat, 1); /* The value is irrelevent */
116
      else
117
        jp_waiting = 1;
118
      return 0;
119
    }
120
  }
121
 
122
  argv = vpi_iterate(vpiArgument, sys);
123
 
124
  /* We got the data, acknowledge it and send it on to the sim */
125
  if(!argv) {
126
    vpi_printf("$jp_in: missing destination argument\n");
127
    vpi_free_object(argv);
128
    return 0;
129
  }
130
  dat_to = vpi_scan(argv);
131
  if(vpi_get(vpiType, dat_to) != vpiMemory) {
132
    vpi_printf("$jp_in: Must have a memory as argument!!\n");
133
    vpi_free_object(argv);
134
    return 0;
135
  }
136
 
137
  value.format = vpiVectorVal;
138
 
139
  vec.aval = (dat & 0xf) | 0x10;
140
  vec.bval = 0;
141
  value.value.vector = &vec;
142
  dat_to_index = vpi_handle_by_index(dat_to, 0);
143
  vpi_put_value(dat_to_index, &value, 0, vpiNoDelay);
144
 
145
  vpi_free_object(argv);
146
 
147
  dat |= 0x10;
148
  write(jp_comm, &dat, 1);
149
 
150
  count_comp = 0;
151
 
152
  return 0;
153
}
154
 
155
/* tells us that we reached a predetermined cycle count */
156
int jp_wait_time(char *xx)
157
{
158
  uint8_t dat = 0;
159
  if(jp_waiting) {
160
    write(jp_comm, &dat, 1);
161
    jp_waiting = 0;
162
  }
163
  count_comp = 1;
164
  return 0;
165
}
166
 
167
/*---------------------------------------------------[ VPI<->jp functions ]---*/
168
int init_sock(char *xx)
169
{
170
  struct sockaddr_un addr;
171
  int ret;
172
  vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
173
  vpiHandle argv = vpi_iterate(vpiArgument, sys);
174
  s_vpi_value value;
175
 
176
  if(!argv) {
177
    vpi_printf("$jp_init: missing destination argument\n");
178
    return 0;
179
  }
180
  vpiHandle sock = vpi_scan(argv);
181
/*
182
  if(vpi_get(vpiConstType, sock) != vpiStringConst) {
183
    vpi_printf("$jp_init: Must have a string as argument!!\n");
184
    vpi_free_object(argv);
185
    return 0;
186
  }
187
*/
188
 
189
  value.format = vpiStringVal;
190
  vpi_get_value(sock, &value);
191
 
192
  addr.sun_family = AF_UNIX;
193
  strcpy(addr.sun_path, value.value.str);
194
 
195
  if((jp_comm_m = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
196
    fprintf(stderr, "Unable to create comm socket\n");
197
    return 0;
198
  }
199
 
200
  if(bind(jp_comm_m, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
201
    fprintf(stderr, "Unable to bind to the unix socket %s\n", addr.sun_path);
202
    return 0;
203
  }
204
 
205
  if(listen(jp_comm_m, 1) == -1) {
206
    fprintf(stderr, "Unable to listen on %s (%s)\n", addr.sun_path,
207
            strerror(errno));
208
    return 0;
209
  }
210
 
211
  ret = fcntl(jp_comm_m, F_GETFL);
212
  ret |= O_NONBLOCK;
213
  fcntl(jp_comm_m, F_SETFL, ret);
214
 
215
  jp_got_con = 0;
216
  jp_waiting = 0;
217
  printf("Just registered socket!!!\n");
218
  return 0;
219
}
220
 
221
/* Checks to see if we got a connection */
222
int jp_check_con()
223
{
224
  int ret;
225
 
226
  if((jp_comm = accept(jp_comm_m, NULL, NULL)) == -1) {
227
    if(errno == EAGAIN)
228
      return 0;
229
    fprintf(stderr, "Unable to accept connection (%s)\n", strerror(errno));
230
    return 0;
231
  }
232
 
233
  /* Set the comm socket to non-blocking */
234
  ret = fcntl(jp_comm, F_GETFL);
235
  ret |= O_NONBLOCK;
236
  fcntl(jp_comm, F_SETFL, ret);
237
 
238
  jp_got_con = 1;
239
  return 1;
240
}
241
 
242
/*------------------------------------------------------------[ VPI stuff ]---*/
243
static void jtag_register()
244
{
245
  s_vpi_systf_data tf_data;
246
 
247
  tf_data.type      = vpiSysTask;
248
  tf_data.tfname    = "$jp_in";
249
  tf_data.calltf    = vpi_jp_in;
250
  tf_data.compiletf = 0;
251
  tf_data.sizetf    = 0;
252
  vpi_register_systf(&tf_data);
253
 
254
  tf_data.type      = vpiSysTask;
255
  tf_data.tfname    = "$jp_out";
256
  tf_data.calltf    = vpi_jp_out;
257
  tf_data.compiletf = 0;
258
  tf_data.sizetf    = 0;
259
  vpi_register_systf(&tf_data);
260
 
261
  tf_data.type      = vpiSysTask;
262
  tf_data.tfname    = "$jp_init";
263
  tf_data.calltf    = init_sock;
264
  tf_data.compiletf = 0;
265
  tf_data.sizetf    = 0;
266
  vpi_register_systf(&tf_data);
267
 
268
  tf_data.type      = vpiSysTask;
269
  tf_data.tfname    = "$jp_wait_time";
270
  tf_data.calltf    = jp_wait_time;
271
  tf_data.compiletf = 0;
272
  tf_data.sizetf    = 0;
273
  vpi_register_systf(&tf_data);
274
}
275
 
276
void (*vlog_startup_routines[])() = {
277
      jtag_register,
278
 
279
};

powered by: WebSVN 2.1.0

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