2 Copyright (C) 1998, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
3 Contributed by Andrew Cagney and Cygnus Solutions.
5 This file is part of GDB, the GNU debugger.
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.
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.
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/>. */
43 struct hw_port_edge
*next
;
44 object_disposition disposition
;
48 hw_port_event_method
*to_port_event
;
49 const struct hw_port_descriptor
*ports
;
50 struct hw_port_edge
*edges
;
53 const struct hw_port_descriptor empty_hw_ports
[] = {
58 panic_hw_port_event (struct hw
*me
,
64 hw_abort (me
, "no port method");
68 create_hw_port_data (struct hw
*me
)
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
);
76 delete_hw_port_data (struct hw
*me
)
78 hw_free (me
, me
->ports_of_hw
);
79 me
->ports_of_hw
= NULL
;
83 set_hw_ports (struct hw
*me
,
84 const struct hw_port_descriptor ports
[])
86 me
->ports_of_hw
->ports
= ports
;
90 set_hw_port_event (struct hw
*me
,
91 hw_port_event_method
*port_event
)
93 me
->ports_of_hw
->to_port_event
= port_event
;
98 attach_hw_port_edge (struct hw
*me
,
99 struct hw_port_edge
**list
,
103 object_disposition disposition
)
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
;
116 detach_hw_port_edge (struct hw
*me
,
117 struct hw_port_edge
**list
,
122 while (*list
!= NULL
)
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
)
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
);
136 hw_abort (me
, "attempt to delete unattached port");
142 clean_hw_port_edges (struct hw_port_edge
**list
)
144 while (*list
!= NULL
)
146 struct hw_port_edge
*old_edge
= *list
;
147 switch (old_edge
->disposition
)
149 case permenant_object
:
150 list
= &old_edge
->next
;
152 case temporary_object
:
153 *list
= old_edge
->next
;
154 hw_free (me
, old_edge
);
165 hw_port_event (struct hw
*me
,
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
;
176 if (edge
->my_port
== my_port
)
178 edge
->dest
->ports_of_hw
->to_port_event (edge
->dest
,
187 hw_abort (me
, "No edge for port %d", my_port
);
192 hw_port_attach (struct hw
*me
,
196 object_disposition disposition
)
198 attach_hw_port_edge (me
,
199 &me
->ports_of_hw
->edges
,
208 hw_port_detach (struct hw
*me
,
213 detach_hw_port_edge (me
,
214 &me
->ports_of_hw
->edges
,
222 hw_port_traverse (struct hw
*me
,
223 hw_port_traverse_function
*handler
,
226 struct hw_port_edge
*port_edge
;
227 for (port_edge
= me
->ports_of_hw
->edges
;
229 port_edge
= port_edge
->next
)
231 handler (me
, port_edge
->my_port
,
232 port_edge
->dest
, port_edge
->dest_port
,
239 hw_port_decode (struct hw
*me
,
240 const char *port_name
,
241 port_direction direction
)
243 if (port_name
== NULL
|| port_name
[0] == '\0')
245 if (isdigit(port_name
[0]))
247 return strtoul (port_name
, NULL
, 0);
251 const struct hw_port_descriptor
*ports
=
252 me
->ports_of_hw
->ports
;
255 while (ports
->name
!= NULL
)
257 if (ports
->direction
== bidirect_port
258 || ports
->direction
== direction
)
260 if (ports
->nr_ports
> 0)
262 int len
= strlen (ports
->name
);
263 if (strncmp (port_name
, ports
->name
, len
) == 0)
265 if (port_name
[len
] == '\0')
266 return ports
->number
;
267 else if(isdigit (port_name
[len
]))
269 int port
= (ports
->number
270 + strtoul (&port_name
[len
], NULL
, 0));
271 if (port
>= ports
->number
+ ports
->nr_ports
)
273 "Port %s out of range",
279 else if (strcmp (port_name
, ports
->name
) == 0)
280 return ports
->number
;
286 hw_abort (me
, "Unreconized port %s", port_name
);
292 hw_port_encode (struct hw
*me
,
296 port_direction direction
)
298 const struct hw_port_descriptor
*ports
= NULL
;
299 ports
= me
->ports_of_hw
->ports
;
301 while (ports
->name
!= NULL
)
303 if (ports
->direction
== bidirect_port
304 || ports
->direction
== direction
)
306 if (ports
->nr_ports
> 0)
308 if (port_number
>= ports
->number
309 && port_number
< ports
->number
+ ports
->nr_ports
)
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");
320 if (ports
->number
== port_number
)
322 if (strlen(ports
->name
) >= sizeof_buf
)
323 hw_abort (me
, "hw_port_encode: buffer overflow");
324 strcpy(buf
, ports
->name
);
332 sprintf (buf
, "%d", port_number
);
333 if (strlen(buf
) >= sizeof_buf
)
334 hw_abort (me
, "hw_port_encode: buffer overflow");