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

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

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

powered by: WebSVN 2.1.0

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