/*
 * Copyright (c) 2014 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2006 The Regents of The University of Michigan
 * Copyright (c) 2013 Advanced Micro Devices, Inc.
 * Copyright (c) 2013 Mark D. Hill and David A. Wood
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Nathan Binkert
 *          Steve Reinhardt
 *          Andrew Bardsley
 */

/**
 * @file
 *
 * Defines an sc_module type to wrap a gem5 simulation.  The 'evaluate'
 * thread on that module implements the gem5 event loop.
 *
 * This currently only supports a single event queue and strictly
 * cooperatively threaded SystemC threads and so there should be at
 * most one Gem5Module instantiated in any simulation.
 */

#include "base/pollevent.hh"
#include "base/trace.hh"
#include "debug/Event.hh"
#include "sim/async.hh"
#include "sim/core.hh"
#include "sim/eventq.hh"
#include "sim/sim_exit.hh"
#include "sim/stat_control.hh"
#include "sc_module.hh"

namespace Gem5SystemC
{

/** There are assumptions throughout Gem5SystemC file that a tick is 1ps.
 *  Make this the case */
void
setTickFrequency()
{
    ::setClockFrequency(1000000000000);
}

Module::Module(sc_core::sc_module_name name) : sc_core::sc_module(name),
    in_simulate(false)
{
    SC_METHOD(eventLoop);
    sensitive << eventLoopEnterEvent;
    dont_initialize();

    SC_METHOD(serviceExternalEvent);
    sensitive << externalSchedulingEvent;
    dont_initialize();
}

void
Module::SCEventQueue::wakeup(Tick when)
{
    DPRINTF(Event, "waking up SCEventQueue\n");
    /* Don't bother to use 'when' for now */
    module.notify();
}

void
Module::setupEventQueues(Module &module)
{
    fatal_if(mainEventQueue.size() != 0,
        "Gem5SystemC::Module::setupEventQueues must be called"
        " before any gem5 event queues are set up");

    numMainEventQueues = 1;
    mainEventQueue.push_back(new SCEventQueue("events", module));
    curEventQueue(getEventQueue(0));
}

void
Module::catchup()
{
    EventQueue *eventq = getEventQueue(0);
    Tick systemc_time = sc_core::sc_time_stamp().value();
    Tick gem5_time = curTick();

    /* gem5 time *must* lag SystemC as SystemC is the master */
    fatal_if(gem5_time > systemc_time, "gem5 time must lag SystemC time"
        " gem5: %d SystemC: %d", gem5_time, systemc_time);

    eventq->setCurTick(systemc_time);

    if (!eventq->empty()) {
        Tick next_event_time M5_VAR_USED = eventq->nextTick();

        fatal_if(gem5_time > next_event_time,
            "Missed an event at time %d gem5: %d, SystemC: %d",
            next_event_time, gem5_time, systemc_time);
    }
}

void
Module::notify(sc_core::sc_time time_from_now)
{
    externalSchedulingEvent.notify(time_from_now);
}

void
Module::serviceAsyncEvent()
{
    EventQueue *eventq = getEventQueue(0);
    std::lock_guard<EventQueue> lock(*eventq);

    assert(async_event);

    /* Catch up gem5 time with SystemC time so that any event here won't
     * be in the past relative to the current time */
    Tick systemc_time = sc_core::sc_time_stamp().value();

    /* Move time on to match SystemC */
    catchup();

    async_event = false;
    if (async_statdump || async_statreset) {
        Stats::schedStatEvent(async_statdump, async_statreset);
        async_statdump = false;
        async_statreset = false;
    }

    if (async_exit) {
        async_exit = false;
        exitSimLoop("user interrupt received");
    }

    if (async_io) {
        async_io = false;
        pollQueue.service();
    }

    if (async_exception)
        fatal("received async_exception, shouldn't be possible");
}

void
Module::serviceExternalEvent()
{
    EventQueue *eventq = getEventQueue(0);

    if (!in_simulate && !async_event)
        warn("Gem5SystemC external event received while not in simulate");

    if (async_event)
        serviceAsyncEvent();

    if (in_simulate && !eventq->empty())
        eventLoop();
}

void
Module::eventLoop()
{
    EventQueue *eventq = getEventQueue(0);

    fatal_if(!in_simulate, "Gem5SystemC event loop entered while"
        " outside Gem5SystemC::Module::simulate");

    if (async_event)
        serviceAsyncEvent();

    while (!eventq->empty()) {
        Tick next_event_time = eventq->nextTick();

        /* Move time on to match SystemC */
        catchup();

        Tick gem5_time = curTick();

        /* Woken up early */
        if (wait_exit_time > sc_core::sc_time_stamp().value()) {
            DPRINTF(Event, "Woken up early\n");
            wait_exit_time = sc_core::sc_time_stamp().value();
        }

        if (gem5_time < next_event_time) {
            Tick wait_period = next_event_time - gem5_time;
            wait_exit_time = gem5_time + wait_period;

            DPRINTF(Event, "Waiting for %d ticks for next gem5 event\n",
                wait_period);

            /* The next event is scheduled in the future, wait until
             *  then or until externalSchedulingEvent */
            eventLoopEnterEvent.notify(sc_core::sc_time(
                sc_dt::uint64(wait_period), 0));

            return;
        } else if (gem5_time > next_event_time) {
            Tick systemc_time = sc_core::sc_time_stamp().value();

            /* Missed event, for some reason the above test didn't work
             *  or an event was scheduled in the past */
            fatal("Missed an event at time %d gem5: %d, SystemC: %d",
                next_event_time, gem5_time, systemc_time);
        } else {
            /* Service an event */
            exitEvent = eventq->serviceOne();

            if (exitEvent) {
                eventLoopExitEvent.notify(sc_core::SC_ZERO_TIME);
                return;
            }
        }
    }

    fatal("Ran out of events without seeing exit event");
}

GlobalSimLoopExitEvent *
Module::simulate(Tick num_cycles)
{
    inform("Entering event queue @ %d.  Starting simulation...", curTick());

    if (num_cycles < MaxTick - curTick())
        num_cycles = curTick() + num_cycles;
    else /* counter would roll over or be set to MaxTick anyhow */
        num_cycles = MaxTick;

    GlobalEvent *limit_event = new GlobalSimLoopExitEvent(num_cycles,
        "simulate() limit reached", 0, 0);

    exitEvent = NULL;

    /* Cancel any outstanding events */
    eventLoopExitEvent.cancel();
    externalSchedulingEvent.cancel();

    in_simulate = true;
    eventLoopEnterEvent.notify(sc_core::SC_ZERO_TIME);

    /* Wait for event queue to exit, guarded by exitEvent just incase
     *  it already has exited and we don't want to completely rely
     *  on notify semantics */
    if (!exitEvent)
        wait(eventLoopExitEvent);

    /* Cancel any outstanding event loop entries */
    eventLoopEnterEvent.cancel();
    in_simulate = false;

    /* Locate the global exit event */
    BaseGlobalEvent *global_event = exitEvent->globalEvent();
    assert(global_event != NULL);

    GlobalSimLoopExitEvent *global_exit_event =
        dynamic_cast<GlobalSimLoopExitEvent *>(global_event);
    assert(global_exit_event != NULL);

    if (global_exit_event != limit_event) {
        limit_event->deschedule();
        delete limit_event;
    }

    return global_exit_event;
}

}
