Tested-by: Jim Shu <jim....@sifive.com> On Thu, May 19, 2022 at 11:41 PM Damien Hedde <damien.he...@greensocs.com> wrote:
> phase_until() is implemented in vl.c and is meant to be used > to make startup progress up to a specified phase being reached(). > At this point, no behavior change is introduced: phase_until() > only supports a single double transition corresponding > to the functionality of qmp_exit_preconfig(): > + accel-created -> machine-initialized -> machine-ready > > As a result qmp_exit_preconfig() now uses phase_until(). > > This commit is a preparation to support cold plugging a device > using qapi command (which will be introduced in a following commit). > For this we need fine grain control of the phase. > > Signed-off-by: Damien Hedde <damien.he...@greensocs.com> > --- > > v5: > + refactor to avoid indentation change > --- > include/hw/qdev-core.h | 14 +++++++++++++ > softmmu/vl.c | 46 ++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 60 insertions(+) > > diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h > index e29c705b74..5f73d06408 100644 > --- a/include/hw/qdev-core.h > +++ b/include/hw/qdev-core.h > @@ -909,4 +909,18 @@ extern bool phase_check(MachineInitPhase phase); > */ > extern void phase_advance(MachineInitPhase phase); > > +/** > + * @phase_until: > + * @phase: the target phase > + * @errp: error report > + * > + * Make the machine init progress until the target phase is reached. > + * > + * Its is a no-op is the target phase is the current or an earlier > + * phase. > + * > + * Returns true in case of success. > + */ > +extern bool phase_until(MachineInitPhase phase, Error **errp); > + > #endif > diff --git a/softmmu/vl.c b/softmmu/vl.c > index 84a31eba76..7f8d15b5b8 100644 > --- a/softmmu/vl.c > +++ b/softmmu/vl.c > @@ -2702,11 +2702,17 @@ void qmp_x_exit_preconfig(Error **errp) > error_setg(errp, "The command is permitted only before machine > initialization"); > return; > } > + phase_until(PHASE_MACHINE_READY, errp); > +} > > +static void qemu_phase_ready(Error **errp) > +{ > qemu_init_board(); > + /* phase is now PHASE_MACHINE_INITIALIZED. */ > qemu_create_cli_devices(); > cxl_fixed_memory_window_link_targets(errp); > qemu_machine_creation_done(); > + /* Phase is now PHASE_MACHINE_READY. */ > > if (loadvm) { > load_snapshot(loadvm, NULL, false, NULL, &error_fatal); > @@ -2729,6 +2735,46 @@ void qmp_x_exit_preconfig(Error **errp) > } > } > > +bool phase_until(MachineInitPhase phase, Error **errp) > +{ > + ERRP_GUARD(); > + if (!phase_check(PHASE_ACCEL_CREATED)) { > + error_setg(errp, "Phase transition is not supported until > accelerator" > + " is created"); > + return false; > + } > + > + while (!phase_check(phase)) { > + MachineInitPhase cur_phase = phase_get(); > + > + switch (cur_phase) { > + case PHASE_ACCEL_CREATED: > + qemu_phase_ready(errp); > + break; > + > + default: > + /* > + * If we end up here, it is because we miss a case above. > + */ > + error_setg(&error_abort, "Requested phase transition is not" > + " implemented"); > + return false; > + } > + > + if (*errp) { > + return false; > + } > + > + /* > + * Ensure we made some progress. > + * With the default case above, it should be enough to prevent > + * any infinite loop. > + */ > + assert(cur_phase < phase_get()); > + } > + return true; > +} > + > void qemu_init(int argc, char **argv, char **envp) > { > QemuOpts *opts; > -- > 2.36.1 > > >