/*
 *  Reset handlers.
 *
 * Copyright (c) 2003-2008 Fabrice Bellard
 * Copyright (c) 2016 Red Hat, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "sysemu/reset.h"
#include "hw/resettable.h"
#include "hw/core/resetcontainer.h"

/*
 * Return a pointer to the singleton container that holds all the Resettable
 * items that will be reset when qemu_devices_reset() is called.
 */
static ResettableContainer *get_root_reset_container(void)
{
    static ResettableContainer *root_reset_container;

    if (!root_reset_container) {
        root_reset_container =
            RESETTABLE_CONTAINER(object_new(TYPE_RESETTABLE_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
 * callback function in the hold phase.
 */
#define TYPE_LEGACY_RESET "legacy-reset"
OBJECT_DECLARE_SIMPLE_TYPE(LegacyReset, LEGACY_RESET)

struct LegacyReset {
    Object parent;
    ResettableState reset_state;
    QEMUResetHandler *func;
    void *opaque;
    bool skip_on_snapshot_load;
};

OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(LegacyReset, legacy_reset, LEGACY_RESET, OBJECT, { TYPE_RESETTABLE_INTERFACE }, { })

static ResettableState *legacy_reset_get_state(Object *obj)
{
    LegacyReset *lr = LEGACY_RESET(obj);
    return &lr->reset_state;
}

static void legacy_reset_hold(Object *obj)
{
    LegacyReset *lr = LEGACY_RESET(obj);

    if (device_reset_reason == SHUTDOWN_CAUSE_SNAPSHOT_LOAD &&
        lr->skip_on_snapshot_load) {
        return;
    }
    lr->func(lr->opaque);
}

static void legacy_reset_init(Object *obj)
{
}

static void legacy_reset_finalize(Object *obj)
{
}

static void legacy_reset_class_init(ObjectClass *klass, void *data)
{
    ResettableClass *rc = RESETTABLE_CLASS(klass);

    rc->get_state = legacy_reset_get_state;
    rc->phases.hold = legacy_reset_hold;
}

void qemu_register_reset(QEMUResetHandler *func, void *opaque)
{
    Object *obj = object_new(TYPE_LEGACY_RESET);
    LegacyReset *lr = LEGACY_RESET(obj);

    lr->func = func;
    lr->opaque = opaque;
    qemu_register_resettable(obj);
}

void qemu_register_reset_nosnapshotload(QEMUResetHandler *func, void *opaque)
{
    Object *obj = object_new(TYPE_LEGACY_RESET);
    LegacyReset *lr = LEGACY_RESET(obj);

    lr->func = func;
    lr->opaque = opaque;
    lr->skip_on_snapshot_load = true;
    qemu_register_resettable(obj);
}

typedef struct FindLegacyInfo {
    QEMUResetHandler *func;
    void *opaque;
    LegacyReset *lr;
} FindLegacyInfo;

static void find_legacy_reset_cb(Object *obj, void *opaque, ResetType type)
{
    LegacyReset *lr;
    FindLegacyInfo *fli = opaque;

    /* Not everything in the ResettableContainer will be a LegacyReset */
    lr = LEGACY_RESET(object_dynamic_cast(obj, TYPE_LEGACY_RESET));
    if (lr && lr->func == fli->func && lr->opaque == fli->opaque) {
        fli->lr = lr;
    }
}

static LegacyReset *find_legacy_reset(QEMUResetHandler *func, void *opaque)
{
    /*
     * Find the LegacyReset with the specified func and opaque,
     * by getting the ResettableContainer to call our callback for
     * every item in it.
     */
    ResettableContainer *rootcon = get_root_reset_container();
    ResettableClass *rc = RESETTABLE_GET_CLASS(rootcon);
    FindLegacyInfo fli;

    fli.func = func;
    fli.opaque = opaque;
    fli.lr = NULL;
    rc->child_foreach(OBJECT(rootcon), find_legacy_reset_cb,
                      &fli, RESET_TYPE_COLD);
    return fli.lr;
}

void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
{
    Object *obj = OBJECT(find_legacy_reset(func, opaque));

    if (obj) {
        qemu_unregister_resettable(obj);
        object_unref(obj);
    }
}

void qemu_register_resettable(Object *obj)
{
    resettable_container_add(get_root_reset_container(), obj);
}

void qemu_unregister_resettable(Object *obj)
{
    resettable_container_remove(get_root_reset_container(), obj);
}

void qemu_devices_reset(ShutdownCause reason)
{
    device_reset_reason = reason;

    /* Reset the simulation */
    resettable_reset(OBJECT(get_root_reset_container()), RESET_TYPE_COLD);
}
