/*
 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
 * Copyright (c) 2009 Advanced Micro Devices, Inc.
 * 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.
 */

#include "cpu/testers/rubytest/Check.hh"

#include "base/random.hh"
#include "base/trace.hh"
#include "debug/RubyTest.hh"
#include "mem/ruby/common/SubBlock.hh"

typedef RubyTester::SenderState SenderState;

Check::Check(Addr address, Addr pc, int _num_writers, int _num_readers,
             RubyTester* _tester)
    : m_num_writers(_num_writers), m_num_readers(_num_readers),
      m_tester_ptr(_tester)
{
    m_status = TesterStatus_Idle;

    pickValue();
    pickInitiatingNode();
    changeAddress(address);
    m_pc = pc;
    m_access_mode = RubyAccessMode(random_mt.random(0,
                                                    RubyAccessMode_NUM - 1));
    m_store_count = 0;
}

void
Check::initiate()
{
    DPRINTF(RubyTest, "initiating\n");
    debugPrint();

    // currently no protocols support prefetches
    if (false && (random_mt.random(0, 0xf) == 0)) {
        initiatePrefetch(); // Prefetch from random processor
    }

        if (m_tester_ptr->getCheckFlush() && (random_mt.random(0, 0xff) == 0)) {
        initiateFlush(); // issue a Flush request from random processor
    }

    if (m_status == TesterStatus_Idle) {
        initiateAction();
    } else if (m_status == TesterStatus_Ready) {
        initiateCheck();
    } else {
        // Pending - do nothing
        DPRINTF(RubyTest,
                "initiating action/check - failed: action/check is pending\n");
    }
}

void
Check::initiatePrefetch()
{
    DPRINTF(RubyTest, "initiating prefetch\n");

    int index = random_mt.random(0, m_num_readers - 1);
    RequestPort* port = m_tester_ptr->getReadableCpuPort(index);

    Request::Flags flags;
    flags.set(Request::PREFETCH);

    Packet::Command cmd;

    // 1 in 8 chance this will be an exclusive prefetch
    if (random_mt.random(0, 0x7) != 0) {
        cmd = MemCmd::ReadReq;

        // if necessary, make the request an instruction fetch
        if (m_tester_ptr->isInstOnlyCpuPort(index) ||
            (m_tester_ptr->isInstDataCpuPort(index) &&
             (random_mt.random(0, 0x1)))) {
            flags.set(Request::INST_FETCH);
        }
    } else {
        cmd = MemCmd::WriteReq;
        flags.set(Request::PF_EXCLUSIVE);
    }

    // Prefetches are assumed to be 0 sized
    RequestPtr req = std::make_shared<Request>(
            m_address, 0, flags, m_tester_ptr->requestorId());
    req->setPC(m_pc);
    req->setContext(index);

    PacketPtr pkt = new Packet(req, cmd);
    // despite the oddity of the 0 size (questionable if this should
    // even be allowed), a prefetch is still a read and as such needs
    // a place to store the result
    uint8_t *data = new uint8_t[1];
    pkt->dataDynamic(data);

    // push the subblock onto the sender state.  The sequencer will
    // update the subblock on the return
    pkt->senderState = new SenderState(m_address, req->getSize());

    if (port->sendTimingReq(pkt)) {
        DPRINTF(RubyTest, "successfully initiated prefetch.\n");
    } else {
        // If the packet did not issue, must delete
        delete pkt->senderState;
        delete pkt;

        DPRINTF(RubyTest,
                "prefetch initiation failed because Port was busy.\n");
    }
}

void
Check::initiateFlush()
{

    DPRINTF(RubyTest, "initiating Flush\n");

    int index = random_mt.random(0, m_num_writers - 1);
    RequestPort* port = m_tester_ptr->getWritableCpuPort(index);

    Request::Flags flags;

    RequestPtr req = std::make_shared<Request>(
            m_address, CHECK_SIZE, flags, m_tester_ptr->requestorId());
    req->setPC(m_pc);

    Packet::Command cmd;

    cmd = MemCmd::FlushReq;

    PacketPtr pkt = new Packet(req, cmd);

    // push the subblock onto the sender state.  The sequencer will
    // update the subblock on the return
    pkt->senderState = new SenderState(m_address, req->getSize());

    if (port->sendTimingReq(pkt)) {
        DPRINTF(RubyTest, "initiating Flush - successful\n");
    }
}

void
Check::initiateAction()
{
    DPRINTF(RubyTest, "initiating Action\n");
    assert(m_status == TesterStatus_Idle);

    int index = random_mt.random(0, m_num_writers - 1);
    RequestPort* port = m_tester_ptr->getWritableCpuPort(index);

    Request::Flags flags;

    // Create the particular address for the next byte to be written
    Addr writeAddr(m_address + m_store_count);

    // Stores are assumed to be 1 byte-sized
    RequestPtr req = std::make_shared<Request>(
        writeAddr, 1, flags, m_tester_ptr->requestorId());
    req->setPC(m_pc);

    req->setContext(index);
    Packet::Command cmd;

    // 1 out of 8 chance, issue an atomic rather than a write
    // if ((random() & 0x7) == 0) {
    //     cmd = MemCmd::SwapReq;
    // } else {
    cmd = MemCmd::WriteReq;
    // }

    PacketPtr pkt = new Packet(req, cmd);
    uint8_t *writeData = new uint8_t[1];
    *writeData = m_value + m_store_count;
    pkt->dataDynamic(writeData);

    DPRINTF(RubyTest, "Seq write: index %d data 0x%x check 0x%x\n", index,
            *(pkt->getConstPtr<uint8_t>()), *writeData);

    // push the subblock onto the sender state.  The sequencer will
    // update the subblock on the return
    pkt->senderState = new SenderState(writeAddr, req->getSize());

    if (port->sendTimingReq(pkt)) {
        DPRINTF(RubyTest, "initiating action - successful\n");
        DPRINTF(RubyTest, "status before action update: %s\n",
                (TesterStatus_to_string(m_status)).c_str());
        m_status = TesterStatus_Action_Pending;
        DPRINTF(RubyTest, "Check %#x, State=Action_Pending\n", m_address);
    } else {
        // If the packet did not issue, must delete
        // Note: No need to delete the data, the packet destructor
        // will delete it
        delete pkt->senderState;
        delete pkt;

        DPRINTF(RubyTest, "failed to initiate action - sequencer not ready\n");
    }

    DPRINTF(RubyTest, "status after action update: %s\n",
            (TesterStatus_to_string(m_status)).c_str());
}

void
Check::initiateCheck()
{
    DPRINTF(RubyTest, "Initiating Check\n");
    assert(m_status == TesterStatus_Ready);

    int index = random_mt.random(0, m_num_readers - 1);
    RequestPort* port = m_tester_ptr->getReadableCpuPort(index);

    Request::Flags flags;

    // If necessary, make the request an instruction fetch
    if (m_tester_ptr->isInstOnlyCpuPort(index) ||
        (m_tester_ptr->isInstDataCpuPort(index) &&
         (random_mt.random(0, 0x1)))) {
        flags.set(Request::INST_FETCH);
    }

    // Checks are sized depending on the number of bytes written
    RequestPtr req = std::make_shared<Request>(
            m_address, CHECK_SIZE, flags, m_tester_ptr->requestorId());
    req->setPC(m_pc);

    req->setContext(index);
    PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
    uint8_t *dataArray = new uint8_t[CHECK_SIZE];
    pkt->dataDynamic(dataArray);

    DPRINTF(RubyTest, "Seq read: index %d\n", index);

    // push the subblock onto the sender state.  The sequencer will
    // update the subblock on the return
    pkt->senderState = new SenderState(m_address, req->getSize());

    if (port->sendTimingReq(pkt)) {
        DPRINTF(RubyTest, "initiating check - successful\n");
        DPRINTF(RubyTest, "status before check update: %s\n",
                TesterStatus_to_string(m_status).c_str());
        m_status = TesterStatus_Check_Pending;
        DPRINTF(RubyTest, "Check %#x, State=Check_Pending\n", m_address);
    } else {
        // If the packet did not issue, must delete
        // Note: No need to delete the data, the packet destructor
        // will delete it
        delete pkt->senderState;
        delete pkt;

        DPRINTF(RubyTest, "failed to initiate check - cpu port not ready\n");
    }

    DPRINTF(RubyTest, "status after check update: %s\n",
            TesterStatus_to_string(m_status).c_str());
}

void
Check::performCallback(NodeID proc, SubBlock* data, Cycles curTime)
{
    Addr address = data->getAddress();

    // This isn't exactly right since we now have multi-byte checks
    //  assert(getAddress() == address);

    assert(makeLineAddress(m_address) == makeLineAddress(address));
    assert(data != NULL);

    DPRINTF(RubyTest, "RubyTester Callback\n");
    debugPrint();

    if (m_status == TesterStatus_Action_Pending) {
        DPRINTF(RubyTest, "Action callback write value: %d, currently %d\n",
                (m_value + m_store_count), data->getByte(0));
        // Perform store one byte at a time
        data->setByte(0, (m_value + m_store_count));
        m_store_count++;
        if (m_store_count == CHECK_SIZE) {
            m_status = TesterStatus_Ready;
            DPRINTF(RubyTest, "Check %#x, State=Ready\n", m_address);
        } else {
            m_status = TesterStatus_Idle;
            DPRINTF(RubyTest, "Check %#x, State=Idle store_count: %d\n",
                    m_address, m_store_count);
        }
        DPRINTF(RubyTest, "Action callback return data now %d\n",
                data->getByte(0));
    } else if (m_status == TesterStatus_Check_Pending) {
        DPRINTF(RubyTest, "Check callback\n");
        // Perform load/check
        for (int byte_number=0; byte_number<CHECK_SIZE; byte_number++) {
            if (uint8_t(m_value + byte_number) != data->getByte(byte_number)) {
                panic("Action/check failure: proc: %d address: %#x data: %s "
                      "byte_number: %d m_value+byte_number: %d byte: %d %s"
                      "Time: %d\n",
                      proc, address, data, byte_number,
                      (int)m_value + byte_number,
                      (int)data->getByte(byte_number), *this, curTime);
            }
        }
        DPRINTF(RubyTest, "Action/check success\n");
        debugPrint();

        // successful check complete, increment complete
        m_tester_ptr->incrementCheckCompletions();

        m_status = TesterStatus_Idle;
        DPRINTF(RubyTest, "Check %#x, State=Idle\n", m_address);
        pickValue();

    } else {
        panic("Unexpected TesterStatus: %s proc: %d data: %s m_status: %s "
              "time: %d\n", *this, proc, data, m_status, curTime);
    }

    DPRINTF(RubyTest, "proc: %d, Address: 0x%x\n", proc,
            makeLineAddress(m_address));
    DPRINTF(RubyTest, "Callback done\n");
    debugPrint();
}

void
Check::changeAddress(Addr address)
{
    assert(m_status == TesterStatus_Idle || m_status == TesterStatus_Ready);
    m_status = TesterStatus_Idle;
    m_address = address;
    DPRINTF(RubyTest, "Check %#x, State=Idle\n", m_address);
    m_store_count = 0;
}

void
Check::pickValue()
{
    assert(m_status == TesterStatus_Idle);
    m_value = random_mt.random(0, 0xff); // One byte
    m_store_count = 0;
}

void
Check::pickInitiatingNode()
{
    assert(m_status == TesterStatus_Idle || m_status == TesterStatus_Ready);
    m_status = TesterStatus_Idle;
    m_initiatingNode = (random_mt.random(0, m_num_writers - 1));
    DPRINTF(RubyTest, "Check %#x, State=Idle, picked initiating node %d\n",
            m_address, m_initiatingNode);
    m_store_count = 0;
}

void
Check::print(std::ostream& out) const
{
    out << "["
        << m_address << ", value: "
        << (int)m_value << ", status: "
        << m_status << ", initiating node: "
        << m_initiatingNode << ", store_count: "
        << m_store_count
        << "]" << std::flush;
}

void
Check::debugPrint()
{
    DPRINTF(RubyTest,
        "[%#x, value: %d, status: %s, initiating node: %d, store_count: %d]\n",
        m_address, (int)m_value, TesterStatus_to_string(m_status).c_str(),
        m_initiatingNode, m_store_count);
}
