xref: /qemu/include/hw/resettable.h (revision db1015e92e04835c9eb50c29625fe566d1202dbd)
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