/*
 * Copyright (c) 2001-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.
 *
 * Authors: Steve Reinhardt
 *          Lisa Hsu
 *          Nathan Binkert
 *          Steve Raasch
 */

#include "config/the_isa.hh"
#if THE_ISA != SPARC_ISA
    #error Legion tracing only works with SPARC simulations!
#endif

#include <sys/ipc.h>
#include <sys/shm.h>

#include <cstdio>
#include <iomanip>

#include "arch/sparc/decoder.hh"
#include "arch/sparc/registers.hh"
#include "arch/sparc/utility.hh"
#include "arch/tlb.hh"
#include "base/socket.hh"
#include "cpu/base.hh"
#include "cpu/legiontrace.hh"
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
#include "sim/full_system.hh"
#include "sim/system.hh"

//XXX This is temporary
#include "cpu/m5legion_interface.h"

using namespace std;
using namespace TheISA;

static int diffcount = 0;
static bool wasMicro = false;

namespace Trace {
SharedData *shared_data = NULL;

void
setupSharedData()
{
    int shmfd = shmget('M' << 24 | getuid(), sizeof(SharedData), 0777);
    if (shmfd < 0)
        fatal("Couldn't get shared memory fd. Is Legion running?");

    shared_data = (SharedData*)shmat(shmfd, NULL, SHM_RND);
    if (shared_data == (SharedData*)-1)
        fatal("Couldn't allocate shared memory");

    if (shared_data->flags != OWN_M5)
        fatal("Shared memory has invalid owner");

    if (shared_data->version != VERSION)
        fatal("Shared Data is wrong version! M5: %d Legion: %d", VERSION,
              shared_data->version);

    // step legion forward one cycle so we can get register values
    shared_data->flags = OWN_LEGION;
}

////////////////////////////////////////////////////////////////////////
//
//  Utility methods for pretty printing a report about a difference
//

inline char * genCenteredLabel(int length, char * buffer, const char * label)
{
    int labelLength = strlen(label);
    assert(labelLength <= length);
    int leftPad = (length - labelLength) / 2;
    int rightPad = length - leftPad - labelLength;
    char format[64];
    sprintf(format, "%%%ds%%s%%%ds", leftPad, rightPad);
    sprintf(buffer, format, "", label, "");
    return buffer;
}

inline void printRegPair(ostream & os, char const * title, uint64_t a, uint64_t b)
{
    ccprintf(os, "  %16s  |  %#018x   %s   %#-018x  \n",
            title, a, (a == b) ? "|" : "X", b);
}

inline void printColumnLabels(ostream & os)
{
    static char * regLabel = genCenteredLabel(16, new char[17], "Register");
    static char * m5Label = genCenteredLabel(18, new char[18], "M5");
    static char * legionLabel = genCenteredLabel(18, new char[18], "Legion");
    ccprintf(os, "  %s  |  %s   |   %s  \n", regLabel, m5Label, legionLabel);
    ccprintf(os, "--------------------+-----------------------+-----------------------\n");
}

inline void printSectionHeader(ostream & os, const char * name)
{
    char sectionString[70];
    genCenteredLabel(69, sectionString, name);
    ccprintf(os, "====================================================================\n");
    ccprintf(os, "%69s\n", sectionString);
    ccprintf(os, "====================================================================\n");
}

inline void printLevelHeader(ostream & os, int level)
{
    char sectionString[70];
    char levelName[70];
    sprintf(levelName, "Trap stack level %d", level);
    genCenteredLabel(69, sectionString, levelName);
    ccprintf(os, "====================================================================\n");
    ccprintf(os, "%69s\n", sectionString);
    ccprintf(os, "====================================================================\n");
}

void
Trace::LegionTraceRecord::dump()
{
    ostream &outs = Trace::output();

    // Compare
    bool compared = false;
    bool diffPC   = false;
    bool diffCC   = false;
    bool diffInst = false;
    bool diffIntRegs = false;
    bool diffFpRegs = false;
    bool diffTpc = false;
    bool diffTnpc = false;
    bool diffTstate = false;
    bool diffTt = false;
    bool diffTba M5_VAR_USED = false;
    bool diffHpstate = false;
    bool diffHtstate = false;
    bool diffHtba = false;
    bool diffPstate = false;
    bool diffY = false;
    bool diffFsr = false;
    bool diffCcr = false;
    bool diffTl = false;
    bool diffGl = false;
    bool diffAsi = false;
    bool diffPil = false;
    bool diffCwp = false;
    bool diffCansave = false;
    bool diffCanrestore = false;
    bool diffOtherwin = false;
    bool diffCleanwin = false;
    bool diffTlb = false;
    Addr m5Pc, lgnPc;

    if (!shared_data)
        setupSharedData();

    // We took a trap on a micro-op...
    if (wasMicro && !staticInst->isMicroop())
    {
        // let's skip comparing this tick
        while (!compared)
            if (shared_data->flags == OWN_M5) {
                shared_data->flags = OWN_LEGION;
                compared = true;
            }
        compared = false;
        wasMicro = false;
    }

    if (staticInst->isLastMicroop())
        wasMicro = false;
    else if (staticInst->isMicroop())
        wasMicro = true;


    if(!staticInst->isMicroop() || staticInst->isLastMicroop()) {
        while (!compared) {
            if (shared_data->flags == OWN_M5) {
                m5Pc = pc.instAddr() & SparcISA::PAddrImplMask;
                if (bits(shared_data->pstate,3,3)) {
                    m5Pc &= mask(32);
                }
                lgnPc = shared_data->pc & SparcISA::PAddrImplMask;
                if (lgnPc != m5Pc)
                   diffPC = true;

                if (shared_data->cycle_count !=
                        thread->getCpuPtr()->instCount())
                    diffCC = true;

                if (shared_data->instruction !=
                        (SparcISA::MachInst)staticInst->machInst) {
                    diffInst = true;
                }
                // assume we have %g0 working correctly
                for (int i = 1; i < TheISA::NumIntArchRegs; i++) {
                    if (thread->readIntReg(i) != shared_data->intregs[i]) {
                        diffIntRegs = true;
                    }
                }
                for (int i = 0; i < TheISA::NumFloatRegs/2; i++) {
                    if (thread->readFloatRegBits(i*2) !=
                            shared_data->fpregs[i]) {
                        diffFpRegs = true;
                    }
                }
                        uint64_t oldTl =
                            thread->readMiscRegNoEffect(MISCREG_TL);
                if (oldTl != shared_data->tl)
                    diffTl = true;
                for (int i = 1; i <= MaxTL; i++) {
                    thread->setMiscRegNoEffect(MISCREG_TL, i);
                    if (thread->readMiscRegNoEffect(MISCREG_TPC) !=
                            shared_data->tpc[i-1])
                        diffTpc = true;
                    if (thread->readMiscRegNoEffect(MISCREG_TNPC) !=
                            shared_data->tnpc[i-1])
                        diffTnpc = true;
                    if (thread->readMiscRegNoEffect(MISCREG_TSTATE) !=
                            shared_data->tstate[i-1])
                        diffTstate = true;
                    if (thread->readMiscRegNoEffect(MISCREG_TT) !=
                            shared_data->tt[i-1])
                        diffTt = true;
                    if (thread->readMiscRegNoEffect(MISCREG_HTSTATE) !=
                            shared_data->htstate[i-1])
                        diffHtstate = true;
                }
                thread->setMiscRegNoEffect(MISCREG_TL, oldTl);

                if(shared_data->tba != thread->readMiscRegNoEffect(MISCREG_TBA))
                    diffTba = true;
                //When the hpstate register is read by an instruction,
                //legion has bit 11 set. When it's in storage, it doesn't.
                //Since we don't directly support seperate interpretations
                //of the registers like that, the bit is always set to 1 and
                //we just don't compare it. It's not supposed to matter
                //anyway.
                if((shared_data->hpstate | (1 << 11)) !=
                        thread->readMiscRegNoEffect(MISCREG_HPSTATE))
                    diffHpstate = true;
                if(shared_data->htba !=
                        thread->readMiscRegNoEffect(MISCREG_HTBA))
                    diffHtba = true;
                if(shared_data->pstate !=
                        thread->readMiscRegNoEffect(MISCREG_PSTATE))
                    diffPstate = true;
                //if(shared_data->y !=
                //        thread->readMiscRegNoEffect(MISCREG_Y))
                if(shared_data->y !=
                        thread->readIntReg(NumIntArchRegs + 1))
                    diffY = true;
                if(shared_data->fsr !=
                        thread->readMiscRegNoEffect(MISCREG_FSR)) {
                    diffFsr = true;
                    if (mbits(shared_data->fsr, 63,10) ==
                            mbits(thread->readMiscRegNoEffect(MISCREG_FSR),
                                63,10)) {
                        thread->setMiscRegNoEffect(MISCREG_FSR,
                                shared_data->fsr);
                        diffFsr = false;
                    }
                }
                //if(shared_data->ccr !=
                //        thread->readMiscRegNoEffect(MISCREG_CCR))
                if(shared_data->ccr !=
                        thread->readIntReg(NumIntArchRegs + 2))
                    diffCcr = true;
                if(shared_data->gl !=
                        thread->readMiscRegNoEffect(MISCREG_GL))
                    diffGl = true;
                if(shared_data->asi !=
                        thread->readMiscRegNoEffect(MISCREG_ASI))
                    diffAsi = true;
                if(shared_data->pil !=
                        thread->readMiscRegNoEffect(MISCREG_PIL))
                    diffPil = true;
                if(shared_data->cwp !=
                        thread->readMiscRegNoEffect(MISCREG_CWP))
                    diffCwp = true;
                //if(shared_data->cansave !=
                //        thread->readMiscRegNoEffect(MISCREG_CANSAVE))
                if(shared_data->cansave !=
                        thread->readIntReg(NumIntArchRegs + 3))
                    diffCansave = true;
                //if(shared_data->canrestore !=
                //        thread->readMiscRegNoEffect(MISCREG_CANRESTORE))
                if(shared_data->canrestore !=
                        thread->readIntReg(NumIntArchRegs + 4))
                    diffCanrestore = true;
                //if(shared_data->otherwin !=
                //        thread->readMiscRegNoEffect(MISCREG_OTHERWIN))
                if(shared_data->otherwin !=
                        thread->readIntReg(NumIntArchRegs + 6))
                    diffOtherwin = true;
                //if(shared_data->cleanwin !=
                //        thread->readMiscRegNoEffect(MISCREG_CLEANWIN))
                if(shared_data->cleanwin !=
                        thread->readIntReg(NumIntArchRegs + 5))
                    diffCleanwin = true;

                for (int i = 0; i < 64; i++) {
                    if (shared_data->itb[i] !=
                            thread->getITBPtr()->TteRead(i))
                        diffTlb = true;
                    if (shared_data->dtb[i] !=
                            thread->getDTBPtr()->TteRead(i))
                        diffTlb = true;
                }

                if (diffPC || diffCC || diffInst ||
                    diffIntRegs || diffFpRegs ||
                    diffTpc || diffTnpc || diffTstate || diffTt ||
                    diffHpstate || diffHtstate || diffHtba ||
                    diffPstate || diffY || diffCcr || diffTl || diffFsr ||
                    diffGl || diffAsi || diffPil || diffCwp ||
                    diffCansave || diffCanrestore ||
                    diffOtherwin || diffCleanwin || diffTlb) {

                    outs << "Differences found between M5 and Legion:";
                    if (diffPC)
                        outs << " [PC]";
                    if (diffCC)
                        outs << " [CC]";
                    if (diffInst)
                        outs << " [Instruction]";
                    if (diffIntRegs)
                        outs << " [IntRegs]";
                    if (diffFpRegs)
                        outs << " [FpRegs]";
                    if (diffTpc)
                        outs << " [Tpc]";
                    if (diffTnpc)
                        outs << " [Tnpc]";
                    if (diffTstate)
                        outs << " [Tstate]";
                    if (diffTt)
                        outs << " [Tt]";
                    if (diffHpstate)
                        outs << " [Hpstate]";
                    if (diffHtstate)
                        outs << " [Htstate]";
                    if (diffHtba)
                        outs << " [Htba]";
                    if (diffPstate)
                        outs << " [Pstate]";
                    if (diffY)
                        outs << " [Y]";
                    if (diffFsr)
                        outs << " [FSR]";
                    if (diffCcr)
                        outs << " [Ccr]";
                    if (diffTl)
                        outs << " [Tl]";
                    if (diffGl)
                        outs << " [Gl]";
                    if (diffAsi)
                        outs << " [Asi]";
                    if (diffPil)
                        outs << " [Pil]";
                    if (diffCwp)
                        outs << " [Cwp]";
                    if (diffCansave)
                        outs << " [Cansave]";
                    if (diffCanrestore)
                        outs << " [Canrestore]";
                    if (diffOtherwin)
                        outs << " [Otherwin]";
                    if (diffCleanwin)
                        outs << " [Cleanwin]";
                    if (diffTlb)
                        outs << " [Tlb]";
                    outs << endl << endl;

                    outs << right << setfill(' ') << setw(15)
                         << "M5 PC: " << "0x"<< setw(16) << setfill('0')
                         << hex << m5Pc << endl;
                    outs << setfill(' ') << setw(15)
                         << "Legion PC: " << "0x"
                         << setw(16) << setfill('0') << hex
                         << lgnPc << endl << endl;

                    outs << right << setfill(' ') << setw(15)
                         << "M5 CC: " << "0x"
                         << setw(16) << setfill('0') << hex
                         << thread->getCpuPtr()->instCount() << endl;
                    outs << setfill(' ') << setw(15)
                         << "Legion CC: " << "0x"
                         << setw(16) << setfill('0') << hex
                         << shared_data->cycle_count << endl << endl;

                    outs << setfill(' ') << setw(15)
                         << "M5 Inst: " << "0x"
                         << setw(8) << setfill('0') << hex
                         << staticInst->machInst
                         << staticInst->disassemble(m5Pc, debugSymbolTable)
                         << endl;

                    TheISA::Decoder *decoder = thread->getDecoderPtr();
                    decoder->moreBytes(m5Pc, m5Pc, shared_data->instruction);

                    assert(decoder->instReady());

                    PCState tempPC = pc;
                    StaticInstPtr legionInst = decoder->decode(tempPC);
                    outs << setfill(' ') << setw(15)
                         << " Legion Inst: "
                         << "0x" << setw(8) << setfill('0') << hex
                         << shared_data->instruction
                         << legionInst->disassemble(lgnPc, debugSymbolTable)
                         << endl << endl;

                    printSectionHeader(outs, "General State");
                    printColumnLabels(outs);
                    printRegPair(outs, "HPstate",
                            thread->readMiscRegNoEffect(MISCREG_HPSTATE),
                            shared_data->hpstate | (1 << 11));
                    printRegPair(outs, "Htba",
                            thread->readMiscRegNoEffect(MISCREG_HTBA),
                            shared_data->htba);
                    printRegPair(outs, "Pstate",
                            thread->readMiscRegNoEffect(MISCREG_PSTATE),
                            shared_data->pstate);
                    printRegPair(outs, "Y",
                            //thread->readMiscRegNoEffect(MISCREG_Y),
                            thread->readIntReg(NumIntArchRegs + 1),
                            shared_data->y);
                    printRegPair(outs, "FSR",
                            thread->readMiscRegNoEffect(MISCREG_FSR),
                            shared_data->fsr);
                    printRegPair(outs, "Ccr",
                            //thread->readMiscRegNoEffect(MISCREG_CCR),
                            thread->readIntReg(NumIntArchRegs + 2),
                            shared_data->ccr);
                    printRegPair(outs, "Tl",
                            thread->readMiscRegNoEffect(MISCREG_TL),
                            shared_data->tl);
                    printRegPair(outs, "Gl",
                            thread->readMiscRegNoEffect(MISCREG_GL),
                            shared_data->gl);
                    printRegPair(outs, "Asi",
                            thread->readMiscRegNoEffect(MISCREG_ASI),
                            shared_data->asi);
                    printRegPair(outs, "Pil",
                            thread->readMiscRegNoEffect(MISCREG_PIL),
                            shared_data->pil);
                    printRegPair(outs, "Cwp",
                            thread->readMiscRegNoEffect(MISCREG_CWP),
                            shared_data->cwp);
                    printRegPair(outs, "Cansave",
                            //thread->readMiscRegNoEffect(MISCREG_CANSAVE),
                            thread->readIntReg(NumIntArchRegs + 3),
                            shared_data->cansave);
                    printRegPair(outs, "Canrestore",
                            //thread->readMiscRegNoEffect(MISCREG_CANRESTORE),
                            thread->readIntReg(NumIntArchRegs + 4),
                            shared_data->canrestore);
                    printRegPair(outs, "Otherwin",
                            //thread->readMiscRegNoEffect(MISCREG_OTHERWIN),
                            thread->readIntReg(NumIntArchRegs + 6),
                            shared_data->otherwin);
                    printRegPair(outs, "Cleanwin",
                            //thread->readMiscRegNoEffect(MISCREG_CLEANWIN),
                            thread->readIntReg(NumIntArchRegs + 5),
                            shared_data->cleanwin);
                    outs << endl;
                    for (int i = 1; i <= MaxTL; i++) {
                        printLevelHeader(outs, i);
                        printColumnLabels(outs);
                        thread->setMiscRegNoEffect(MISCREG_TL, i);
                        printRegPair(outs, "Tpc",
                                thread->readMiscRegNoEffect(MISCREG_TPC),
                                shared_data->tpc[i-1]);
                        printRegPair(outs, "Tnpc",
                                thread->readMiscRegNoEffect(MISCREG_TNPC),
                                shared_data->tnpc[i-1]);
                        printRegPair(outs, "Tstate",
                                thread->readMiscRegNoEffect(MISCREG_TSTATE),
                                shared_data->tstate[i-1]);
                        printRegPair(outs, "Tt",
                                thread->readMiscRegNoEffect(MISCREG_TT),
                                shared_data->tt[i-1]);
                        printRegPair(outs, "Htstate",
                                thread->readMiscRegNoEffect(MISCREG_HTSTATE),
                                shared_data->htstate[i-1]);
                    }
                    thread->setMiscRegNoEffect(MISCREG_TL, oldTl);
                    outs << endl;

                    printSectionHeader(outs, "General Purpose Registers");
                    static const char * regtypes[4] =
                        {"%g", "%o", "%l", "%i"};
                    for(int y = 0; y < 4; y++) {
                        for(int x = 0; x < 8; x++) {
                            char label[8];
                            sprintf(label, "%s%d", regtypes[y], x);
                            printRegPair(outs, label,
                                    thread->readIntReg(y*8+x),
                                    shared_data->intregs[y*8+x]);
                        }
                    }
                    if (diffFpRegs) {
                        for (int x = 0; x < 32; x++) {
                            char label[8];
                            sprintf(label, "%%f%d", x);
                            printRegPair(outs, label,
                                thread->readFloatRegBits(x*2),
                                shared_data->fpregs[x]);
                        }
                    }
                    if (diffTlb) {
                        printColumnLabels(outs);
                        char label[9];
                        for (int x = 0; x < 64; x++) {
                            if (shared_data->itb[x] !=
                                    ULL(0xFFFFFFFFFFFFFFFF) ||
                                thread->getITBPtr()->TteRead(x) !=
                                ULL(0xFFFFFFFFFFFFFFFF)) {
                                    sprintf(label, "I-TLB:%02d", x);
                                    printRegPair(outs, label,
                                            thread->getITBPtr()->TteRead(x),
                                            shared_data->itb[x]);
                            }
                        }
                        for (int x = 0; x < 64; x++) {
                            if (shared_data->dtb[x] !=
                                    ULL(0xFFFFFFFFFFFFFFFF) ||
                                thread->getDTBPtr()->TteRead(x) !=
                                ULL(0xFFFFFFFFFFFFFFFF))  {
                                    sprintf(label, "D-TLB:%02d", x);
                                    printRegPair(outs, label,
                                            thread->getDTBPtr()->TteRead(x),
                                            shared_data->dtb[x]);
                            }
                        }
                        thread->getITBPtr()->dumpAll();
                        thread->getDTBPtr()->dumpAll();
                    }

                    diffcount++;
                    if (diffcount > 3)
                        fatal("Differences found between Legion and M5\n");
                } else
                    diffcount = 0;

                compared = true;
                shared_data->flags = OWN_LEGION;
            }
        } // while
    } // if not microop
}

} // namespace Trace

////////////////////////////////////////////////////////////////////////
//
//  ExeTracer Simulation Object
//
Trace::LegionTrace *
LegionTraceParams::create()
{
    if (!FullSystem)
        panic("Legion tracing only works in full system!");
    return new Trace::LegionTrace(this);
};
