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