legiontrace.cc

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· CC 代码 · 共 600 行 · 第 1/2 页

CC
600
字号
/* * Copyright (c) 2001, 2002, 2003, 2004, 2005 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. * * Authors: Steven K. Reinhardt *          Lisa R. Hsu *          Nathan L. Binkert *          Steven E. Raasch */#include "arch/isa_specific.hh"#if THE_ISA != SPARC_ISA    #error Legion tracing only works with SPARC simulations!#endif#include "config/full_system.hh"#if !FULL_SYSTEM    #error Legion tracing only works in full system!#endif#include <iomanip>#include <sys/ipc.h>#include <sys/shm.h>#include "arch/sparc/predecoder.hh"#include "arch/sparc/regfile.hh"#include "arch/sparc/utility.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/system.hh"#if FULL_SYSTEM#include "arch/tlb.hh"#endif//XXX This is temporary#include "cpu/m5legion_interface.h"using namespace std;using namespace TheISA;#if FULL_SYSTEMstatic int diffcount = 0;static bool wasMicro = false;#endifnamespace Trace {SharedData *shared_data = NULL;voidsetupSharedData(){    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");}voidTrace::LegionTraceRecord::dump(){    ostream &outs = Trace::output();    static TheISA::Predecoder predecoder(NULL);    // 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 = 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 & 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,                                FloatRegFile::DoubleWidth) !=                            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 !=

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?