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 42

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

powered by: WebSVN 2.1.0

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