1 /* This file is part of the program psim.
3 Copyright (C) 1994-1998, Andrew Cagney <cagney@highland.com.au>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 #include "sim-assert.h"
28 struct hw_instance_data
{
29 hw_finish_instance_method
*to_finish
;
30 struct hw_instance
*instances
;
33 static hw_finish_instance_method abort_hw_finish_instance
;
36 create_hw_instance_data (struct hw
*me
)
38 me
->instances_of_hw
= HW_ZALLOC (me
, struct hw_instance_data
);
39 set_hw_finish_instance (me
, abort_hw_finish_instance
);
43 delete_hw_instance_data (struct hw
*me
)
50 abort_hw_finish_instance (struct hw
*hw
,
51 struct hw_instance
*instance
)
53 hw_abort (hw
, "no instance finish method");
57 set_hw_finish_instance (struct hw
*me
,
58 hw_finish_instance_method
*finish
)
60 me
->instances_of_hw
->to_finish
= finish
;
66 clean_hw_instances (struct hw
*me
)
68 struct hw_instance
**instance
= &me
->instances
;
69 while (*instance
!= NULL
)
71 struct hw_instance
*old_instance
= *instance
;
72 hw_instance_delete (old_instance
);
73 instance
= &me
->instances
;
80 hw_instance_delete (struct hw_instance
*instance
)
83 hw_abort (hw_instance_hw (instance
), "not implemented");
85 struct hw
*me
= hw_instance_hw (instance
);
86 if (instance
->to_instance_delete
== NULL
)
87 hw_abort (me
, "no delete method");
88 instance
->method
->delete(instance
);
89 if (instance
->args
!= NULL
)
90 zfree (instance
->args
);
91 if (instance
->path
!= NULL
)
92 zfree (instance
->path
);
93 if (instance
->child
== NULL
)
95 /* only remove leaf nodes */
96 struct hw_instance
**curr
= &me
->instances
;
97 while (*curr
!= instance
)
99 ASSERT (*curr
!= NULL
);
100 curr
= &(*curr
)->next
;
102 *curr
= instance
->next
;
106 /* check it isn't in the instance list */
107 struct hw_instance
*curr
= me
->instances
;
110 ASSERT(curr
!= instance
);
113 /* unlink the child */
114 ASSERT (instance
->child
->parent
== instance
);
115 instance
->child
->parent
= NULL
;
117 cap_remove (me
->ihandles
, instance
);
124 panic_hw_instance_read (struct hw_instance
*instance
,
128 hw_abort (hw_instance_hw (instance
), "no read method");
135 panic_hw_instance_write (struct hw_instance
*instance
,
139 hw_abort (hw_instance_hw (instance
), "no write method");
145 panic_hw_instance_seek (struct hw_instance
*instance
,
146 unsigned_word pos_hi
,
147 unsigned_word pos_lo
)
149 hw_abort (hw_instance_hw (instance
), "no seek method");
155 hw_instance_call_method (struct hw_instance
*instance
,
156 const char *method_name
,
158 unsigned_cell stack_args
[/*n_stack_args*/],
160 unsigned_cell stack_returns
[/*n_stack_args*/])
163 hw_abort (hw_instance_hw (instance
), "not implemented");
166 struct hw
*me
= instance
->owner
;
167 const hw_instance_methods
*method
= instance
->method
->methods
;
170 hw_abort (me
, "no methods (want %s)", method_name
);
172 while (method
->name
!= NULL
)
174 if (strcmp(method
->name
, method_name
) == 0)
176 return method
->method (instance
,
177 n_stack_args
, stack_args
,
178 n_stack_returns
, stack_returns
);
182 hw_abort (me
, "no %s method", method_name
);
188 #define set_hw_instance_read(instance, method)\
189 ((instance)->to_instance_read = (method))
191 #define set_hw_instance_write(instance, method)\
192 ((instance)->to_instance_write = (method))
194 #define set_hw_instance_seek(instance, method)\
195 ((instance)->to_instance_seek = (method))
200 set_hw_instance_finish (struct hw
*me
,
201 hw_instance_finish_method
*method
)
203 if (me
->instances_of_hw
== NULL
)
204 me
->instances_of_hw
= HW_ZALLOC (me
, struct hw_instance_data
);
205 me
->instances_of_hw
->to_finish
= method
;
211 hw_instance_create (struct hw
*me
,
212 struct hw_instance
*parent
,
216 struct hw_instance
*instance
= ZALLOC (struct hw_instance
);
218 /* link this instance into the devices list */
219 instance
->hw_of_instance
= me
;
220 instance
->parent_of_instance
= NULL
;
221 /* link this instance into the front of the devices instance list */
222 instance
->sibling_of_instance
= me
->instances_of_hw
->instances
;
223 me
->instances_of_hw
->instances
= instance
;
226 ASSERT (parent
->child_of_instance
== NULL
);
227 parent
->child_of_instance
= instance
;
228 instance
->parent_of_instance
= parent
;
230 instance
->args_of_instance
= hw_strdup (me
, args
);
231 instance
->path_of_instance
= hw_strdup (me
, path
);
232 set_hw_instance_read (instance
, panic_hw_instance_read
);
233 set_hw_instance_write (instance
, panic_hw_instance_write
);
234 set_hw_instance_seek (instance
, panic_hw_instance_seek
);
235 hw_handle_add_ihandle (me
, instance
);
236 me
->instances_of_hw
->to_finish (me
, instance
);
242 hw_instance_interceed (struct hw_instance
*parent
,
249 struct hw_instance
*instance
= ZALLOC (struct hw_instance
);
251 /* link this instance into the devices list */
254 ASSERT (parent
== NULL
);
255 instance
->hw_of_instance
= me
;
256 instance
->parent_of_instance
= NULL
;
257 /* link this instance into the front of the devices instance list */
258 instance
->sibling_of_instance
= me
->instances_of_hw
->instances
;
259 me
->instances_of_hw
->instances
= instance
;
263 struct hw_instance
**previous
;
264 ASSERT (parent
->child_of_instance
== NULL
);
265 parent
->child_of_instance
= instance
;
266 instance
->owner
= parent
->owner
;
267 instance
->parent_of_instance
= parent
;
268 /* in the devices instance list replace the parent instance with
270 instance
->next
= parent
->next
;
271 /* replace parent with this new node */
272 previous
= &instance
->owner
->instances
;
273 while (*previous
!= parent
)
275 ASSERT (*previous
!= NULL
);
276 previous
= &(*previous
)->next
;
278 *previous
= instance
;
280 instance
->data
= data
;
281 instance
->args
= (args
== NULL
? NULL
: (char *) strdup(args
));
282 instance
->path
= (path
== NULL
? NULL
: (char *) strdup(path
));
283 cap_add (instance
->owner
->ihandles
, instance
);