 8110fa1d94
			
		
	
	
		8110fa1d94
		
	
	
	
	
		
			
			Generated using: $ ./scripts/codeconverter/converter.py -i \ --pattern=TypeCheckMacro $(git grep -l '' -- '*.[ch]') Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Reviewed-by: Juan Quintela <quintela@redhat.com> Message-Id: <20200831210740.126168-12-ehabkost@redhat.com> Reviewed-by: Juan Quintela <quintela@redhat.com> Message-Id: <20200831210740.126168-13-ehabkost@redhat.com> Message-Id: <20200831210740.126168-14-ehabkost@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
		
			
				
	
	
		
			247 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			247 lines
		
	
	
		
			9.1 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;
 | |
| 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.
 | |
|  *
 | |
|  * 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
 |