qemu/include/hw/resettable.h
Eduardo Habkost db1015e92e Move QOM typedefs and add missing includes
Some typedefs and macros are defined after the type check macros.
This makes it difficult to automatically replace their
definitions with OBJECT_DECLARE_TYPE.

Patch generated using:

 $ ./scripts/codeconverter/converter.py -i \
   --pattern=QOMStructTypedefSplit $(git grep -l '' -- '*.[ch]')

which will split "typdef struct { ... } TypedefName"
declarations.

Followed by:

 $ ./scripts/codeconverter/converter.py -i --pattern=MoveSymbols \
    $(git grep -l '' -- '*.[ch]')

which will:
- move the typedefs and #defines above the type check macros
- add missing #include "qom/object.h" lines if necessary

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Message-Id: <20200831210740.126168-9-ehabkost@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Message-Id: <20200831210740.126168-10-ehabkost@redhat.com>
Message-Id: <20200831210740.126168-11-ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2020-09-09 09:26:43 -04:00

249 lines
9.2 KiB
C

/*
* 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;
#define RESETTABLE_CLASS(class) \
OBJECT_CLASS_CHECK(ResettableClass, (class), TYPE_RESETTABLE_INTERFACE)
#define RESETTABLE_GET_CLASS(obj) \
OBJECT_GET_CLASS(ResettableClass, (obj), TYPE_RESETTABLE_INTERFACE)
typedef struct ResettableState ResettableState;
/**
* ResetType:
* Types of reset.
*
* + Cold: reset resulting from a power cycle of the object.
*
* TODO: Support has to be added to handle more types. In particular,
* ResettableState structure needs to be expanded.
*/
typedef enum ResetType {
RESET_TYPE_COLD,
} 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.
*
* @get_transitional_function: transitional method to handle Resettable objects
* not yet fully moved to this interface. It will be removed as soon as it is
* not needed anymore. This method is optional and may return a pointer to a
* function to be used instead of the phases. If the method exists and returns
* a non-NULL function pointer then that function is executed as a replacement
* of the 'hold' phase method taking the object as argument. The two other phase
* methods are not executed.
*
* @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);
typedef void (*ResettableExitPhase)(Object *obj);
typedef ResettableState * (*ResettableGetState)(Object *obj);
typedef void (*ResettableTrFunction)(Object *obj);
typedef ResettableTrFunction (*ResettableGetTrFunction)(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;
/* Transitional method for legacy reset compatibility */
ResettableGetTrFunction get_transitional_function;
/* 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