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

/**
 * @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 <cassert>

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

namespace Gem5SystemC
{

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

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

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

void
Module::SCEventQueue::wakeup(gem5::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");

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

void
Module::catchup()
{
    gem5::EventQueue *eventq = getEventQueue(0);
    gem5::Tick systemc_time = sc_core::sc_time_stamp().value();
    gem5::Tick gem5_time = gem5::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()) {
        gem5::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()
{
    gem5::EventQueue *eventq = gem5::getEventQueue(0);
    std::lock_guard<gem5::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 */
    gem5::Tick systemc_time = sc_core::sc_time_stamp().value();

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

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

    if (async_exit) {
        async_exit = false;
        gem5::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()
{
    gem5::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()
{
    gem5::EventQueue *eventq = getEventQueue(0);

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

    if (async_event)
        serviceAsyncEvent();

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

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

        gem5::Tick gem5_time = gem5::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) {
            gem5::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::from_value(
                sc_dt::uint64(wait_period)));

            return;
        } else if (gem5_time > next_event_time) {
            gem5::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...",
        gem5::curTick());

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

    gem5::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 */
    gem5::BaseGlobalEvent *global_event = exitEvent->globalEvent();
    assert(global_event != NULL);

    gem5::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;
}

} // namespace Gem5SystemC
