| /* | |
| * Resettable interface header. | |
| * | |
| * Copyright (c) 2019 GreenSocs SAS | |
| * | |
| * Authors: | |
| * Damien Hedde | |
| * | |
| * This work is licensed under the terms of the GNU GPL, version 2 or later. | |
| * See the COPYING file in the top-level directory. | |
| */ | |
| #ifndef HW_RESETTABLE_H | |
| #define HW_RESETTABLE_H | |
| #include "qom/object.h" | |
| #define TYPE_RESETTABLE_INTERFACE "resettable" | |
| typedef struct ResettableClass ResettableClass; | |
| DECLARE_CLASS_CHECKERS(ResettableClass, RESETTABLE, | |
| TYPE_RESETTABLE_INTERFACE) | |
| typedef struct ResettableState ResettableState; | |
| /** | |
| * ResetType: | |
| * Types of reset. | |
| * | |
| * + Cold: reset resulting from a power cycle of the object. | |
| * + Wakeup: reset resulting from a wake-up from a suspended state. | |
| * | |
| * TODO: Support has to be added to handle more types. In particular, | |
| * ResettableState structure needs to be expanded. | |
| */ | |
| typedef enum ResetType { | |
| RESET_TYPE_COLD, | |
| RESET_TYPE_SNAPSHOT_LOAD, | |
| RESET_TYPE_WAKEUP, | |
| RESET_TYPE_S390_CPU_INITIAL, | |
| RESET_TYPE_S390_CPU_NORMAL, | |
| } ResetType; | |
| /* | |
| * ResettableClass: | |
| * Interface for resettable objects. | |
| * | |
| * See docs/devel/reset.rst for more detailed information about how QEMU models | |
| * reset. This whole API must only be used when holding the iothread mutex. | |
| * | |
| * All objects which can be reset must implement this interface; | |
| * it is usually provided by a base class such as DeviceClass or BusClass. | |
| * Every Resettable object must maintain some state tracking the | |
| * progress of a reset operation by providing a ResettableState structure. | |
| * The functions defined in this module take care of updating the | |
| * state of the reset. | |
| * The base class implementation of the interface provides this | |
| * state and implements the associated method: get_state. | |
| * | |
| * Concrete object implementations (typically specific devices | |
| * such as a UART model) should provide the functions | |
| * for the phases.enter, phases.hold and phases.exit methods, which | |
| * they can set in their class init function, either directly or | |
| * by calling resettable_class_set_parent_phases(). | |
| * The phase methods are guaranteed to only only ever be called once | |
| * for any reset event, in the order 'enter', 'hold', 'exit'. | |
| * An object will always move quickly from 'enter' to 'hold' | |
| * but might remain in 'hold' for an arbitrary period of time | |
| * before eventually reset is deasserted and the 'exit' phase is called. | |
| * Object implementations should be prepared for functions handling | |
| * inbound connections from other devices (such as qemu_irq handler | |
| * functions) to be called at any point during reset after their | |
| * 'enter' method has been called. | |
| * | |
| * Users of a resettable object should not call these methods | |
| * directly, but instead use the function resettable_reset(). | |
| * | |
| * @phases.enter: This phase is called when the object enters reset. It | |
| * should reset local state of the object, but it must not do anything that | |
| * has a side-effect on other objects, such as raising or lowering a qemu_irq | |
| * line or reading or writing guest memory. It takes the reset's type as | |
| * argument. | |
| * | |
| * @phases.hold: This phase is called for entry into reset, once every object | |
| * in the system which is being reset has had its @phases.enter method called. | |
| * At this point devices can do actions that affect other objects. | |
| * | |
| * @phases.exit: This phase is called when the object leaves the reset state. | |
| * Actions affecting other objects are permitted. | |
| * | |
| * @get_state: Mandatory method which must return a pointer to a | |
| * ResettableState. | |
| * | |
| * @child_foreach: Executes a given callback on every Resettable child. Child | |
| * in this context means a child in the qbus tree, so the children of a qbus | |
| * are the devices on it, and the children of a device are all the buses it | |
| * owns. This is not the same as the QOM object hierarchy. The function takes | |
| * additional opaque and ResetType arguments which must be passed unmodified to | |
| * the callback. | |
| */ | |
| typedef void (*ResettableEnterPhase)(Object *obj, ResetType type); | |
| typedef void (*ResettableHoldPhase)(Object *obj, ResetType type); | |
| typedef void (*ResettableExitPhase)(Object *obj, ResetType type); | |
| typedef ResettableState * (*ResettableGetState)(Object *obj); | |
| typedef void (*ResettableChildCallback)(Object *, void *opaque, | |
| ResetType type); | |
| typedef void (*ResettableChildForeach)(Object *obj, | |
| ResettableChildCallback cb, | |
| void *opaque, ResetType type); | |
| typedef struct ResettablePhases { | |
| ResettableEnterPhase enter; | |
| ResettableHoldPhase hold; | |
| ResettableExitPhase exit; | |
| } ResettablePhases; | |
| struct ResettableClass { | |
| InterfaceClass parent_class; | |
| /* Phase methods */ | |
| ResettablePhases phases; | |
| /* State access method */ | |
| ResettableGetState get_state; | |
| /* Hierarchy handling method */ | |
| ResettableChildForeach child_foreach; | |
| }; | |
| /** | |
| * ResettableState: | |
| * Structure holding reset related state. The fields should not be accessed | |
| * directly; the definition is here to allow further inclusion into other | |
| * objects. | |
| * | |
| * @count: Number of reset level the object is into. It is incremented when | |
| * the reset operation starts and decremented when it finishes. | |
| * @hold_phase_pending: flag which indicates that we need to invoke the 'hold' | |
| * phase handler for this object. | |
| * @exit_phase_in_progress: true if we are currently in the exit phase | |
| */ | |
| struct ResettableState { | |
| unsigned count; | |
| bool hold_phase_pending; | |
| bool exit_phase_in_progress; | |
| }; | |
| /** | |
| * resettable_state_clear: | |
| * Clear the state. It puts the state to the initial (zeroed) state required | |
| * to reuse an object. Typically used in realize step of base classes | |
| * implementing the interface. | |
| */ | |
| static inline void resettable_state_clear(ResettableState *state) | |
| { | |
| memset(state, 0, sizeof(ResettableState)); | |
| } | |
| /** | |
| * resettable_reset: | |
| * Trigger a reset on an object @obj of type @type. @obj must implement | |
| * Resettable interface. | |
| * | |
| * Calling this function is equivalent to calling @resettable_assert_reset() | |
| * then @resettable_release_reset(). | |
| */ | |
| void resettable_reset(Object *obj, ResetType type); | |
| /** | |
| * resettable_assert_reset: | |
| * Put an object @obj into reset. @obj must implement Resettable interface. | |
| * | |
| * @resettable_release_reset() must eventually be called after this call. | |
| * There must be one call to @resettable_release_reset() per call of | |
| * @resettable_assert_reset(), with the same type argument. | |
| * | |
| * NOTE: Until support for migration is added, the @resettable_release_reset() | |
| * must not be delayed. It must occur just after @resettable_assert_reset() so | |
| * that migration cannot be triggered in between. Prefer using | |
| * @resettable_reset() for now. | |
| */ | |
| void resettable_assert_reset(Object *obj, ResetType type); | |
| /** | |
| * resettable_release_reset: | |
| * Release the object @obj from reset. @obj must implement Resettable interface. | |
| * | |
| * See @resettable_assert_reset() description for details. | |
| */ | |
| void resettable_release_reset(Object *obj, ResetType type); | |
| /** | |
| * resettable_is_in_reset: | |
| * Return true if @obj is under reset. | |
| * | |
| * @obj must implement Resettable interface. | |
| */ | |
| bool resettable_is_in_reset(Object *obj); | |
| /** | |
| * resettable_change_parent: | |
| * Indicate that the parent of Ressettable @obj is changing from @oldp to @newp. | |
| * All 3 objects must implement resettable interface. @oldp or @newp may be | |
| * NULL. | |
| * | |
| * This function will adapt the reset state of @obj so that it is coherent | |
| * with the reset state of @newp. It may trigger @resettable_assert_reset() | |
| * or @resettable_release_reset(). It will do such things only if the reset | |
| * state of @newp and @oldp are different. | |
| * | |
| * When using this function during reset, it must only be called during | |
| * a hold phase method. Calling this during enter or exit phase is an error. | |
| */ | |
| void resettable_change_parent(Object *obj, Object *newp, Object *oldp); | |
| /** | |
| * resettable_cold_reset_fn: | |
| * Helper to call resettable_reset((Object *) opaque, RESET_TYPE_COLD). | |
| * | |
| * This function is typically useful to register a reset handler with | |
| * qemu_register_reset. | |
| */ | |
| void resettable_cold_reset_fn(void *opaque); | |
| /** | |
| * resettable_class_set_parent_phases: | |
| * | |
| * Save @rc current reset phases into @parent_phases and override @rc phases | |
| * by the given new methods (@enter, @hold and @exit). | |
| * Each phase is overridden only if the new one is not NULL allowing to | |
| * override a subset of phases. | |
| */ | |
| void resettable_class_set_parent_phases(ResettableClass *rc, | |
| ResettableEnterPhase enter, | |
| ResettableHoldPhase hold, | |
| ResettableExitPhase exit, | |
| ResettablePhases *parent_phases); | |
| #endif |