2 Copyright (C) 1998-2021 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/>. */
34 struct hw_port_edge
*next
;
35 object_disposition disposition
;
40 hw_port_event_method
*to_port_event
;
41 const struct hw_port_descriptor
*ports
;
42 struct hw_port_edge
*edges
;
45 const struct hw_port_descriptor empty_hw_ports
[] =
51 panic_hw_port_event (struct hw
*me
,
57 hw_abort (me
, "no port method");
61 create_hw_port_data (struct hw
*me
)
63 me
->ports_of_hw
= HW_ZALLOC (me
, struct hw_port_data
);
64 set_hw_port_event (me
, panic_hw_port_event
);
65 set_hw_ports (me
, empty_hw_ports
);
69 delete_hw_port_data (struct hw
*me
)
71 hw_free (me
, me
->ports_of_hw
);
72 me
->ports_of_hw
= NULL
;
76 set_hw_ports (struct hw
*me
,
77 const struct hw_port_descriptor ports
[])
79 me
->ports_of_hw
->ports
= ports
;
83 set_hw_port_event (struct hw
*me
,
84 hw_port_event_method
*port_event
)
86 me
->ports_of_hw
->to_port_event
= port_event
;
91 attach_hw_port_edge (struct hw
*me
,
92 struct hw_port_edge
**list
,
96 object_disposition disposition
)
98 struct hw_port_edge
*new_edge
= HW_ZALLOC (me
, struct hw_port_edge
);
99 new_edge
->my_port
= my_port
;
100 new_edge
->dest
= dest
;
101 new_edge
->dest_port
= dest_port
;
102 new_edge
->next
= *list
;
103 new_edge
->disposition
= disposition
;
109 detach_hw_port_edge (struct hw
*me
,
110 struct hw_port_edge
**list
,
115 while (*list
!= NULL
)
117 struct hw_port_edge
*old_edge
= *list
;
118 if (old_edge
->dest
== dest
119 && old_edge
->dest_port
== dest_port
120 && old_edge
->my_port
== my_port
)
122 if (old_edge
->disposition
== permenant_object
)
123 hw_abort (me
, "attempt to delete permenant port edge");
124 *list
= old_edge
->next
;
125 hw_free (me
, old_edge
);
129 hw_abort (me
, "attempt to delete unattached port");
135 clean_hw_port_edges (struct hw_port_edge
**list
)
137 while (*list
!= NULL
)
139 struct hw_port_edge
*old_edge
= *list
;
140 switch (old_edge
->disposition
)
142 case permenant_object
:
143 list
= &old_edge
->next
;
145 case temporary_object
:
146 *list
= old_edge
->next
;
147 hw_free (me
, old_edge
);
158 hw_port_event (struct hw
*me
,
162 int found_an_edge
= 0;
163 struct hw_port_edge
*edge
;
164 /* device's lines directly connected */
165 for (edge
= me
->ports_of_hw
->edges
;
169 if (edge
->my_port
== my_port
)
171 edge
->dest
->ports_of_hw
->to_port_event (edge
->dest
,
180 hw_abort (me
, "No edge for port %d", my_port
);
185 hw_port_attach (struct hw
*me
,
189 object_disposition disposition
)
191 attach_hw_port_edge (me
,
192 &me
->ports_of_hw
->edges
,
201 hw_port_detach (struct hw
*me
,
206 detach_hw_port_edge (me
,
207 &me
->ports_of_hw
->edges
,
215 hw_port_traverse (struct hw
*me
,
216 hw_port_traverse_function
*handler
,
219 struct hw_port_edge
*port_edge
;
220 for (port_edge
= me
->ports_of_hw
->edges
;
222 port_edge
= port_edge
->next
)
224 handler (me
, port_edge
->my_port
,
225 port_edge
->dest
, port_edge
->dest_port
,
232 hw_port_decode (struct hw
*me
,
233 const char *port_name
,
234 port_direction direction
)
236 if (port_name
== NULL
|| port_name
[0] == '\0')
238 if (isdigit (port_name
[0]))
240 return strtoul (port_name
, NULL
, 0);
244 const struct hw_port_descriptor
*ports
=
245 me
->ports_of_hw
->ports
;
248 while (ports
->name
!= NULL
)
250 if (ports
->direction
== bidirect_port
251 || ports
->direction
== direction
)
253 if (ports
->nr_ports
> 0)
255 int len
= strlen (ports
->name
);
256 if (strncmp (port_name
, ports
->name
, len
) == 0)
258 if (port_name
[len
] == '\0')
259 return ports
->number
;
260 else if (isdigit (port_name
[len
]))
262 int port
= (ports
->number
263 + strtoul (&port_name
[len
], NULL
, 0));
264 if (port
>= ports
->number
+ ports
->nr_ports
)
266 "Port %s out of range",
272 else if (strcmp (port_name
, ports
->name
) == 0)
273 return ports
->number
;
279 hw_abort (me
, "Unrecognized port %s", port_name
);
285 hw_port_encode (struct hw
*me
,
289 port_direction direction
)
291 const struct hw_port_descriptor
*ports
= NULL
;
292 ports
= me
->ports_of_hw
->ports
;
294 while (ports
->name
!= NULL
)
296 if (ports
->direction
== bidirect_port
297 || ports
->direction
== direction
)
299 if (ports
->nr_ports
> 0)
301 if (port_number
>= ports
->number
302 && port_number
< ports
->number
+ ports
->nr_ports
)
304 strcpy (buf
, ports
->name
);
305 sprintf (buf
+ strlen (buf
), "%d", port_number
- ports
->number
);
306 if (strlen (buf
) >= sizeof_buf
)
307 hw_abort (me
, "hw_port_encode: buffer overflow");
313 if (ports
->number
== port_number
)
315 if (strlen (ports
->name
) >= sizeof_buf
)
316 hw_abort (me
, "hw_port_encode: buffer overflow");
317 strcpy (buf
, ports
->name
);
325 sprintf (buf
, "%d", port_number
);
326 if (strlen (buf
) >= sizeof_buf
)
327 hw_abort (me
, "hw_port_encode: buffer overflow");