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