4 * Copyright (c) 2003-2008 Fabrice Bellard
5 * Copyright (c) 2016 Red Hat, Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 #include "qemu/osdep.h"
27 #include "sysemu/reset.h"
28 #include "hw/resettable.h"
29 #include "hw/core/resetcontainer.h"
32 * Return a pointer to the singleton container that holds all the Resettable
33 * items that will be reset when qemu_devices_reset() is called.
35 static ResettableContainer
*get_root_reset_container(void)
37 static ResettableContainer
*root_reset_container
;
39 if (!root_reset_container
) {
40 root_reset_container
=
41 RESETTABLE_CONTAINER(object_new(TYPE_RESETTABLE_CONTAINER
));
43 return root_reset_container
;
47 * This is an Object which implements Resettable simply to call the
48 * callback function in the hold phase.
50 #define TYPE_LEGACY_RESET "legacy-reset"
51 OBJECT_DECLARE_SIMPLE_TYPE(LegacyReset
, LEGACY_RESET
)
55 ResettableState reset_state
;
56 QEMUResetHandler
*func
;
58 bool skip_on_snapshot_load
;
61 OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(LegacyReset
, legacy_reset
, LEGACY_RESET
, OBJECT
, { TYPE_RESETTABLE_INTERFACE
}, { })
63 static ResettableState
*legacy_reset_get_state(Object
*obj
)
65 LegacyReset
*lr
= LEGACY_RESET(obj
);
66 return &lr
->reset_state
;
69 static void legacy_reset_hold(Object
*obj
, ResetType type
)
71 LegacyReset
*lr
= LEGACY_RESET(obj
);
73 if (type
== RESET_TYPE_SNAPSHOT_LOAD
&& lr
->skip_on_snapshot_load
) {
79 static void legacy_reset_init(Object
*obj
)
83 static void legacy_reset_finalize(Object
*obj
)
87 static void legacy_reset_class_init(ObjectClass
*klass
, void *data
)
89 ResettableClass
*rc
= RESETTABLE_CLASS(klass
);
91 rc
->get_state
= legacy_reset_get_state
;
92 rc
->phases
.hold
= legacy_reset_hold
;
95 void qemu_register_reset(QEMUResetHandler
*func
, void *opaque
)
97 Object
*obj
= object_new(TYPE_LEGACY_RESET
);
98 LegacyReset
*lr
= LEGACY_RESET(obj
);
102 qemu_register_resettable(obj
);
105 void qemu_register_reset_nosnapshotload(QEMUResetHandler
*func
, void *opaque
)
107 Object
*obj
= object_new(TYPE_LEGACY_RESET
);
108 LegacyReset
*lr
= LEGACY_RESET(obj
);
112 lr
->skip_on_snapshot_load
= true;
113 qemu_register_resettable(obj
);
116 typedef struct FindLegacyInfo
{
117 QEMUResetHandler
*func
;
122 static void find_legacy_reset_cb(Object
*obj
, void *opaque
, ResetType type
)
125 FindLegacyInfo
*fli
= opaque
;
127 /* Not everything in the ResettableContainer will be a LegacyReset */
128 lr
= LEGACY_RESET(object_dynamic_cast(obj
, TYPE_LEGACY_RESET
));
129 if (lr
&& lr
->func
== fli
->func
&& lr
->opaque
== fli
->opaque
) {
134 static LegacyReset
*find_legacy_reset(QEMUResetHandler
*func
, void *opaque
)
137 * Find the LegacyReset with the specified func and opaque,
138 * by getting the ResettableContainer to call our callback for
141 ResettableContainer
*rootcon
= get_root_reset_container();
142 ResettableClass
*rc
= RESETTABLE_GET_CLASS(rootcon
);
148 rc
->child_foreach(OBJECT(rootcon
), find_legacy_reset_cb
,
149 &fli
, RESET_TYPE_COLD
);
153 void qemu_unregister_reset(QEMUResetHandler
*func
, void *opaque
)
155 Object
*obj
= OBJECT(find_legacy_reset(func
, opaque
));
158 qemu_unregister_resettable(obj
);
163 void qemu_register_resettable(Object
*obj
)
165 resettable_container_add(get_root_reset_container(), obj
);
168 void qemu_unregister_resettable(Object
*obj
)
170 resettable_container_remove(get_root_reset_container(), obj
);
173 void qemu_devices_reset(ShutdownCause reason
)
175 ResetType type
= (reason
== SHUTDOWN_CAUSE_SNAPSHOT_LOAD
) ?
176 RESET_TYPE_SNAPSHOT_LOAD
: RESET_TYPE_COLD
;
178 /* Reset the simulation */
179 resettable_reset(OBJECT(get_root_reset_container()), type
);