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 220

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 220 jeremybenn
  /* Dummy argv array to pass arguments to or1ksim_init. Varies depending on
250
     whether an image file is specified. */
251
  int   dummy_argc;
252
  char *dummy_argv[5];
253
 
254
  dummy_argv[0] = "libsim";
255
  dummy_argv[1] = "-q";
256
  dummy_argv[2] = "-f";
257
  dummy_argv[3] = argv[1];
258
  dummy_argv[4] = argv[2];
259
 
260
  dummy_argc = 5;
261
 
262 97 jeremybenn
  /* Initialize the program. Put the initialization message afterwards, or it
263
     will get swamped by the Or1ksim header. */
264 220 jeremybenn
  if (0 == or1ksim_init (dummy_argc, dummy_argv, NULL, NULL, NULL))
265 97 jeremybenn
    {
266
      printf ("Initalization succeeded.\n");
267
    }
268
  else
269
    {
270
      printf ("Initalization failed.\n");
271
      return  1;
272
    }
273
 
274
  /* Run repeatedly for 1 millisecond until we have processed all JTAG
275
     registers */
276
  int  next_jreg = 3;                   /* Offset to next JTAG register */
277
 
278
  do
279
    {
280
      switch (or1ksim_run (1.0e-3))
281
        {
282
        case OR1KSIM_RC_OK:
283
          printf ("Execution step completed OK.\n");
284
          break;
285
 
286
        case OR1KSIM_RC_BRKPT:
287
          printf ("Execution step completed with breakpoint.\n");
288
          break;
289
 
290
        default:
291
          printf ("ERROR: run failed.\n");
292
          return  1;
293
        }
294
 
295
      /* Process the next arg appropriately. */
296
      switch (argv[next_jreg++][0])
297
        {
298
        case 'R':
299
          printf ("Resetting JTAG.\n");
300
          or1ksim_jtag_reset ();
301
          break;
302
 
303
        case 'I':
304
          printf ("Shifting instruction register.\n");
305
 
306 98 jeremybenn
          if (process_jreg ('I', next_jreg, argc, argv))
307 97 jeremybenn
            {
308 98 jeremybenn
              next_jreg += 2;
309
            }
310
          else
311
            {
312 97 jeremybenn
              return  1;                /* Something went wrong */
313
            }
314 98 jeremybenn
 
315 97 jeremybenn
          break;
316
 
317
        case 'D':
318
          printf ("Shifting data register.\n");
319
 
320 98 jeremybenn
          if (process_jreg ('D', next_jreg, argc, argv))
321 97 jeremybenn
            {
322 98 jeremybenn
              next_jreg += 2;
323
            }
324
          else
325
            {
326 97 jeremybenn
              return  1;                /* Something went wrong */
327
            }
328
 
329
          break;
330
 
331
        default:
332
          printf ("ERROR: unknown JTAG request type.\n");
333
          return  1;
334
        }
335
    }
336
  while (next_jreg < argc);
337
 
338
  /* A little longer to allow response to last upcall to be handled. */
339
  switch (or1ksim_run (1.0e-3))
340
    {
341
    case OR1KSIM_RC_OK:
342
      printf ("Execution step completed OK.\n");
343
      break;
344
 
345
    case OR1KSIM_RC_BRKPT:
346
      printf ("Execution step completed with breakpoint.\n");
347
      break;
348
 
349
    default:
350
      printf ("ERROR: run failed.\n");
351
      return  1;
352
    }
353
 
354
  printf ("Test completed successfully.\n");
355
  return  0;
356
 
357
}       /* main () */

powered by: WebSVN 2.1.0

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