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