aboutsummaryrefslogtreecommitdiff
path: root/sim/common/hw-base.c
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>1998-03-22 05:06:27 +0000
committerAndrew Cagney <cagney@redhat.com>1998-03-22 05:06:27 +0000
commite5f0d498af49da4680564df06b9709423523ba6e (patch)
tree0e052b4638713a10794e9fbd11df0651dcf974c7 /sim/common/hw-base.c
parentb1e9223cee0728b89f6b909c445a896d9fe41452 (diff)
downloadfsf-binutils-gdb-e5f0d498af49da4680564df06b9709423523ba6e.zip
fsf-binutils-gdb-e5f0d498af49da4680564df06b9709423523ba6e.tar.gz
fsf-binutils-gdb-e5f0d498af49da4680564df06b9709423523ba6e.tar.bz2
Add hw_{malloc,zalloc,free} functions to hw_device. Any memory
allocated using these functions is reclaimed when the corresponding device is deleted.
Diffstat (limited to 'sim/common/hw-base.c')
-rw-r--r--sim/common/hw-base.c68
1 files changed, 61 insertions, 7 deletions
diff --git a/sim/common/hw-base.c b/sim/common/hw-base.c
index 0c4b8a5..495f96d 100644
--- a/sim/common/hw-base.c
+++ b/sim/common/hw-base.c
@@ -24,10 +24,6 @@
/* LATER: #include "hwconfig.h" */
-struct hw_base_data {
- int finished_p;
- const struct hw_device_descriptor *descriptor;
-};
extern const struct hw_device_descriptor dv_core_descriptor[];
extern const struct hw_device_descriptor dv_pal_descriptor[];
const struct hw_device_descriptor *hw_descriptors[] = {
@@ -50,6 +46,11 @@ const struct hw_device_descriptor *hw_descriptors[] = {
#include <ctype.h>
+struct hw_base_data {
+ int finished_p;
+ const struct hw_device_descriptor *descriptor;
+ hw_delete_callback *to_delete;
+};
static int
generic_hw_unit_decode (struct hw *bus,
@@ -287,6 +288,14 @@ panic_hw_port_event (struct hw *me,
hw_abort (me, "no port method");
}
+static void
+ignore_hw_delete (struct hw *me)
+{
+ /* NOP */
+}
+
+
+
static const char *
full_name_of_hw (struct hw *leaf,
@@ -345,6 +354,7 @@ hw_create (SIM_DESC sd,
const char *unit,
const char *args)
{
+ /* NOTE: HW must be allocated using ZALLOC, others use HW_ZALLOC */
struct hw *hw = ZALLOC (struct hw);
/* our identity */
@@ -391,6 +401,10 @@ hw_create (SIM_DESC sd,
else
hw->path_of_hw = "/";
+ /* create our base type */
+ hw->base_of_hw = HW_ZALLOC (hw, struct hw_base_data);
+ hw->base_of_hw->finished_p = 0;
+
/* our callbacks */
set_hw_io_read_buffer (hw, panic_hw_io_read_buffer);
set_hw_io_write_buffer (hw, panic_hw_io_write_buffer);
@@ -402,6 +416,7 @@ hw_create (SIM_DESC sd,
set_hw_unit_size_to_attach_size (hw, generic_hw_unit_size_to_attach_size);
set_hw_attach_address (hw, passthrough_hw_attach_address);
set_hw_detach_address (hw, passthrough_hw_detach_address);
+ set_hw_delete (hw, ignore_hw_delete);
/* locate a descriptor */
{
@@ -417,13 +432,11 @@ hw_create (SIM_DESC sd,
{
if (strcmp (family, entry->family) == 0)
{
- hw->base_of_hw = ZALLOC (struct hw_base_data);
hw->base_of_hw->descriptor = entry;
- hw->base_of_hw->finished_p = 0;
}
}
}
- if (hw->base_of_hw == NULL)
+ if (hw->base_of_hw->descriptor == NULL)
{
hw_abort (parent, "Unknown device `%s'", family);
}
@@ -465,3 +478,44 @@ hw_finish (struct hw *me)
me->base_of_hw->descriptor->to_finish (me);
me->base_of_hw->finished_p = 1;
}
+
+
+void
+hw_delete (struct hw *me)
+{
+ /* give the object a chance to tidy up */
+ me->base_of_hw->to_delete (me);
+
+ /* now unlink us from the tree */
+ if (hw_parent (me))
+ {
+ struct hw **sibling = &hw_parent (me)->child_of_hw;
+ while (*sibling != NULL)
+ {
+ if (*sibling == me)
+ {
+ *sibling = me->sibling_of_hw;
+ me->sibling_of_hw = NULL;
+ me->parent_of_hw = NULL;
+ break;
+ }
+ }
+ }
+
+ /* some sanity checks */
+ if (hw_child (me) != NULL)
+ {
+ hw_abort (me, "attempt to delete device with children");
+ }
+ if (hw_sibling (me) != NULL)
+ {
+ hw_abort (me, "attempt to delete device with siblings");
+ }
+
+ /* blow away all memory belonging to the device */
+ hw_free_all (me);
+
+ /* finally */
+ zfree (me->base_of_hw);
+ zfree (me);
+}