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