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

Subversion Repositories or1k

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

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

Line No. Rev Author Line
1 1380 phoenix
/* jp-io.c -- Low level JTAG communications
2
   Copyright (C) 2001 Marko Mlinar, markom@opencores.org
3
   Copyright (C) 2004 György Jeney, nog@sdf.lonestar.org
4
   Code for TCP/IP copied from gdb, by Chris Ziomkowski
5
 
6
This file is part of OpenRISC 1000 Architectural Simulator.
7
 
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 2 of the License, or
11
(at your option) any later version.
12
 
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
GNU General Public License for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
21
 
22
/* This handles all the low-level io with the selected cable */
23
 
24
#include <stdio.h>
25
#include <stdint.h>
26
#include <string.h>
27
#include <sys/io.h>
28
#include <sys/types.h>
29
#include <unistd.h>
30
#include <errno.h>
31
#include <stdlib.h>
32
 
33
#include <sys/socket.h>
34
#include <sys/un.h>
35
 
36
#include "jp.h"
37
 
38
static int jp_parallel_init();
39
static void jp_parallel_out(uint8_t value);
40
static uint8_t jp_parallel_in();
41
static int jp_parallel_opt(int c, char *str);
42
 
43
static void jp_phys_wait();
44
 
45
static int jp_rtl_sim_init();
46
static void jp_rtl_sim_out(uint8_t value);
47
static uint8_t jp_rtl_sim_in();
48
static void jp_rtl_sim_wait();
49
static int jp_rtl_sim_opt(int c, char *str);
50
 
51
static int jp_vpi_init();
52
static void jp_vpi_out(uint8_t value);
53
static uint8_t jp_vpi_in();
54
static void jp_vpi_wait();
55
static int jp_vpi_opt(int c, char *str);
56
 
57
static uint8_t jp_xpc3_in();
58
static void jp_xpc3_out(uint8_t value);
59
 
60
static uint8_t jp_xess_in();
61
static void jp_xess_out(uint8_t value);
62
 
63
static struct jtag_cable {
64
  const char *name;
65
  uint8_t (*in_func)();
66
  void (*out_func)(uint8_t);
67
  int (*init_func)();
68
  void (*wait_func)();
69
  int (*opt_func)(int c, char *str);
70
  const char *opts;
71
  const char *help;
72
} jtag_cables[] = {
73
  { "rtl_sim", jp_rtl_sim_in, jp_rtl_sim_out, jp_rtl_sim_init, jp_rtl_sim_wait,
74
    jp_rtl_sim_opt, "d:",
75
    "-d [directory] Directory in which gdb_in.dat/gdb_out.dat may be found\n" },
76
  { "vpi", jp_vpi_in, jp_vpi_out, jp_vpi_init, jp_vpi_wait, jp_vpi_opt, "s:",
77
    "-s [socket] Location of socket that the vpi module created\n" },
78
  { "xpc3", jp_xpc3_in, jp_xpc3_out, jp_parallel_init, jp_phys_wait,
79
    jp_parallel_opt, "p:",
80
    "-p [port] Which port to use when communicateing with the parport hardware (eg. 0x378)\n" },
81
  { "xess", jp_xess_in, jp_xess_out, jp_parallel_init, jp_phys_wait,
82
    jp_parallel_opt, "p:",
83
    "-p [port] Which port to use when communicateing with the parport hardware (eg. 0x378)\n" },
84
  { NULL, NULL, NULL, NULL } };
85
 
86
static struct jtag_cable *jtag_cable_in_use = NULL; /* The current selected cable */
87
 
88
/* Only used for the parport */
89
static int base = 0x378;
90
 
91
/* Only used in the vpi */
92
static int vpi_comm;
93
static char *sock_loc = "/tmp/jp-vpi";
94
 
95
/* Only used for the rtl_sim */
96
static char *gdb_in = "gdb_in.dat";
97
static char *gdb_out = "gdb_out.dat";
98
 
99
void jp_out (uint8_t value)
100
{
101
  /* finally call the cable-specific out-function */
102
  jtag_cable_in_use->out_func(value);
103
 
104
  if(!(value & 1))
105
    debug("[%x%c]", (value & TDI_BIT) != 0, (value & TMS_BIT) ? '^' : '_');
106
  flush_debug();
107
}
108
 
109
/* Receive a byte from the board.  */
110
uint8_t jp_in()
111
{
112
  int data;
113
 
114
  /* Get the data from the board */
115
  data = jtag_cable_in_use->in_func();
116
 
117
  debug(" R%01X ", data);
118
  flush_debug();
119
  return data;
120
}
121
 
122
/* waits */
123
void jp_wait()
124
{
125
  jtag_cable_in_use->wait_func();
126
}
127
 
128
/* Selects a cable for use, returns non-null on success */
129
int jp_select_cable(const char *cable)
130
{
131
  int i;
132
 
133
  for(i = 0; jtag_cables[i].name; i++) {
134
    if(!strcmp(cable, jtag_cables[i].name)) {
135
      jtag_cable_in_use = &jtag_cables[i];
136
      return 1;
137
    }
138
  }
139
 
140
  return 0;
141
}
142
 
143
/* Calls the init-fucntion of the cable */
144
int jp_init_cable()
145
{
146
  return jtag_cable_in_use->init_func();
147
}
148
 
149
/* Parses command-line options specific to the selected cable */
150
int jp_cable_opt(int c, char *str)
151
{
152
  return jtag_cable_in_use->opt_func(c, str);
153
}
154
 
155
const char *jp_get_cable_args()
156
{
157
  return jtag_cable_in_use->opts;
158
}
159
 
160
/* Prints a (short) useage message for each availible cable */
161
void jp_print_cable_help()
162
{
163
  int i;
164
  printf("Availible cables: ");
165
 
166
  for(i = 0; jtag_cables[i].name; i++) {
167
    if(i)
168
      printf(", ");
169
    printf(jtag_cables[i].name);
170
  }
171
 
172
  printf("\n\nOptions availible for the cables:\n");
173
  for(i = 0; jtag_cables[i].name; i++) {
174
    if(!jtag_cables[i].help)
175
      continue;
176
    printf("  %s:\n    %s", jtag_cables[i].name, jtag_cables[i].help);
177
  }
178
}
179
 
180
/*-------------------------------------[ Parallel port specific functions ]---*/
181
static int jp_parallel_init()
182
{
183
  if (ioperm(base, 3, 1)) {
184
    fprintf(stderr, "Couldn't get the port at %x\n", base);
185
    perror("Root privileges are required.\n");
186
    return 0;
187
  }
188
  printf("Connected to parallel port at %x\n", base);
189
  printf("Dropping root privileges.\n");
190
  setreuid(getuid(), getuid());
191
  return 1;
192
}
193
 
194
static void jp_parallel_out(uint8_t value)
195
{
196
  outb(value, LPT_WRITE);
197
}
198
 
199
static uint8_t jp_parallel_in()
200
{
201
  return inb(LPT_READ);
202
}
203
 
204
static int jp_parallel_opt(int c, char *str)
205
{
206
  switch(c) {
207
  case 'p':
208
    if(!sscanf(str, "%x", &base)) {
209
      fprintf(stderr, "p parameter must have a hex number as parameter\n");
210
      return 0;
211
    }
212
    break;
213
  default:
214
    fprintf(stderr, "Unknown parameter '%c'\n", c);
215
    return 0;
216
  }
217
  return 1;
218
}
219
 
220
/*-----------------------------------------[ Physical board wait function ]---*/
221
static void jp_phys_wait()
222
{
223
  /* FIXME: this needs some real TLC */
224
  int i;
225
  volatile int j;
226
  for(i = 0; i < 1000; i++)
227
    j = i;
228
}
229
 
230
/*----------------------------------------------[ xpc3 specific functions ]---*/
231
static void jp_xpc3_out(uint8_t value)
232
{
233
  uint8_t out = 0;
234
 
235
  /* First convert the bits in value byte to the ones that the cable wants */
236
  if(value & TCLK_BIT)
237
    out |= 0x02; /* D1 pin 3 */
238
  if(value & TRST_BIT)
239
    out |= 0x10; /* Not used */
240
  if(value & TDI_BIT)
241
    out |= 0x01; /* D0 pin 2 */
242
  if(value & TMS_BIT)
243
    out |= 0x04; /* D2 pin 4 */
244
 
245
  jp_parallel_out(out);
246
}
247
 
248
static uint8_t jp_xpc3_in()
249
{
250
  uint8_t in;
251
 
252
  in = jp_parallel_in();
253
 
254
  if(in & 0x10) /* S6 pin 13 */
255
    return 1;
256
  return 0;
257
}
258
 
259
/*----------------------------------------------[ xess specific functions ]---*/
260
static void jp_xess_out(uint8_t value)
261
{
262
  uint8_t out = 0;
263
 
264
  /* First convert the bits in value byte to the ones that the cable wants */
265
  if(value & TCLK_BIT)
266
    out |= 0x04; /* D2 pin 4 */
267
  if(value & TRST_BIT)
268
    out |= 0x08; /* D3 pin 5 */
269
  if(value & TDI_BIT)
270
    out |= 0x10; /* D4 pin 6 */
271
  if(value & TMS_BIT)
272
    out |= 0x20; /* D3 pin 5 */
273
 
274
  jp_parallel_out(out);
275
}
276
 
277
static uint8_t jp_xess_in()
278
{
279
  uint8_t in;
280
 
281
  in = jp_parallel_in();
282
 
283
  if(in & 0x20) /* S5 pin 12*/
284
    return 1;
285
  return 0;
286
}
287
 
288
/*-------------------------------------------[ rtl_sim specific functions ]---*/
289
static int jp_rtl_sim_init()
290
{
291
  FILE *fin = fopen (gdb_in, "wt+");
292
  if(!fin) {
293
    fprintf(stderr, "Can not open %s\n", gdb_in);
294
    return 0;
295
  }
296
  fclose(fin);
297
  return 1;
298
}
299
 
300
static void jp_rtl_sim_out(uint8_t value)
301
{
302
  FILE *fout;
303
  int num_read;
304
  int r;
305
  fout = fopen(gdb_in, "wt+");
306
  fprintf(fout, "F\n");
307
  fclose(fout);
308
  fout = fopen(gdb_out, "wt+");
309
  fprintf(fout, "%02X\n", value);
310
  fclose(fout);
311
  do {
312
    fout = fopen(gdb_out, "rt");
313
    r = fscanf(fout,"%x", &num_read);
314
    fclose(fout);
315
  } while(!r || (num_read != (0x10 | value)));
316
}
317
 
318
static uint8_t jp_rtl_sim_in()
319
{
320
  FILE *fin = 0;
321
  char ch;
322
  uint8_t data;
323
  while(1) {
324
    fin = fopen(gdb_in, "rt");
325
    if(!fin)
326
      continue;
327
    ch = fgetc(fin);
328
    fclose(fin);
329
    if((ch != '0') && (ch != '1'))
330
      continue;
331
    else
332
      break;
333
  }
334
  data = ch == '1' ? 1 : 0;
335
  return data;
336
}
337
 
338
static void jp_rtl_sim_wait()
339
{
340
  usleep(1000);
341
}
342
 
343
static int jp_rtl_sim_opt(int c, char *str)
344
{
345
  switch(c) {
346
  case 'd':
347
    if(!(gdb_in = malloc(strlen(str) + 12))) { /* 12 == strlen("gdb_in.dat") + 2 */
348
      fprintf(stderr, "Unable to allocate enough memory\n");
349
      return 0;
350
    }
351
    if(!(gdb_out = malloc(strlen(str) + 13))) { /* 13 == strlen("gdb_out.dat") + 2 */
352
      fprintf(stderr, "Unable to allocate enough memory\n");
353
      free(gdb_in);
354
      return 0;
355
    }
356
 
357
    sprintf(gdb_in, "%s/gdb_in.dat", str);
358
    sprintf(gdb_out, "%s/gdb_out.dat", str);
359
    break;
360
  default:
361
    fprintf(stderr, "Unknown parameter '%c'\n", c);
362
    return 0;
363
  }
364
  return 1;
365
}
366
 
367
/*-----------------------------------------------[ VPI specific functions ]---*/
368
static int jp_vpi_init()
369
{
370
  struct sockaddr_un addr;
371
 
372
  if((vpi_comm = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
373
    fprintf(stderr, "Unable to create socket (%s)\n", strerror(errno));
374
    return 0;
375
  }
376
 
377
  addr.sun_family = AF_UNIX;
378
  strcpy(addr.sun_path, sock_loc);
379
 
380
  if(connect(vpi_comm, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
381
    fprintf(stderr, "Unable to connect to %s (%s)\n", addr.sun_path,
382
            strerror(errno));
383
    return 0;
384
  }
385
  return 1;
386
}
387
 
388
static void jp_vpi_out(uint8_t value)
389
{
390
  uint8_t ack;
391
 
392
  /* Send the data to the socket */
393
  write(vpi_comm, &value, 1);
394
 
395
  do {
396
    /* Ok, read the data */
397
    read(vpi_comm, &ack, 1);
398
  } while(ack != (value | 0x10));
399
}
400
 
401
static uint8_t jp_vpi_in()
402
{
403
  uint8_t dat;
404
 
405
  /* ask vpi to send us the out-bit */
406
  dat = 0x80;
407
  write(vpi_comm, &dat, 1);
408
 
409
  /* Wait and read the data */
410
  read(vpi_comm, &dat, 1);
411
 
412
  if(dat > 1)
413
    fprintf(stderr, "Unexpected value: %i\n", dat);
414
 
415
  return dat;
416
}
417
 
418
static void jp_vpi_wait()
419
{
420
  uint8_t dat = 0x81;
421
 
422
  /* Get the sim to reply when the timeout has been reached */
423
  write(vpi_comm, &dat, 1);
424
 
425
  /* block, waiting for the data */
426
  read(vpi_comm, &dat, 1);
427
}
428
 
429
static int jp_vpi_opt(int c, char *str)
430
{
431
  switch(c) {
432
  case 's':
433
    if(!(sock_loc = strdup(str))) {
434
      fprintf(stderr, "Unable to allocate memory\n");
435
      return 0;
436
    }
437
    break;
438
  default:
439
    fprintf(stderr, "Unknown parameter '%c'\n", c);
440
    return 0;
441
  }
442
  return 1;
443
}

powered by: WebSVN 2.1.0

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