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