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

namespace gem5
{

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 = ruby::TesterStatus_Idle;

    pickValue();
    pickInitiatingNode();
    changeAddress(address);
    m_pc = pc;
    m_access_mode = ruby::RubyAccessMode(
        random_mt.random(0, ruby::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 == ruby::TesterStatus_Idle) {
        initiateAction();
    } else if (m_status == ruby::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 == ruby::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",
                (ruby::TesterStatus_to_string(m_status)).c_str());
        m_status = ruby::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",
            (ruby::TesterStatus_to_string(m_status)).c_str());
}

void
Check::initiateCheck()
{
    DPRINTF(RubyTest, "Initiating Check\n");
    assert(m_status == ruby::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",
                ruby::TesterStatus_to_string(m_status).c_str());
        m_status = ruby::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",
            ruby::TesterStatus_to_string(m_status).c_str());
}

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

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

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

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

    if (m_status == ruby::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 = ruby::TesterStatus_Ready;
            DPRINTF(RubyTest, "Check %#x, State=Ready\n", m_address);
        } else {
            m_status = ruby::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 == ruby::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 = ruby::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,
            ruby::makeLineAddress(m_address));
    DPRINTF(RubyTest, "Callback done\n");
    debugPrint();
}

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

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

void
Check::pickInitiatingNode()
{
    assert(m_status == ruby::TesterStatus_Idle ||
        m_status == ruby::TesterStatus_Ready);
    m_status = ruby::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,
        ruby::TesterStatus_to_string(m_status).c_str(),
        m_initiatingNode, m_store_count);
}

} // namespace gem5
