qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

resettable.h (9304B)


      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 } 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  */
    105 typedef void (*ResettableEnterPhase)(Object *obj, ResetType type);
    106 typedef void (*ResettableHoldPhase)(Object *obj);
    107 typedef void (*ResettableExitPhase)(Object *obj);
    108 typedef ResettableState * (*ResettableGetState)(Object *obj);
    109 typedef void (*ResettableTrFunction)(Object *obj);
    110 typedef ResettableTrFunction (*ResettableGetTrFunction)(Object *obj);
    111 typedef void (*ResettableChildCallback)(Object *, void *opaque,
    112                                         ResetType type);
    113 typedef void (*ResettableChildForeach)(Object *obj,
    114                                        ResettableChildCallback cb,
    115                                        void *opaque, ResetType type);
    116 typedef struct ResettablePhases {
    117     ResettableEnterPhase enter;
    118     ResettableHoldPhase hold;
    119     ResettableExitPhase exit;
    120 } ResettablePhases;
    121 struct 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  */
    149 struct 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  */
    161 static 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  */
    174 void 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  */
    189 void 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  */
    197 void 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  */
    205 bool 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  */
    221 void 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  */
    230 void 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  */
    240 void resettable_class_set_parent_phases(ResettableClass *rc,
    241                                         ResettableEnterPhase enter,
    242                                         ResettableHoldPhase hold,
    243                                         ResettableExitPhase exit,
    244                                         ResettablePhases *parent_phases);
    245 
    246 #endif