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