summary refs log tree commit diff stats
path: root/hw/core
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2024-09-13 16:14:33 +0100
committerPeter Maydell <peter.maydell@linaro.org>2024-09-13 16:14:33 +0100
commit28ae3179fc52d2e4d870b635c4a412aab99759e7 (patch)
tree13db2e7974cf23becc98de328c5907f373f0fc31 /hw/core
parent63731c346f071a77e1bb1789bef1ac9d592b6d4f (diff)
parent110684c9a69a02cbabfbddcd3afa921826ad565c (diff)
downloadfocaccia-qemu-28ae3179fc52d2e4d870b635c4a412aab99759e7.tar.gz
focaccia-qemu-28ae3179fc52d2e4d870b635c4a412aab99759e7.zip
Merge tag 'pull-target-arm-20240913' of https://git.linaro.org/people/pmaydell/qemu-arm into staging
target-arm queue:
 * s390: convert s390 virtio-ccw and CPU to three-phase reset
 * reset: remove now-unused device_class_set_parent_reset()
 * reset: introduce device_class_set_legacy_reset()
 * reset: remove unneeded transitional machinery
 * kvm: Use 'unsigned long' for request argument in functions wrapping ioctl()
 * hvf: arm: Implement and use hvf_get_physical_address_range
   so VMs can have larger-than-36-bit IPA spaces when the host
   supports this
 * target/arm/tcg: refine cache descriptions with a wrapper
 * hw/net/can/xlnx-versal-canfd: fix various bugs
 * MAINTAINERS: update versal, CAN maintainer entries
 * hw/intc/arm_gic: fix spurious level triggered interrupts

# -----BEGIN PGP SIGNATURE-----
#
# iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmbkVokZHHBldGVyLm1h
# eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3pR5D/0ZJzJi7C0HIa4KYuBkcpZQ
# M3iUa1uiZoCniXlWuKFt2rUBrmhbW30YHw5gQjnxoUO4VVqREkFi3e5nzUKRQmvP
# FRm8dnuC36qwQJFhm+rQqUb8/AyqrVFnIaHhn7dBKLwRFm9+kbZ0v9x1Eq1DZk3S
# mijBQRiOjrj+FRkmyNJLhylGpm+p9VRdnBjmUtN2Yw+2fPkHmUURRSUvhwCK4BB5
# AvKgMC0EIIsLJKLfrWzk/EsYC8ogrGitISzFt8iWLAqxuxtuhv1StstleD4mZMK8
# gH+ZH5tsls2IiTIKkHfcbUcA55efDrQHGDat7n1Q0EWqOjET0soES+GpS0Jj6IXK
# uOnsDZ7MLFU/SbpckicLQ/JwNi3HiIfQgBVB2aJZ+cg8CGqaQCI5ZvWs7XFpUgkb
# naA4IR5mdNgXJm7ttBKbWarPNcmdODqa/5YDjXdyHmMx3JD994k1y5LIi3o69TgI
# rgHzU8ChZqaBDEvNa5KGtadQPnaSBP15Yqbp5rn2knVRKjDdyCdB94aWO5tZkmaO
# ARFmNk6h5bhwXdXl2Hu67RS2Kd0/fHMFWsxyHAX4NYT+Vq+ZTjLdaPzwFdfA0yAz
# wXWn0EAeYQ5M2xOPfDM/JYSc1THSzhpwy/CBrRjrCRZMDE+bx9BRC7pUXwquE8xF
# CW1NUxkvZikQeiMzgEBbTA==
# =u6u8
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 13 Sep 2024 16:13:13 BST
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [ultimate]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate]
# gpg:                 aka "Peter Maydell <peter@archaic.org.uk>" [ultimate]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* tag 'pull-target-arm-20240913' of https://git.linaro.org/people/pmaydell/qemu-arm: (27 commits)
  hw/intc/arm_gic: fix spurious level triggered interrupts
  MAINTAINERS: Add my-self as CAN maintainer
  MAINTAINERS: Update Xilinx Versal OSPI maintainer's email address
  MAINTAINERS: Remove Vikram Garhwal as maintainer
  hw/net/can/xlnx-versal-canfd: Fix FIFO issues
  hw/net/can/xlnx-versal-canfd: Simplify DLC conversions
  hw/net/can/xlnx-versal-canfd: Fix byte ordering
  hw/net/can/xlnx-versal-canfd: Handle flags correctly
  hw/net/can/xlnx-versal-canfd: Translate CAN ID registers
  hw/net/can/xlnx-versal-canfd: Fix CAN FD flag check
  hw/net/can/xlnx-versal-canfd: Fix interrupt level
  target/arm/tcg: refine cache descriptions with a wrapper
  hvf: arm: Implement and use hvf_get_physical_address_range
  hvf: Split up hv_vm_create logic per arch
  hw/boards: Add hvf_get_physical_address_range to MachineClass
  kvm: Use 'unsigned long' for request argument in functions wrapping ioctl()
  hw/core/resettable: Remove transitional_function machinery
  hw/core/qdev: Simplify legacy_reset handling
  hw: Remove device_phases_reset()
  hw: Rename DeviceClass::reset field to legacy_reset
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/core')
-rw-r--r--hw/core/or-irq.c2
-rw-r--r--hw/core/qdev.c97
-rw-r--r--hw/core/resettable.c24
3 files changed, 32 insertions, 91 deletions
diff --git a/hw/core/or-irq.c b/hw/core/or-irq.c
index 13907df026..b25468e38a 100644
--- a/hw/core/or-irq.c
+++ b/hw/core/or-irq.c
@@ -124,7 +124,7 @@ static void or_irq_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
 
-    dc->reset = or_irq_reset;
+    device_class_set_legacy_reset(dc, or_irq_reset);
     device_class_set_props(dc, or_irq_properties);
     dc->realize = or_irq_realize;
     dc->vmsd = &vmstate_or_irq;
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index f3a996f57d..db36f54d91 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -747,57 +747,6 @@ device_vmstate_if_get_id(VMStateIf *obj)
     return qdev_get_dev_path(dev);
 }
 
-/**
- * device_phases_reset:
- * Transition reset method for devices to allow moving
- * smoothly from legacy reset method to multi-phases
- */
-static void device_phases_reset(DeviceState *dev)
-{
-    ResettableClass *rc = RESETTABLE_GET_CLASS(dev);
-
-    if (rc->phases.enter) {
-        rc->phases.enter(OBJECT(dev), RESET_TYPE_COLD);
-    }
-    if (rc->phases.hold) {
-        rc->phases.hold(OBJECT(dev), RESET_TYPE_COLD);
-    }
-    if (rc->phases.exit) {
-        rc->phases.exit(OBJECT(dev), RESET_TYPE_COLD);
-    }
-}
-
-static void device_transitional_reset(Object *obj)
-{
-    DeviceClass *dc = DEVICE_GET_CLASS(obj);
-
-    /*
-     * This will call either @device_phases_reset (for multi-phases transitioned
-     * devices) or a device's specific method for not-yet transitioned devices.
-     * In both case, it does not reset children.
-     */
-    if (dc->reset) {
-        dc->reset(DEVICE(obj));
-    }
-}
-
-/**
- * device_get_transitional_reset:
- * check if the device's class is ready for multi-phase
- */
-static ResettableTrFunction device_get_transitional_reset(Object *obj)
-{
-    DeviceClass *dc = DEVICE_GET_CLASS(obj);
-    if (dc->reset != device_phases_reset) {
-        /*
-         * dc->reset has been overridden by a subclass,
-         * the device is not ready for multi phase yet.
-         */
-        return device_transitional_reset;
-    }
-    return NULL;
-}
-
 static void device_class_init(ObjectClass *class, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(class);
@@ -819,20 +768,12 @@ static void device_class_init(ObjectClass *class, void *data)
     rc->child_foreach = device_reset_child_foreach;
 
     /*
-     * @device_phases_reset is put as the default reset method below, allowing
-     * to do the multi-phase transition from base classes to leaf classes. It
-     * allows a legacy-reset Device class to extend a multi-phases-reset
-     * Device class for the following reason:
-     * + If a base class B has been moved to multi-phase, then it does not
-     *   override this default reset method and may have defined phase methods.
-     * + A child class C (extending class B) which uses
-     *   device_class_set_parent_reset() (or similar means) to override the
-     *   reset method will still work as expected. @device_phases_reset function
-     *   will be registered as the parent reset method and effectively call
-     *   parent reset phases.
+     * A NULL legacy_reset implies a three-phase reset device. Devices can
+     * only be reset using three-phase aware mechanisms, but we still support
+     * for transitional purposes leaf classes which set the old legacy_reset
+     * method via device_class_set_legacy_reset().
      */
-    dc->reset = device_phases_reset;
-    rc->get_transitional_function = device_get_transitional_reset;
+    dc->legacy_reset = NULL;
 
     object_class_property_add_bool(class, "realized",
                                    device_get_realized, device_set_realized);
@@ -844,12 +785,30 @@ static void device_class_init(ObjectClass *class, void *data)
                                    offsetof(DeviceState, parent_bus), NULL, 0);
 }
 
-void device_class_set_parent_reset(DeviceClass *dc,
-                                   DeviceReset dev_reset,
-                                   DeviceReset *parent_reset)
+static void do_legacy_reset(Object *obj, ResetType type)
 {
-    *parent_reset = dc->reset;
-    dc->reset = dev_reset;
+    DeviceClass *dc = DEVICE_GET_CLASS(obj);
+
+    dc->legacy_reset(DEVICE(obj));
+}
+
+void device_class_set_legacy_reset(DeviceClass *dc, DeviceReset dev_reset)
+{
+    /*
+     * A legacy DeviceClass::reset has identical semantics to the
+     * three-phase "hold" method, with no "enter" or "exit"
+     * behaviour. Classes that use this legacy function must be leaf
+     * classes that do not chain up to their parent class reset.
+     * There is no mechanism for resetting a device that does not
+     * use the three-phase APIs, so the only place which calls
+     * the legacy_reset hook is do_legacy_reset().
+     */
+    ResettableClass *rc = RESETTABLE_CLASS(dc);
+
+    rc->phases.enter = NULL;
+    rc->phases.hold = do_legacy_reset;
+    rc->phases.exit = NULL;
+    dc->legacy_reset = dev_reset;
 }
 
 void device_class_set_parent_realize(DeviceClass *dc,
diff --git a/hw/core/resettable.c b/hw/core/resettable.c
index 6dd3e3dc48..5cdb4a4f8d 100644
--- a/hw/core/resettable.c
+++ b/hw/core/resettable.c
@@ -93,20 +93,6 @@ static void resettable_child_foreach(ResettableClass *rc, Object *obj,
     }
 }
 
-/**
- * resettable_get_tr_func:
- * helper to fetch transitional reset callback if any.
- */
-static ResettableTrFunction resettable_get_tr_func(ResettableClass *rc,
-                                                   Object *obj)
-{
-    ResettableTrFunction tr_func = NULL;
-    if (rc->get_transitional_function) {
-        tr_func = rc->get_transitional_function(obj);
-    }
-    return tr_func;
-}
-
 static void resettable_phase_enter(Object *obj, void *opaque, ResetType type)
 {
     ResettableClass *rc = RESETTABLE_GET_CLASS(obj);
@@ -146,7 +132,7 @@ static void resettable_phase_enter(Object *obj, void *opaque, ResetType type)
     if (action_needed) {
         trace_resettable_phase_enter_exec(obj, obj_typename, type,
                                           !!rc->phases.enter);
-        if (rc->phases.enter && !resettable_get_tr_func(rc, obj)) {
+        if (rc->phases.enter) {
             rc->phases.enter(obj, type);
         }
         s->hold_phase_pending = true;
@@ -171,12 +157,8 @@ static void resettable_phase_hold(Object *obj, void *opaque, ResetType type)
     /* exec hold phase */
     if (s->hold_phase_pending) {
         s->hold_phase_pending = false;
-        ResettableTrFunction tr_func = resettable_get_tr_func(rc, obj);
         trace_resettable_phase_hold_exec(obj, obj_typename, !!rc->phases.hold);
-        if (tr_func) {
-            trace_resettable_transitional_function(obj, obj_typename);
-            tr_func(obj);
-        } else if (rc->phases.hold) {
+        if (rc->phases.hold) {
             rc->phases.hold(obj, type);
         }
     }
@@ -199,7 +181,7 @@ static void resettable_phase_exit(Object *obj, void *opaque, ResetType type)
     assert(s->count > 0);
     if (--s->count == 0) {
         trace_resettable_phase_exit_exec(obj, obj_typename, !!rc->phases.exit);
-        if (rc->phases.exit && !resettable_get_tr_func(rc, obj)) {
+        if (rc->phases.exit) {
             rc->phases.exit(obj, type);
         }
     }