Skip to content

Commit

Permalink
hw/core: Add ResetContainer which holds objects implementing Resettable
Browse files Browse the repository at this point in the history
Implement a ResetContainer.  This is a subclass of Object, and it
implements the Resettable interface.  The container holds a list of
arbitrary other objects which implement Resettable, and when the
container is reset, all the objects it contains are also reset.

This will allow us to have a 3-phase-reset equivalent of the old
qemu_register_reset() API: we will have a single "simulation reset"
top level ResetContainer, and objects in it are the equivalent of the
old QEMUResetHandler functions.

The qemu_register_reset() API manages its list of callbacks using a
QTAILQ, but here we use a GPtrArray for our list of Resettable
children: we expect the "remove" operation (which will need to do an
iteration through the list) to be fairly uncommon, and we get simpler
code with fewer memory allocations.

Since there is currently no listed owner in MAINTAINERS for the
existing reset-related source files, create a new section for
them, and add these new files there also.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Message-id: 20240220160622.114437-7-peter.maydell@linaro.org
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
  • Loading branch information
pm215 committed Feb 27, 2024
1 parent 9f1c70a commit 4c046ce
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 0 deletions.
10 changes: 10 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -3676,6 +3676,16 @@ F: hw/core/clock-vmstate.c
F: hw/core/qdev-clock.c
F: docs/devel/clocks.rst

Reset framework
M: Peter Maydell <peter.maydell@linaro.org>
S: Maintained
F: include/hw/resettable.h
F: include/hw/core/resetcontainer.h
F: include/sysemu/reset.h
F: hw/core/reset.c
F: hw/core/resettable.c
F: hw/core/resetcontainer.c

Usermode Emulation
------------------
Overall usermode emulation
Expand Down
1 change: 1 addition & 0 deletions hw/core/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ hwcore_ss.add(files(
'qdev-properties.c',
'qdev.c',
'reset.c',
'resetcontainer.c',
'resettable.c',
'vmstate-if.c',
# irq.c needed for qdev GPIO handling:
Expand Down
77 changes: 77 additions & 0 deletions hw/core/resetcontainer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Reset container
*
* Copyright (c) 2024 Linaro, Ltd
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/

/*
* The "reset container" is an object which implements the Resettable
* interface. It contains a list of arbitrary other objects which also
* implement Resettable. Resetting the reset container resets all the
* objects in it.
*/

#include "qemu/osdep.h"
#include "hw/resettable.h"
#include "hw/core/resetcontainer.h"

struct ResettableContainer {
Object parent;
ResettableState reset_state;
GPtrArray *children;
};

OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(ResettableContainer, resettable_container, RESETTABLE_CONTAINER, OBJECT, { TYPE_RESETTABLE_INTERFACE }, { })

void resettable_container_add(ResettableContainer *rc, Object *obj)
{
INTERFACE_CHECK(void, obj, TYPE_RESETTABLE_INTERFACE);
g_ptr_array_add(rc->children, obj);
}

void resettable_container_remove(ResettableContainer *rc, Object *obj)
{
g_ptr_array_remove(rc->children, obj);
}

static ResettableState *resettable_container_get_state(Object *obj)
{
ResettableContainer *rc = RESETTABLE_CONTAINER(obj);
return &rc->reset_state;
}

static void resettable_container_child_foreach(Object *obj,
ResettableChildCallback cb,
void *opaque, ResetType type)
{
ResettableContainer *rc = RESETTABLE_CONTAINER(obj);
unsigned int len = rc->children->len;

for (unsigned int i = 0; i < len; i++) {
cb(g_ptr_array_index(rc->children, i), opaque, type);
/* Detect callbacks trying to unregister themselves */
assert(len == rc->children->len);
}
}

static void resettable_container_init(Object *obj)
{
ResettableContainer *rc = RESETTABLE_CONTAINER(obj);

rc->children = g_ptr_array_new();
}

static void resettable_container_finalize(Object *obj)
{
}

static void resettable_container_class_init(ObjectClass *klass, void *data)
{
ResettableClass *rc = RESETTABLE_CLASS(klass);

rc->get_state = resettable_container_get_state;
rc->child_foreach = resettable_container_child_foreach;
}
48 changes: 48 additions & 0 deletions include/hw/core/resetcontainer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Reset container
*
* Copyright (c) 2024 Linaro, Ltd
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/

#ifndef HW_RESETCONTAINER_H
#define HW_RESETCONTAINER_H

/*
* The "reset container" is an object which implements the Resettable
* interface. It contains a list of arbitrary other objects which also
* implement Resettable. Resetting the reset container resets all the
* objects in it.
*/

#include "qom/object.h"

#define TYPE_RESETTABLE_CONTAINER "resettable-container"
OBJECT_DECLARE_TYPE(ResettableContainer, ResettableContainerClass, RESETTABLE_CONTAINER)

/**
* resettable_container_add: Add a resettable object to the container
* @rc: container
* @obj: object to add to the container
*
* Add @obj to the ResettableContainer @rc. @obj must implement the
* Resettable interface.
*
* When @rc is reset, it will reset every object that has been added
* to it, in the order they were added.
*/
void resettable_container_add(ResettableContainer *rc, Object *obj);

/**
* resettable_container_remove: Remove an object from the container
* @rc: container
* @obj: object to remove from the container
*
* Remove @obj from the ResettableContainer @rc. @obj must have been
* previously added to this container.
*/
void resettable_container_remove(ResettableContainer *rc, Object *obj);

#endif

0 comments on commit 4c046ce

Please sign in to comment.