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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [sim/] [common/] [hw-ports.c] - Blame information for rev 855

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

Line No. Rev Author Line
1 330 jeremybenn
/* Hardware ports.
2
   Copyright (C) 1998, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
3
   Contributed by Andrew Cagney and Cygnus Solutions.
4
 
5
This file is part of GDB, the GNU debugger.
6
 
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 3 of the License, or
10
(at your option) any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
 
20
 
21
#include "hw-main.h"
22
#include "hw-base.h"
23
 
24
#ifdef HAVE_STDLIB_H
25
#include <stdlib.h>
26
#endif
27
 
28
#ifdef HAVE_STRING_H
29
#include <string.h>
30
#else
31
#ifdef HAVE_STRINGS_H
32
#include <strings.h>
33
#endif
34
#endif
35
 
36
#include <ctype.h>
37
 
38
 
39
struct hw_port_edge {
40
  int my_port;
41
  struct hw *dest;
42
  int dest_port;
43
  struct hw_port_edge *next;
44
  object_disposition disposition;
45
};
46
 
47
struct hw_port_data {
48
  hw_port_event_method *to_port_event;
49
  const struct hw_port_descriptor *ports;
50
  struct hw_port_edge *edges;
51
};
52
 
53
const struct hw_port_descriptor empty_hw_ports[] = {
54
  { NULL, 0, 0, 0 },
55
};
56
 
57
static void
58
panic_hw_port_event (struct hw *me,
59
                     int my_port,
60
                     struct hw *source,
61
                     int source_port,
62
                     int level)
63
{
64
  hw_abort (me, "no port method");
65
}
66
 
67
void
68
create_hw_port_data (struct hw *me)
69
{
70
  me->ports_of_hw = HW_ZALLOC (me, struct hw_port_data);
71
  set_hw_port_event (me, panic_hw_port_event);
72
  set_hw_ports (me, empty_hw_ports);
73
}
74
 
75
void
76
delete_hw_port_data (struct hw *me)
77
{
78
  hw_free (me, me->ports_of_hw);
79
  me->ports_of_hw = NULL;
80
}
81
 
82
void
83
set_hw_ports (struct hw *me,
84
              const struct hw_port_descriptor ports[])
85
{
86
  me->ports_of_hw->ports = ports;
87
}
88
 
89
void
90
set_hw_port_event (struct hw *me,
91
                   hw_port_event_method *port_event)
92
{
93
  me->ports_of_hw->to_port_event = port_event;
94
}
95
 
96
 
97
static void
98
attach_hw_port_edge (struct hw *me,
99
                     struct hw_port_edge **list,
100
                     int my_port,
101
                     struct hw *dest,
102
                     int dest_port,
103
                     object_disposition disposition)
104
{
105
  struct hw_port_edge *new_edge = HW_ZALLOC (me, struct hw_port_edge);
106
  new_edge->my_port = my_port;
107
  new_edge->dest = dest;
108
  new_edge->dest_port = dest_port;
109
  new_edge->next = *list;
110
  new_edge->disposition = disposition;
111
  *list = new_edge;
112
}
113
 
114
 
115
static void
116
detach_hw_port_edge (struct hw *me,
117
                     struct hw_port_edge **list,
118
                     int my_port,
119
                     struct hw *dest,
120
                     int dest_port)
121
{
122
  while (*list != NULL)
123
    {
124
      struct hw_port_edge *old_edge = *list;
125
      if (old_edge->dest == dest
126
          && old_edge->dest_port == dest_port
127
          && old_edge->my_port == my_port)
128
        {
129
          if (old_edge->disposition == permenant_object)
130
            hw_abort (me, "attempt to delete permenant port edge");
131
          *list = old_edge->next;
132
          hw_free (me, old_edge);
133
          return;
134
        }
135
    }
136
  hw_abort (me, "attempt to delete unattached port");
137
}
138
 
139
 
140
#if 0
141
static void
142
clean_hw_port_edges (struct hw_port_edge **list)
143
{
144
  while (*list != NULL)
145
    {
146
      struct hw_port_edge *old_edge = *list;
147
      switch (old_edge->disposition)
148
        {
149
        case permenant_object:
150
          list = &old_edge->next;
151
          break;
152
        case temporary_object:
153
          *list = old_edge->next;
154
          hw_free (me, old_edge);
155
          break;
156
        }
157
    }
158
}
159
#endif
160
 
161
 
162
/* Ports: */
163
 
164
void
165
hw_port_event (struct hw *me,
166
               int my_port,
167
               int level)
168
{
169
  int found_an_edge = 0;
170
  struct hw_port_edge *edge;
171
  /* device's lines directly connected */
172
  for (edge = me->ports_of_hw->edges;
173
       edge != NULL;
174
       edge = edge->next)
175
    {
176
      if (edge->my_port == my_port)
177
        {
178
          edge->dest->ports_of_hw->to_port_event (edge->dest,
179
                                                  edge->dest_port,
180
                                                  me,
181
                                                  my_port,
182
                                                  level);
183
          found_an_edge = 1;
184
        }
185
    }
186
  if (!found_an_edge)
187
    hw_abort (me, "No edge for port %d", my_port);
188
}
189
 
190
 
191
void
192
hw_port_attach (struct hw *me,
193
                int my_port,
194
                struct hw *dest,
195
                int dest_port,
196
                object_disposition disposition)
197
{
198
  attach_hw_port_edge (me,
199
                       &me->ports_of_hw->edges,
200
                       my_port,
201
                       dest,
202
                       dest_port,
203
                       disposition);
204
}
205
 
206
 
207
void
208
hw_port_detach (struct hw *me,
209
                int my_port,
210
                struct hw *dest,
211
                int dest_port)
212
{
213
  detach_hw_port_edge (me,
214
                       &me->ports_of_hw->edges,
215
                       my_port,
216
                       dest,
217
                       dest_port);
218
}
219
 
220
 
221
void
222
hw_port_traverse (struct hw *me,
223
                  hw_port_traverse_function *handler,
224
                  void *data)
225
{
226
  struct hw_port_edge *port_edge;
227
  for (port_edge = me->ports_of_hw->edges;
228
       port_edge != NULL;
229
       port_edge = port_edge->next)
230
    {
231
      handler (me, port_edge->my_port,
232
               port_edge->dest, port_edge->dest_port,
233
               data);
234
    }
235
}
236
 
237
 
238
int
239
hw_port_decode (struct hw *me,
240
                const char *port_name,
241
                port_direction direction)
242
{
243
  if (port_name == NULL || port_name[0] == '\0')
244
    return 0;
245
  if (isdigit(port_name[0]))
246
    {
247
      return strtoul (port_name, NULL, 0);
248
    }
249
  else
250
    {
251
      const struct hw_port_descriptor *ports =
252
        me->ports_of_hw->ports;
253
      if (ports != NULL)
254
        {
255
          while (ports->name != NULL)
256
            {
257
              if (ports->direction == bidirect_port
258
                  || ports->direction == direction)
259
                {
260
                  if (ports->nr_ports > 0)
261
                    {
262
                      int len = strlen (ports->name);
263
                      if (strncmp (port_name, ports->name, len) == 0)
264
                        {
265
                          if (port_name[len] == '\0')
266
                            return ports->number;
267
                          else if(isdigit (port_name[len]))
268
                            {
269
                              int port = (ports->number
270
                                          + strtoul (&port_name[len], NULL, 0));
271
                              if (port >= ports->number + ports->nr_ports)
272
                                hw_abort (me,
273
                                          "Port %s out of range",
274
                                          port_name);
275
                              return port;
276
                            }
277
                        }
278
                    }
279
                  else if (strcmp (port_name, ports->name) == 0)
280
                    return ports->number;
281
                }
282
              ports++;
283
            }
284
        }
285
    }
286
  hw_abort (me, "Unreconized port %s", port_name);
287
  return 0;
288
}
289
 
290
 
291
int
292
hw_port_encode (struct hw *me,
293
                int port_number,
294
                char *buf,
295
                int sizeof_buf,
296
                port_direction direction)
297
{
298
  const struct hw_port_descriptor *ports = NULL;
299
  ports = me->ports_of_hw->ports;
300
  if (ports != NULL) {
301
    while (ports->name != NULL)
302
      {
303
        if (ports->direction == bidirect_port
304
            || ports->direction == direction)
305
          {
306
            if (ports->nr_ports > 0)
307
              {
308
                if (port_number >= ports->number
309
                    && port_number < ports->number + ports->nr_ports)
310
                  {
311
                    strcpy (buf, ports->name);
312
                    sprintf (buf + strlen(buf), "%d", port_number - ports->number);
313
                    if (strlen (buf) >= sizeof_buf)
314
                      hw_abort (me, "hw_port_encode: buffer overflow");
315
                    return strlen (buf);
316
                  }
317
              }
318
            else
319
              {
320
                if (ports->number == port_number)
321
                  {
322
                    if (strlen(ports->name) >= sizeof_buf)
323
                      hw_abort (me, "hw_port_encode: buffer overflow");
324
                    strcpy(buf, ports->name);
325
                    return strlen(buf);
326
                  }
327
              }
328
          }
329
        ports++;
330
      }
331
  }
332
  sprintf (buf, "%d", port_number);
333
  if (strlen(buf) >= sizeof_buf)
334
    hw_abort (me, "hw_port_encode: buffer overflow");
335
  return strlen(buf);
336
}

powered by: WebSVN 2.1.0

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