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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [common/] [hw-ports.c] - Blame information for rev 578

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

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

powered by: WebSVN 2.1.0

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