mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-18 23:52:14 -06:00
reset: Add RESET_TYPE_SNAPSHOT_LOAD
Some devices and machines need to handle the reset before a vmsave snapshot is loaded differently -- the main user is the handling of RNG seed information, which does not want to put a new RNG seed into a ROM blob when we are doing a snapshot load. Currently this kind of reset handling is supported only for: * TYPE_MACHINE reset methods, which take a ShutdownCause argument * reset functions registered with qemu_register_reset_nosnapshotload To allow a three-phase-reset device to also distinguish "snapshot load" reset from the normal kind, add a new ResetType RESET_TYPE_SNAPSHOT_LOAD. All our existing reset methods ignore the reset type, so we don't need to update any device code. Add the enum type, and make qemu_devices_reset() use the right reset type for the ShutdownCause it is passed. This allows us to get rid of the device_reset_reason global we were using to implement qemu_register_reset_nosnapshotload(). Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Luc Michel <luc.michel@amd.com> Message-id: 20240412160809.1260625-7-peter.maydell@linaro.org
This commit is contained in:
parent
41d49ec190
commit
631f46d4ea
4 changed files with 19 additions and 18 deletions
|
@ -27,9 +27,7 @@ instantly reset an object, without keeping it in reset state, just call
|
||||||
``resettable_reset()``. These functions take two parameters: a pointer to the
|
``resettable_reset()``. These functions take two parameters: a pointer to the
|
||||||
object to reset and a reset type.
|
object to reset and a reset type.
|
||||||
|
|
||||||
Several types of reset will be supported. For now only cold reset is defined;
|
The Resettable interface handles reset types with an enum ``ResetType``:
|
||||||
others may be added later. The Resettable interface handles reset types with an
|
|
||||||
enum:
|
|
||||||
|
|
||||||
``RESET_TYPE_COLD``
|
``RESET_TYPE_COLD``
|
||||||
Cold reset is supported by every resettable object. In QEMU, it means we reset
|
Cold reset is supported by every resettable object. In QEMU, it means we reset
|
||||||
|
@ -37,6 +35,19 @@ enum:
|
||||||
from what is a real hardware cold reset. It differs from other resets (like
|
from what is a real hardware cold reset. It differs from other resets (like
|
||||||
warm or bus resets) which may keep certain parts untouched.
|
warm or bus resets) which may keep certain parts untouched.
|
||||||
|
|
||||||
|
``RESET_TYPE_SNAPSHOT_LOAD``
|
||||||
|
This is called for a reset which is being done to put the system into a
|
||||||
|
clean state prior to loading a snapshot. (This corresponds to a reset
|
||||||
|
with ``SHUTDOWN_CAUSE_SNAPSHOT_LOAD``.) Almost all devices should treat
|
||||||
|
this the same as ``RESET_TYPE_COLD``. The main exception is devices which
|
||||||
|
have some non-deterministic state they want to reinitialize to a different
|
||||||
|
value on each cold reset, such as RNG seed information, and which they
|
||||||
|
must not reinitialize on a snapshot-load reset.
|
||||||
|
|
||||||
|
Devices which implement reset methods must treat any unknown ``ResetType``
|
||||||
|
as equivalent to ``RESET_TYPE_COLD``; this will reduce the amount of
|
||||||
|
existing code we need to change if we add more types in future.
|
||||||
|
|
||||||
Calling ``resettable_reset()`` is equivalent to calling
|
Calling ``resettable_reset()`` is equivalent to calling
|
||||||
``resettable_assert_reset()`` then ``resettable_release_reset()``. It is
|
``resettable_assert_reset()`` then ``resettable_release_reset()``. It is
|
||||||
possible to interleave multiple calls to these three functions. There may
|
possible to interleave multiple calls to these three functions. There may
|
||||||
|
|
|
@ -43,13 +43,6 @@ static ResettableContainer *get_root_reset_container(void)
|
||||||
return root_reset_container;
|
return root_reset_container;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Reason why the currently in-progress qemu_devices_reset() was called.
|
|
||||||
* If we made at least SHUTDOWN_CAUSE_SNAPSHOT_LOAD have a corresponding
|
|
||||||
* ResetType we could perhaps avoid the need for this global.
|
|
||||||
*/
|
|
||||||
static ShutdownCause device_reset_reason;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is an Object which implements Resettable simply to call the
|
* This is an Object which implements Resettable simply to call the
|
||||||
* callback function in the hold phase.
|
* callback function in the hold phase.
|
||||||
|
@ -77,8 +70,7 @@ static void legacy_reset_hold(Object *obj, ResetType type)
|
||||||
{
|
{
|
||||||
LegacyReset *lr = LEGACY_RESET(obj);
|
LegacyReset *lr = LEGACY_RESET(obj);
|
||||||
|
|
||||||
if (device_reset_reason == SHUTDOWN_CAUSE_SNAPSHOT_LOAD &&
|
if (type == RESET_TYPE_SNAPSHOT_LOAD && lr->skip_on_snapshot_load) {
|
||||||
lr->skip_on_snapshot_load) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lr->func(lr->opaque);
|
lr->func(lr->opaque);
|
||||||
|
@ -180,8 +172,9 @@ void qemu_unregister_resettable(Object *obj)
|
||||||
|
|
||||||
void qemu_devices_reset(ShutdownCause reason)
|
void qemu_devices_reset(ShutdownCause reason)
|
||||||
{
|
{
|
||||||
device_reset_reason = reason;
|
ResetType type = (reason == SHUTDOWN_CAUSE_SNAPSHOT_LOAD) ?
|
||||||
|
RESET_TYPE_SNAPSHOT_LOAD : RESET_TYPE_COLD;
|
||||||
|
|
||||||
/* Reset the simulation */
|
/* Reset the simulation */
|
||||||
resettable_reset(OBJECT(get_root_reset_container()), RESET_TYPE_COLD);
|
resettable_reset(OBJECT(get_root_reset_container()), type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,8 +48,6 @@ void resettable_reset(Object *obj, ResetType type)
|
||||||
|
|
||||||
void resettable_assert_reset(Object *obj, ResetType type)
|
void resettable_assert_reset(Object *obj, ResetType type)
|
||||||
{
|
{
|
||||||
/* TODO: change this assert when adding support for other reset types */
|
|
||||||
assert(type == RESET_TYPE_COLD);
|
|
||||||
trace_resettable_reset_assert_begin(obj, type);
|
trace_resettable_reset_assert_begin(obj, type);
|
||||||
assert(!enter_phase_in_progress);
|
assert(!enter_phase_in_progress);
|
||||||
|
|
||||||
|
@ -64,8 +62,6 @@ void resettable_assert_reset(Object *obj, ResetType type)
|
||||||
|
|
||||||
void resettable_release_reset(Object *obj, ResetType type)
|
void resettable_release_reset(Object *obj, ResetType type)
|
||||||
{
|
{
|
||||||
/* TODO: change this assert when adding support for other reset types */
|
|
||||||
assert(type == RESET_TYPE_COLD);
|
|
||||||
trace_resettable_reset_release_begin(obj, type);
|
trace_resettable_reset_release_begin(obj, type);
|
||||||
assert(!enter_phase_in_progress);
|
assert(!enter_phase_in_progress);
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ typedef struct ResettableState ResettableState;
|
||||||
*/
|
*/
|
||||||
typedef enum ResetType {
|
typedef enum ResetType {
|
||||||
RESET_TYPE_COLD,
|
RESET_TYPE_COLD,
|
||||||
|
RESET_TYPE_SNAPSHOT_LOAD,
|
||||||
} ResetType;
|
} ResetType;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue