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