123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- /*
- * 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
|