2 Copyright (C) 1998, 2007, 2008, 2009, 2010, 2011
3 Free Software Foundation, Inc.
4 Contributed by Andrew Cagney and Cygnus Solutions.
6 This file is part of GDB, the GNU debugger.
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.
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.
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/>. */
44 struct hw_port_edge
*next
;
45 object_disposition disposition
;
49 hw_port_event_method
*to_port_event
;
50 const struct hw_port_descriptor
*ports
;
51 struct hw_port_edge
*edges
;
54 const struct hw_port_descriptor empty_hw_ports
[] = {
59 panic_hw_port_event (struct hw
*me
,
65 hw_abort (me
, "no port method");
69 create_hw_port_data (struct hw
*me
)
71 me
->ports_of_hw
= HW_ZALLOC (me
, struct hw_port_data
);
72 set_hw_port_event (me
, panic_hw_port_event
);
73 set_hw_ports (me
, empty_hw_ports
);
77 delete_hw_port_data (struct hw
*me
)
79 hw_free (me
, me
->ports_of_hw
);
80 me
->ports_of_hw
= NULL
;
84 set_hw_ports (struct hw
*me
,
85 const struct hw_port_descriptor ports
[])
87 me
->ports_of_hw
->ports
= ports
;
91 set_hw_port_event (struct hw
*me
,
92 hw_port_event_method
*port_event
)
94 me
->ports_of_hw
->to_port_event
= port_event
;
99 attach_hw_port_edge (struct hw
*me
,
100 struct hw_port_edge
**list
,
104 object_disposition disposition
)
106 struct hw_port_edge
*new_edge
= HW_ZALLOC (me
, struct hw_port_edge
);
107 new_edge
->my_port
= my_port
;
108 new_edge
->dest
= dest
;
109 new_edge
->dest_port
= dest_port
;
110 new_edge
->next
= *list
;
111 new_edge
->disposition
= disposition
;
117 detach_hw_port_edge (struct hw
*me
,
118 struct hw_port_edge
**list
,
123 while (*list
!= NULL
)
125 struct hw_port_edge
*old_edge
= *list
;
126 if (old_edge
->dest
== dest
127 && old_edge
->dest_port
== dest_port
128 && old_edge
->my_port
== my_port
)
130 if (old_edge
->disposition
== permenant_object
)
131 hw_abort (me
, "attempt to delete permenant port edge");
132 *list
= old_edge
->next
;
133 hw_free (me
, old_edge
);
137 hw_abort (me
, "attempt to delete unattached port");
143 clean_hw_port_edges (struct hw_port_edge
**list
)
145 while (*list
!= NULL
)
147 struct hw_port_edge
*old_edge
= *list
;
148 switch (old_edge
->disposition
)
150 case permenant_object
:
151 list
= &old_edge
->next
;
153 case temporary_object
:
154 *list
= old_edge
->next
;
155 hw_free (me
, old_edge
);
166 hw_port_event (struct hw
*me
,
170 int found_an_edge
= 0;
171 struct hw_port_edge
*edge
;
172 /* device's lines directly connected */
173 for (edge
= me
->ports_of_hw
->edges
;
177 if (edge
->my_port
== my_port
)
179 edge
->dest
->ports_of_hw
->to_port_event (edge
->dest
,
188 hw_abort (me
, "No edge for port %d", my_port
);
193 hw_port_attach (struct hw
*me
,
197 object_disposition disposition
)
199 attach_hw_port_edge (me
,
200 &me
->ports_of_hw
->edges
,
209 hw_port_detach (struct hw
*me
,
214 detach_hw_port_edge (me
,
215 &me
->ports_of_hw
->edges
,
223 hw_port_traverse (struct hw
*me
,
224 hw_port_traverse_function
*handler
,
227 struct hw_port_edge
*port_edge
;
228 for (port_edge
= me
->ports_of_hw
->edges
;
230 port_edge
= port_edge
->next
)
232 handler (me
, port_edge
->my_port
,
233 port_edge
->dest
, port_edge
->dest_port
,
240 hw_port_decode (struct hw
*me
,
241 const char *port_name
,
242 port_direction direction
)
244 if (port_name
== NULL
|| port_name
[0] == '\0')
246 if (isdigit(port_name
[0]))
248 return strtoul (port_name
, NULL
, 0);
252 const struct hw_port_descriptor
*ports
=
253 me
->ports_of_hw
->ports
;
256 while (ports
->name
!= NULL
)
258 if (ports
->direction
== bidirect_port
259 || ports
->direction
== direction
)
261 if (ports
->nr_ports
> 0)
263 int len
= strlen (ports
->name
);
264 if (strncmp (port_name
, ports
->name
, len
) == 0)
266 if (port_name
[len
] == '\0')
267 return ports
->number
;
268 else if(isdigit (port_name
[len
]))
270 int port
= (ports
->number
271 + strtoul (&port_name
[len
], NULL
, 0));
272 if (port
>= ports
->number
+ ports
->nr_ports
)
274 "Port %s out of range",
280 else if (strcmp (port_name
, ports
->name
) == 0)
281 return ports
->number
;
287 hw_abort (me
, "Unreconized port %s", port_name
);
293 hw_port_encode (struct hw
*me
,
297 port_direction direction
)
299 const struct hw_port_descriptor
*ports
= NULL
;
300 ports
= me
->ports_of_hw
->ports
;
302 while (ports
->name
!= NULL
)
304 if (ports
->direction
== bidirect_port
305 || ports
->direction
== direction
)
307 if (ports
->nr_ports
> 0)
309 if (port_number
>= ports
->number
310 && port_number
< ports
->number
+ ports
->nr_ports
)
312 strcpy (buf
, ports
->name
);
313 sprintf (buf
+ strlen(buf
), "%d", port_number
- ports
->number
);
314 if (strlen (buf
) >= sizeof_buf
)
315 hw_abort (me
, "hw_port_encode: buffer overflow");
321 if (ports
->number
== port_number
)
323 if (strlen(ports
->name
) >= sizeof_buf
)
324 hw_abort (me
, "hw_port_encode: buffer overflow");
325 strcpy(buf
, ports
->name
);
333 sprintf (buf
, "%d", port_number
);
334 if (strlen(buf
) >= sizeof_buf
)
335 hw_abort (me
, "hw_port_encode: buffer overflow");