/*
 * Resettable interface.
 *
 * 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.
 */

#include "qemu/osdep.h"
#include "qemu/module.h"
#include "hw/resettable.h"
#include "trace.h"

/**
 * resettable_phase_enter/hold/exit:
 * Function executing a phase recursively in a resettable object and its
 * children.
 */
static void resettable_phase_enter(Object *obj, void *opaque, ResetType type);
static void resettable_phase_hold(Object *obj, void *opaque, ResetType type);
static void resettable_phase_exit(Object *obj, void *opaque, ResetType type);

/**
 * enter_phase_in_progress:
 * True if we are currently in reset enter phase.
 *
 * exit_phase_in_progress:
 * count the number of exit phase we are in.
 *
 * Note: These flags are only used to guarantee (using asserts) that the reset
 * API is used correctly. We can use global variables because we rely on the
 * iothread mutex to ensure only one reset operation is in a progress at a
 * given time.
 */
static bool enter_phase_in_progress;
static unsigned exit_phase_in_progress;

void resettable_reset(Object *obj, ResetType type)
{
    trace_resettable_reset(obj, type);
    resettable_assert_reset(obj, type);
    resettable_release_reset(obj, 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);
    assert(!enter_phase_in_progress);

    enter_phase_in_progress = true;
    resettable_phase_enter(obj, NULL, type);
    enter_phase_in_progress = false;

    resettable_phase_hold(obj, NULL, type);

    trace_resettable_reset_assert_end(obj);
}

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);
    assert(!enter_phase_in_progress);

    exit_phase_in_progress += 1;
    resettable_phase_exit(obj, NULL, type);
    exit_phase_in_progress -= 1;

    trace_resettable_reset_release_end(obj);
}

bool resettable_is_in_reset(Object *obj)
{
    ResettableClass *rc = RESETTABLE_GET_CLASS(obj);
    ResettableState *s = rc->get_state(obj);

    return s->count > 0;
}

/**
 * resettable_child_foreach:
 * helper to avoid checking the existence of the method.
 */
static void resettable_child_foreach(ResettableClass *rc, Object *obj,
                                     ResettableChildCallback cb,
                                     void *opaque, ResetType type)
{
    if (rc->child_foreach) {
        rc->child_foreach(obj, cb, opaque, type);
    }
}

/**
 * resettable_get_tr_func:
 * helper to fetch transitional reset callback if any.
 */
static ResettableTrFunction resettable_get_tr_func(ResettableClass *rc,
                                                   Object *obj)
{
    ResettableTrFunction tr_func = NULL;
    if (rc->get_transitional_function) {
        tr_func = rc->get_transitional_function(obj);
    }
    return tr_func;
}

static void resettable_phase_enter(Object *obj, void *opaque, ResetType type)
{
    ResettableClass *rc = RESETTABLE_GET_CLASS(obj);
    ResettableState *s = rc->get_state(obj);
    const char *obj_typename = object_get_typename(obj);
    bool action_needed = false;

    /* exit phase has to finish properly before entering back in reset */
    assert(!s->exit_phase_in_progress);

    trace_resettable_phase_enter_begin(obj, obj_typename, s->count, type);

    /* Only take action if we really enter reset for the 1st time. */
    /*
     * TODO: if adding more ResetType support, some additional checks
     * are probably needed here.
     */
    if (s->count++ == 0) {
        action_needed = true;
    }
    /*
     * We limit the count to an arbitrary "big" value. The value is big
     * enough not to be triggered normally.
     * The assert will stop an infinite loop if there is a cycle in the
     * reset tree. The loop goes through resettable_foreach_child below
     * which at some point will call us again.
     */
    assert(s->count <= 50);

    /*
     * handle the children even if action_needed is at false so that
     * child counts are incremented too
     */
    resettable_child_foreach(rc, obj, resettable_phase_enter, NULL, type);

    /* execute enter phase for the object if needed */
    if (action_needed) {
        trace_resettable_phase_enter_exec(obj, obj_typename, type,
                                          !!rc->phases.enter);
        if (rc->phases.enter && !resettable_get_tr_func(rc, obj)) {
            rc->phases.enter(obj, type);
        }
        s->hold_phase_pending = true;
    }
    trace_resettable_phase_enter_end(obj, obj_typename, s->count);
}

static void resettable_phase_hold(Object *obj, void *opaque, ResetType type)
{
    ResettableClass *rc = RESETTABLE_GET_CLASS(obj);
    ResettableState *s = rc->get_state(obj);
    const char *obj_typename = object_get_typename(obj);

    /* exit phase has to finish properly before entering back in reset */
    assert(!s->exit_phase_in_progress);

    trace_resettable_phase_hold_begin(obj, obj_typename, s->count, type);

    /* handle children first */
    resettable_child_foreach(rc, obj, resettable_phase_hold, NULL, type);

    /* exec hold phase */
    if (s->hold_phase_pending) {
        s->hold_phase_pending = false;
        ResettableTrFunction tr_func = resettable_get_tr_func(rc, obj);
        trace_resettable_phase_hold_exec(obj, obj_typename, !!rc->phases.hold);
        if (tr_func) {
            trace_resettable_transitional_function(obj, obj_typename);
            tr_func(obj);
        } else if (rc->phases.hold) {
            rc->phases.hold(obj);
        }
    }
    trace_resettable_phase_hold_end(obj, obj_typename, s->count);
}

static void resettable_phase_exit(Object *obj, void *opaque, ResetType type)
{
    ResettableClass *rc = RESETTABLE_GET_CLASS(obj);
    ResettableState *s = rc->get_state(obj);
    const char *obj_typename = object_get_typename(obj);

    assert(!s->exit_phase_in_progress);
    trace_resettable_phase_exit_begin(obj, obj_typename, s->count, type);

    /* exit_phase_in_progress ensures this phase is 'atomic' */
    s->exit_phase_in_progress = true;
    resettable_child_foreach(rc, obj, resettable_phase_exit, NULL, type);

    assert(s->count > 0);
    if (--s->count == 0) {
        trace_resettable_phase_exit_exec(obj, obj_typename, !!rc->phases.exit);
        if (rc->phases.exit && !resettable_get_tr_func(rc, obj)) {
            rc->phases.exit(obj);
        }
    }
    s->exit_phase_in_progress = false;
    trace_resettable_phase_exit_end(obj, obj_typename, s->count);
}

/*
 * resettable_get_count:
 * Get the count of the Resettable object @obj. Return 0 if @obj is NULL.
 */
static unsigned resettable_get_count(Object *obj)
{
    if (obj) {
        ResettableClass *rc = RESETTABLE_GET_CLASS(obj);
        return rc->get_state(obj)->count;
    }
    return 0;
}

void resettable_change_parent(Object *obj, Object *newp, Object *oldp)
{
    ResettableClass *rc = RESETTABLE_GET_CLASS(obj);
    ResettableState *s = rc->get_state(obj);
    unsigned newp_count = resettable_get_count(newp);
    unsigned oldp_count = resettable_get_count(oldp);

    /*
     * Ensure we do not change parent when in enter or exit phase.
     * During these phases, the reset subtree being updated is partly in reset
     * and partly not in reset (it depends on the actual position in
     * resettable_child_foreach()s). We are not able to tell in which part is a
     * leaving or arriving device. Thus we cannot set the reset count of the
     * moving device to the proper value.
     */
    assert(!enter_phase_in_progress && !exit_phase_in_progress);
    trace_resettable_change_parent(obj, oldp, oldp_count, newp, newp_count);

    /*
     * At most one of the two 'for' loops will be executed below
     * in order to cope with the difference between the two counts.
     */
    /* if newp is more reset than oldp */
    for (unsigned i = oldp_count; i < newp_count; i++) {
        resettable_assert_reset(obj, RESET_TYPE_COLD);
    }
    /*
     * if obj is leaving a bus under reset, we need to ensure
     * hold phase is not pending.
     */
    if (oldp_count && s->hold_phase_pending) {
        resettable_phase_hold(obj, NULL, RESET_TYPE_COLD);
    }
    /* if oldp is more reset than newp */
    for (unsigned i = newp_count; i < oldp_count; i++) {
        resettable_release_reset(obj, RESET_TYPE_COLD);
    }
}

void resettable_cold_reset_fn(void *opaque)
{
    resettable_reset((Object *) opaque, RESET_TYPE_COLD);
}

void resettable_class_set_parent_phases(ResettableClass *rc,
                                        ResettableEnterPhase enter,
                                        ResettableHoldPhase hold,
                                        ResettableExitPhase exit,
                                        ResettablePhases *parent_phases)
{
    *parent_phases = rc->phases;
    if (enter) {
        rc->phases.enter = enter;
    }
    if (hold) {
        rc->phases.hold = hold;
    }
    if (exit) {
        rc->phases.exit = exit;
    }
}

static const TypeInfo resettable_interface_info = {
    .name       = TYPE_RESETTABLE_INTERFACE,
    .parent     = TYPE_INTERFACE,
    .class_size = sizeof(ResettableClass),
};

static void reset_register_types(void)
{
    type_register_static(&resettable_interface_info);
}

type_init(reset_register_types)
