2 Copyright (C) 1998-2022 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/>. */
20 /* This must come before any other includes. */
36 struct hw_port_edge
*next
;
37 object_disposition disposition
;
42 hw_port_event_method
*to_port_event
;
43 const struct hw_port_descriptor
*ports
;
44 struct hw_port_edge
*edges
;
47 const struct hw_port_descriptor empty_hw_ports
[] =
53 panic_hw_port_event (struct hw
*me
,
59 hw_abort (me
, "no port method");
63 create_hw_port_data (struct hw
*me
)
65 me
->ports_of_hw
= HW_ZALLOC (me
, struct hw_port_data
);
66 set_hw_port_event (me
, panic_hw_port_event
);
67 set_hw_ports (me
, empty_hw_ports
);
71 delete_hw_port_data (struct hw
*me
)
73 hw_free (me
, me
->ports_of_hw
);
74 me
->ports_of_hw
= NULL
;
78 set_hw_ports (struct hw
*me
,
79 const struct hw_port_descriptor ports
[])
81 me
->ports_of_hw
->ports
= ports
;
85 set_hw_port_event (struct hw
*me
,
86 hw_port_event_method
*port_event
)
88 me
->ports_of_hw
->to_port_event
= port_event
;
93 attach_hw_port_edge (struct hw
*me
,
94 struct hw_port_edge
**list
,
98 object_disposition disposition
)
100 struct hw_port_edge
*new_edge
= HW_ZALLOC (me
, struct hw_port_edge
);
101 new_edge
->my_port
= my_port
;
102 new_edge
->dest
= dest
;
103 new_edge
->dest_port
= dest_port
;
104 new_edge
->next
= *list
;
105 new_edge
->disposition
= disposition
;
111 detach_hw_port_edge (struct hw
*me
,
112 struct hw_port_edge
**list
,
117 while (*list
!= NULL
)
119 struct hw_port_edge
*old_edge
= *list
;
120 if (old_edge
->dest
== dest
121 && old_edge
->dest_port
== dest_port
122 && old_edge
->my_port
== my_port
)
124 if (old_edge
->disposition
== permenant_object
)
125 hw_abort (me
, "attempt to delete permenant port edge");
126 *list
= old_edge
->next
;
127 hw_free (me
, old_edge
);
131 hw_abort (me
, "attempt to delete unattached port");
137 clean_hw_port_edges (struct hw_port_edge
**list
)
139 while (*list
!= NULL
)
141 struct hw_port_edge
*old_edge
= *list
;
142 switch (old_edge
->disposition
)
144 case permenant_object
:
145 list
= &old_edge
->next
;
147 case temporary_object
:
148 *list
= old_edge
->next
;
149 hw_free (me
, old_edge
);
160 hw_port_event (struct hw
*me
,
164 int found_an_edge
= 0;
165 struct hw_port_edge
*edge
;
166 /* device's lines directly connected */
167 for (edge
= me
->ports_of_hw
->edges
;
171 if (edge
->my_port
== my_port
)
173 edge
->dest
->ports_of_hw
->to_port_event (edge
->dest
,
182 hw_abort (me
, "No edge for port %d", my_port
);
187 hw_port_attach (struct hw
*me
,
191 object_disposition disposition
)
193 attach_hw_port_edge (me
,
194 &me
->ports_of_hw
->edges
,
203 hw_port_detach (struct hw
*me
,
208 detach_hw_port_edge (me
,
209 &me
->ports_of_hw
->edges
,
217 hw_port_traverse (struct hw
*me
,
218 hw_port_traverse_function
*handler
,
221 struct hw_port_edge
*port_edge
;
222 for (port_edge
= me
->ports_of_hw
->edges
;
224 port_edge
= port_edge
->next
)
226 handler (me
, port_edge
->my_port
,
227 port_edge
->dest
, port_edge
->dest_port
,
234 hw_port_decode (struct hw
*me
,
235 const char *port_name
,
236 port_direction direction
)
238 if (port_name
== NULL
|| port_name
[0] == '\0')
240 if (isdigit (port_name
[0]))
242 return strtoul (port_name
, NULL
, 0);
246 const struct hw_port_descriptor
*ports
=
247 me
->ports_of_hw
->ports
;
250 while (ports
->name
!= NULL
)
252 if (ports
->direction
== bidirect_port
253 || ports
->direction
== direction
)
255 if (ports
->nr_ports
> 0)
257 int len
= strlen (ports
->name
);
258 if (strncmp (port_name
, ports
->name
, len
) == 0)
260 if (port_name
[len
] == '\0')
261 return ports
->number
;
262 else if (isdigit (port_name
[len
]))
264 int port
= (ports
->number
265 + strtoul (&port_name
[len
], NULL
, 0));
266 if (port
>= ports
->number
+ ports
->nr_ports
)
268 "Port %s out of range",
274 else if (strcmp (port_name
, ports
->name
) == 0)
275 return ports
->number
;
281 hw_abort (me
, "Unrecognized port %s", port_name
);
287 hw_port_encode (struct hw
*me
,
291 port_direction direction
)
293 const struct hw_port_descriptor
*ports
= NULL
;
294 ports
= me
->ports_of_hw
->ports
;
296 while (ports
->name
!= NULL
)
298 if (ports
->direction
== bidirect_port
299 || ports
->direction
== direction
)
301 if (ports
->nr_ports
> 0)
303 if (port_number
>= ports
->number
304 && port_number
< ports
->number
+ ports
->nr_ports
)
306 strcpy (buf
, ports
->name
);
307 sprintf (buf
+ strlen (buf
), "%d", port_number
- ports
->number
);
308 if (strlen (buf
) >= sizeof_buf
)
309 hw_abort (me
, "hw_port_encode: buffer overflow");
315 if (ports
->number
== port_number
)
317 if (strlen (ports
->name
) >= sizeof_buf
)
318 hw_abort (me
, "hw_port_encode: buffer overflow");
319 strcpy (buf
, ports
->name
);
327 sprintf (buf
, "%d", port_number
);
328 if (strlen (buf
) >= sizeof_buf
)
329 hw_abort (me
, "hw_port_encode: buffer overflow");