[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC PATCH 04/17] Add local reset methods in Device class
From: |
Damien Hedde |
Subject: |
[Qemu-devel] [RFC PATCH 04/17] Add local reset methods in Device class |
Date: |
Mon, 25 Mar 2019 12:01:47 +0100 |
Add 3 methods in device class corresponding to the local part of
the 3-phases reset. This allows specialization classes not to care
about the ressetting counter and sub-buses. The exit phase method
is called only if resetting counter hits 0.
Also, these methods are called in `device_reset`. Specializations can switch
from the single-phase reset to the 3-phases reset with no effects on the
`device_reset` behavior.
Signed-off-by: Damien Hedde <address@hidden>
---
hw/core/qdev.c | 44 ++++++++++++++++++++++++++++++++++++++++++
include/hw/qdev-core.h | 17 ++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 98d173f34f..884a49efa4 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -280,21 +280,30 @@ static void device_reset_init_phase(Object *obj, bool
cold)
if (dc->reset) {
dc->reset(dev);
}
+ if (dc->reset_phases.init) {
+ dc->reset_phases.init(OBJECT(dev), cold);
+ }
}
static void device_reset_hold_phase(Object *obj)
{
DeviceState *dev = DEVICE(obj);
+ DeviceClass *dc = DEVICE_GET_CLASS(obj);
BusState *child;
QLIST_FOREACH(child, &dev->child_bus, sibling) {
resettable_hold_phase(OBJECT(child));
}
+
+ if (dc->reset_phases.hold) {
+ dc->reset_phases.hold(OBJECT(dev));
+ }
}
static void device_reset_exit_phase(Object *obj)
{
DeviceState *dev = DEVICE(obj);
+ DeviceClass *dc = DEVICE_GET_CLASS(obj);
BusState *child;
QLIST_FOREACH(child, &dev->child_bus, sibling) {
@@ -303,6 +312,12 @@ static void device_reset_exit_phase(Object *obj)
assert(dev->resetting > 0);
dev->resetting -= 1;
+
+ if (dev->resetting == 0) {
+ if (dc->reset_phases.exit) {
+ dc->reset_phases.exit(OBJECT(dev));
+ }
+ }
}
static int qdev_reset_one(DeviceState *dev, void *opaque)
@@ -1143,6 +1158,24 @@ void device_class_set_parent_unrealize(DeviceClass *dc,
dc->unrealize = dev_unrealize;
}
+void device_class_set_parent_reset_phases(DeviceClass *dc,
+ ResettableInitPhase dev_reset_init,
+ ResettableHoldPhase dev_reset_hold,
+ ResettableExitPhase dev_reset_exit,
+ ResettablePhases *parent_phases)
+{
+ *parent_phases = dc->reset_phases;
+ if (dev_reset_init) {
+ dc->reset_phases.init = dev_reset_init;
+ }
+ if (dev_reset_hold) {
+ dc->reset_phases.hold = dev_reset_hold;
+ }
+ if (dev_reset_exit) {
+ dc->reset_phases.exit = dev_reset_exit;
+ }
+}
+
void device_reset(DeviceState *dev)
{
DeviceClass *klass = DEVICE_GET_CLASS(dev);
@@ -1150,6 +1183,17 @@ void device_reset(DeviceState *dev)
if (klass->reset) {
klass->reset(dev);
}
+ dev->resetting += 1;
+ if (klass->reset_phases.init) {
+ klass->reset_phases.init(OBJECT(dev), false);
+ }
+ if (klass->reset_phases.hold) {
+ klass->reset_phases.hold(OBJECT(dev));
+ }
+ dev->resetting -= 1;
+ if (klass->reset_phases.exit) {
+ klass->reset_phases.exit(OBJECT(dev));
+ }
}
Object *qdev_get_machine(void)
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index f4aa8dbaa2..0ef4d6c920 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -6,6 +6,7 @@
#include "qom/object.h"
#include "hw/irq.h"
#include "hw/hotplug.h"
+#include "hw/resettable.h"
enum {
DEV_NVECTORS_UNSPECIFIED = -1,
@@ -110,6 +111,7 @@ typedef struct DeviceClass {
DeviceReset reset;
DeviceRealize realize;
DeviceUnrealize unrealize;
+ ResettablePhases reset_phases;
/* device state */
const struct VMStateDescription *vmsd;
@@ -455,6 +457,21 @@ void device_class_set_parent_unrealize(DeviceClass *dc,
DeviceUnrealize dev_unrealize,
DeviceUnrealize *parent_unrealize);
+/**
+ * @device_class_set_parent_reset_phases:
+ *
+ * Save @dc current reset phases into @parent_phases and override @dc phases
+ * by the given new methods (@dev_reset_init, @dev_reset_hold and
+ * @dev_reset_exit).
+ * Each phase is overriden only if the new one is not NULL allowing to
+ * override a subset of phases.
+ */
+void device_class_set_parent_reset_phases(DeviceClass *dc,
+ ResettableInitPhase dev_reset_init,
+ ResettableHoldPhase dev_reset_hold,
+ ResettableExitPhase dev_reset_exit,
+ ResettablePhases *parent_phases);
+
const struct VMStateDescription *qdev_get_vmsd(DeviceState *dev);
const char *qdev_fw_name(DeviceState *dev);
--
2.21.0
- [Qemu-devel] [RFC 00/17] multi-phase reset mechanism, Damien Hedde, 2019/03/25
- [Qemu-devel] [RFC PATCH 07/17] convert qdev/bus_reset_all to Resettable, Damien Hedde, 2019/03/25
- [Qemu-devel] [RFC PATCH 02/17] Create the ResetDomain QOM object, Damien Hedde, 2019/03/25
- [Qemu-devel] [RFC PATCH 08/17] Add a global ResetDomain object for system emulation, Damien Hedde, 2019/03/25
- [Qemu-devel] [RFC PATCH 03/17] make Device and Bus Resettable, Damien Hedde, 2019/03/25
- [Qemu-devel] [RFC PATCH 09/17] global ResetDomain support for legacy reset handlers, Damien Hedde, 2019/03/25
- [Qemu-devel] [RFC PATCH 10/17] Delete the system ResetDomain at the end of emulation, Damien Hedde, 2019/03/25
- [Qemu-devel] [RFC PATCH 04/17] Add local reset methods in Device class,
Damien Hedde <=
- [Qemu-devel] [RFC PATCH 05/17] add vmstate description for device reset state, Damien Hedde, 2019/03/25
- [Qemu-devel] [RFC PATCH 06/17] Add function to control reset with gpio inputs, Damien Hedde, 2019/03/25
- [Qemu-devel] [RFC PATCH 01/17] Create Resettable QOM interface, Damien Hedde, 2019/03/25
- [Qemu-devel] [RFC PATCH 11/17] Put orphan buses in system reset domain, Damien Hedde, 2019/03/25
- [Qemu-devel] [RFC PATCH 12/17] Put default sysbus in system reset domain, Damien Hedde, 2019/03/25
- [Qemu-devel] [RFC PATCH 17/17] Connect the uart reset gpios in the zynq platform, Damien Hedde, 2019/03/25
- [Qemu-devel] [RFC PATCH 14/17] convert cadence_uart to 3-phases reset, Damien Hedde, 2019/03/25
- [Qemu-devel] [RFC PATCH 16/17] Add uart reset support in zynq_slcr, Damien Hedde, 2019/03/25
- [Qemu-devel] [RFC PATCH 13/17] hw/misc/zynq_slcr: use standard register definition, Damien Hedde, 2019/03/25
- [Qemu-devel] [RFC PATCH 15/17] Convert zynq's slcr to 3-phases reset, Damien Hedde, 2019/03/25