| 1 | /* |
| 2 | * Resettable interface header. |
| 3 | * |
| 4 | * Copyright (c) 2019 GreenSocs SAS |
| 5 | * |
| 6 | * Authors: |
| 7 | * Damien Hedde |
| 8 | * |
| 9 | * This work is licensed under the terms of the GNU GPL, version 2 or later. |
| 10 | * See the COPYING file in the top-level directory. |
| 11 | */ |
| 12 | |
| 13 | #ifndef HW_RESETTABLE_H |
| 14 | #define HW_RESETTABLE_H |
| 15 | |
| 16 | #include "qom/object.h" |
| 17 | |
| 18 | #define TYPE_RESETTABLE_INTERFACE "resettable" |
| 19 | |
| 20 | typedef struct ResettableClass ResettableClass; |
| 21 | DECLARE_CLASS_CHECKERS(ResettableClass, RESETTABLE, |
| 22 | TYPE_RESETTABLE_INTERFACE) |
| 23 | |
| 24 | |
| 25 | typedef struct ResettableState ResettableState; |
| 26 | |
| 27 | /** |
| 28 | * ResetType: |
| 29 | * Types of reset. |
| 30 | * |
| 31 | * + Cold: reset resulting from a power cycle of the object. |
| 32 | * + Wakeup: reset resulting from a wake-up from a suspended state. |
| 33 | * |
| 34 | * TODO: Support has to be added to handle more types. In particular, |
| 35 | * ResettableState structure needs to be expanded. |
| 36 | */ |
| 37 | typedef enum ResetType { |
| 38 | RESET_TYPE_COLD, |
| 39 | RESET_TYPE_SNAPSHOT_LOAD, |
| 40 | RESET_TYPE_WAKEUP, |
| 41 | RESET_TYPE_S390_CPU_INITIAL, |
| 42 | RESET_TYPE_S390_CPU_NORMAL, |
| 43 | } ResetType; |
| 44 | |
| 45 | /* |
| 46 | * ResettableClass: |
| 47 | * Interface for resettable objects. |
| 48 | * |
| 49 | * See docs/devel/reset.rst for more detailed information about how QEMU models |
| 50 | * reset. This whole API must only be used when holding the iothread mutex. |
| 51 | * |
| 52 | * All objects which can be reset must implement this interface; |
| 53 | * it is usually provided by a base class such as DeviceClass or BusClass. |
| 54 | * Every Resettable object must maintain some state tracking the |
| 55 | * progress of a reset operation by providing a ResettableState structure. |
| 56 | * The functions defined in this module take care of updating the |
| 57 | * state of the reset. |
| 58 | * The base class implementation of the interface provides this |
| 59 | * state and implements the associated method: get_state. |
| 60 | * |
| 61 | * Concrete object implementations (typically specific devices |
| 62 | * such as a UART model) should provide the functions |
| 63 | * for the phases.enter, phases.hold and phases.exit methods, which |
| 64 | * they can set in their class init function, either directly or |
| 65 | * by calling resettable_class_set_parent_phases(). |
| 66 | * The phase methods are guaranteed to only only ever be called once |
| 67 | * for any reset event, in the order 'enter', 'hold', 'exit'. |
| 68 | * An object will always move quickly from 'enter' to 'hold' |
| 69 | * but might remain in 'hold' for an arbitrary period of time |
| 70 | * before eventually reset is deasserted and the 'exit' phase is called. |
| 71 | * Object implementations should be prepared for functions handling |
| 72 | * inbound connections from other devices (such as qemu_irq handler |
| 73 | * functions) to be called at any point during reset after their |
| 74 | * 'enter' method has been called. |
| 75 | * |
| 76 | * Users of a resettable object should not call these methods |
| 77 | * directly, but instead use the function resettable_reset(). |
| 78 | * |
| 79 | * @phases.enter: This phase is called when the object enters reset. It |
| 80 | * should reset local state of the object, but it must not do anything that |
| 81 | * has a side-effect on other objects, such as raising or lowering a qemu_irq |
| 82 | * line or reading or writing guest memory. It takes the reset's type as |
| 83 | * argument. |
| 84 | * |
| 85 | * @phases.hold: This phase is called for entry into reset, once every object |
| 86 | * in the system which is being reset has had its @phases.enter method called. |
| 87 | * At this point devices can do actions that affect other objects. |
| 88 | * |
| 89 | * @phases.exit: This phase is called when the object leaves the reset state. |
| 90 | * Actions affecting other objects are permitted. |
| 91 | * |
| 92 | * @get_state: Mandatory method which must return a pointer to a |
| 93 | * ResettableState. |
| 94 | * |
| 95 | * @child_foreach: Executes a given callback on every Resettable child. Child |
| 96 | * in this context means a child in the qbus tree, so the children of a qbus |
| 97 | * are the devices on it, and the children of a device are all the buses it |
| 98 | * owns. This is not the same as the QOM object hierarchy. The function takes |
| 99 | * additional opaque and ResetType arguments which must be passed unmodified to |
| 100 | * the callback. |
| 101 | */ |
| 102 | typedef void (*ResettableEnterPhase)(Object *obj, ResetType type); |
| 103 | typedef void (*ResettableHoldPhase)(Object *obj, ResetType type); |
| 104 | typedef void (*ResettableExitPhase)(Object *obj, ResetType type); |
| 105 | typedef ResettableState * (*ResettableGetState)(Object *obj); |
| 106 | typedef void (*ResettableChildCallback)(Object *, void *opaque, |
| 107 | ResetType type); |
| 108 | typedef void (*ResettableChildForeach)(Object *obj, |
| 109 | ResettableChildCallback cb, |
| 110 | void *opaque, ResetType type); |
| 111 | typedef struct ResettablePhases { |
| 112 | ResettableEnterPhase enter; |
| 113 | ResettableHoldPhase hold; |
| 114 | ResettableExitPhase exit; |
| 115 | } ResettablePhases; |
| 116 | struct ResettableClass { |
| 117 | InterfaceClass parent_class; |
| 118 | |
| 119 | /* Phase methods */ |
| 120 | ResettablePhases phases; |
| 121 | |
| 122 | /* State access method */ |
| 123 | ResettableGetState get_state; |
| 124 | |
| 125 | /* Hierarchy handling method */ |
| 126 | ResettableChildForeach child_foreach; |
| 127 | }; |
| 128 | |
| 129 | /** |
| 130 | * ResettableState: |
| 131 | * Structure holding reset related state. The fields should not be accessed |
| 132 | * directly; the definition is here to allow further inclusion into other |
| 133 | * objects. |
| 134 | * |
| 135 | * @count: Number of reset level the object is into. It is incremented when |
| 136 | * the reset operation starts and decremented when it finishes. |
| 137 | * @hold_phase_pending: flag which indicates that we need to invoke the 'hold' |
| 138 | * phase handler for this object. |
| 139 | * @exit_phase_in_progress: true if we are currently in the exit phase |
| 140 | */ |
| 141 | struct ResettableState { |
| 142 | unsigned count; |
| 143 | bool hold_phase_pending; |
| 144 | bool exit_phase_in_progress; |
| 145 | }; |
| 146 | |
| 147 | /** |
| 148 | * resettable_state_clear: |
| 149 | * Clear the state. It puts the state to the initial (zeroed) state required |
| 150 | * to reuse an object. Typically used in realize step of base classes |
| 151 | * implementing the interface. |
| 152 | */ |
| 153 | static inline void resettable_state_clear(ResettableState *state) |
| 154 | { |
| 155 | memset(state, 0, sizeof(ResettableState)); |
| 156 | } |
| 157 | |
| 158 | /** |
| 159 | * resettable_reset: |
| 160 | * Trigger a reset on an object @obj of type @type. @obj must implement |
| 161 | * Resettable interface. |
| 162 | * |
| 163 | * Calling this function is equivalent to calling @resettable_assert_reset() |
| 164 | * then @resettable_release_reset(). |
| 165 | */ |
| 166 | void resettable_reset(Object *obj, ResetType type); |
| 167 | |
| 168 | /** |
| 169 | * resettable_assert_reset: |
| 170 | * Put an object @obj into reset. @obj must implement Resettable interface. |
| 171 | * |
| 172 | * @resettable_release_reset() must eventually be called after this call. |
| 173 | * There must be one call to @resettable_release_reset() per call of |
| 174 | * @resettable_assert_reset(), with the same type argument. |
| 175 | * |
| 176 | * NOTE: Until support for migration is added, the @resettable_release_reset() |
| 177 | * must not be delayed. It must occur just after @resettable_assert_reset() so |
| 178 | * that migration cannot be triggered in between. Prefer using |
| 179 | * @resettable_reset() for now. |
| 180 | */ |
| 181 | void resettable_assert_reset(Object *obj, ResetType type); |
| 182 | |
| 183 | /** |
| 184 | * resettable_release_reset: |
| 185 | * Release the object @obj from reset. @obj must implement Resettable interface. |
| 186 | * |
| 187 | * See @resettable_assert_reset() description for details. |
| 188 | */ |
| 189 | void resettable_release_reset(Object *obj, ResetType type); |
| 190 | |
| 191 | /** |
| 192 | * resettable_is_in_reset: |
| 193 | * Return true if @obj is under reset. |
| 194 | * |
| 195 | * @obj must implement Resettable interface. |
| 196 | */ |
| 197 | bool resettable_is_in_reset(Object *obj); |
| 198 | |
| 199 | /** |
| 200 | * resettable_change_parent: |
| 201 | * Indicate that the parent of Ressettable @obj is changing from @oldp to @newp. |
| 202 | * All 3 objects must implement resettable interface. @oldp or @newp may be |
| 203 | * NULL. |
| 204 | * |
| 205 | * This function will adapt the reset state of @obj so that it is coherent |
| 206 | * with the reset state of @newp. It may trigger @resettable_assert_reset() |
| 207 | * or @resettable_release_reset(). It will do such things only if the reset |
| 208 | * state of @newp and @oldp are different. |
| 209 | * |
| 210 | * When using this function during reset, it must only be called during |
| 211 | * a hold phase method. Calling this during enter or exit phase is an error. |
| 212 | */ |
| 213 | void resettable_change_parent(Object *obj, Object *newp, Object *oldp); |
| 214 | |
| 215 | /** |
| 216 | * resettable_cold_reset_fn: |
| 217 | * Helper to call resettable_reset((Object *) opaque, RESET_TYPE_COLD). |
| 218 | * |
| 219 | * This function is typically useful to register a reset handler with |
| 220 | * qemu_register_reset. |
| 221 | */ |
| 222 | void resettable_cold_reset_fn(void *opaque); |
| 223 | |
| 224 | /** |
| 225 | * resettable_class_set_parent_phases: |
| 226 | * |
| 227 | * Save @rc current reset phases into @parent_phases and override @rc phases |
| 228 | * by the given new methods (@enter, @hold and @exit). |
| 229 | * Each phase is overridden only if the new one is not NULL allowing to |
| 230 | * override a subset of phases. |
| 231 | */ |
| 232 | void resettable_class_set_parent_phases(ResettableClass *rc, |
| 233 | ResettableEnterPhase enter, |
| 234 | ResettableHoldPhase hold, |
| 235 | ResettableExitPhase exit, |
| 236 | ResettablePhases *parent_phases); |
| 237 | |
| 238 | #endif |