/*
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * 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.
 */

// FIX ME: make trackBlkAddr use blocksize from actual cache, not hard coded

#include <iomanip>
#include <set>
#include <sstream>
#include <string>
#include <vector>

#include "base/misc.hh"
#include "base/statistics.hh"
#include "cpu/exec_context.hh"
#include "cpu/memtest/memtest.hh"
#include "mem/cache/base_cache.hh"
#include "sim/builder.hh"
#include "sim/sim_events.hh"
#include "sim/stats.hh"

using namespace std;

int TESTER_ALLOCATOR=0;

MemTest::MemTest(const string &name,
                 MemInterface *_cache_interface,
                 FunctionalMemory *main_mem,
                 FunctionalMemory *check_mem,
                 unsigned _memorySize,
                 unsigned _percentReads,
                 unsigned _percentCopies,
                 unsigned _percentUncacheable,
                 unsigned _progressInterval,
                 unsigned _percentSourceUnaligned,
                 unsigned _percentDestUnaligned,
                 Addr _traceAddr,
                 Counter _max_loads)
    : SimObject(name),
      tickEvent(this),
      cacheInterface(_cache_interface),
      mainMem(main_mem),
      checkMem(check_mem),
      size(_memorySize),
      percentReads(_percentReads),
      percentCopies(_percentCopies),
      percentUncacheable(_percentUncacheable),
      progressInterval(_progressInterval),
      nextProgressMessage(_progressInterval),
      percentSourceUnaligned(_percentSourceUnaligned),
      percentDestUnaligned(percentDestUnaligned),
      maxLoads(_max_loads)
{
    vector<string> cmd;
    cmd.push_back("/bin/ls");
    vector<string> null_vec;
    xc = new ExecContext(NULL, 0, mainMem, 0);

    blockSize = cacheInterface->getBlockSize();
    blockAddrMask = blockSize - 1;
    traceBlockAddr = blockAddr(_traceAddr);

    //setup data storage with interesting values
    uint8_t *data1 = new uint8_t[size];
    uint8_t *data2 = new uint8_t[size];
    uint8_t *data3 = new uint8_t[size];
    memset(data1, 1, size);
    memset(data2, 2, size);
    memset(data3, 3, size);
    curTick = 0;

    baseAddr1 = 0x100000;
    baseAddr2 = 0x400000;
    uncacheAddr = 0x800000;

    // set up intial memory contents here
    mainMem->prot_write(baseAddr1, data1, size);
    checkMem->prot_write(baseAddr1, data1, size);
    mainMem->prot_write(baseAddr2, data2, size);
    checkMem->prot_write(baseAddr2, data2, size);
    mainMem->prot_write(uncacheAddr, data3, size);
    checkMem->prot_write(uncacheAddr, data3, size);

    delete [] data1;
    delete [] data2;
    delete [] data3;

    // set up counters
    noResponseCycles = 0;
    numReads = 0;
    tickEvent.schedule(0);

    id = TESTER_ALLOCATOR++;
}

static void
printData(ostream &os, uint8_t *data, int nbytes)
{
    os << hex << setfill('0');
    // assume little-endian: print bytes from highest address to lowest
    for (uint8_t *dp = data + nbytes - 1; dp >= data; --dp) {
        os << setw(2) << (unsigned)*dp;
    }
    os << dec;
}

void
MemTest::completeRequest(MemReqPtr &req, uint8_t *data)
{
    //Remove the address from the list of outstanding
    std::set<unsigned>::iterator removeAddr = outstandingAddrs.find(req->paddr);
    assert(removeAddr != outstandingAddrs.end());
    outstandingAddrs.erase(removeAddr);

    switch (req->cmd) {
      case Read:
        if (memcmp(req->data, data, req->size) != 0) {
            cerr << name() << ": on read of 0x" << hex << req->paddr
                 << " (0x" << hex << blockAddr(req->paddr) << ")"
                 << "@ cycle " << dec << curTick
                 << ", cache returns 0x";
            printData(cerr, req->data, req->size);
            cerr << ", expected 0x";
            printData(cerr, data, req->size);
            cerr << endl;
            fatal("");
        }

        numReads++;
        numReadsStat++;

        if (numReads == nextProgressMessage) {
            ccprintf(cerr, "%s: completed %d read accesses @%d\n",
                     name(), numReads, curTick);
            nextProgressMessage += progressInterval;
        }

        if (numReads >= maxLoads)
            SimExit(curTick, "Maximum number of loads reached!");
        break;

      case Write:
        numWritesStat++;
        break;

      case Copy:
        //Also remove dest from outstanding list
        removeAddr = outstandingAddrs.find(req->dest);
        assert(removeAddr != outstandingAddrs.end());
        outstandingAddrs.erase(removeAddr);
        numCopiesStat++;
        break;

      default:
        panic("invalid command");
    }

    if (blockAddr(req->paddr) == traceBlockAddr) {
        cerr << name() << ": completed "
             << (req->cmd.isWrite() ? "write" : "read")
             << " access of "
             << dec << req->size << " bytes at address 0x"
             << hex << req->paddr
             << " (0x" << hex << blockAddr(req->paddr) << ")"
             << ", value = 0x";
        printData(cerr, req->data, req->size);
        cerr << " @ cycle " << dec << curTick;

        cerr << endl;
    }

    noResponseCycles = 0;
    delete [] data;
}


void
MemTest::regStats()
{
    using namespace Stats;


    numReadsStat
        .name(name() + ".num_reads")
        .desc("number of read accesses completed")
        ;

    numWritesStat
        .name(name() + ".num_writes")
        .desc("number of write accesses completed")
        ;

    numCopiesStat
        .name(name() + ".num_copies")
        .desc("number of copy accesses completed")
        ;
}

void
MemTest::tick()
{
    if (!tickEvent.scheduled())
        tickEvent.schedule(curTick + cycles(1));

    if (++noResponseCycles >= 500000) {
        cerr << name() << ": deadlocked at cycle " << curTick << endl;
        fatal("");
    }

    if (cacheInterface->isBlocked()) {
        return;
    }

    //make new request
    unsigned cmd = random() % 100;
    unsigned offset = random() % size;
    unsigned base = random() % 2;
    uint64_t data = random();
    unsigned access_size = random() % 4;
    unsigned cacheable = random() % 100;

    //If we aren't doing copies, use id as offset, and do a false sharing
    //mem tester
    if (percentCopies == 0) {
        //We can eliminate the lower bits of the offset, and then use the id
        //to offset within the blks
        offset &= ~63; //Not the low order bits
        offset += id;
        access_size = 0;
    }

    MemReqPtr req = new MemReq();

    if (cacheable < percentUncacheable) {
        req->flags |= UNCACHEABLE;
        req->paddr = uncacheAddr + offset;
    } else {
        req->paddr = ((base) ? baseAddr1 : baseAddr2) + offset;
    }
    // bool probe = (random() % 2 == 1) && !req->isUncacheable();
    bool probe = false;

    req->size = 1 << access_size;
    req->data = new uint8_t[req->size];
    req->paddr &= ~(req->size - 1);
    req->time = curTick;
    req->xc = xc;

    if (cmd < percentReads) {
        // read

        //For now we only allow one outstanding request per addreess per tester
        //This means we assume CPU does write forwarding to reads that alias something
        //in the cpu store buffer.
        if (outstandingAddrs.find(req->paddr) != outstandingAddrs.end()) return;
        else outstandingAddrs.insert(req->paddr);

        req->cmd = Read;
        uint8_t *result = new uint8_t[8];
        checkMem->access(Read, req->paddr, result, req->size);
        if (blockAddr(req->paddr) == traceBlockAddr) {
            cerr << name()
                 << ": initiating read "
                 << ((probe) ? "probe of " : "access of ")
                 << dec << req->size << " bytes from addr 0x"
                 << hex << req->paddr
                 << " (0x" << hex << blockAddr(req->paddr) << ")"
                 << " at cycle "
                 << dec << curTick << endl;
        }
        if (probe) {
            cacheInterface->probeAndUpdate(req);
            completeRequest(req, result);
        } else {
            req->completionEvent = new MemCompleteEvent(req, result, this);
            cacheInterface->access(req);
        }
    } else if (cmd < (100 - percentCopies)){
        // write

        //For now we only allow one outstanding request per addreess per tester
        //This means we assume CPU does write forwarding to reads that alias something
        //in the cpu store buffer.
        if (outstandingAddrs.find(req->paddr) != outstandingAddrs.end()) return;
        else outstandingAddrs.insert(req->paddr);

        req->cmd = Write;
        memcpy(req->data, &data, req->size);
        checkMem->access(Write, req->paddr, req->data, req->size);
        if (blockAddr(req->paddr) == traceBlockAddr) {
            cerr << name() << ": initiating write "
                 << ((probe)?"probe of ":"access of ")
                 << dec << req->size << " bytes (value = 0x";
            printData(cerr, req->data, req->size);
            cerr << ") to addr 0x"
                 << hex << req->paddr
                 << " (0x" << hex << blockAddr(req->paddr) << ")"
                 << " at cycle "
                 << dec << curTick << endl;
        }
        if (probe) {
            cacheInterface->probeAndUpdate(req);
            completeRequest(req, NULL);
        } else {
            req->completionEvent = new MemCompleteEvent(req, NULL, this);
            cacheInterface->access(req);
        }
    } else {
        // copy
        unsigned source_align = random() % 100;
        unsigned dest_align = random() % 100;
        unsigned offset2 = random() % size;

        Addr source = ((base) ? baseAddr1 : baseAddr2) + offset;
        Addr dest = ((base) ? baseAddr2 : baseAddr1) + offset2;
        if (outstandingAddrs.find(source) != outstandingAddrs.end()) return;
        else outstandingAddrs.insert(source);
        if (outstandingAddrs.find(dest) != outstandingAddrs.end()) return;
        else outstandingAddrs.insert(dest);

        if (source_align >= percentSourceUnaligned) {
            source = blockAddr(source);
        }
        if (dest_align >= percentDestUnaligned) {
            dest = blockAddr(dest);
        }
        req->cmd = Copy;
        req->flags &= ~UNCACHEABLE;
        req->paddr = source;
        req->dest = dest;
        delete [] req->data;
        req->data = new uint8_t[blockSize];
        req->size = blockSize;
        if (source == traceBlockAddr || dest == traceBlockAddr) {
            cerr << name()
                 << ": initiating copy of "
                 << dec << req->size << " bytes from addr 0x"
                 << hex << source
                 << " (0x" << hex << blockAddr(source) << ")"
                 << " to addr 0x"
                 << hex << dest
                 << " (0x" << hex << blockAddr(dest) << ")"
                 << " at cycle "
                 << dec << curTick << endl;
        }
        cacheInterface->access(req);
        uint8_t result[blockSize];
        checkMem->access(Read, source, &result, blockSize);
        checkMem->access(Write, dest, &result, blockSize);
    }
}


void
MemCompleteEvent::process()
{
    tester->completeRequest(req, data);
    delete this;
}


const char *
MemCompleteEvent::description()
{
    return "memory access completion";
}


BEGIN_DECLARE_SIM_OBJECT_PARAMS(MemTest)

    SimObjectParam<BaseCache *> cache;
    SimObjectParam<FunctionalMemory *> main_mem;
    SimObjectParam<FunctionalMemory *> check_mem;
    Param<unsigned> memory_size;
    Param<unsigned> percent_reads;
    Param<unsigned> percent_copies;
    Param<unsigned> percent_uncacheable;
    Param<unsigned> progress_interval;
    Param<unsigned> percent_source_unaligned;
    Param<unsigned> percent_dest_unaligned;
    Param<Addr> trace_addr;
    Param<Counter> max_loads;

END_DECLARE_SIM_OBJECT_PARAMS(MemTest)


BEGIN_INIT_SIM_OBJECT_PARAMS(MemTest)

    INIT_PARAM(cache, "L1 cache"),
    INIT_PARAM(main_mem, "hierarchical memory"),
    INIT_PARAM(check_mem, "check memory"),
    INIT_PARAM(memory_size, "memory size"),
    INIT_PARAM(percent_reads, "target read percentage"),
    INIT_PARAM(percent_copies, "target copy percentage"),
    INIT_PARAM(percent_uncacheable, "target uncacheable percentage"),
    INIT_PARAM(progress_interval, "progress report interval (in accesses)"),
    INIT_PARAM(percent_source_unaligned,
               "percent of copy source address that are unaligned"),
    INIT_PARAM(percent_dest_unaligned,
               "percent of copy dest address that are unaligned"),
    INIT_PARAM(trace_addr, "address to trace"),
    INIT_PARAM(max_loads, "terminate when we have reached this load count")

END_INIT_SIM_OBJECT_PARAMS(MemTest)


CREATE_SIM_OBJECT(MemTest)
{
    return new MemTest(getInstanceName(), cache->getInterface(), main_mem,
                       check_mem, memory_size, percent_reads, percent_copies,
                       percent_uncacheable, progress_interval,
                       percent_source_unaligned, percent_dest_unaligned,
                       trace_addr, max_loads);
}

REGISTER_SIM_OBJECT("MemTest", MemTest)
