All objects contained in this ResetDomain are cold-reset when calling qemu_devices_reset. Also add 2 functions to register/unregister object in this ResetDomain.
Signed-off-by: Damien Hedde <damien.he...@greensocs.com> --- hw/core/reset.c | 56 +++++++++++++++++++++++++++++++++++++++++- include/sysemu/reset.h | 47 +++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) diff --git a/hw/core/reset.c b/hw/core/reset.c index 9c477f2bf5..d013c9feb9 100644 --- a/hw/core/reset.c +++ b/hw/core/reset.c @@ -3,6 +3,7 @@ * * Copyright (c) 2003-2008 Fabrice Bellard * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2019 GreenSocs * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,6 +27,7 @@ #include "qemu/osdep.h" #include "qemu/queue.h" #include "sysemu/reset.h" +#include "hw/reset-domain.h" /* reset/shutdown handler */ @@ -38,6 +40,49 @@ typedef struct QEMUResetEntry { static QTAILQ_HEAD(, QEMUResetEntry) reset_handlers = QTAILQ_HEAD_INITIALIZER(reset_handlers); +/* global/system reset domain */ +static ResetDomain *reset_domain; + +static ResetDomain *get_reset_domain(void) +{ + if (reset_domain == NULL) { + /* + * the ref to the object will be deleted by + * qemu_delete_system_reset_domain function below. + */ + reset_domain = RESET_DOMAIN(object_new(TYPE_RESET_DOMAIN)); + } + return reset_domain; +} + +ResetDomain *qemu_get_system_reset_domain(void) +{ + return get_reset_domain(); +} + +void qemu_delete_system_reset_domain(void) +{ + /* unref the reset_domain object if it exists */ + if (reset_domain != NULL) { + object_unref(OBJECT(reset_domain)); + reset_domain = NULL; + } +} + +void qemu_register_system_reset_domain_object(Object *obj) +{ + ResetDomain *domain = get_reset_domain(); + + reset_domain_register_object(domain, obj); +} + +void qemu_unregister_system_reset_domain_object(Object *obj) +{ + ResetDomain *domain = get_reset_domain(); + + reset_domain_unregister_object(domain, obj); +} + void qemu_register_reset(QEMUResetHandler *func, void *opaque) { QEMUResetEntry *re = g_malloc0(sizeof(QEMUResetEntry)); @@ -62,11 +107,20 @@ void qemu_unregister_reset(QEMUResetHandler *func, void *opaque) void qemu_devices_reset(void) { + qemu_system_reset_domain_reset(true); +} + +void qemu_system_reset_domain_reset(bool cold) +{ + ResetDomain *domain = get_reset_domain(); QEMUResetEntry *re, *nre; - /* reset all devices */ + /* call function handlers first */ QTAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) { re->func(re->opaque); } + + /* then handle the objects in the ResetDomain */ + resettable_reset(OBJECT(domain), cold); } diff --git a/include/sysemu/reset.h b/include/sysemu/reset.h index 0b0d6d7598..29843eca92 100644 --- a/include/sysemu/reset.h +++ b/include/sysemu/reset.h @@ -1,10 +1,57 @@ #ifndef QEMU_SYSEMU_RESET_H #define QEMU_SYSEMU_RESET_H +#include "qom/object.h" +#include "hw/reset-domain.h" + +/** + * qemu_get_system_reset_domain: + * Get the global system reset domain object + */ +ResetDomain *qemu_get_system_reset_domain(void); + +/** + * qemu_delete_system_reset_domain: + * Delete the global system reset domain object + */ +void qemu_delete_system_reset_domain(void); + +/** + * qemu_register_system_reset_domain_object: + * Register @obj in the system reset domain + */ +void qemu_register_system_reset_domain_object(Object *obj); + +/** + * qemu_unregister_system_reset_domain_object: + * Unregister @obj from the global reset domain + */ +void qemu_unregister_system_reset_domain_object(Object *obj); + +/** + * @qemu_system_reset_domain_reset: + * Do a cold or warm system reset based on @cold + */ +void qemu_system_reset_domain_reset(bool cold); + typedef void QEMUResetHandler(void *opaque); +/** + * qemu_resgiter_reset: + * Register @func with @opaque in the global reset procedure. + */ void qemu_register_reset(QEMUResetHandler *func, void *opaque); + +/** + * qemu_unregister_reset: + * Unregister @func with @opaque from the global reset procedure. + */ void qemu_unregister_reset(QEMUResetHandler *func, void *opaque); + +/** + * qemu_devices_reset: + * Trigger a reset of registered handlers and objects. + */ void qemu_devices_reset(void); #endif -- 2.21.0