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/] [adv_jtag_bridge.c] - Blame information for rev 12

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

Line No. Rev Author Line
1 12 xianfeng
/* adv_jtag_bridge.c -- JTAG protocol bridge between GDB and Advanced debug module.
2
   Copyright(C) 2001 Marko Mlinar, markom@opencores.org
3
   Code for TCP/IP copied from gdb, by Chris Ziomkowski
4
   Refactoring by Nathan Yawn, nyawn@opencores.org
5
 
6
   This file was part of the OpenRISC 1000 Architectural Simulator.
7
   It is now also used to connect GDB to a running hardware OpenCores / OR1200
8
   advanced debug unit.
9
 
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 2 of the License, or
13
   (at your option) any later version.
14
 
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
 
20
   You should have received a copy of the GNU General Public License
21
   along with this program; if not, write to the Free Software
22
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
23
 
24
/* Establishes jtag proxy server and communicates with parallel
25
   port directly.  Requires root access. */
26
 
27
#include <stdio.h>
28
#include <stdlib.h>  // for exit(), atoi(), strtoul()
29
#include <unistd.h>
30
#include <stdarg.h>
31
#include <string.h>  // for strstr()
32
#include <sys/types.h>
33
 
34
 
35
#include "adv_jtag_bridge.h"
36
#include "rsp-server.h"
37
#include "chain_commands.h"
38
#include "cable_common.h"
39
#include "or32_selftest.h"
40
#include "bsdl.h"
41
#include "errcodes.h"
42
#include "cable_usbblaster.h"
43
 
44
#define debug(...) //fprintf(stderr, __VA_ARGS__ )
45
 
46
// How many command-line IR length settings to create by default
47
#define IR_START_SETS 16
48
 
49
//////////////////////////////////////////////////
50
// Command line option flags / values
51
 
52
/* Which device in the scan chain we want to target.
53
 * 0 is the first device we find, which is nearest the data input of the cable.
54
 */
55
unsigned int target_dev_pos = 0;
56
 
57
// Do test before setting up server?
58
unsigned char do_selftest = 0;
59
 
60
// IR register length in TAP of 
61
// Can override autoprobe, or set if IDCODE not supported
62
typedef struct {
63
  int dev_index;
64
  int ir_length;
65
} irset;
66
 
67
#define START_IR_SETS 16
68
int reallocs = 0;
69
int num_ir_sets = 0;
70
irset * cmd_line_ir_sizes = NULL;
71
 
72
// DEBUG command for target device TAP
73
// May actually be USER1, for Xilinx devices using internal BSCAN modules
74
// Can override autoprobe, or set if unable to find in BSDL files
75
int cmd_line_cmd_debug = -1;  // 0 is a valid debug command, so use -1
76
 
77
// TCP port to set up the server for GDB on
78
char *port;
79
char default_port[] = "9999";
80
 
81
// Force altera virtual jtag mode on(1) or off(-1)
82
int force_alt_vjtag = 0;
83
 
84
 
85
// Pointer to the command line arg used as the cable name
86
char * cable_name = NULL;
87
 
88
// How many jtag devices in the scan chain.  
89
unsigned int max_devices = 1;
90
 
91
////////////////////////////////////////////////////////
92
// List of IDCODES of devices on the JTAG scan chain
93
// The array is dynamically allocated in chain_commands/jtag_enumerate_chain()
94
 
95
uint32_t *idcodes = NULL;
96
int num_devices = 0;
97
 
98
 
99
const char *name_not_found = "(unknown)";
100
 
101
///////////////////////////////////////////////////////////
102
// JTAG constants
103
 
104
// Defines for Altera JTAG constants
105
#define ALTERA_MANUFACTURER_ID   0x6E
106
 
107
// Defines for Xilinx JTAG constants
108
#define XILINX_MANUFACTURER_ID   0x49
109
 
110
 
111
///////////////////////////////////////////////////
112
// Prototypes for local / helper functions
113
int get_IR_size(int devidx);
114
uint32_t get_debug_cmd(int devidx);
115
void configure_chain(void);
116
void print_usage(char *func);
117
void parse_args(int argc, char **argv);
118
void get_ir_opts(char *optstr, int *idx, int *val);
119
 
120
 
121
//////////////////////////////////////////////////////////////////////////////////////
122
/*----------------------------------------------------------------------------------*/
123
// Functions
124
/////////////////////////////////////////////////////////////////////////////////////
125
 
126
 
127
// If we are using ftdi library for usb-blaster, close the device before we leave
128
void close_ftdi_device(void)
129
{
130
#ifdef __SUPPORT_FTDI_CABLES__ 
131
        if (!strcmp(cable_name, "usbblaster_ftdi")) {
132
                printf("Free ftdi device\n");
133
                ftdi_usb_blaster_quit();
134
        }
135
#endif
136
        return;
137
}
138
 
139
// Resets JTAG, and sets up DEBUG scan chain
140
void configure_chain(void)
141
{
142
  int i;
143
  unsigned int manuf_id;
144
  uint32_t cmd;
145
  const char *name;
146
  int irlen;
147
  int err = APP_ERR_NONE;
148
 
149
  err |= tap_reset();
150
  err |= jtag_enumerate_chain(&idcodes, &num_devices);
151
 
152
  if(err != APP_ERR_NONE) {
153
    printf("Error %s enumerating JTAG chain, aborting.\n", get_err_string(err));
154
    exit(1);
155
  }
156
 
157
  printf("\nDevices on JTAG chain:\n");
158
  printf("Index\tName\t\tID Code\t\tIR Length\n");
159
  printf("----------------------------------------------------------------\n");
160
  for(i = 0; i < num_devices; i++)
161
    {
162
      if(idcodes[i] != IDCODE_INVALID) {
163
        name = bsdl_get_name(idcodes[i]);
164
        irlen = bsdl_get_IR_size(idcodes[i]);
165
        if(name == NULL)
166
          name = name_not_found;
167
      } else {
168
        name = name_not_found;
169
        irlen = -1;
170
      }
171
      printf("%d: \t%s \t0x%08X \t%d\n", i, name, idcodes[i], irlen);
172
    }
173
  printf("\n");
174
 
175
#ifdef __LEGACY__
176
// The legacy debug interface cannot support multi-device chains.  If there is more than
177
// one device on this chain, pull the cord.
178
if(num_devices > 1) {
179
        fprintf(stderr, "\n*** ERROR: The legacy debug hardware cannot support JTAG chains with\n");
180
        fprintf(stderr, "*** more than one device.  Reconnect the JTAG cable to ONLY the legacy\n");
181
        fprintf(stderr, "*** debug unit, or change your SoC to use the Advanced Debug Unit.\n");
182
        exit(0);
183
}
184
#endif
185
 
186
  if(target_dev_pos >= num_devices) {
187
    printf("ERROR:  Requested target device (%i) beyond highest device index (%i).\n", target_dev_pos, num_devices-1);
188
    exit(1);
189
  } else {
190
    printf("Target device %i, JTAG ID = 0x%08x\n", target_dev_pos, idcodes[target_dev_pos]);
191
  }
192
 
193
  manuf_id = (idcodes[target_dev_pos] >> 1) & 0x7FF;
194
 
195
  // Note that there's a little translation here, since device index 0 is actually closest to the cable data input
196
  config_set_DR_prefix_bits(num_devices - target_dev_pos - 1);  // number of devices between cable data out and target device
197
  config_set_DR_postfix_bits(target_dev_pos);  // number of devices between target device and cable data in
198
 
199
  // Set Altera Virtual JTAG mode on or off.  If not forced, then enable
200
  // if the target device has an Altera manufacturer IDCODE
201
  if(force_alt_vjtag == 1 || manuf_id == ALTERA_MANUFACTURER_ID) {
202
    int ir_size;
203
    int debug_cmd;
204
 
205
    ir_size   = cmd_line_ir_sizes[target_dev_pos].ir_length > 0 ? cmd_line_ir_sizes[target_dev_pos].ir_length : 10;
206
    debug_cmd = cmd_line_cmd_debug > 0 ? cmd_line_cmd_debug : 0x8;
207
 
208
    printf("Working on Altera Virtual JTAG device. IR size = %d, Debeg command = 0x%x\n", ir_size, debug_cmd);
209
 
210
    config_set_alt_vjtag(1);
211
    config_set_IR_size(ir_size);
212
    config_set_debug_cmd(debug_cmd);
213
 
214
  } else { // Not a Altera JTAG
215
 
216
    // Use BSDL files to determine prefix bits, postfix bits, debug command, IR length
217
    config_set_IR_size(get_IR_size(target_dev_pos));
218
 
219
    // Set the IR prefix / postfix bits
220
    int total = 0;
221
    for(i = 0; i < num_devices; i++) {
222
      if(i == target_dev_pos) {
223
        config_set_IR_postfix_bits(total);
224
        //debug("Postfix bits: %d\n", total);
225
        total = 0;
226
        continue;
227
      }
228
 
229
      total += get_IR_size(i);
230
      debug("Adding %i to total for devidx %i\n", get_IR_size(i), i);
231
    }
232
    config_set_IR_prefix_bits(total);
233
    debug("Prefix bits: %d\n", total);
234
 
235
    // Set the DEBUG command for the IR of the target device.
236
    // If this is a Xilinx device, use USER1 instead of DEBUG
237
    // If we Altera Virtual JTAG mode, we don't care.
238
    if((force_alt_vjtag == 0) &&  (manuf_id != ALTERA_MANUFACTURER_ID)) {
239
      cmd = get_debug_cmd(target_dev_pos);
240
      if(cmd == TAP_CMD_INVALID) {
241
        printf("Unable to find DEBUG command, aborting.\n");
242
        exit(1);
243
      }
244
      config_set_debug_cmd(cmd);  // This may have to be USER1 if this is a Xilinx device   
245
    }
246
 
247
    // Enable the kludge for Xilinx BSCAN, if necessary.
248
    // Safe, but slower, for non-BSCAN TAPs.
249
    if(manuf_id == XILINX_MANUFACTURER_ID) {
250
      config_set_xilinx_bscan(1);
251
    }
252
 
253
    config_set_alt_vjtag(0);
254
  }
255
 
256
  // Do a sanity test
257
  cmd = bsdl_get_idcode_cmd(idcodes[target_dev_pos]);
258
  if(cmd != TAP_CMD_INVALID) {
259
       uint32_t id_read;
260
       err |= jtag_get_idcode(cmd, &id_read);
261
 
262
       if(err != APP_ERR_NONE) {
263
         printf("Error %s checking IDCODE, aborting.\n", get_err_string(err));
264
         exit(1);
265
       }
266
 
267
       if(id_read == idcodes[target_dev_pos]) {
268
         printf("IDCODE sanity test passed, chain OK!\n");
269
       } else {
270
         printf("Warning: IDCODE sanity test failed.  Read IDCODE 0x%08X, expected 0x%08X\n", id_read, idcodes[target_dev_pos]);
271
       }
272
     }
273
 
274
  printf("Enable Debug Module\n");
275
  if(err |= tap_enable_debug_module()) {  // Select the debug unit in the TAP.
276
    printf("Error %s enabling debug module, aborting.\n", get_err_string(err));
277
    close_ftdi_device();
278
    exit(1);
279
  }
280
}
281
 
282
 
283
void print_usage(char *func)
284
{
285
  printf("JTAG connection between GDB and the SoC debug interface.\n");
286
#ifdef __LEGACY__
287
  printf("Compiled with support for the Legacy debug unit (debug_if).\n");
288
#else
289
  printf("Compiled with support for the Advanced Debug Interface (adv_dbg_if).\n");
290
#endif
291
  printf("Copyright (C) 2008 Nathan Yawn, nathan.yawn@opencores.org\n\n");
292
  printf("Usage: %s (options) [cable] (cable options)\n", func);
293
  printf("Options:\n");
294
  printf("\t-g [port]     : port number for GDB (default: 9999)\n");
295
  printf("\t-d [num]      : Set the maximum devices in the scan chain (default: 1)\n");
296
  printf("\t-x [index]    : Position of the target device in the scan chain\n");
297
  printf("\t-a [0 / 1]    : force Altera virtual JTAG mode off (0) or on (1)\n");
298
  printf("\t-l [<index>:<bits>]     : Specify length of IR register for device\n");
299
  printf("\t                <index>, override autodetect (if any)\n");
300
  printf("\t-c [hex cmd]  : Debug command for target TAP, override autodetect\n");
301
  printf("\t                (ignored for Altera targets)\n");
302
  printf("\t-v [hex cmd]  : VIR command for target TAP, override autodetect\n");
303
  printf("\t                (Altera virtual JTAG targets only)\n");
304
  printf("\t-r [hex cmd]  : VDR for target TAP, override autodetect\n");
305
  printf("\t                (Altera virtual JTAG targets only)\n");
306
  printf("\t-b [dirname]  : Add a directory to search for BSDL files\n");
307
  printf("\t-t            : perform CPU / memory self-test before starting server\n");
308
  printf("\t-h            : show help\n\n");
309
  cable_print_help();
310
}
311
 
312
 
313
void parse_args(int argc, char **argv)
314
{
315
  int c;
316
  int i;
317
  int idx, val;
318
  const char *valid_cable_args = NULL;
319
  port = NULL;
320
  force_alt_vjtag = 0;
321
  cmd_line_cmd_debug = -1;
322
 
323
  /* Parse the global arguments (if-any) */
324
  while((c = getopt(argc, argv, "+g:d:x:a:l:c:v:r:b:th")) != -1) {
325
    switch(c) {
326
    case 'h':
327
      print_usage(argv[0]);
328
      exit(0);
329
      break;
330
    case 'g':
331
      port = optarg;
332
      break;
333
    case 'd':
334
      max_devices = atoi(optarg);
335
      break;
336
    case 'x':
337
      target_dev_pos = atoi(optarg);
338
      break;
339
    case 'l':
340
      get_ir_opts(optarg, &idx, &val);        // parse the option
341
      if(num_ir_sets >= (IR_START_SETS<<reallocs)) {
342
        cmd_line_ir_sizes = (irset *) realloc(cmd_line_ir_sizes, (IR_START_SETS<<reallocs)*sizeof(irset));
343
        if(cmd_line_ir_sizes == NULL) {
344
          printf("Error: out of memory while parsing command line.  Aborting.\n");
345
          exit(1);
346
        }
347
      }
348
      cmd_line_ir_sizes[num_ir_sets].dev_index = idx;
349
      cmd_line_ir_sizes[num_ir_sets].ir_length = val;
350
      num_ir_sets++;
351
      break;
352
    case 'c':
353
      cmd_line_cmd_debug = strtoul(optarg, NULL, 16);
354
      break;
355
    case 'v':
356
      config_set_vjtag_cmd_vir(strtoul(optarg, NULL, 16));
357
      break;
358
    case 'r':
359
      config_set_vjtag_cmd_vdr(strtoul(optarg, NULL, 16));
360
      break;
361
    case 't':
362
      do_selftest = 1;
363
      break;
364
     case 'a':
365
       if(atoi(optarg) == 1)
366
        force_alt_vjtag = 1;
367
       else
368
        force_alt_vjtag = -1;
369
       break;
370
    case 'b':
371
       bsdl_add_directory(optarg);
372
      break;
373
    default:
374
      print_usage(argv[0]);
375
      exit(1);
376
    }
377
  }
378
 
379
  if(port == NULL)
380
    port = default_port;
381
 
382
  int found_cable = 0;
383
  char* start_str = argv[optind];
384
  int start_idx = optind;
385
  for(i = optind; i < argc; i++) {
386
    if(cable_select(argv[i]) == APP_ERR_NONE) {
387
      found_cable = 1;
388
      cable_name = argv[i];
389
      argv[optind] = argv[start_idx];  // swap the cable name with the other arg,
390
      argv[start_idx] = start_str;     // keep all cable opts at the end
391
      break;
392
    }
393
  }
394
 
395
 
396
  if(!found_cable) {
397
    fprintf(stderr, "No valid cable specified.\n");
398
    exit(1);
399
  }
400
 
401
  optind = start_idx+1;  // reset the parse index
402
 
403
    /* Get the cable-arguments */
404
  valid_cable_args = cable_get_args();
405
 
406
  /* Parse the remaining options for the cable.
407
   * Note that this will include unrecognized option from before the cable name.
408
   */
409
  while((c = getopt(argc, argv, valid_cable_args)) != -1) {
410
    //printf("Got cable opt %c (0x%X)\n", (char)c, c);
411
    if(c == '?') {
412
      printf("\nERROR:  Unknown cable option \'-%c\'\n\n", optopt);
413
      print_usage(argv[0]);
414
      exit(1);
415
    }
416
    else if(cable_parse_opt(c, optarg) != APP_ERR_NONE) {
417
      printf("\nERROR:  Failed to parse cable option \'-%c\' %s\n\n", (char)c, optarg);
418
      print_usage(argv[0]);
419
      exit(1);
420
    }
421
  }
422
}
423
 
424
 
425
int main(int argc,  char *argv[]) {
426
  char *s;
427
  long int serverPort;
428
 
429
  srand(getpid());
430
  bsdl_init();
431
  cmd_line_ir_sizes = (irset *) malloc(IR_START_SETS * sizeof(irset));
432
  if(cmd_line_ir_sizes == NULL) {
433
    printf("ERROR: out of memory allocating array for IR sizes.\n");
434
    return 1;
435
  }
436
 
437
  parse_args(argc, argv);
438
 
439
  if(cable_init() != APP_ERR_NONE) {
440
    printf("Failed to initialize cable \'%s\', aborting.\n", cable_name);
441
    exit(1);
442
  }
443
 
444
 
445
  /* Initialize a new connection to the or1k board, and make sure we are
446
     really connected.  */
447
  configure_chain();
448
 
449
  if(do_selftest) {
450
    // Test the connection.
451
    printf("*** Doing self-test ***\n");
452
    if(dbg_test() != APP_ERR_NONE) {
453
      printf("Self-test FAILED *** Bailing out!\n");
454
      close_ftdi_device();
455
      exit(1);
456
    }
457
    printf("*** Self-test PASSED ***\n");
458
  }
459
 
460
  /* We have a connection.  Establish server.  */
461
  serverPort = strtol(port,&s,10);
462
  if(*s) {
463
    close_ftdi_device();
464
    return -1;
465
  }
466
 
467
  rsp_init(serverPort);
468
 
469
  printf("JTAG bridge ready!\n");
470
 
471
  // This handles requests from GDB.  I'd prefer the while() loop to be in the function
472
  // with the select()/poll(), but the or1ksim rsp code (ported for use here) doesn't work 
473
  // that way, and I don't want to rework that code (to make it easier to import fixes
474
  // written for the or1ksim rsp server).  --NAY
475
  while(handle_rsp());
476
 
477
  close_ftdi_device();
478
 
479
  return 0;
480
}
481
 
482
//////////////////////////////////////////////////
483
// Helper functions
484
 
485
int get_IR_size(int devidx)
486
{
487
  int retval = -1;
488
  int i;
489
 
490
  if(idcodes[devidx] != IDCODE_INVALID) {
491
    retval = bsdl_get_IR_size(idcodes[devidx]);
492
  }
493
 
494
  // Search for this devices in the array of command line IR sizes
495
  for(i = 0; i < num_ir_sets; i++) {
496
    if(cmd_line_ir_sizes[i].dev_index == devidx) {
497
      if((retval > 0) && (retval != cmd_line_ir_sizes[i].ir_length))
498
        printf("Warning: overriding autoprobed IR length (%i) with command line value (%i) for device %i\n", retval,
499
                            cmd_line_ir_sizes[i].ir_length, devidx);
500
      retval = cmd_line_ir_sizes[i].ir_length;
501
    }
502
  }
503
 
504
  if(retval < 0) {  // Make sure we have a value
505
    printf("ERROR! Unable to autoprobe IR length for device index %i;  Must set IR size on command line. Aborting.\n", devidx);
506
    exit(1);
507
  }
508
 
509
  return retval;
510
}
511
 
512
 
513
uint32_t get_debug_cmd(int devidx)
514
{
515
  int retval = TAP_CMD_INVALID;
516
  uint32_t manuf_id = (idcodes[devidx] >> 1) & 0x7FF;
517
 
518
  if(idcodes[devidx] != IDCODE_INVALID) {
519
    if(manuf_id == XILINX_MANUFACTURER_ID) {
520
      retval = bsdl_get_user1_cmd(idcodes[devidx]);
521
      if(cmd_line_cmd_debug < 0) printf("Xilinx IDCODE, assuming internal BSCAN mode\n\t(using USER1 instead of DEBUG TAP command)\n");
522
    } else {
523
      retval = bsdl_get_debug_cmd(idcodes[devidx]);
524
    }
525
  }
526
 
527
  if(cmd_line_cmd_debug >= 0) {
528
    if(retval != TAP_CMD_INVALID) {
529
      printf("Warning: overriding autoprobe debug command (0x%X) with command line value (0x%X)\n", retval, cmd_line_cmd_debug);
530
    } else {
531
      printf("Using command-line debug command 0x%X\n", cmd_line_cmd_debug);
532
    }
533
    retval = cmd_line_cmd_debug;
534
  }
535
 
536
  if(retval == TAP_CMD_INVALID) {
537
    printf("ERROR!  Unable to find DEBUG command for device index %i, device ID 0x%0X\n", devidx, idcodes[devidx]);
538
  }
539
 
540
  return retval;
541
}
542
 
543
 
544
// Extracts two values from an option string
545
// of the form "<index>:<value>", where both args
546
// are in base 10
547
void get_ir_opts(char *optstr, int *idx, int *val)
548
{
549
  char *ptr;
550
 
551
  ptr = strstr(optstr, ":");
552
  if(ptr == NULL) {
553
    printf("Error: badly formatted IR length option.  Use format \'<index>:<value>\', without spaces, where both args are in base 10\n");
554
    exit(1);
555
  }
556
 
557
  *ptr = '\0';
558
  ptr++;  // This now points to the second (value) arg string
559
 
560
  *idx = strtoul(optstr, NULL, 10);
561
  *val = strtoul(ptr, NULL, 10);
562
  // ***CHECK FOR SUCCESS
563
}
564
 

powered by: WebSVN 2.1.0

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