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

Subversion Repositories adv_debug_sys

[/] [adv_debug_sys/] [tags/] [ADS_RELEASE_1_1_0/] [Software/] [adv_jtag_bridge/] [bsdl.c] - Blame information for rev 19

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 nyawn
/* bsdl.c - BSDL file handler for the advanced JTAG bridge
2
   Copyright(C) 2008 Nathan Yawn
3
 
4
   This program is free software; you can redistribute it and/or modify
5
   it under the terms of the GNU General Public License as published by
6
   the Free Software Foundation; either version 2 of the License, or
7
   (at your option) any later version.
8
 
9
   This program is distributed in the hope that it will be useful,
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
   GNU General Public License for more details.
13
 
14
   You should have received a copy of the GNU General Public License
15
   along with this program; if not, write to the Free Software
16
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
*/
18
 
19
#include <sys/types.h>
20
#include <string.h>
21
#include <stdio.h>
22
#include <dirent.h>
23
#include "bsdl.h"
24
#include "bsdl_parse.h"
25
 
26
 
27
#define debug(...) //fprintf(stderr, __VA_ARGS__ ) 
28
 
29
// Globals to deal with directory names
30
#define MAX_BSDL_DIRS 64  // Any more than this would take a looooong time...
31
static char *bsdl_dirs[MAX_BSDL_DIRS];
32
static int bsdl_current_dir = 0;  // We try them in reverse order
33
 
34
// Globals to hold the current, open directory
35
DIR *bsdl_open_dir = NULL;
36
 
37
// Globals to hold BSDL info
38
static bsdlinfo *bsdl_head = NULL;
39
static bsdlinfo *bsdl_tail = NULL;
40
static bsdlinfo *bsdl_last = NULL;  // optimization: pointer to the last struct we used (not necessarily the last in the linked list)
41
 
42
// Prototypes for local functions
43
bsdlinfo *get_bsdl_info(uint32_t idcode);
44
 
45
 
46
 
47
//////////////////////////////////////////////////////////////////////
48
// API for init and config
49
 
50
void bsdl_init(void)
51
{
52
  bsdl_dirs[0] = strdup("/opt/bsdl");
53
  bsdl_dirs[1] = strdup("/usr/share/bsdl");
54
  bsdl_dirs[2] = strdup("~/.bsdl");
55
  bsdl_dirs[3] = strdup(".");
56
  bsdl_current_dir = 3;
57
}
58
 
59
void bsdl_add_directory(const char *dirname)
60
{
61
  if(bsdl_current_dir >= (MAX_BSDL_DIRS-1)) {
62
    printf("Max BSDL dirs (%d) exceeded; failed to add directory %s\n", MAX_BSDL_DIRS, dirname);
63
    return;
64
  }
65
 
66
  bsdl_current_dir++;
67
  bsdl_dirs[bsdl_current_dir] = strdup(dirname);
68
}
69
 
70
 
71
///////////////////////////////////////////////////////////////////
72
// API  to get device info from BSDL files, if available
73
 
74
 
75
const char * bsdl_get_name(uint32_t idcode)
76
{
77
  bsdlinfo *info;
78
  info = get_bsdl_info(idcode);
79
  if(info != NULL)
80
    return info->name;
81
 
82
  return NULL;
83
 
84
 
85
}
86
 
87
// Return the IR length of the device with the given IDCODE,
88
// if its BSDL file is available.  Returns -1 on
89
// error, which is an invalid size.
90
 
91
int bsdl_get_IR_size(uint32_t idcode)
92
{
93
  bsdlinfo *info;
94
  info = get_bsdl_info(idcode);
95
  if(info != NULL)
96
    return info->IR_size;
97
 
98
  return -1;
99
}
100
 
101
 
102
// Returns the DEBUG command for the device with the gived IDCODE,
103
// if its BSDL file is available.  Returns 0xFFFFFFFF on error,
104
// which is as invalid command (because it's the BYPASS command)
105
uint32_t bsdl_get_debug_cmd(uint32_t idcode)
106
{
107
  bsdlinfo *info;
108
  info = get_bsdl_info(idcode);
109
  if(info != NULL)
110
    return info->cmd_debug;
111
  return TAP_CMD_INVALID;
112
}
113
 
114
// Returns the USER1 command for the device with the gived IDCODE,
115
// if its BSDL file is available.  Returns 0xFFFFFFFF on error,
116
// which is as invalid command (because it's the BYPASS command)
117
uint32_t bsdl_get_user1_cmd(uint32_t idcode)
118
{
119
  bsdlinfo *info;
120
  info = get_bsdl_info(idcode);
121
  if(info != NULL)
122
    return info->cmd_user1;
123
  return TAP_CMD_INVALID;
124
}
125
 
126
// Returns the IDCODE command for the device with the gived IDCODE,
127
// if its BSDL file is available.  Returns 0xFFFFFFFF on error,
128
// which is as invalid command (because it's the BYPASS command)
129
uint32_t bsdl_get_idcode_cmd(uint32_t idcode)
130
{
131
  bsdlinfo *info;
132
  info = get_bsdl_info(idcode);
133
  if(info != NULL)
134
    return info->cmd_idcode;
135
  return TAP_CMD_INVALID;
136
}
137
 
138
/////////////////////////////////////////////////////////////////////////////
139
// Internal routines
140
 
141
 
142
// This uses a lazy algorithm...first, search data we already have.
143
// Then, parse new files (storing all data) only until we find
144
// the data we want.
145
bsdlinfo *get_bsdl_info(uint32_t idcode)
146
{
147
  struct dirent *direntry = NULL;
148
  bsdlinfo *ptr = bsdl_head;
149
  char *c;
150
 
151
  // Check the last place we looked
152
  if(bsdl_last != NULL)
153
      if((bsdl_last->idcode & bsdl_last->idcode_mask) == (idcode & bsdl_last->idcode_mask))
154
        return bsdl_last;
155
 
156
  // First, search through the info already parsed
157
  while(ptr != NULL)
158
    {
159
      if((ptr->idcode & ptr->idcode_mask) == (idcode & ptr->idcode_mask))
160
        {
161
          bsdl_last = ptr;
162
          return ptr;
163
        }
164
      ptr = ptr->next;
165
    }
166
 
167
  // Parse files until we get the IDCODE we want
168
  while(1)
169
    {
170
      // Find and open a valid directory 
171
      while(bsdl_open_dir == NULL)
172
        {
173
          if(bsdl_current_dir < 0)
174
            return NULL;  // There are no more directories to check
175
          debug("Trying BSDL dir \'%s\'\n", bsdl_dirs[bsdl_current_dir]);
176
          bsdl_open_dir = opendir(bsdl_dirs[bsdl_current_dir]);
177
          if((bsdl_open_dir == NULL) && (bsdl_current_dir > 2))  // Don't warn if default dirs not found
178
            printf("Warning: unable to open BSDL directory \'%s\'\n", bsdl_dirs[bsdl_current_dir]);
179
          bsdl_current_dir--;
180
          direntry = NULL;
181
        }
182
 
183
      // Find a BSDL file
184
      do
185
        {
186
          direntry = readdir(bsdl_open_dir);
187
          if(direntry == NULL)
188
            {  // We've exhausted this directory
189
              closedir(bsdl_open_dir);
190
              bsdl_open_dir = NULL;
191
              break;
192
            }
193
 
194
          // *** If a subdirectory, continue!!
195
 
196
          // Check if it's a BSDL file: .bsd, .bsdl, .BSD, .BSDL
197
          debug("Checking file \'%s\'\n", direntry->d_name);
198
          c = strrchr(direntry->d_name, '.');
199
          debug("File extension is \'%s\'\n", c);
200
          if(c == NULL)
201
            continue;
202
          if(!strcmp(c, ".bsd") || !strcmp(c, ".bsdl") || !strcmp(c, ".BSD") || !strcmp(c, ".BSDL"))
203
            break;
204
 
205
        }
206
      while(1);
207
 
208
      if(direntry == NULL)  // We need a new directory
209
        continue;
210
 
211
      // Parse the BSDL file we found
212
      debug("Parsing file \'%s\'\n", direntry->d_name);
213
      ptr = parse_extract_values(direntry->d_name);
214
 
215
      // If we got good data...
216
      if(ptr != NULL)
217
        {
218
          // Store the values...
219
          if(bsdl_head == NULL) {
220
            bsdl_head = ptr;
221
            bsdl_tail = ptr;
222
          } else {
223
            bsdl_tail->next = ptr;
224
            bsdl_tail = ptr;
225
          }
226
 
227
          // ...and return if we got an IDCODE match
228
          if((ptr->idcode & ptr->idcode_mask) == (idcode & ptr->idcode_mask)) {
229
            bsdl_last = ptr;
230
            return ptr;
231
          }
232
        }
233
    } // while(1), parse files until we find a match or run out of dirs / files
234
 
235
 
236
  // If no more files to parse and not found, return NULL
237
  return NULL;
238
}

powered by: WebSVN 2.1.0

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