/*
 * Copyright (c) 2013-2015 Advanced Micro Devices, Inc.
 * All rights reserved.
 *
 * For use for simulation and test purposes only
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. Neither the name of the copyright holder 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 HOLDER 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: Sooraj Puthoor
 */

#include "base/logging.hh"
#include "base/str.hh"
#include "config/the_isa.hh"

#if THE_ISA == X86_ISA
#include "arch/x86/insts/microldstop.hh"

#endif // X86_ISA
#include "mem/ruby/system/VIPERCoalescer.hh"

#include "cpu/testers/rubytest/RubyTester.hh"
#include "debug/GPUCoalescer.hh"
#include "debug/MemoryAccess.hh"
#include "mem/packet.hh"
#include "mem/ruby/common/SubBlock.hh"
#include "mem/ruby/network/MessageBuffer.hh"
#include "mem/ruby/profiler/Profiler.hh"
#include "mem/ruby/slicc_interface/AbstractController.hh"
#include "mem/ruby/slicc_interface/RubyRequest.hh"
#include "mem/ruby/structures/CacheMemory.hh"
#include "mem/ruby/system/GPUCoalescer.hh"
#include "mem/ruby/system/RubySystem.hh"
#include "params/VIPERCoalescer.hh"

using namespace std;

VIPERCoalescer *
VIPERCoalescerParams::create()
{
    return new VIPERCoalescer(this);
}

VIPERCoalescer::VIPERCoalescer(const Params *p)
    : GPUCoalescer(p)
{
    m_max_wb_per_cycle=p->max_wb_per_cycle;
    m_max_inv_per_cycle=p->max_inv_per_cycle;
    m_outstanding_inv = 0;
    m_outstanding_wb = 0;
}

VIPERCoalescer::~VIPERCoalescer()
{
}

// Analyzes the packet to see if this request can be coalesced.
// If request can be coalesced, this request is added to the reqCoalescer table
// and makeRequest returns RequestStatus_Issued;
// If this is the first request to a cacheline, request is added to both
// newRequests queue and to the reqCoalescer table; makeRequest
// returns RequestStatus_Issued.
// If there is a pending request to this cacheline and this request
// can't be coalesced, RequestStatus_Aliased is returned and
// the packet needs to be reissued.
RequestStatus
VIPERCoalescer::makeRequest(PacketPtr pkt)
{
    if (m_outstanding_wb | m_outstanding_inv) {
        DPRINTF(GPUCoalescer,
                "There are %d Writebacks and %d Invalidatons\n",
                m_outstanding_wb, m_outstanding_inv);
    }
    // Are we in the middle of a release
    if ((m_outstanding_wb) > 0) {
        if (pkt->req->isKernel()) {
            // Everythign is fine
            // Barriers and Kernel End scan coalesce
            // If it is a Kerenl Begin flush the cache
            if (pkt->req->isAcquire() && (m_outstanding_inv == 0)) {
                invL1();
            }

            if (pkt->req->isRelease()) {
                insertKernel(pkt->req->contextId(), pkt);
            }

            return RequestStatus_Issued;
        }
//        return RequestStatus_Aliased;
    } else if (pkt->req->isKernel() && pkt->req->isRelease()) {
        // Flush Dirty Data on Kernel End
        // isKernel + isRelease
        insertKernel(pkt->req->contextId(), pkt);
        wbL1();
        if (m_outstanding_wb == 0) {
            for (auto it =  kernelEndList.begin(); it != kernelEndList.end(); it++) {
                newKernelEnds.push_back(it->first);
            }
            completeIssue();
        }
        return RequestStatus_Issued;
    }
    RequestStatus requestStatus = GPUCoalescer::makeRequest(pkt);
    if (requestStatus!=RequestStatus_Issued) {
        // Request not isssued
        // enqueue Retry
        DPRINTF(GPUCoalescer, "Request not issued by GPUCoaleser\n");
        return requestStatus;
    } else if (pkt->req->isKernel() && pkt->req->isAcquire()) {
        // Invalidate clean Data on Kernel Begin
        // isKernel + isAcquire
        invL1();
    } else if (pkt->req->isAcquire() && pkt->req->isRelease()) {
        // Deschedule the AtomicAcqRel and
        // Flush and Invalidate the L1 cache
        invwbL1();
        if (m_outstanding_wb > 0 && issueEvent.scheduled()) {
            DPRINTF(GPUCoalescer, "issueEvent Descheduled\n");
            deschedule(issueEvent);
        }
    } else if (pkt->req->isRelease()) {
        // Deschedule the StoreRel and
        // Flush the L1 cache
        wbL1();
        if (m_outstanding_wb > 0 && issueEvent.scheduled()) {
            DPRINTF(GPUCoalescer, "issueEvent Descheduled\n");
            deschedule(issueEvent);
        }
    } else if (pkt->req->isAcquire()) {
        // LoadAcq or AtomicAcq
        // Invalidate the L1 cache
        invL1();
    }
    // Request was successful
    if (m_outstanding_wb == 0) {
        if (!issueEvent.scheduled()) {
            DPRINTF(GPUCoalescer, "issueEvent Rescheduled\n");
            schedule(issueEvent, curTick());
        }
    }
    return RequestStatus_Issued;
}

void
VIPERCoalescer::wbCallback(Addr addr)
{
    m_outstanding_wb--;
    // if L1 Flush Complete
    // attemnpt to schedule issueEvent
    assert(((int) m_outstanding_wb) >= 0);
    if (m_outstanding_wb == 0) {
        for (auto it =  kernelEndList.begin(); it != kernelEndList.end(); it++) {
            newKernelEnds.push_back(it->first);
        }
        completeIssue();
    }
    trySendRetries();
}

void
VIPERCoalescer::invCallback(Addr addr)
{
    m_outstanding_inv--;
    // if L1 Flush Complete
    // attemnpt to schedule issueEvent
    // This probably won't happen, since
    // we dont wait on cache invalidations
    if (m_outstanding_wb == 0) {
        for (auto it =  kernelEndList.begin(); it != kernelEndList.end(); it++) {
            newKernelEnds.push_back(it->first);
        }
        completeIssue();
    }
    trySendRetries();
}

/**
  * Invalidate L1 cache (Acquire)
  */
void
VIPERCoalescer::invL1()
{
    int size = m_dataCache_ptr->getNumBlocks();
    DPRINTF(GPUCoalescer,
            "There are %d Invalidations outstanding before Cache Walk\n",
            m_outstanding_inv);
    // Walk the cache
    for (int i = 0; i < size; i++) {
        Addr addr = m_dataCache_ptr->getAddressAtIdx(i);
        // Evict Read-only data
        std::shared_ptr<RubyRequest> msg = std::make_shared<RubyRequest>(
            clockEdge(), addr, (uint8_t*) 0, 0, 0,
            RubyRequestType_REPLACEMENT, RubyAccessMode_Supervisor,
            nullptr);
        assert(m_mandatory_q_ptr != NULL);
        m_mandatory_q_ptr->enqueue(msg, clockEdge(), m_data_cache_hit_latency);
        m_outstanding_inv++;
    }
    DPRINTF(GPUCoalescer,
            "There are %d Invalidatons outstanding after Cache Walk\n",
            m_outstanding_inv);
}

/**
  * Writeback L1 cache (Release)
  */
void
VIPERCoalescer::wbL1()
{
    int size = m_dataCache_ptr->getNumBlocks();
    DPRINTF(GPUCoalescer,
            "There are %d Writebacks outstanding before Cache Walk\n",
            m_outstanding_wb);
    // Walk the cache
    for (int i = 0; i < size; i++) {
        Addr addr = m_dataCache_ptr->getAddressAtIdx(i);
        // Write dirty data back
        std::shared_ptr<RubyRequest> msg = std::make_shared<RubyRequest>(
            clockEdge(), addr, (uint8_t*) 0, 0, 0,
            RubyRequestType_FLUSH, RubyAccessMode_Supervisor,
            nullptr);
        assert(m_mandatory_q_ptr != NULL);
        m_mandatory_q_ptr->enqueue(msg, clockEdge(), m_data_cache_hit_latency);
        m_outstanding_wb++;
    }
    DPRINTF(GPUCoalescer,
            "There are %d Writebacks outstanding after Cache Walk\n",
            m_outstanding_wb);
}

/**
  * Invalidate and Writeback L1 cache (Acquire&Release)
  */
void
VIPERCoalescer::invwbL1()
{
    int size = m_dataCache_ptr->getNumBlocks();
    // Walk the cache
    for (int i = 0; i < size; i++) {
        Addr addr = m_dataCache_ptr->getAddressAtIdx(i);
        // Evict Read-only data
        std::shared_ptr<RubyRequest> msg = std::make_shared<RubyRequest>(
            clockEdge(), addr, (uint8_t*) 0, 0, 0,
            RubyRequestType_REPLACEMENT, RubyAccessMode_Supervisor,
            nullptr);
        assert(m_mandatory_q_ptr != NULL);
        m_mandatory_q_ptr->enqueue(msg, clockEdge(), m_data_cache_hit_latency);
        m_outstanding_inv++;
    }
    // Walk the cache
    for (int i = 0; i< size; i++) {
        Addr addr = m_dataCache_ptr->getAddressAtIdx(i);
        // Write dirty data back
        std::shared_ptr<RubyRequest> msg = std::make_shared<RubyRequest>(
            clockEdge(), addr, (uint8_t*) 0, 0, 0,
            RubyRequestType_FLUSH, RubyAccessMode_Supervisor,
            nullptr);
        assert(m_mandatory_q_ptr != NULL);
        m_mandatory_q_ptr->enqueue(msg, clockEdge(), m_data_cache_hit_latency);
        m_outstanding_wb++;
    }
}
