/*
 * Copyright (c) 2014-2017 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: Anthony Gutierrez,
 *          Brad Beckmann,
 *          Sooraj Puthoor
 */

#include "gpu-compute/fetch_unit.hh"

#include "debug/GPUFetch.hh"
#include "debug/GPUPort.hh"
#include "debug/GPUTLB.hh"
#include "gpu-compute/compute_unit.hh"
#include "gpu-compute/gpu_dyn_inst.hh"
#include "gpu-compute/gpu_static_inst.hh"
#include "gpu-compute/shader.hh"
#include "gpu-compute/wavefront.hh"
#include "mem/ruby/system/RubySystem.hh"

uint32_t FetchUnit::globalFetchUnitID;

FetchUnit::FetchUnit(const ComputeUnitParams* params) :
    timingSim(true),
    computeUnit(nullptr),
    fetchScheduler(params),
    waveList(nullptr)
{
}

FetchUnit::~FetchUnit()
{
    fetchQueue.clear();
    fetchStatusQueue.clear();
}

void
FetchUnit::init(ComputeUnit *cu)
{
    computeUnit = cu;
    timingSim = computeUnit->shader->timingSim;
    fetchQueue.clear();
    fetchStatusQueue.resize(computeUnit->shader->n_wf);

    for (int j = 0; j < computeUnit->shader->n_wf; ++j) {
        fetchStatusQueue[j] = std::make_pair(waveList->at(j), false);
    }

    fetchScheduler.bindList(&fetchQueue);
}

void
FetchUnit::exec()
{
    // re-evaluate waves which are marked as not ready for fetch
    for (int j = 0; j < computeUnit->shader->n_wf; ++j) {
        // Following code assumes 64-bit opertaion and all insts are
        // represented by 64-bit pointers to inst objects.
        Wavefront *curWave = fetchStatusQueue[j].first;
        assert (curWave);

        // The wavefront has to be active, the IB occupancy has to be
        // 4 or less instructions and it can not have any branches to
        // prevent speculative instruction fetches
        if (!fetchStatusQueue[j].second) {
            if (curWave->status == Wavefront::S_RUNNING &&
                curWave->instructionBuffer.size() <= 4 &&
                !curWave->instructionBufferHasBranch() &&
                !curWave->pendingFetch) {
                fetchQueue.push_back(curWave);
                fetchStatusQueue[j].second = true;
            }
        }
    }

    // Fetch only if there is some wave ready to be fetched
    // An empty fetchQueue will cause the schedular to panic
    if (fetchQueue.size()) {
        Wavefront *waveToBeFetched = fetchScheduler.chooseWave();
        waveToBeFetched->pendingFetch = true;
        fetchStatusQueue[waveToBeFetched->wfSlotId].second = false;
        initiateFetch(waveToBeFetched);
    }
}

void
FetchUnit::initiateFetch(Wavefront *wavefront)
{
    // calculate the virtual address to fetch from the SQC
    Addr vaddr = wavefront->pc();

    /**
     * the instruction buffer holds one instruction per entry, regardless
     * of the underlying instruction's size. the PC, however, addresses
     * instrutions on a 32b granularity so we must account for that here.
    */
    for (int i = 0; i < wavefront->instructionBuffer.size(); ++i) {
        vaddr +=
            wavefront->instructionBuffer.at(i)->staticInstruction()->instSize();
    }
    vaddr = wavefront->basePtr +  vaddr;

    DPRINTF(GPUTLB, "CU%d: WF[%d][%d]: Initiating fetch translation: %#x\n",
            computeUnit->cu_id, wavefront->simdId, wavefront->wfSlotId, vaddr);

    // Since this is an instruction prefetch, if you're split then just finish
    // out the current line.
    int block_size = computeUnit->cacheLineSize();
    // check for split accesses
    Addr split_addr = roundDown(vaddr + block_size - 1, block_size);
    int size = block_size;

    if (split_addr > vaddr) {
        // misaligned access, just grab the rest of the line
        size = split_addr - vaddr;
    }

    // set up virtual request
    RequestPtr req = std::make_shared<Request>(
        0, vaddr, size, Request::INST_FETCH,
        computeUnit->masterId(), 0, 0, nullptr);

    PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
    // This fetchBlock is kind of faux right now - because the translations so
    // far don't actually return Data
    uint64_t fetchBlock;
    pkt->dataStatic(&fetchBlock);

    if (timingSim) {
        // SenderState needed on Return
        pkt->senderState = new ComputeUnit::ITLBPort::SenderState(wavefront);

        // Sender State needed by TLB hierarchy
        pkt->senderState =
            new TheISA::GpuTLB::TranslationState(BaseTLB::Execute,
                                                 computeUnit->shader->gpuTc,
                                                 false, pkt->senderState);

        if (computeUnit->sqcTLBPort->isStalled()) {
            assert(computeUnit->sqcTLBPort->retries.size() > 0);

            DPRINTF(GPUTLB, "Failed to send TLB req for FETCH addr %#x\n",
                    vaddr);

            computeUnit->sqcTLBPort->retries.push_back(pkt);
        } else if (!computeUnit->sqcTLBPort->sendTimingReq(pkt)) {
            // Stall the data port;
            // No more packet is issued till
            // ruby indicates resources are freed by
            // a recvReqRetry() call back on this port.
            computeUnit->sqcTLBPort->stallPort();

            DPRINTF(GPUTLB, "Failed to send TLB req for FETCH addr %#x\n",
                    vaddr);

            computeUnit->sqcTLBPort->retries.push_back(pkt);
        } else {
            DPRINTF(GPUTLB, "sent FETCH translation request for %#x\n", vaddr);
        }
    } else {
        pkt->senderState =
            new TheISA::GpuTLB::TranslationState(BaseTLB::Execute,
                                                 computeUnit->shader->gpuTc);

        computeUnit->sqcTLBPort->sendFunctional(pkt);

        TheISA::GpuTLB::TranslationState *sender_state =
             safe_cast<TheISA::GpuTLB::TranslationState*>(pkt->senderState);

        delete sender_state->tlbEntry;
        delete sender_state;
        // fetch the instructions from the SQC when we operate in
        // functional mode only
        fetch(pkt, wavefront);
    }
}

void
FetchUnit::fetch(PacketPtr pkt, Wavefront *wavefront)
{
    assert(pkt->req->hasPaddr());
    assert(pkt->req->hasSize());

    DPRINTF(GPUFetch, "CU%d: WF[%d][%d]: Fetch Access: %#x\n",
            computeUnit->cu_id, wavefront->simdId, wavefront->wfSlotId,
            pkt->req->getPaddr());

    // this is necessary because the GPU TLB receives packets instead of
    // requests. when the translation is complete, all relevent fields in the
    // request will be populated, but not in the packet. here we create the
    // new packet so we can set the size, addr, and proper flags.
    PacketPtr oldPkt = pkt;
    pkt = new Packet(oldPkt->req, oldPkt->cmd);
    delete oldPkt;

    TheGpuISA::RawMachInst *data =
        new TheGpuISA::RawMachInst[pkt->req->getSize() /
        sizeof(TheGpuISA::RawMachInst)];

    pkt->dataDynamic<TheGpuISA::RawMachInst>(data);

    // New SenderState for the memory access
    pkt->senderState = new ComputeUnit::SQCPort::SenderState(wavefront);

    if (timingSim) {
        // translation is done. Send the appropriate timing memory request.

        if (!computeUnit->sqcPort->sendTimingReq(pkt)) {
            computeUnit->sqcPort->retries.push_back(std::make_pair(pkt,
                                                                   wavefront));

            DPRINTF(GPUPort, "CU%d: WF[%d][%d]: Fetch addr %#x failed!\n",
                    computeUnit->cu_id, wavefront->simdId, wavefront->wfSlotId,
                    pkt->req->getPaddr());
        } else {
            DPRINTF(GPUPort, "CU%d: WF[%d][%d]: Fetch addr %#x sent!\n",
                    computeUnit->cu_id, wavefront->simdId, wavefront->wfSlotId,
                    pkt->req->getPaddr());
        }
    } else {
        computeUnit->sqcPort->sendFunctional(pkt);
        processFetchReturn(pkt);
    }
}

void
FetchUnit::processFetchReturn(PacketPtr pkt)
{
    ComputeUnit::SQCPort::SenderState *sender_state =
        safe_cast<ComputeUnit::SQCPort::SenderState*>(pkt->senderState);

    Wavefront *wavefront = sender_state->wavefront;

    DPRINTF(GPUFetch, "CU%d: WF[%d][%d]: Fetch addr %#x returned "
            "%d bytes, %d instructions!\n", computeUnit->cu_id,
            wavefront->simdId, wavefront->wfSlotId, pkt->req->getPaddr(),
            pkt->req->getSize(), pkt->req->getSize() /
            sizeof(TheGpuISA::RawMachInst));

    if (wavefront->dropFetch) {
        assert(wavefront->instructionBuffer.empty());
        wavefront->dropFetch = false;
    } else {
        TheGpuISA::RawMachInst *inst_index_ptr =
            (TheGpuISA::RawMachInst*)pkt->getPtr<uint8_t>();

        assert(wavefront->instructionBuffer.size() <= 4);

        for (int i = 0; i < pkt->req->getSize() /
             sizeof(TheGpuISA::RawMachInst); ++i) {
            GPUStaticInst *inst_ptr = decoder.decode(inst_index_ptr[i]);

            assert(inst_ptr);

            if (inst_ptr->instSize() == 8) {
                /**
                 * this instruction occupies 2 consecutive
                 * entries in the instruction array, the
                 * second of which contains a nullptr. so if
                 * this inst is 8 bytes we advance two entries
                 * instead of 1
                 */
                ++i;
            }

            DPRINTF(GPUFetch, "CU%d: WF[%d][%d]: added %s\n",
                    computeUnit->cu_id, wavefront->simdId,
                    wavefront->wfSlotId, inst_ptr->disassemble());

            GPUDynInstPtr gpuDynInst =
                std::make_shared<GPUDynInst>(computeUnit, wavefront, inst_ptr,
                                             computeUnit->getAndIncSeqNum());

            wavefront->instructionBuffer.push_back(gpuDynInst);
        }
    }

    wavefront->pendingFetch = false;

    delete pkt->senderState;
    delete pkt;
}

void
FetchUnit::bindWaveList(std::vector<Wavefront*> *wave_list)
{
    waveList = wave_list;
}
