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.
27 struct hw_instance_data
{
28 hw_finish_instance_method
*to_finish
;
29 struct hw_instance
*instances
;
32 static hw_finish_instance_method abort_hw_finish_instance
;
35 create_hw_instance_data (struct hw
*me
)
37 me
->instances_of_hw
= HW_ZALLOC (me
, struct hw_instance_data
);
38 set_hw_finish_instance (me
, abort_hw_finish_instance
);
42 delete_hw_instance_data (struct hw
*me
)
49 abort_hw_finish_instance (struct hw
*hw
,
50 struct hw_instance
*instance
)
52 hw_abort (hw
, "no instance finish method");
56 set_hw_finish_instance (struct hw
*me
,
57 hw_finish_instance_method
*finish
)
59 me
->instances_of_hw
->to_finish
= finish
;
65 clean_hw_instances (struct hw
*me
)
67 struct hw_instance
**instance
= &me
->instances
;
68 while (*instance
!= NULL
)
70 struct hw_instance
*old_instance
= *instance
;
71 hw_instance_delete (old_instance
);
72 instance
= &me
->instances
;
79 hw_instance_delete (struct hw_instance
*instance
)
82 hw_abort (hw_instance_hw (instance
), "not implemented");
84 struct hw
*me
= hw_instance_hw (instance
);
85 if (instance
->to_instance_delete
== NULL
)
86 hw_abort (me
, "no delete method");
87 instance
->method
->delete(instance
);
88 if (instance
->args
!= NULL
)
89 zfree (instance
->args
);
90 if (instance
->path
!= NULL
)
91 zfree (instance
->path
);
92 if (instance
->child
== NULL
)
94 /* only remove leaf nodes */
95 struct hw_instance
**curr
= &me
->instances
;
96 while (*curr
!= instance
)
98 ASSERT (*curr
!= NULL
);
99 curr
= &(*curr
)->next
;
101 *curr
= instance
->next
;
105 /* check it isn't in the instance list */
106 struct hw_instance
*curr
= me
->instances
;
109 ASSERT(curr
!= instance
);
112 /* unlink the child */
113 ASSERT (instance
->child
->parent
== instance
);
114 instance
->child
->parent
= NULL
;
116 cap_remove (me
->ihandles
, instance
);
123 panic_hw_instance_read (struct hw_instance
*instance
,
127 hw_abort (hw_instance_hw (instance
), "no read method");
134 panic_hw_instance_write (struct hw_instance
*instance
,
138 hw_abort (hw_instance_hw (instance
), "no write method");
144 panic_hw_instance_seek (struct hw_instance
*instance
,
145 unsigned_word pos_hi
,
146 unsigned_word pos_lo
)
148 hw_abort (hw_instance_hw (instance
), "no seek method");
154 hw_instance_call_method (struct hw_instance
*instance
,
155 const char *method_name
,
157 unsigned_cell stack_args
[/*n_stack_args*/],
159 unsigned_cell stack_returns
[/*n_stack_args*/])
162 hw_abort (hw_instance_hw (instance
), "not implemented");
165 struct hw
*me
= instance
->owner
;
166 const hw_instance_methods
*method
= instance
->method
->methods
;
169 hw_abort (me
, "no methods (want %s)", method_name
);
171 while (method
->name
!= NULL
)
173 if (strcmp(method
->name
, method_name
) == 0)
175 return method
->method (instance
,
176 n_stack_args
, stack_args
,
177 n_stack_returns
, stack_returns
);
181 hw_abort (me
, "no %s method", method_name
);
187 #define set_hw_instance_read(instance, method)\
188 ((instance)->to_instance_read = (method))
190 #define set_hw_instance_write(instance, method)\
191 ((instance)->to_instance_write = (method))
193 #define set_hw_instance_seek(instance, method)\
194 ((instance)->to_instance_seek = (method))
199 set_hw_instance_finish (struct hw
*me
,
200 hw_instance_finish_method
*method
)
202 if (me
->instances_of_hw
== NULL
)
203 me
->instances_of_hw
= HW_ZALLOC (me
, struct hw_instance_data
);
204 me
->instances_of_hw
->to_finish
= method
;
210 hw_instance_create (struct hw
*me
,
211 struct hw_instance
*parent
,
215 struct hw_instance
*instance
= ZALLOC (struct hw_instance
);
217 /* link this instance into the devices list */
218 instance
->hw_of_instance
= me
;
219 instance
->parent_of_instance
= NULL
;
220 /* link this instance into the front of the devices instance list */
221 instance
->sibling_of_instance
= me
->instances_of_hw
->instances
;
222 me
->instances_of_hw
->instances
= instance
;
225 ASSERT (parent
->child_of_instance
== NULL
);
226 parent
->child_of_instance
= instance
;
227 instance
->parent_of_instance
= parent
;
229 instance
->args_of_instance
= hw_strdup (me
, args
);
230 instance
->path_of_instance
= hw_strdup (me
, path
);
231 set_hw_instance_read (instance
, panic_hw_instance_read
);
232 set_hw_instance_write (instance
, panic_hw_instance_write
);
233 set_hw_instance_seek (instance
, panic_hw_instance_seek
);
234 hw_handle_add_ihandle (me
, instance
);
235 me
->instances_of_hw
->to_finish (me
, instance
);
241 hw_instance_interceed (struct hw_instance
*parent
,
248 struct hw_instance
*instance
= ZALLOC (struct hw_instance
);
250 /* link this instance into the devices list */
253 ASSERT (parent
== NULL
);
254 instance
->hw_of_instance
= me
;
255 instance
->parent_of_instance
= NULL
;
256 /* link this instance into the front of the devices instance list */
257 instance
->sibling_of_instance
= me
->instances_of_hw
->instances
;
258 me
->instances_of_hw
->instances
= instance
;
262 struct hw_instance
**previous
;
263 ASSERT (parent
->child_of_instance
== NULL
);
264 parent
->child_of_instance
= instance
;
265 instance
->owner
= parent
->owner
;
266 instance
->parent_of_instance
= parent
;
267 /* in the devices instance list replace the parent instance with
269 instance
->next
= parent
->next
;
270 /* replace parent with this new node */
271 previous
= &instance
->owner
->instances
;
272 while (*previous
!= parent
)
274 ASSERT (*previous
!= NULL
);
275 previous
= &(*previous
)->next
;
277 *previous
= instance
;
279 instance
->data
= data
;
280 instance
->args
= (args
== NULL
? NULL
: (char *) strdup(args
));
281 instance
->path
= (path
== NULL
? NULL
: (char *) strdup(path
));
282 cap_add (instance
->owner
->ihandles
, instance
);