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

Subversion Repositories adv_debug_sys

[/] [adv_debug_sys/] [trunk/] [Software/] [adv_jtag_bridge/] [sim_lib/] [src/] [jp-io-vpi.c] - Blame information for rev 51

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

Line No. Rev Author Line
1 4 nyawn
/* jp-io-vpi.c -- JTAG communications vpi plugin
2
   Copyright (C) 2004 György Jeney, nog@sdf.lonestar.org
3
   Modifications copyright (C) 2008 Nathan Yawn, nathan.yawn@opencores.org
4
 
5
   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
 
17
   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
 
21
/* This plugs into an rtl simulator via vpi */
22
 
23
#include <stdio.h>
24 51 nyawn
#include <stdlib.h>
25 4 nyawn
#include <unistd.h>
26
#include <stdint.h>
27
#include <errno.h>
28
#include <string.h>
29
 
30
#ifdef WIN32
31
#include <winsock2.h>
32
#else
33
#include <sys/types.h>
34
#include <sys/socket.h>
35
#include <netinet/in.h>
36
#include <arpa/inet.h>
37
#include <fcntl.h>
38
#endif
39
 
40
#include <vpi_user.h>
41
 
42
/* The vpi<->jp connection is `mastered' by jp1.  Therefore we just sit doing
43
 * `nothing', waiting for jp1 to request or send us some data */
44
static uint8_t vpi_out; /* data that the sim gives to us */
45
 
46
#ifdef WIN32
47
SOCKET jp_comm_m;
48
SOCKET jp_comm;
49
char msgbuf[64];
50
char * get_ws_error(void);
51
#define GET_ERR_MSG get_ws_error()
52
#ifndef EAGAIN
53
#define EAGAIN WSAEWOULDBLOCK
54
#endif
55
#ifndef EWOULDBLOCK
56
#define EWOULDBLOCK WSAEWOULDBLOCK
57
#endif
58
#else
59
static int jp_comm_m; /* The listening socket */
60
static int jp_comm; /* The socket for communitateing with jp1 */
61
#define GET_ERR_MSG strerror(errno)
62
#endif
63
 
64
#ifndef SOCKET_ERROR
65
#define SOCKET_ERROR -1
66
#endif
67
 
68
 
69
static int jp_got_con; /* Have we got a connection ? */
70
 
71
static int count_comp; /* Has the predetermined cycle-count been reached ? */
72
static int jp_waiting; /* Is jp-waiting for count_comp ? */
73
 
74
int jp_check_con();
75
 
76
/*---------------------------------------------[ VPI interface to the sim ]---*/
77
/* Sends a byte from the sim */
78
int vpi_jp_out(char *xx)
79
{
80
  vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
81
  vpiHandle argv = vpi_iterate(vpiArgument, sys);
82
  s_vpi_value value;
83
 
84
  if(!argv) {
85
    vpi_printf("$jp_out: missing destination argument\n");
86
    vpi_free_object(argv);
87
    return 0;
88
  }
89
  vpiHandle dat_to = vpi_scan(argv);
90
  if(vpi_get(vpiType, dat_to) != vpiNet) {
91
    vpi_printf("$jp_out: Must have a net as argument!!\n");
92
    vpi_free_object(argv);
93
    return 0;
94
  }
95
 
96
  value.format = vpiVectorVal;
97
  vpi_get_value(dat_to, &value);
98
 
99
  if((value.value.vector->bval & 1)) {
100
    vpi_free_object(argv);
101
    return 0;
102
  }
103
  vpi_out = value.value.vector->aval & 1;
104
 
105
  vpi_free_object(argv);
106
 
107
  return 0;
108
}
109
 
110
/* Sends a byte to the sim */
111
int vpi_jp_in(char *xx)
112
{
113
  int ret;
114
  uint8_t dat;
115
  s_vpi_vecval vec;
116
 
117
  s_vpi_value value;
118
  vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
119
  vpiHandle argv;
120
  vpiHandle dat_to;
121
 
122
  if(!jp_got_con) {
123
    if(!jp_check_con())
124
      return 0;
125
  }
126
 
127
  ret = recv(jp_comm, &dat, 1, 0);
128
  if(!ret)
129
    return 0;
130
  if(ret == SOCKET_ERROR)
131
    {
132
#ifdef WIN32
133
      if(WSAGetLastError() == WSAEWOULDBLOCK)
134
#else
135
      if(errno == EAGAIN)
136
#endif
137
        {
138
          return 0;
139
        }
140
      else {
141
        vpi_printf("Socket recv error: %s\n", GET_ERR_MSG);
142
        return 0;
143
      }
144
 
145
}
146
 
147
 
148
  if(dat & 0x80) {
149
    switch(dat & 0x7f) {
150
    case 0:
151
      /* jp1 wants the TDO */
152
      send(jp_comm, &vpi_out, 1, 0);
153
      return 0;
154
    case 1:
155
      /* jp wants a time-out */
156
      if(count_comp) {
157
        dat = 0xFF;                   /* A value of 0xFF is expected, but not required */
158
        send(jp_comm, &dat, 1, 0);
159
      }
160
      else {
161
        jp_waiting = 1;
162
      }
163
      return 0;
164
    }
165
  }
166
 
167
  argv = vpi_iterate(vpiArgument, sys);
168
 
169
  /* We got the data, acknowledge it and send it on to the sim */
170
  if(!argv) {
171
    vpi_printf("$jp_in: missing destination argument\n");
172
    vpi_free_object(argv);
173
    return 0;
174
  }
175
  dat_to = vpi_scan(argv);
176
  if(vpi_get(vpiType, dat_to) != vpiReg) {
177
    vpi_printf("$jp_in: Must have a register (vpiReg) as argument (type is %d)!!\n", vpi_get(vpiType, dat_to));
178
    vpi_free_object(argv);
179
    return 0;
180
  }
181
 
182
  value.format = vpiVectorVal;
183
 
184
  vec.aval = (dat & 0xf) | 0x10;
185
  vec.bval = 0;
186
  value.value.vector = &vec;
187
  vpi_put_value(dat_to, &value, 0, vpiNoDelay);
188
 
189
  vpi_free_object(argv);
190
 
191
  dat |= 0x10;
192
  ret = send(jp_comm, &dat, 1, 0);
193
 
194
  count_comp = 0;
195
 
196
  return 0;
197
}
198
 
199
/* tells us that we reached a predetermined cycle count */
200
int jp_wait_time(char *xx)
201
{
202
  uint8_t dat = 0xFF;
203
  if(jp_waiting) {
204
    send(jp_comm, &dat, 1, 0);
205
    jp_waiting = 0;
206
  }
207
 
208
  count_comp = 1;
209
  return 0;
210
}
211
 
212
/*---------------------------------------------------[ VPI<->jp functions ]---*/
213
int init_sock(char *xx)
214
{
215
 
216
  struct sockaddr_in addr;
217
  int ret;
218
  vpiHandle sys = vpi_handle(vpiSysTfCall, 0);
219
  vpiHandle argv = vpi_iterate(vpiArgument, sys);
220
  s_vpi_value value;
221
 
222
  if(!argv) {
223
    vpi_printf("$jp_init: missing port argument\n");
224
    return 0;
225
  }
226
  vpiHandle sock = vpi_scan(argv);
227
/* orig
228
  if(vpi_get(vpiConstType, sock) != vpiStringConst) {
229
    vpi_printf("$jp_init: Must have a string as argument!!\n");
230
    vpi_free_object(argv);
231
    return 0;
232
  }
233
*/
234
 
235
#ifdef WIN32
236
  WSADATA wsaData;
237
  ret = WSAStartup(MAKEWORD(2,2), &wsaData);  // must be called before all socket operations
238
  if(ret != 0) {
239
    vpi_printf("$jp_init: Winsock startup failed.");
240
    return 0;
241
  }
242
#endif
243
 
244
  value.format = vpiStringVal;
245
  vpi_get_value(sock, &value);
246
 
247
  addr.sin_family = AF_INET;
248
  addr.sin_port = atoi(value.value.str);
249
  addr.sin_addr.s_addr = INADDR_ANY;
250
  memset(addr.sin_zero, '\0', sizeof(addr.sin_zero));
251
 
252
  jp_comm_m = socket(PF_INET, SOCK_STREAM, 0);
253
#ifdef WIN32
254
  if(jp_comm_m == INVALID_SOCKET)
255
#else
256
  if(jp_comm_m < 0)
257
#endif
258
   {
259
     fprintf(stderr, "Unable to create comm socket: %s\n", GET_ERR_MSG);
260
    return 0;
261
  }
262
 
263
  if(bind(jp_comm_m, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) {
264
    fprintf(stderr, "Unable to bind the socket: %s\n", GET_ERR_MSG);
265
    return 0;
266
  }
267
 
268
  if(listen(jp_comm_m, 1) == SOCKET_ERROR) {
269
    fprintf(stderr, "Unable to listen: %s\n", GET_ERR_MSG);
270
    return 0;
271
  }
272
 
273
#ifdef WIN32
274
  u_long arg = 1;
275
  ioctlsocket(jp_comm_m, FIONBIO, &arg);
276
#else
277
  ret = fcntl(jp_comm_m, F_GETFL);
278
  ret |= O_NONBLOCK;
279
  fcntl(jp_comm_m, F_SETFL, ret);
280
#endif
281
 
282
  jp_got_con = 0;
283
  jp_waiting = 0;
284
  return 0;
285
}
286
 
287
/* Checks to see if we got a connection */
288
int jp_check_con()
289
{
290
  int ret;
291
 
292
  if((jp_comm = accept(jp_comm_m, NULL, NULL)) == SOCKET_ERROR) {
293
#ifdef WIN32
294
    if(WSAGetLastError() == WSAEWOULDBLOCK)
295
#else
296
    if(errno == EAGAIN)
297
#endif
298
      return 0;
299
    fprintf(stderr, "Unable to accept connection: %s\n", GET_ERR_MSG);
300
    return 0;
301
  }
302
 
303
 
304
  // Set the comm socket to non-blocking.
305
  // Close the server socket, so that the port can be taken again
306
  // if the simulator is reset.
307
#ifdef WIN32
308
  u_long arg = 1;
309
  ioctlsocket(jp_comm, FIONBIO, &arg);
310
  closesocket(jp_comm_m);
311
#else
312
  ret = fcntl(jp_comm, F_GETFL);
313
  ret |= O_NONBLOCK;
314
  fcntl(jp_comm, F_SETFL, ret);
315
  close(jp_comm_m);
316
#endif
317
 
318
  vpi_printf("JTAG communication connected!\n");
319
  jp_got_con = 1;
320
  return 1;
321
}
322
 
323
/*------------------------------------------------------------[ VPI stuff ]---*/
324
static void jtag_register()
325
{
326
  s_vpi_systf_data tf_data;
327
 
328
  tf_data.type      = vpiSysTask;
329
  tf_data.tfname    = "$jp_in";
330
  tf_data.calltf    = vpi_jp_in;
331
  tf_data.compiletf = 0;
332
  tf_data.sizetf    = 0;
333
  vpi_register_systf(&tf_data);
334
 
335
  tf_data.type      = vpiSysTask;
336
  tf_data.tfname    = "$jp_out";
337
  tf_data.calltf    = vpi_jp_out;
338
  tf_data.compiletf = 0;
339
  tf_data.sizetf    = 0;
340
  vpi_register_systf(&tf_data);
341
 
342
  tf_data.type      = vpiSysTask;
343
  tf_data.tfname    = "$jp_init";
344
  tf_data.calltf    = init_sock;
345
  tf_data.compiletf = 0;
346
  tf_data.sizetf    = 0;
347
  vpi_register_systf(&tf_data);
348
 
349
  tf_data.type      = vpiSysTask;
350
  tf_data.tfname    = "$jp_wait_time";
351
  tf_data.calltf    = jp_wait_time;
352
  tf_data.compiletf = 0;
353
  tf_data.sizetf    = 0;
354
  vpi_register_systf(&tf_data);
355
}
356
 
357
void (*vlog_startup_routines[])() = {
358
      jtag_register,
359
 
360
};
361
 
362
 
363
#ifdef WIN32
364
char *get_ws_error(void)
365
{
366
  snprintf(msgbuf, 64, "%d", WSAGetLastError());
367
  return msgbuf;
368
}
369
#endif
370
 

powered by: WebSVN 2.1.0

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