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