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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [soc/] [sw/] [adv_jtag_bridge/] [sim_lib/] [src/] [jp-io-vpi.c] - Blame information for rev 12

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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