sim: fix func call style (space before paren)
[deliverable/binutils-gdb.git] / sim / common / hw-ports.c
1 /* Hardware ports.
2 Copyright (C) 1998, 2007, 2008, 2009, 2010, 2011
3 Free Software Foundation, Inc.
4 Contributed by Andrew Cagney and Cygnus Solutions.
5
6 This file is part of GDB, the GNU debugger.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
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
40 struct hw_port_edge
41 {
42 int my_port;
43 struct hw *dest;
44 int dest_port;
45 struct hw_port_edge *next;
46 object_disposition disposition;
47 };
48
49 struct hw_port_data
50 {
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 {
58 { NULL, 0, 0, 0 },
59 };
60
61 static void
62 panic_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
71 void
72 create_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
79 void
80 delete_hw_port_data (struct hw *me)
81 {
82 hw_free (me, me->ports_of_hw);
83 me->ports_of_hw = NULL;
84 }
85
86 void
87 set_hw_ports (struct hw *me,
88 const struct hw_port_descriptor ports[])
89 {
90 me->ports_of_hw->ports = ports;
91 }
92
93 void
94 set_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
101 static void
102 attach_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
119 static void
120 detach_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
145 static void
146 clean_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
168 void
169 hw_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
195 void
196 hw_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
211 void
212 hw_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
225 void
226 hw_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
242 int
243 hw_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;
249 if (isdigit (port_name[0]))
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;
257 if (ports != NULL)
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;
271 else if (isdigit (port_name[len]))
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
295 int
296 hw_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);
316 sprintf (buf + strlen (buf), "%d", port_number - ports->number);
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 {
326 if (strlen (ports->name) >= sizeof_buf)
327 hw_abort (me, "hw_port_encode: buffer overflow");
328 strcpy (buf, ports->name);
329 return strlen (buf);
330 }
331 }
332 }
333 ports++;
334 }
335 }
336 sprintf (buf, "%d", port_number);
337 if (strlen (buf) >= sizeof_buf)
338 hw_abort (me, "hw_port_encode: buffer overflow");
339 return strlen (buf);
340 }
This page took 0.036292 seconds and 4 git commands to generate.