xref: /qemu/hw/core/reset.c (revision 86fae16ed298518ea851d6accc48643e6bdf8ed1)
12f7b92a0SPaolo Bonzini /*
22f7b92a0SPaolo Bonzini  *  Reset handlers.
32f7b92a0SPaolo Bonzini  *
42f7b92a0SPaolo Bonzini  * Copyright (c) 2003-2008 Fabrice Bellard
52f7b92a0SPaolo Bonzini  * Copyright (c) 2016 Red Hat, Inc.
62f7b92a0SPaolo Bonzini  *
72f7b92a0SPaolo Bonzini  * Permission is hereby granted, free of charge, to any person obtaining a copy
82f7b92a0SPaolo Bonzini  * of this software and associated documentation files (the "Software"), to deal
92f7b92a0SPaolo Bonzini  * in the Software without restriction, including without limitation the rights
102f7b92a0SPaolo Bonzini  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
112f7b92a0SPaolo Bonzini  * copies of the Software, and to permit persons to whom the Software is
122f7b92a0SPaolo Bonzini  * furnished to do so, subject to the following conditions:
132f7b92a0SPaolo Bonzini  *
142f7b92a0SPaolo Bonzini  * The above copyright notice and this permission notice shall be included in
152f7b92a0SPaolo Bonzini  * all copies or substantial portions of the Software.
162f7b92a0SPaolo Bonzini  *
172f7b92a0SPaolo Bonzini  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
182f7b92a0SPaolo Bonzini  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
192f7b92a0SPaolo Bonzini  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
202f7b92a0SPaolo Bonzini  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
212f7b92a0SPaolo Bonzini  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
222f7b92a0SPaolo Bonzini  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
232f7b92a0SPaolo Bonzini  * THE SOFTWARE.
242f7b92a0SPaolo Bonzini  */
252f7b92a0SPaolo Bonzini 
262f7b92a0SPaolo Bonzini #include "qemu/osdep.h"
272f7b92a0SPaolo Bonzini #include "qemu/queue.h"
282f7b92a0SPaolo Bonzini #include "sysemu/reset.h"
29*86fae16eSPeter Maydell #include "hw/resettable.h"
30*86fae16eSPeter Maydell #include "hw/core/resetcontainer.h"
312f7b92a0SPaolo Bonzini 
32*86fae16eSPeter Maydell /*
33*86fae16eSPeter Maydell  * Return a pointer to the singleton container that holds all the Resettable
34*86fae16eSPeter Maydell  * items that will be reset when qemu_devices_reset() is called.
35*86fae16eSPeter Maydell  */
36*86fae16eSPeter Maydell static ResettableContainer *get_root_reset_container(void)
37*86fae16eSPeter Maydell {
38*86fae16eSPeter Maydell     static ResettableContainer *root_reset_container;
39*86fae16eSPeter Maydell 
40*86fae16eSPeter Maydell     if (!root_reset_container) {
41*86fae16eSPeter Maydell         root_reset_container =
42*86fae16eSPeter Maydell             RESETTABLE_CONTAINER(object_new(TYPE_RESETTABLE_CONTAINER));
43*86fae16eSPeter Maydell     }
44*86fae16eSPeter Maydell     return root_reset_container;
45*86fae16eSPeter Maydell }
462f7b92a0SPaolo Bonzini 
472f7b92a0SPaolo Bonzini typedef struct QEMUResetEntry {
482f7b92a0SPaolo Bonzini     QTAILQ_ENTRY(QEMUResetEntry) entry;
492f7b92a0SPaolo Bonzini     QEMUResetHandler *func;
502f7b92a0SPaolo Bonzini     void *opaque;
517966d70fSJason A. Donenfeld     bool skip_on_snapshot_load;
522f7b92a0SPaolo Bonzini } QEMUResetEntry;
532f7b92a0SPaolo Bonzini 
54b58deb34SPaolo Bonzini static QTAILQ_HEAD(, QEMUResetEntry) reset_handlers =
552f7b92a0SPaolo Bonzini     QTAILQ_HEAD_INITIALIZER(reset_handlers);
562f7b92a0SPaolo Bonzini 
572f7b92a0SPaolo Bonzini void qemu_register_reset(QEMUResetHandler *func, void *opaque)
582f7b92a0SPaolo Bonzini {
59b21e2380SMarkus Armbruster     QEMUResetEntry *re = g_new0(QEMUResetEntry, 1);
602f7b92a0SPaolo Bonzini 
612f7b92a0SPaolo Bonzini     re->func = func;
622f7b92a0SPaolo Bonzini     re->opaque = opaque;
632f7b92a0SPaolo Bonzini     QTAILQ_INSERT_TAIL(&reset_handlers, re, entry);
642f7b92a0SPaolo Bonzini }
652f7b92a0SPaolo Bonzini 
667966d70fSJason A. Donenfeld void qemu_register_reset_nosnapshotload(QEMUResetHandler *func, void *opaque)
677966d70fSJason A. Donenfeld {
687966d70fSJason A. Donenfeld     QEMUResetEntry *re = g_new0(QEMUResetEntry, 1);
697966d70fSJason A. Donenfeld 
707966d70fSJason A. Donenfeld     re->func = func;
717966d70fSJason A. Donenfeld     re->opaque = opaque;
727966d70fSJason A. Donenfeld     re->skip_on_snapshot_load = true;
737966d70fSJason A. Donenfeld     QTAILQ_INSERT_TAIL(&reset_handlers, re, entry);
747966d70fSJason A. Donenfeld }
757966d70fSJason A. Donenfeld 
762f7b92a0SPaolo Bonzini void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
772f7b92a0SPaolo Bonzini {
782f7b92a0SPaolo Bonzini     QEMUResetEntry *re;
792f7b92a0SPaolo Bonzini 
802f7b92a0SPaolo Bonzini     QTAILQ_FOREACH(re, &reset_handlers, entry) {
812f7b92a0SPaolo Bonzini         if (re->func == func && re->opaque == opaque) {
822f7b92a0SPaolo Bonzini             QTAILQ_REMOVE(&reset_handlers, re, entry);
832f7b92a0SPaolo Bonzini             g_free(re);
842f7b92a0SPaolo Bonzini             return;
852f7b92a0SPaolo Bonzini         }
862f7b92a0SPaolo Bonzini     }
872f7b92a0SPaolo Bonzini }
882f7b92a0SPaolo Bonzini 
89*86fae16eSPeter Maydell void qemu_register_resettable(Object *obj)
90*86fae16eSPeter Maydell {
91*86fae16eSPeter Maydell     resettable_container_add(get_root_reset_container(), obj);
92*86fae16eSPeter Maydell }
93*86fae16eSPeter Maydell 
94*86fae16eSPeter Maydell void qemu_unregister_resettable(Object *obj)
95*86fae16eSPeter Maydell {
96*86fae16eSPeter Maydell     resettable_container_remove(get_root_reset_container(), obj);
97*86fae16eSPeter Maydell }
98*86fae16eSPeter Maydell 
997966d70fSJason A. Donenfeld void qemu_devices_reset(ShutdownCause reason)
1002f7b92a0SPaolo Bonzini {
1012f7b92a0SPaolo Bonzini     QEMUResetEntry *re, *nre;
1022f7b92a0SPaolo Bonzini 
1032f7b92a0SPaolo Bonzini     /* reset all devices */
1042f7b92a0SPaolo Bonzini     QTAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) {
1057966d70fSJason A. Donenfeld         if (reason == SHUTDOWN_CAUSE_SNAPSHOT_LOAD &&
1067966d70fSJason A. Donenfeld             re->skip_on_snapshot_load) {
1077966d70fSJason A. Donenfeld             continue;
1087966d70fSJason A. Donenfeld         }
1092f7b92a0SPaolo Bonzini         re->func(re->opaque);
1102f7b92a0SPaolo Bonzini     }
1112f7b92a0SPaolo Bonzini 
112*86fae16eSPeter Maydell     /* Reset the simulation */
113*86fae16eSPeter Maydell     resettable_reset(OBJECT(get_root_reset_container()), RESET_TYPE_COLD);
114*86fae16eSPeter Maydell }
115