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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [testsuite/] [test-code/] [lib-jtag/] [lib-jtag.c] - Blame information for rev 98

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

Line No. Rev Author Line
1 97 jeremybenn
/* lib-jtag.c. Basic test of Or1ksim library JTAG interface.
2
 
3
   Copyright (C) 1999-2006 OpenCores
4
   Copyright (C) 2010 Embecosm Limited
5
 
6
   Contributors various OpenCores participants
7
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
8
 
9
   This file is part of OpenRISC 1000 Architectural Simulator.
10
 
11
   This program is free software; you can redistribute it and/or modify it
12
   under the terms of the GNU General Public License as published by the Free
13
   Software Foundation; either version 3 of the License, or (at your option)
14
   any later version.
15
 
16
   This program is distributed in the hope that it will be useful, but WITHOUT
17
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
19
   more details.
20
 
21
   You should have received a copy of the GNU General Public License along
22
   with this program.  If not, see <http:  www.gnu.org/licenses/>.  */
23
 
24
/* ----------------------------------------------------------------------------
25
   This code is commented throughout for use with Doxygen.
26
   --------------------------------------------------------------------------*/
27
 
28
#include <errno.h>
29
#include <stddef.h>
30
#include <stdlib.h>
31
#include <stdio.h>
32
#include <string.h>
33
 
34
#include "or1ksim.h"
35
 
36
 
37
/* --------------------------------------------------------------------------*/
38
/*!Dump a JTAG register
39
 
40
   Prefix with the supplied string and add a newline afterwards.
41
 
42
   @param[in] prefix     Prefix string to print out
43
   @param[in] jreg       The JTAG register
44
   @param[in] num_bytes  The number of bytes in the register                 */
45
/* --------------------------------------------------------------------------*/
46
static void
47
dump_jreg (const char    *prefix,
48
           unsigned char *jreg,
49
           int            num_bytes)
50
{
51
  int  i;
52
 
53
  printf ("%s: ", prefix);
54
 
55
  /* Dump each byte in turn */
56
  for (i = num_bytes - 1; i >=0; i--)
57
    {
58
      printf ("%02x", jreg[i]);
59
    }
60
 
61
  printf ("\n");
62
 
63
}       /* dump_jreg () */
64
 
65
 
66
/* --------------------------------------------------------------------------*/
67
/*!Convert a hex char into its value.
68
 
69
   @param[in] c  The char to convert
70
 
71
   @return  The value represented by the char, or -1 if it's not a valid
72
            char.                                                            */
73
/* --------------------------------------------------------------------------*/
74
static int
75
hexch2val (char  c)
76
{
77
  switch (c)
78
    {
79
    case '0': return  0;
80
    case '1': return  1;
81
    case '2': return  2;
82
    case '3': return  3;
83
    case '4': return  4;
84
    case '5': return  5;
85
    case '6': return  6;
86
    case '7': return  7;
87
    case '8': return  8;
88
    case '9': return  9;
89
 
90
    case 'a': case 'A': return 10;
91
    case 'b': case 'B': return 11;
92
    case 'c': case 'C': return 12;
93
    case 'd': case 'D': return 13;
94
    case 'e': case 'E': return 14;
95
    case 'f': case 'F': return 15;
96
 
97
    default:
98
      return  -1;
99
    }
100
}       /* hexch2val () */
101
 
102
 
103
/* --------------------------------------------------------------------------*/
104
/*!Shift a JTAG register.
105
 
106
   Almost all this code is common between the instruction and data
107
   registers. All that varies is the library function called and the error
108
   message if anything goes wrong. So we common things up here.
109
 
110
   @param[in] type       'D' if this is a data register, 'I' if an instruction
111
                         register.
112 98 jeremybenn
   @param[in] next_jreg  Offset into argv of the next JTAG register length
113
                         field.
114 97 jeremybenn
   @param[in] argc       argc from the main program (for checking next_jref).
115
   @param[in] argv       argv from the main program.
116
 
117
   @return  1 (TRUE) on success, 0 (FALSE) on failure.                       */
118
/* --------------------------------------------------------------------------*/
119
static int
120
process_jreg (const char  type,
121
              int         next_jreg,
122
              int         argc,
123
              char       *argv[])
124
{
125
  const char *long_name = ('D' == type) ? "data" : "instruction";
126
 
127 98 jeremybenn
  /* Do we have the arg (length and value)? */
128
  if ((next_jreg + 1) > argc)
129 97 jeremybenn
    {
130
      printf ("ERROR: no %s register found.\n", long_name);
131
      return  0;
132
    }
133
 
134 98 jeremybenn
  /* Get the length field */
135
  int  bit_len = strtol (argv[next_jreg++], NULL, 0);
136
 
137
  if (0 == bit_len)
138
    {
139
      printf ("ERROR: invalid register length\n");
140
      return  0;
141
    }
142
 
143 97 jeremybenn
  /* Is the reg an exact number of bytes? */
144
  char *hex_str   = argv[next_jreg];
145
  int   num_chars = strlen (hex_str);
146 98 jeremybenn
  int   num_bytes = (bit_len + 7) / 8;
147 97 jeremybenn
 
148 98 jeremybenn
  if (num_chars > (2 * num_bytes))
149 97 jeremybenn
    {
150 98 jeremybenn
      printf ("Warning: Too many digits for register: truncated.\n");
151 97 jeremybenn
    }
152
 
153 98 jeremybenn
  /* Allocate and clear space */
154
  unsigned char *jreg = malloc (num_bytes);
155 97 jeremybenn
 
156
  if (NULL == jreg)
157
    {
158
      printf ("ERROR: malloc for %s register failed.\n", long_name);
159
      return  0;
160
    }
161
 
162 98 jeremybenn
  memset (jreg, 0, num_bytes);
163
 
164 97 jeremybenn
  /* Initialize the register. The hex presentation is MS byte of the string on
165
     the left (i.e. at offset 0), but the internal representation is LS byte
166
     at the lowest address. */
167
  int  i;
168
 
169 98 jeremybenn
  for (i = num_chars - 1; i >= 0; i--)
170 97 jeremybenn
    {
171 98 jeremybenn
      int  dig_num  = num_chars - 1 - i;        /* Which digit */
172
      int  dig_val  = hexch2val (hex_str[i]);
173 97 jeremybenn
 
174 98 jeremybenn
      if (dig_val < 0)
175 97 jeremybenn
        {
176 98 jeremybenn
          printf ("ERROR: %c not valid hex digit.\n", hex_str[i]);
177
          free (jreg);
178
          return  0;
179
        }
180 97 jeremybenn
 
181 98 jeremybenn
      /* MS digits are the odd numbered ones */
182
      jreg[dig_num / 2] |= (0 == (dig_num % 2)) ? dig_val : dig_val << 4;
183 97 jeremybenn
    }
184
 
185
  /* Note what we are doing */
186
  dump_jreg ("  shifting in", jreg, num_bytes);
187
 
188
  double  t;
189
 
190
  if ('D' == type)
191
    {
192 98 jeremybenn
      t = or1ksim_jtag_shift_dr (jreg, bit_len);
193 97 jeremybenn
    }
194
  else
195
    {
196 98 jeremybenn
      t = or1ksim_jtag_shift_ir (jreg, bit_len);
197 97 jeremybenn
    }
198
 
199
  dump_jreg ("  shifted out", jreg, num_bytes);
200
  printf ("  time taken %.12fs\n", t);
201
 
202
  free (jreg);
203
  return  1;                    /* Completed successfully */
204
 
205
}       /* process_jreg () */
206
 
207
 
208
/* --------------------------------------------------------------------------*/
209
/*!Main program
210
 
211
   Build an or1ksim program using the library which loads a program and config
212
   from the command line which will drive JTAG.
213
 
214 98 jeremybenn
   lib-jtag <config-file> <image> <jtype> [<bitlen> <reg>]
215
            [<jtype> [<bitlen> <reg>]] ...
216 97 jeremybenn
 
217
   - config-file  An Or1ksim configuration file.
218
   - image        A OpenRISC binary image to load into Or1ksim
219
   - jtype        One of 'R' (JTAG reset), 'I' (JTAG instruction register) or
220
                  'D' (JTAG data register).
221 98 jeremybenn
   - bitlen       If jtype is 'D' or 'I', the number of bits in the JTAG
222
                  register.
223 97 jeremybenn
   - reg          If jtype is 'D' or 'I', a JTAG register specified in
224 98 jeremybenn
                  hex. Specified LS digit on the right, and leading zeros may
225
                  be omitted.
226 97 jeremybenn
 
227
   The target program is run in bursts of 1ms execution, and the type of
228
   return (OK, hit breakpoint) noted. Between each burst of execution, the
229
   next register is submitted to the corresponding Or1ksim JTAG interface
230
   function, and the resulting register (for 'I' and 'D') noted.
231
 
232
   @param[in] argc  Number of elements in argv
233
   @param[in] argv  Vector of program name and arguments
234
 
235
   @return  Return code for the program.                                     */
236
/* --------------------------------------------------------------------------*/
237
int
238
main (int   argc,
239
      char *argv[])
240
{
241
  /* Check we have minimum number of args. */
242
  if (argc < 4)
243
    {
244 98 jeremybenn
      printf ("usage: lib-jtag <config-file> <image> <jtype> [<bitlen> <reg>] "
245
              "[<jtype> [<bitlen> <reg>]] ...\n");
246 97 jeremybenn
      return  1;
247
    }
248
 
249
  /* Initialize the program. Put the initialization message afterwards, or it
250
     will get swamped by the Or1ksim header. */
251
  if (0 == or1ksim_init (argv[1], argv[2], NULL, NULL, NULL))
252
    {
253
      printf ("Initalization succeeded.\n");
254
    }
255
  else
256
    {
257
      printf ("Initalization failed.\n");
258
      return  1;
259
    }
260
 
261
  /* Run repeatedly for 1 millisecond until we have processed all JTAG
262
     registers */
263
  int  next_jreg = 3;                   /* Offset to next JTAG register */
264
 
265
  do
266
    {
267
      switch (or1ksim_run (1.0e-3))
268
        {
269
        case OR1KSIM_RC_OK:
270
          printf ("Execution step completed OK.\n");
271
          break;
272
 
273
        case OR1KSIM_RC_BRKPT:
274
          printf ("Execution step completed with breakpoint.\n");
275
          break;
276
 
277
        default:
278
          printf ("ERROR: run failed.\n");
279
          return  1;
280
        }
281
 
282
      /* Process the next arg appropriately. */
283
      switch (argv[next_jreg++][0])
284
        {
285
        case 'R':
286
          printf ("Resetting JTAG.\n");
287
          or1ksim_jtag_reset ();
288
          break;
289
 
290
        case 'I':
291
          printf ("Shifting instruction register.\n");
292
 
293 98 jeremybenn
          if (process_jreg ('I', next_jreg, argc, argv))
294 97 jeremybenn
            {
295 98 jeremybenn
              next_jreg += 2;
296
            }
297
          else
298
            {
299 97 jeremybenn
              return  1;                /* Something went wrong */
300
            }
301 98 jeremybenn
 
302 97 jeremybenn
          break;
303
 
304
        case 'D':
305
          printf ("Shifting data register.\n");
306
 
307 98 jeremybenn
          if (process_jreg ('D', next_jreg, argc, argv))
308 97 jeremybenn
            {
309 98 jeremybenn
              next_jreg += 2;
310
            }
311
          else
312
            {
313 97 jeremybenn
              return  1;                /* Something went wrong */
314
            }
315
 
316
          break;
317
 
318
        default:
319
          printf ("ERROR: unknown JTAG request type.\n");
320
          return  1;
321
        }
322
    }
323
  while (next_jreg < argc);
324
 
325
  /* A little longer to allow response to last upcall to be handled. */
326
  switch (or1ksim_run (1.0e-3))
327
    {
328
    case OR1KSIM_RC_OK:
329
      printf ("Execution step completed OK.\n");
330
      break;
331
 
332
    case OR1KSIM_RC_BRKPT:
333
      printf ("Execution step completed with breakpoint.\n");
334
      break;
335
 
336
    default:
337
      printf ("ERROR: run failed.\n");
338
      return  1;
339
    }
340
 
341
  printf ("Test completed successfully.\n");
342
  return  0;
343
 
344
}       /* main () */

powered by: WebSVN 2.1.0

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