cp_annotate.cc revision 5952
1360SN/A/*
21458SN/A * Copyright (c) 2006-2009 The Regents of The University of Michigan
3360SN/A * All rights reserved.
4360SN/A *
5360SN/A * Redistribution and use in source and binary forms, with or without
6360SN/A * modification, are permitted provided that the following conditions are
7360SN/A * met: redistributions of source code must retain the above copyright
8360SN/A * notice, this list of conditions and the following disclaimer;
9360SN/A * redistributions in binary form must reproduce the above copyright
10360SN/A * notice, this list of conditions and the following disclaimer in the
11360SN/A * documentation and/or other materials provided with the distribution;
12360SN/A * neither the name of the copyright holders nor the names of its
13360SN/A * contributors may be used to endorse or promote products derived from
14360SN/A * this software without specific prior written permission.
15360SN/A *
16360SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17360SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18360SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19360SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20360SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21360SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22360SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23360SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24360SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25360SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26360SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Ali Saidi
292665Ssaidi@eecs.umich.edu */
30360SN/A
31360SN/A#include "arch/utility.hh"
321354SN/A#include "arch/alpha/linux/threadinfo.hh"
331354SN/A#include "base/cp_annotate.hh"
34360SN/A#include "base/callback.hh"
352764Sstever@eecs.umich.edu#include "base/loader/object_file.hh"
362764Sstever@eecs.umich.edu#include "base/output.hh"
372064SN/A#include "base/trace.hh"
38360SN/A#include "cpu/thread_context.hh"
39360SN/A#include "sim/arguments.hh"
40360SN/A#include "sim/core.hh"
41360SN/A#include "sim/sim_exit.hh"
42360SN/A#include "sim/system.hh"
43360SN/A
441809SN/Astruct CPAIgnoreSymbol
455543Ssaidi@eecs.umich.edu{
461809SN/A    const char *symbol;
473113Sgblack@eecs.umich.edu    size_t len;
488229Snate@binkert.org};
498229Snate@binkert.org#define CPA_IGNORE_SYMBOL(sym) { #sym, sizeof(#sym) }
503113Sgblack@eecs.umich.edu
517075Snate@binkert.orgCPAIgnoreSymbol ignoreSymbols[] = {
528229Snate@binkert.org    CPA_IGNORE_SYMBOL("m5a_"),
537075Snate@binkert.org    CPA_IGNORE_SYMBOL("ret_from_sys_call"),
54360SN/A    CPA_IGNORE_SYMBOL("ret_from_reschedule"),
552474SN/A    CPA_IGNORE_SYMBOL("_spin_"),
565543Ssaidi@eecs.umich.edu    CPA_IGNORE_SYMBOL("local_bh_"),
572462SN/A    CPA_IGNORE_SYMBOL("restore_all"),
581354SN/A    CPA_IGNORE_SYMBOL("Call_Pal_"),
596216Snate@binkert.org    CPA_IGNORE_SYMBOL("pal_post_interrupt"),
606658Snate@binkert.org    CPA_IGNORE_SYMBOL("rti_to_"),
612474SN/A    CPA_IGNORE_SYMBOL("sys_int_2"),
622680Sktlim@umich.edu    CPA_IGNORE_SYMBOL("sys_interrupt"),
638229Snate@binkert.org    CPA_IGNORE_SYMBOL("normal_int"),
642474SN/A    CPA_IGNORE_SYMBOL("TRAP_INTERRUPT_10_"),
657678Sgblack@eecs.umich.edu    CPA_IGNORE_SYMBOL("Trap_Interrupt"),
668229Snate@binkert.org    CPA_IGNORE_SYMBOL("do_entInt"),
676640Svince@csl.cornell.edu    CPA_IGNORE_SYMBOL("__do_softirq"),
68360SN/A    CPA_IGNORE_SYMBOL("_end"),
69360SN/A    CPA_IGNORE_SYMBOL("entInt"),
70360SN/A    CPA_IGNORE_SYMBOL("entSys"),
71360SN/A    {0,0}
72360SN/A};
73360SN/A#undef CPA_IGNORE_SYMBOL
74360SN/A
75360SN/Ausing namespace std;
76378SN/Ausing namespace TheISA;
771450SN/A
783114Sgblack@eecs.umich.edubool CPA::exists;
79360SN/ACPA *CPA::_cpa;
805543Ssaidi@eecs.umich.edu
815543Ssaidi@eecs.umich.educlass AnnotateDumpCallback : public Callback
825543Ssaidi@eecs.umich.edu{
83360SN/A
84360SN/A  private:
85360SN/A    CPA *cpa;
86360SN/A  public:
87360SN/A    virtual void process();
882680Sktlim@umich.edu    AnnotateDumpCallback(CPA *_cpa)
89360SN/A        : cpa(_cpa)
90360SN/A    {}
91360SN/A};
92360SN/A
93360SN/Avoid
94360SN/AAnnotateDumpCallback::process()
95360SN/A{
96360SN/A    cpa->dump(true);
97360SN/A    cpa->dumpKey();
98360SN/A}
99360SN/A
1003114Sgblack@eecs.umich.edu
101360SN/ACPA::CPA(Params *p)
102360SN/A    : SimObject(p), numSm(0), numSmt(0), numSys(0), numQs(0), conId(0)
103360SN/A{
104360SN/A    if (exists)
105360SN/A        fatal("Multiple annotation objects found in system");
106360SN/A    exists = true;
107360SN/A
108360SN/A    _enabled = p->enabled;
109360SN/A    _cpa = this;
110360SN/A
111360SN/A    vector<string>::iterator i;
112360SN/A    i = p->user_apps.begin();
113360SN/A
114360SN/A    while (i != p->user_apps.end()) {
115360SN/A        ObjectFile *of = createObjectFile(*i);
116360SN/A        string sf;
117360SN/A        if (!of)
118360SN/A            fatal("Couldn't load symbols from file: %s\n", *i);
119360SN/A        sf = *i;
120360SN/A        sf.erase(0, sf.rfind('/') + 1);;
121360SN/A        DPRINTFN("file %s short: %s\n", *i, sf);
1222400SN/A        userApp[sf] = new SymbolTable;
123360SN/A        bool result1 = of->loadGlobalSymbols(userApp[sf]);
1242461SN/A        bool result2 = of->loadLocalSymbols(userApp[sf]);
1255543Ssaidi@eecs.umich.edu        if (!result1 || !result2)
126360SN/A            panic("blah");
127360SN/A        assert(result1 && result2);
128360SN/A        i++;
129360SN/A    }
130360SN/A}
1312400SN/A
132360SN/Avoid
1332461SN/ACPA::startup()
1345543Ssaidi@eecs.umich.edu{
135360SN/A    osbin = simout.create("annotate.bin", true);
136360SN/A    // MAGIC version number 'M''5''A'N' + version/capabilities
137360SN/A    ah.version = 0x4D35414E00000101ULL;
138360SN/A    ah.num_recs = 0;
139360SN/A    ah.key_off = 0;
140360SN/A    osbin->write((char*)&ah, sizeof(AnnotateHeader));
141360SN/A
142360SN/A    registerExitCallback(new AnnotateDumpCallback(this));
143360SN/A}
144360SN/Avoid
145360SN/ACPA::swSmBegin(ThreadContext *tc)
146360SN/A{
147360SN/A    if (!enabled())
1485543Ssaidi@eecs.umich.edu        return;
149360SN/A
150360SN/A    Arguments args(tc);
151360SN/A    std::string st;
152360SN/A    Addr junk;
153360SN/A    char sm[50];
154360SN/A    if (!TheISA::inUserMode(tc))
155360SN/A        debugSymbolTable->findNearestSymbol(
156360SN/A            tc->readIntReg(ReturnAddressReg), st, junk);
157360SN/A
158360SN/A    CopyStringOut(tc, sm, args[0], 50);
159360SN/A    System *sys = tc->getSystemPtr();
160360SN/A    StringWrap name(sys->name());
161360SN/A
162360SN/A    if (!sm[0])
163360SN/A        warn("Got null SM at tick %d\n", curTick);
164360SN/A
165360SN/A    int sysi = getSys(sys);
1665543Ssaidi@eecs.umich.edu    int smi = getSm(sysi, sm, args[1]);
1675543Ssaidi@eecs.umich.edu    DPRINTF(Annotate,  "Starting machine: %s(%d) sysi: %d id: %#x\n", sm,
168502SN/A            smi, sysi, args[1]);
169360SN/A    DPRINTF(Annotate, "smMap[%d] = %d, %s, %#x\n", smi,
170360SN/A            smMap[smi-1].first, smMap[smi-1].second.first,
171360SN/A            smMap[smi-1].second.second);
172360SN/A
173360SN/A    uint64_t frame = getFrame(tc);
174360SN/A    StackId sid = StackId(sysi, frame);
175360SN/A
176360SN/A    // check if we need to link to the previous state machine
177360SN/A    int flags = args[2];
178360SN/A    if (flags & FL_LINK) {
179360SN/A        if (smStack[sid].size()) {
180378SN/A            int prev_smi = smStack[sid].back();
1811706SN/A            DPRINTF(Annotate, "Linking from %d to state machine %s(%d) [%#x]\n",
1823114Sgblack@eecs.umich.edu                    prev_smi, sm, smi, args[1]);
183378SN/A
184378SN/A            if (lnMap[smi])
185378SN/A                DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n",
186378SN/A                        smi, lnMap[smi]);
187378SN/A            assert(lnMap[smi] == 0);
1881706SN/A            lnMap[smi] =  prev_smi;
1893114Sgblack@eecs.umich.edu
1908149SChris.Emmons@ARM.com            add(OP_LINK, FL_NONE, tc->contextId(), prev_smi, smi);
1918149SChris.Emmons@ARM.com        } else {
192360SN/A            DPRINTF(Annotate, "Not Linking to state machine %s(%d) [%#x]\n",
1936109Ssanchezd@stanford.edu                    sm, smi, args[1]);
1941706SN/A        }
1953114Sgblack@eecs.umich.edu    }
196378SN/A
1976109Ssanchezd@stanford.edu
1986109Ssanchezd@stanford.edu    smStack[sid].push_back(smi);
1996109Ssanchezd@stanford.edu
2006109Ssanchezd@stanford.edu    DPRINTF(Annotate, "Stack Now (%#X):\n", frame);
201378SN/A    for (int x = smStack[sid].size()-1; x >= 0; x--)
2021706SN/A        DPRINTF(Annotate, "-- %d\n", smStack[sid][x]);
2033114Sgblack@eecs.umich.edu
204378SN/A    // reset the sw state exculsion to false
2055748SSteve.Reinhardt@amd.com    if (swExpl[sid])
2065748SSteve.Reinhardt@amd.com        swExpl[sid] = false;
2075748SSteve.Reinhardt@amd.com
208378SN/A
209378SN/A    Id id = Id(sm, frame);
2101706SN/A    if (scLinks[sysi-1][id]) {
2113114Sgblack@eecs.umich.edu        AnnDataPtr an = scLinks[sysi-1][id];
212378SN/A        scLinks[sysi-1].erase(id);
213378SN/A        an->stq = smi;
2141706SN/A        an->dump = true;
2153114Sgblack@eecs.umich.edu        DPRINTF(Annotate,
216378SN/A                "Found prev unknown linking from %d to state machine %s(%d)\n",
217378SN/A                an->sm, sm, smi);
2181706SN/A
2193114Sgblack@eecs.umich.edu        if (lnMap[smi])
220378SN/A            DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n",
221378SN/A                    smi, lnMap[smi]);
2221706SN/A        assert(lnMap[smi] == 0);
2233114Sgblack@eecs.umich.edu        lnMap[smi] =  an->sm;
224378SN/A    }
2254118Sgblack@eecs.umich.edu
2264118Sgblack@eecs.umich.edu    // add a new begin ifwe have that info
2274118Sgblack@eecs.umich.edu    if (st != "") {
2284118Sgblack@eecs.umich.edu        DPRINTF(Annotate, "st: %s smi: %d stCache.size %d\n", st,
229378SN/A                smi, stCache.size());
2301706SN/A        int sti = getSt(sm, st);
2313114Sgblack@eecs.umich.edu        lastState[smi] = sti;
232378SN/A        add(OP_BEGIN, FL_NONE, tc->contextId(), smi, sti);
233378SN/A    }
2341706SN/A}
2353114Sgblack@eecs.umich.edu
236360SN/Avoid
2375513SMichael.Adler@intel.comCPA::swSmEnd(ThreadContext *tc)
2385513SMichael.Adler@intel.com{
2395513SMichael.Adler@intel.com    if (!enabled())
2405513SMichael.Adler@intel.com        return;
2415513SMichael.Adler@intel.com
2425513SMichael.Adler@intel.com    Arguments args(tc);
2435513SMichael.Adler@intel.com    char sm[50];
2445513SMichael.Adler@intel.com    CopyStringOut(tc, sm, args[0], 50);
245511SN/A    System *sys = tc->getSystemPtr();
2461706SN/A    doSwSmEnd(sys, tc->contextId(), sm, getFrame(tc));
2473114Sgblack@eecs.umich.edu}
248511SN/A
2495513SMichael.Adler@intel.comvoid
2505513SMichael.Adler@intel.comCPA::doSwSmEnd(System *sys, int cpuid, string sm, uint64_t frame)
2515513SMichael.Adler@intel.com{
2525513SMichael.Adler@intel.com    int sysi = getSys(sys);
253511SN/A    StackId sid = StackId(sysi, frame);
2541706SN/A
2553114Sgblack@eecs.umich.edu
2561706SN/A    // reset the sw state exculsion to false
2571706SN/A    if (swExpl[sid])
2581706SN/A        swExpl[sid] = false;
2591706SN/A
2603114Sgblack@eecs.umich.edu
2611706SN/A    int smib = smStack[sid].back();
2621706SN/A    StringWrap name(sys->name());
2631706SN/A    DPRINTF(Annotate, "Ending machine: %s[%d, %#x] (%d?)\n", sm, sysi,
2641706SN/A            frame, smib);
2653114Sgblack@eecs.umich.edu
2661706SN/A    if (!smStack[sid].size() || smMap[smib-1].second.first != sm) {
267511SN/A        DPRINTF(Annotate, "State Machine not unwinding correctly. sid: %d, %#x"
2686703Svince@csl.cornell.edu                " top of stack: %s Current Stack:\n",
2696703Svince@csl.cornell.edu                sysi, frame, smMap[smib-1].second.first);
2706703Svince@csl.cornell.edu        for (int x = smStack[sid].size()-1; x >= 0; x--)
2716703Svince@csl.cornell.edu            DPRINTF(Annotate, "-- %d\n", smStack[sid][x]);
2726685Stjones1@inf.ed.ac.uk        DPRINTF(Annotate, "Ending machine: %s; end stack: %s\n", sm,
2736685Stjones1@inf.ed.ac.uk                smMap[smib-1].second.first);
2746685Stjones1@inf.ed.ac.uk
2756685Stjones1@inf.ed.ac.uk        warn("State machine stack not unwinding correctly at %d\n", curTick);
2766685Stjones1@inf.ed.ac.uk    } else {
2775513SMichael.Adler@intel.com        DPRINTF(Annotate,
2785513SMichael.Adler@intel.com                "State machine ending:%s sysi:%d id:%#x back:%d getSm:%d\n",
2795513SMichael.Adler@intel.com                sm, sysi, smMap[smib-1].second.second, smStack[sid].back(),
2805513SMichael.Adler@intel.com                getSm(sysi, sm, smMap[smib-1].second.second));
2815513SMichael.Adler@intel.com        assert(getSm(sysi, sm, smMap[smib-1].second.second) ==
2821999SN/A                smStack[sid].back());
2831999SN/A
2843114Sgblack@eecs.umich.edu        int smi = smStack[sid].back();
2851999SN/A        smStack[sid].pop_back();
2861999SN/A
2871999SN/A        if (lnMap[smi]) {
2881999SN/A            DPRINTF(Annotate, "Linking %d back to %d\n", smi, lnMap[smi]);
2893114Sgblack@eecs.umich.edu            add(OP_LINK, FL_NONE, cpuid, smi, lnMap[smi]);
2901999SN/A            lnMap.erase(smi);
2913079Sstever@eecs.umich.edu        }
2923079Sstever@eecs.umich.edu
2933114Sgblack@eecs.umich.edu        if (smStack[sid].size()) {
2943079Sstever@eecs.umich.edu            add(OP_BEGIN, FL_NONE, cpuid, smi, lastState[smi]);
2952093SN/A        }
2962093SN/A
2973114Sgblack@eecs.umich.edu        DPRINTF(Annotate, "Stack Now:\n");
2982093SN/A        for (int x = smStack[sid].size()-1; x >= 0; x--)
2992687Sksewell@umich.edu            DPRINTF(Annotate, "-- %d\n", smStack[sid][x]);
3002687Sksewell@umich.edu    }
3013114Sgblack@eecs.umich.edu}
3022687Sksewell@umich.edu
3032238SN/A
3042238SN/Avoid
3053114Sgblack@eecs.umich.eduCPA::swExplictBegin(ThreadContext *tc)
3062238SN/A{
3072238SN/A    if (!enabled())
3082238SN/A        return;
3093114Sgblack@eecs.umich.edu
3102238SN/A    Arguments args(tc);
3112238SN/A    char st[50];
3122238SN/A    CopyStringOut(tc, st, args[1], 50);
3133114Sgblack@eecs.umich.edu
3142238SN/A    StringWrap name(tc->getSystemPtr()->name());
3152238SN/A    DPRINTF(Annotate, "Explict begin of state %s\n", st);
3162238SN/A    uint32_t flags = args[0];
3173114Sgblack@eecs.umich.edu    if (flags & FL_BAD)
3182238SN/A        warn("BAD state encountered: at cycle %d: %s\n", curTick, st);
3192238SN/A    swBegin(tc->getSystemPtr(), tc->contextId(), st, getFrame(tc), true, args[0]);
3202238SN/A}
3213114Sgblack@eecs.umich.edu
3222238SN/Avoid
3232238SN/ACPA::swAutoBegin(ThreadContext *tc, Addr next_pc)
3242238SN/A{
3253114Sgblack@eecs.umich.edu    if (!enabled())
3262238SN/A        return;
3272238SN/A
3282238SN/A    string sym;
3293114Sgblack@eecs.umich.edu    Addr sym_addr = 0;
3302238SN/A    SymbolTable *symtab = NULL;
3316109Ssanchezd@stanford.edu
3326109Ssanchezd@stanford.edu
3336109Ssanchezd@stanford.edu    if (!TheISA::inUserMode(tc)) {
3342238SN/A        debugSymbolTable->findNearestSymbol(next_pc, sym, sym_addr);
3352238SN/A        symtab = debugSymbolTable;
3362238SN/A    } else {
3372238SN/A        Linux::ThreadInfo ti(tc);
3382238SN/A        string app = ti.curTaskName();
3393114Sgblack@eecs.umich.edu        if (userApp.count(app))
3402238SN/A            userApp[app]->findNearestSymbol(next_pc, sym, sym_addr);
3412238SN/A    }
3422238SN/A
3433114Sgblack@eecs.umich.edu    if (sym_addr)
3442238SN/A        swBegin(tc->getSystemPtr(), tc->contextId(), sym, getFrame(tc));
3452238SN/A}
3462238SN/A
3473114Sgblack@eecs.umich.eduvoid
3482238SN/ACPA::swBegin(System *sys, int cpuid, std::string st, uint64_t frame, bool expl,
3492238SN/A        int flags)
3502238SN/A{
3513114Sgblack@eecs.umich.edu    int x = 0;
3522238SN/A    int len;
3532238SN/A    while (ignoreSymbols[x].len)
3541354SN/A    {
3551354SN/A        len = ignoreSymbols[x].len;
3561354SN/A        if (!st.compare(0,len, ignoreSymbols[x].symbol, len))
3571354SN/A            return;
3581354SN/A        x++;
3591354SN/A    }
3601354SN/A
3611354SN/A    int sysi = getSys(sys);
3621354SN/A    StackId sid = StackId(sysi, frame);
3631354SN/A    // if expl is true suspend symbol table based states
3641354SN/A    if (!smStack[sid].size())
3651354SN/A        return;
3661354SN/A    if (!expl && swExpl[sid])
3671354SN/A        return;
3687823Ssteve.reinhardt@amd.com    if (expl)
3691354SN/A        swExpl[sid] = true;
3701354SN/A    DPRINTFS(AnnotateVerbose, sys, "SwBegin: %s sysi: %d\n", st, sysi);
3711354SN/A    int smi = smStack[sid].back();
3721354SN/A    int sti = getSt(smMap[smi-1].second.first, st);
373360SN/A    if (lastState[smi] != sti) {
374360SN/A        lastState[smi] = sti;
375360SN/A        add(OP_BEGIN, flags, cpuid, smi, sti);
376360SN/A    }
377360SN/A}
378360SN/A
379360SN/Avoid
3803113Sgblack@eecs.umich.eduCPA::swEnd(ThreadContext *tc)
3813113Sgblack@eecs.umich.edu{
3823113Sgblack@eecs.umich.edu    if (!enabled())
3833113Sgblack@eecs.umich.edu        return;
3843113Sgblack@eecs.umich.edu
3853113Sgblack@eecs.umich.edu    std::string st;
3863113Sgblack@eecs.umich.edu    Addr junk;
3873113Sgblack@eecs.umich.edu    if (!TheISA::inUserMode(tc))
3883113Sgblack@eecs.umich.edu        debugSymbolTable->findNearestSymbol(
3893113Sgblack@eecs.umich.edu            tc->readIntReg(ReturnAddressReg), st, junk);
3903113Sgblack@eecs.umich.edu    System *sys = tc->getSystemPtr();
3913113Sgblack@eecs.umich.edu    StringWrap name(sys->name());
3923113Sgblack@eecs.umich.edu
3933113Sgblack@eecs.umich.edu    int sysi = getSys(sys);
3943113Sgblack@eecs.umich.edu    StackId sid = StackId(sysi, getFrame(tc));
3953113Sgblack@eecs.umich.edu    if (!smStack[sid].size()) {
3964189Sgblack@eecs.umich.edu        DPRINTF(Annotate, "Explict end of State: %s IGNORED\n",  st);
3974189Sgblack@eecs.umich.edu        return;
3983113Sgblack@eecs.umich.edu    }
3993113Sgblack@eecs.umich.edu    DPRINTF(Annotate, "Explict end of State: %s\n",  st);
4003113Sgblack@eecs.umich.edu    // return back to symbol table based states
4013113Sgblack@eecs.umich.edu    swExpl[sid] = false;
4023113Sgblack@eecs.umich.edu    int smi = smStack[sid].back();
4033113Sgblack@eecs.umich.edu    if (st != "") {
4043113Sgblack@eecs.umich.edu        int sti = getSt(smMap[smi-1].second.first, st);
4053277Sgblack@eecs.umich.edu        lastState[smi] = sti;
4065515SMichael.Adler@intel.com        add(OP_BEGIN, FL_NONE, tc->contextId(), smi, sti);
4075515SMichael.Adler@intel.com    }
4085515SMichael.Adler@intel.com}
4095515SMichael.Adler@intel.com
4105515SMichael.Adler@intel.comvoid
4113277Sgblack@eecs.umich.eduCPA::swQ(ThreadContext *tc)
4123277Sgblack@eecs.umich.edu{
4133277Sgblack@eecs.umich.edu    if (!enabled())
4143277Sgblack@eecs.umich.edu        return;
4153277Sgblack@eecs.umich.edu
4163277Sgblack@eecs.umich.edu    char q[50];
4173277Sgblack@eecs.umich.edu    Arguments args(tc);
4183113Sgblack@eecs.umich.edu    uint64_t id = args[0];
4193113Sgblack@eecs.umich.edu    CopyStringOut(tc, q, args[1], 50);
4203113Sgblack@eecs.umich.edu    int32_t count = args[2];
4213113Sgblack@eecs.umich.edu    System *sys = tc->getSystemPtr();
4223113Sgblack@eecs.umich.edu
4233113Sgblack@eecs.umich.edu    int sysi = getSys(sys);
4243113Sgblack@eecs.umich.edu    StackId sid = StackId(sysi, getFrame(tc));
4253114Sgblack@eecs.umich.edu    if (!smStack[sid].size())
4263113Sgblack@eecs.umich.edu        return;
4273114Sgblack@eecs.umich.edu    int smi = smStack[sid].back();
4283113Sgblack@eecs.umich.edu    if (swExpl[sid])
4293114Sgblack@eecs.umich.edu        swExpl[sid] = false;
4303113Sgblack@eecs.umich.edu    int qi = getQ(sysi, q, id);
4314061Sgblack@eecs.umich.edu    if (count == 0) {
4324061Sgblack@eecs.umich.edu        //warn("Tried to queue 0 bytes in %s, ignoring\n", q);
4334061Sgblack@eecs.umich.edu        return;
4343113Sgblack@eecs.umich.edu    }
4353113Sgblack@eecs.umich.edu    DPRINTFS(AnnotateQ, sys,
4363113Sgblack@eecs.umich.edu            "swQ: %s[%#x] cur size %d %d bytes: %d adding: %d\n",
4373113Sgblack@eecs.umich.edu            q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
4383113Sgblack@eecs.umich.edu    doQ(sys, FL_NONE, tc->contextId(), smi, q, qi, count);
4393113Sgblack@eecs.umich.edu}
4403113Sgblack@eecs.umich.edu
4413113Sgblack@eecs.umich.eduvoid
4423113Sgblack@eecs.umich.eduCPA::swDq(ThreadContext *tc)
4433113Sgblack@eecs.umich.edu{
4443113Sgblack@eecs.umich.edu    if (!enabled())
4454189Sgblack@eecs.umich.edu        return;
4464189Sgblack@eecs.umich.edu
4473113Sgblack@eecs.umich.edu    char q[50];
4483113Sgblack@eecs.umich.edu    Arguments args(tc);
4493113Sgblack@eecs.umich.edu    uint64_t id = args[0];
4503113Sgblack@eecs.umich.edu    CopyStringOut(tc, q, args[1], 50);
4513113Sgblack@eecs.umich.edu    int32_t count = args[2];
4523113Sgblack@eecs.umich.edu    System *sys = tc->getSystemPtr();
4533113Sgblack@eecs.umich.edu
4543113Sgblack@eecs.umich.edu    int sysi = getSys(sys);
4553113Sgblack@eecs.umich.edu    StackId sid = StackId(sysi, getFrame(tc));
4563113Sgblack@eecs.umich.edu    if (!smStack[sid].size())
4573113Sgblack@eecs.umich.edu        return;
4583113Sgblack@eecs.umich.edu    int smi = smStack[sid].back();
4593113Sgblack@eecs.umich.edu    int qi = getQ(sysi, q, id);
4603113Sgblack@eecs.umich.edu    if (swExpl[sid])
4613113Sgblack@eecs.umich.edu        swExpl[sid] = false;
4623113Sgblack@eecs.umich.edu    DPRINTFS(AnnotateQ, sys,
4633113Sgblack@eecs.umich.edu            "swDq: %s[%#x] cur size %d %d bytes: %d removing: %d\n",
4643113Sgblack@eecs.umich.edu            q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
4653113Sgblack@eecs.umich.edu    assert(count != 0);
4663113Sgblack@eecs.umich.edu
4673113Sgblack@eecs.umich.edu    doDq(sys, FL_NONE, tc->contextId(), smi, q, qi, count);
4683113Sgblack@eecs.umich.edu}
4693113Sgblack@eecs.umich.edu
4703113Sgblack@eecs.umich.eduvoid
4713113Sgblack@eecs.umich.eduCPA::swPq(ThreadContext *tc)
4723113Sgblack@eecs.umich.edu{
4733113Sgblack@eecs.umich.edu    if (!enabled())
4743113Sgblack@eecs.umich.edu        return;
4753113Sgblack@eecs.umich.edu
4763113Sgblack@eecs.umich.edu    char q[50];
4773113Sgblack@eecs.umich.edu    Arguments args(tc);
4783113Sgblack@eecs.umich.edu    uint64_t id = args[0];
4793113Sgblack@eecs.umich.edu    CopyStringOut(tc, q, args[1], 50);
4803113Sgblack@eecs.umich.edu    System *sys = tc->getSystemPtr();
4816686Stjones1@inf.ed.ac.uk    int32_t count = args[2];
4823113Sgblack@eecs.umich.edu
4833113Sgblack@eecs.umich.edu    int sysi = getSys(sys);
4843113Sgblack@eecs.umich.edu    StackId sid = StackId(sysi, getFrame(tc));
485378SN/A    if (!smStack[sid].size())
486378SN/A        return;
487378SN/A    int smi = smStack[sid].back();
488360SN/A    int qi = getQ(sysi, q, id);
4891450SN/A    if (swExpl[sid])
4903114Sgblack@eecs.umich.edu        swExpl[sid] = false;
4912680Sktlim@umich.edu    DPRINTFS(AnnotateQ, sys,
492360SN/A            "swPq: %s [%#x] cur size %d %d bytes: %d peeking: %d\n",
4936701Sgblack@eecs.umich.edu            q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
4946701Sgblack@eecs.umich.edu
4956701Sgblack@eecs.umich.edu    assert(count != 0);
496360SN/A    if (qBytes[qi-1] < count) {
4971969SN/A        dump(true);
498360SN/A        dumpKey();
499360SN/A        fatal("Queue %s peeking with not enough bytes available in queue!\n", q);
500360SN/A    }
5011458SN/A
502360SN/A    add(OP_PEEK, FL_NONE, tc->contextId(), smi, qi, count);
503360SN/A}
504360SN/A
5054131Sbinkertn@umich.eduvoid
5064131Sbinkertn@umich.eduCPA::swRq(ThreadContext *tc)
5074131Sbinkertn@umich.edu{
5084131Sbinkertn@umich.edu    if (!enabled())
5094131Sbinkertn@umich.edu        return;
5104131Sbinkertn@umich.edu
5114131Sbinkertn@umich.edu    char q[50];
5124131Sbinkertn@umich.edu    Arguments args(tc);
5136689Stjones1@inf.ed.ac.uk    uint64_t id = args[0];
5141458SN/A    CopyStringOut(tc, q, args[1], 50);
515360SN/A    System *sys = tc->getSystemPtr();
516360SN/A    int32_t count = args[2];
5177720Sgblack@eecs.umich.edu
5187720Sgblack@eecs.umich.edu    int sysi = getSys(sys);
519360SN/A    StackId sid = StackId(sysi, getFrame(tc));
520360SN/A    if (!smStack[sid].size())
521360SN/A        return;
522378SN/A    int smi = smStack[sid].back();
523360SN/A    int qi = getQ(sysi, q, id);
5241450SN/A    if (swExpl[sid])
5253114Sgblack@eecs.umich.edu        swExpl[sid] = false;
5262680Sktlim@umich.edu    DPRINTFS(AnnotateQ, sys,
527360SN/A            "swRq: %s [%#x] cur size %d %d bytes: %d reserve: %d\n",
528360SN/A            q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
529360SN/A
5306701Sgblack@eecs.umich.edu    assert(count != 0);
5316701Sgblack@eecs.umich.edu
5326701Sgblack@eecs.umich.edu    add(OP_RESERVE, FL_NONE, tc->contextId(), smi, qi, count);
5331458SN/A}
534360SN/A
535360SN/A
536360SN/Avoid
537360SN/ACPA::swWf(ThreadContext *tc)
5381706SN/A{
5391458SN/A    if (!enabled())
540360SN/A        return;
541360SN/A
5426701Sgblack@eecs.umich.edu    char q[50];
5436701Sgblack@eecs.umich.edu    Arguments args(tc);
544360SN/A    uint64_t id = args[0];
545360SN/A    CopyStringOut(tc, q, args[1], 50);
546360SN/A    System *sys = tc->getSystemPtr();
547360SN/A    int32_t count = args[3];
548360SN/A
549360SN/A    int sysi = getSys(sys);
550360SN/A    StackId sid = StackId(sysi, getFrame(tc));
551360SN/A    if (!smStack[sid].size())
552360SN/A        return;
553360SN/A    int smi = smStack[sid].back();
554360SN/A    int qi = getQ(sysi, q, id);
555360SN/A    add(OP_WAIT_FULL, FL_NONE, tc->contextId(), smi, qi, count);
5561706SN/A
557360SN/A    if (!!args[2]) {
558360SN/A        char sm[50];
559360SN/A        CopyStringOut(tc, sm, args[2], 50);
560360SN/A        doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
561360SN/A    }
5623669Sbinkertn@umich.edu}
5633669Sbinkertn@umich.edu
5643669Sbinkertn@umich.eduvoid
5651706SN/ACPA::swWe(ThreadContext *tc)
5661706SN/A{
5675795Ssaidi@eecs.umich.edu    if (!enabled())
5685795Ssaidi@eecs.umich.edu        return;
5695795Ssaidi@eecs.umich.edu
5705795Ssaidi@eecs.umich.edu    char q[50];
5715795Ssaidi@eecs.umich.edu    Arguments args(tc);
5725795Ssaidi@eecs.umich.edu    uint64_t id = args[0];
5735795Ssaidi@eecs.umich.edu    CopyStringOut(tc, q, args[1], 50);
5745795Ssaidi@eecs.umich.edu    System *sys = tc->getSystemPtr();
5755795Ssaidi@eecs.umich.edu    int32_t count = args[3];
5765795Ssaidi@eecs.umich.edu
5775795Ssaidi@eecs.umich.edu    int sysi = getSys(sys);
578360SN/A    StackId sid = StackId(sysi, getFrame(tc));
579360SN/A    if (!smStack[sid].size())
580360SN/A        return;
5816640Svince@csl.cornell.edu    int smi = smStack[sid].back();
5826640Svince@csl.cornell.edu    int qi = getQ(sysi, q, id);
5836640Svince@csl.cornell.edu    add(OP_WAIT_EMPTY, FL_NONE, tc->contextId(), smi, qi, count);
5846640Svince@csl.cornell.edu
5856640Svince@csl.cornell.edu    if (!!args[2]) {
5866640Svince@csl.cornell.edu        char sm[50];
5876640Svince@csl.cornell.edu        CopyStringOut(tc, sm, args[2], 50);
5886701Sgblack@eecs.umich.edu        doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
5896701Sgblack@eecs.umich.edu    }
5906701Sgblack@eecs.umich.edu}
5916640Svince@csl.cornell.edu
5926701Sgblack@eecs.umich.eduvoid
5936701Sgblack@eecs.umich.eduCPA::swSq(ThreadContext *tc)
5946640Svince@csl.cornell.edu{
5956701Sgblack@eecs.umich.edu    if (!enabled())
5966640Svince@csl.cornell.edu        return;
5976701Sgblack@eecs.umich.edu
5986640Svince@csl.cornell.edu    char q[50];
599360SN/A    Arguments args(tc);
6001999SN/A    uint64_t id = args[0];
6011999SN/A    CopyStringOut(tc, q, args[1], 50);
6021999SN/A    System *sys = tc->getSystemPtr();
6033114Sgblack@eecs.umich.edu    StringWrap name(sys->name());
6042680Sktlim@umich.edu    int32_t size = args[2];
6051999SN/A    int flags = args[3];
6061999SN/A
6071999SN/A    int sysi = getSys(sys);
6086701Sgblack@eecs.umich.edu    StackId sid = StackId(sysi, getFrame(tc));
6096701Sgblack@eecs.umich.edu    if (!smStack[sid].size())
6106701Sgblack@eecs.umich.edu        return;
6111999SN/A    int smi = smStack[sid].back();
6126701Sgblack@eecs.umich.edu    int qi = getQ(sysi, q, id);
6131999SN/A    DPRINTF(AnnotateQ, "swSq: %s [%#x] cur size: %d bytes: %d, new size: %d\n",
6146701Sgblack@eecs.umich.edu             q, id, qSize[qi-1], qBytes[qi-1], size);
6151999SN/A
6161999SN/A    if (FL_RESET & flags) {
6171999SN/A        DPRINTF(AnnotateQ, "Resetting Queue %s\n", q);
6181999SN/A        add(OP_SIZE_QUEUE, FL_NONE, tc->contextId(), smi, qi, 0);
6191999SN/A        qData[qi-1].clear();
6203669Sbinkertn@umich.edu        qSize[qi-1] = 0;
6213669Sbinkertn@umich.edu        qBytes[qi-1] = 0;
6223669Sbinkertn@umich.edu    }
6231999SN/A
6241999SN/A    if (qBytes[qi-1] < size)
6251999SN/A        doQ(sys, FL_NONE, tc->contextId(), smi, q, qi, size - qBytes[qi-1]);
6262218SN/A    else if (qBytes[qi-1] > size) {
6271999SN/A        DPRINTF(AnnotateQ, "removing for resize of queue %s\n", q);
6281999SN/A        add(OP_SIZE_QUEUE, FL_NONE, tc->contextId(), smi, qi, size);
6291999SN/A        if (size <= 0) {
6301999SN/A            qData[qi-1].clear();
6311999SN/A            qSize[qi-1] = 0;
6321999SN/A            qBytes[qi-1] = 0;
6331999SN/A            return;
6341999SN/A        }
6353114Sgblack@eecs.umich.edu        int need = qBytes[qi-1] - size;
6362680Sktlim@umich.edu        qBytes[qi-1] = size;
6371999SN/A        while (need > 0) {
6386701Sgblack@eecs.umich.edu            int32_t tail_bytes = qData[qi-1].back()->data;
6396701Sgblack@eecs.umich.edu            if (qSize[qi-1] <= 0 || qBytes[qi-1] < 0) {
6401999SN/A                dump(true);
6411999SN/A                dumpKey();
6421999SN/A                fatal("Queue %s had inconsistancy when doing size queue!\n", q);
6431999SN/A            }
6441999SN/A            if (tail_bytes > need) {
6456701Sgblack@eecs.umich.edu                qData[qi-1].back()->data -= need;
6461999SN/A                need = 0;
6471999SN/A            } else if (tail_bytes == need) {
6481999SN/A                qData[qi-1].pop_back();
6491999SN/A                qSize[qi-1]--;
6501999SN/A                need = 0;
6511999SN/A            } else {
6521999SN/A                qData[qi-1].pop_back();
6531999SN/A                qSize[qi-1]--;
6542218SN/A                need -= tail_bytes;
6551999SN/A            }
6561999SN/A        }
6571999SN/A    }
6581999SN/A}
6595877Shsul@eecs.umich.edu
6605877Shsul@eecs.umich.eduvoid
6615877Shsul@eecs.umich.eduCPA::swAq(ThreadContext *tc)
6625877Shsul@eecs.umich.edu{
6635877Shsul@eecs.umich.edu    if (!enabled())
6646701Sgblack@eecs.umich.edu        return;
6656701Sgblack@eecs.umich.edu
6666701Sgblack@eecs.umich.edu    char q[50];
6676701Sgblack@eecs.umich.edu    Arguments args(tc);
6686701Sgblack@eecs.umich.edu    uint64_t id = args[0];
6695877Shsul@eecs.umich.edu    CopyStringOut(tc, q, args[1], 50);
6705877Shsul@eecs.umich.edu    System *sys = tc->getSystemPtr();
6715877Shsul@eecs.umich.edu    StringWrap name(sys->name());
6725877Shsul@eecs.umich.edu    int32_t size = args[2];
6735877Shsul@eecs.umich.edu
6745877Shsul@eecs.umich.edu    int sysi = getSys(sys);
6755877Shsul@eecs.umich.edu    int qi = getQ(sysi, q, id);
6765877Shsul@eecs.umich.edu    if (qBytes[qi-1] != size) {
6775877Shsul@eecs.umich.edu        DPRINTF(AnnotateQ, "Queue %s [%#x] has inconsintant size\n", q, id);
6785877Shsul@eecs.umich.edu        //dump(true);
6795877Shsul@eecs.umich.edu        //dumpKey();
6805877Shsul@eecs.umich.edu        std::list<AnnDataPtr>::iterator ai = qData[qi-1].begin();
6815877Shsul@eecs.umich.edu        int x = 0;
6825877Shsul@eecs.umich.edu        while (ai != qData[qi-1].end()) {
6835877Shsul@eecs.umich.edu            DPRINTF(AnnotateQ, "--Element %d size %d\n", x, (*ai)->data);
6845877Shsul@eecs.umich.edu            ai++;
6855877Shsul@eecs.umich.edu            x++;
6865877Shsul@eecs.umich.edu        }
6875877Shsul@eecs.umich.edu
6885877Shsul@eecs.umich.edu        warn("%d: Queue Assert: SW said there should be %d byte(s) in %s,"
6895877Shsul@eecs.umich.edu                "however there are %d byte(s)\n",
6905877Shsul@eecs.umich.edu            curTick, size, q, qBytes[qi-1]);
6915877Shsul@eecs.umich.edu        DPRINTF(AnnotateQ, "%d: Queue Assert: SW said there should be %d"
6925877Shsul@eecs.umich.edu                " byte(s) in %s, however there are %d byte(s)\n",
6935877Shsul@eecs.umich.edu            curTick, size, q, qBytes[qi-1]);
6945877Shsul@eecs.umich.edu    }
6955877Shsul@eecs.umich.edu}
6965877Shsul@eecs.umich.edu
6975877Shsul@eecs.umich.eduvoid
6985877Shsul@eecs.umich.eduCPA::swLink(ThreadContext *tc)
6995877Shsul@eecs.umich.edu{
7005877Shsul@eecs.umich.edu    if (!enabled())
7015877Shsul@eecs.umich.edu        return;
7025877Shsul@eecs.umich.edu
7035877Shsul@eecs.umich.edu    char lsm[50];
7045877Shsul@eecs.umich.edu    Arguments args(tc);
7051999SN/A    CopyStringOut(tc, lsm, args[0], 50);
706378SN/A    System *sys = tc->getSystemPtr();
707360SN/A    StringWrap name(sys->name());
7081450SN/A
7093114Sgblack@eecs.umich.edu    int sysi = getSys(sys);
7102680Sktlim@umich.edu    StackId sid = StackId(sysi, getFrame(tc));
711360SN/A    if (!smStack[sid].size())
712360SN/A        return;
713360SN/A    int smi = smStack[sid].back();
7146701Sgblack@eecs.umich.edu    int lsmi = getSm(sysi, lsm, args[1]);
7156701Sgblack@eecs.umich.edu
7166701Sgblack@eecs.umich.edu    DPRINTF(Annotate, "Linking from %d to state machine %s(%d) [%#x]\n",
7176701Sgblack@eecs.umich.edu            smi, lsm, lsmi, args[1]);
7186701Sgblack@eecs.umich.edu
7196701Sgblack@eecs.umich.edu    if (lnMap[lsmi])
720360SN/A        DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n",
7213669Sbinkertn@umich.edu                lsmi, lnMap[lsmi]);
7223669Sbinkertn@umich.edu    assert(lnMap[lsmi] == 0);
7233669Sbinkertn@umich.edu    lnMap[lsmi] =  smi;
724360SN/A
725360SN/A    add(OP_LINK, FL_NONE, tc->contextId(), smi, lsmi);
726360SN/A
727360SN/A    if (!!args[2]) {
7282218SN/A        char sm[50];
729360SN/A        CopyStringOut(tc, sm, args[2], 50);
7306701Sgblack@eecs.umich.edu        doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
731360SN/A    }
7321458SN/A}
733360SN/A
734360SN/Avoid
735360SN/ACPA::swIdentify(ThreadContext *tc)
7365074Ssaidi@eecs.umich.edu{
7375074Ssaidi@eecs.umich.edu    if (!enabled())
7385074Ssaidi@eecs.umich.edu        return;
7395074Ssaidi@eecs.umich.edu
7405074Ssaidi@eecs.umich.edu    Arguments args(tc);
7415074Ssaidi@eecs.umich.edu    int sysi = getSys(tc->getSystemPtr());
7425074Ssaidi@eecs.umich.edu    StackId sid = StackId(sysi, getFrame(tc));
7435074Ssaidi@eecs.umich.edu    if (!smStack[sid].size())
7446701Sgblack@eecs.umich.edu        return;
7456701Sgblack@eecs.umich.edu    int smi = smStack[sid].back();
7466701Sgblack@eecs.umich.edu
7475074Ssaidi@eecs.umich.edu    DPRINTFS(Annotate, tc->getSystemPtr(), "swIdentify: id %#X\n", args[0]);
7486701Sgblack@eecs.umich.edu
7495074Ssaidi@eecs.umich.edu    add(OP_IDENT, FL_NONE, tc->contextId(), smi, 0, args[0]);
7505074Ssaidi@eecs.umich.edu}
7515074Ssaidi@eecs.umich.edu
7525074Ssaidi@eecs.umich.eduuint64_t
7535208Ssaidi@eecs.umich.eduCPA::swGetId(ThreadContext *tc)
7545208Ssaidi@eecs.umich.edu{
7555208Ssaidi@eecs.umich.edu    if (!enabled())
7565208Ssaidi@eecs.umich.edu        return 0;
7575074Ssaidi@eecs.umich.edu
7585074Ssaidi@eecs.umich.edu    uint64_t id = ++conId;
7595208Ssaidi@eecs.umich.edu    int sysi = getSys(tc->getSystemPtr());
7605074Ssaidi@eecs.umich.edu    StackId sid = StackId(sysi, getFrame(tc));
7615074Ssaidi@eecs.umich.edu    if (!smStack[sid].size())
7625074Ssaidi@eecs.umich.edu        panic("swGetId called without a state machine stack!");
7635074Ssaidi@eecs.umich.edu    int smi = smStack[sid].back();
7646701Sgblack@eecs.umich.edu
7655074Ssaidi@eecs.umich.edu    DPRINTFS(Annotate, tc->getSystemPtr(), "swGetId: id %#X\n", id);
7665074Ssaidi@eecs.umich.edu
7675074Ssaidi@eecs.umich.edu    add(OP_IDENT, FL_NONE, tc->contextId(), smi, 0, id);
7685074Ssaidi@eecs.umich.edu    return id;
7695074Ssaidi@eecs.umich.edu}
7701999SN/A
7711999SN/A
7721999SN/Avoid
7733114Sgblack@eecs.umich.eduCPA::swSyscallLink(ThreadContext  *tc)
7742680Sktlim@umich.edu{
7751999SN/A    if (!enabled())
7766701Sgblack@eecs.umich.edu        return;
7776701Sgblack@eecs.umich.edu
7786701Sgblack@eecs.umich.edu    char lsm[50];
7791999SN/A    Arguments args(tc);
7801999SN/A    CopyStringOut(tc, lsm, args[0], 50);
7811999SN/A    System *sys = tc->getSystemPtr();
7821999SN/A    StringWrap name(sys->name());
7831999SN/A    int sysi = getSys(sys);
7842764Sstever@eecs.umich.edu
7852064SN/A    Id id = Id(lsm, getFrame(tc));
7862064SN/A    StackId sid = StackId(sysi, getFrame(tc));
7872064SN/A
7882064SN/A    if (!smStack[sid].size())
7891999SN/A        return;
7902064SN/A
7911999SN/A    int smi = smStack[sid].back();
7921999SN/A
7932218SN/A    DPRINTF(Annotate, "Linking from %d to state machine %s(UNKNOWN)\n",
7941999SN/A            smi, lsm);
7956701Sgblack@eecs.umich.edu
7961999SN/A    if (scLinks[sysi-1][id])
7971999SN/A        DPRINTF(Annotate,
7981999SN/A                "scLinks already contains entry for system %d %s[%x] of %d\n",
7991999SN/A                sysi, lsm, getFrame(tc), scLinks[sysi-1][id]);
8001999SN/A    assert(scLinks[sysi-1][id] == 0);
801378SN/A    scLinks[sysi-1][id] = add(OP_LINK, FL_NONE, tc->contextId(), smi, 0xFFFF);
802360SN/A    scLinks[sysi-1][id]->dump = false;
8031450SN/A
8043114Sgblack@eecs.umich.edu    if (!!args[1]) {
8052680Sktlim@umich.edu        char sm[50];
806360SN/A        CopyStringOut(tc, sm, args[1], 50);
807360SN/A        doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
808360SN/A    }
8096701Sgblack@eecs.umich.edu}
8106701Sgblack@eecs.umich.edu
8116701Sgblack@eecs.umich.eduCPA::AnnDataPtr
8126701Sgblack@eecs.umich.eduCPA::add(int t, int f, int c, int sm, int stq, int32_t d)
8136701Sgblack@eecs.umich.edu{
8146701Sgblack@eecs.umich.edu    AnnDataPtr an = new AnnotateData;
815360SN/A    an->time = curTick;
8163669Sbinkertn@umich.edu    an->data = d;
8173669Sbinkertn@umich.edu    an->orig_data = d;
8183669Sbinkertn@umich.edu    an->op = t;
819360SN/A    an->flag = f;
820360SN/A    an->sm = sm;
821360SN/A    an->stq = stq;
822360SN/A    an->cpu = c;
8231458SN/A    an->dump = true;
824360SN/A
8256701Sgblack@eecs.umich.edu    data.push_back(an);
826360SN/A
8271458SN/A    DPRINTF(AnnotateVerbose, "Annotate: op: %d flags: 0x%x sm: %d state: %d time: %d, data: %d\n",
828360SN/A            an->op, an->flag, an->sm, an->stq, an->time, an->data);
829360SN/A
8301999SN/A    // Don't dump Links because we might be setting no-dump on it
8311999SN/A    if (an->op != OP_LINK)
8321999SN/A        dump(false);
8333114Sgblack@eecs.umich.edu
8342680Sktlim@umich.edu    return an;
8351999SN/A}
8361999SN/A
8371999SN/Avoid
8386701Sgblack@eecs.umich.eduCPA::dumpKey()
8396701Sgblack@eecs.umich.edu{
8406701Sgblack@eecs.umich.edu    std::streampos curpos = osbin->tellp();
8416701Sgblack@eecs.umich.edu    ah.key_off = curpos;
8426701Sgblack@eecs.umich.edu
8436701Sgblack@eecs.umich.edu    // Output the various state machines and their corresponding states
8441999SN/A    *osbin << "# Automatically generated state machine descriptor file" << endl;
8453669Sbinkertn@umich.edu
8463669Sbinkertn@umich.edu    *osbin << "sms = {}" << endl << endl;
8473669Sbinkertn@umich.edu    vector<string> state_machines;
8482764Sstever@eecs.umich.edu    state_machines.resize(numSmt+1);
8492064SN/A
8502064SN/A    // State machines, id -> states
8512064SN/A    SCache::iterator i = smtCache.begin();
8521999SN/A    while (i != smtCache.end()) {
8531999SN/A        state_machines[i->second] = i->first;
8542064SN/A        i++;
8551999SN/A    }
8561999SN/A
8571999SN/A    for (int x = 1; x < state_machines.size(); x++) {
8581999SN/A        vector<string> states;
8596701Sgblack@eecs.umich.edu        states.resize(numSt[x-1]+1);
8601999SN/A        assert(x-1 < stCache.size());
8611999SN/A        SCache::iterator i = stCache[x-1].begin();
8621999SN/A        while (i != stCache[x-1].end()) {
8631999SN/A            states[i->second] = i->first;
864378SN/A            i++;
865360SN/A        }
8661450SN/A        *osbin << "sms[\"" << state_machines[x] << "\"] = [\"NULL\"";
8673114Sgblack@eecs.umich.edu        for (int y = 1; y < states.size(); y++)
8682680Sktlim@umich.edu            *osbin << ", \"" << states[y] << "\"";
869360SN/A        *osbin << "]" << endl;
8706701Sgblack@eecs.umich.edu    }
8716701Sgblack@eecs.umich.edu
8726701Sgblack@eecs.umich.edu    *osbin << endl << endl << endl;
873360SN/A
8741969SN/A    // state machine number -> system, name, id
875360SN/A    *osbin << "smNum = [\"NULL\"";
876360SN/A    for (int x = 0; x < smMap.size(); x++)
8771458SN/A        *osbin << ", (" << smMap[x].first << ", \"" << smMap[x].second.first <<
878360SN/A            "\", " << smMap[x].second.second << ")";
879360SN/A    *osbin << "]" << endl;
880360SN/A
881360SN/A    *osbin << endl << endl << endl;
882360SN/A
8831458SN/A    // Output the systems
884360SN/A    vector<string> systems;
8856701Sgblack@eecs.umich.edu    systems.resize(numSys+1);
8862021SN/A    NameCache::iterator i2 = nameCache.begin();
8871458SN/A    while (i2 != nameCache.end()) {
888360SN/A        systems[i2->second.second] = i2->second.first;
889360SN/A        i2++;
890360SN/A    }
8911706SN/A
8921706SN/A    *osbin << "sysNum = [\"NULL\"";
8931706SN/A    for (int x = 1; x < systems.size(); x++) {
8943114Sgblack@eecs.umich.edu        *osbin << ", \"" << systems[x] << "\"";
8952680Sktlim@umich.edu    }
8961706SN/A    *osbin << "]" << endl;
8971706SN/A
8981706SN/A    // queue number -> system, qname, qid
8996701Sgblack@eecs.umich.edu    *osbin << "queues = [\"NULL\"";
9006701Sgblack@eecs.umich.edu    for (int x = 0; x < qMap.size(); x++)
9016701Sgblack@eecs.umich.edu        *osbin << ", (" << qMap[x].first << ", \"" << qMap[x].second.first <<
9026701Sgblack@eecs.umich.edu            "\", " << qMap[x].second.second << ")";
9036701Sgblack@eecs.umich.edu    *osbin << "]" << endl;
9046701Sgblack@eecs.umich.edu
9051706SN/A    *osbin << "smComb = [s for s in [(i,r) for i in xrange(1,len(sysNum)) "
9063669Sbinkertn@umich.edu           << "for r in xrange (1,len(smNum))]]" << endl;
9073669Sbinkertn@umich.edu    ah.key_len = osbin->tellp() - curpos;
9083669Sbinkertn@umich.edu
9091706SN/A    // output index
9101706SN/A    curpos = osbin->tellp();
9111706SN/A    ah.idx_off = curpos;
9121706SN/A
9132218SN/A    for (int x = 0; x < annotateIdx.size(); x++)
9141706SN/A        osbin->write((char*)&annotateIdx[x], sizeof(uint64_t));
9156701Sgblack@eecs.umich.edu    ah.idx_len = osbin->tellp() - curpos;
9161706SN/A
9171706SN/A    osbin->seekp(0);
9181706SN/A    osbin->write((char*)&ah, sizeof(AnnotateHeader));
9191706SN/A    osbin->flush();
9201706SN/A
9211706SN/A}
9221706SN/A
9231706SN/Avoid
9243114Sgblack@eecs.umich.eduCPA::dump(bool all)
9252680Sktlim@umich.edu{
9261706SN/A
9276701Sgblack@eecs.umich.edu    list<AnnDataPtr>::iterator i;
9286701Sgblack@eecs.umich.edu
9296701Sgblack@eecs.umich.edu    i = data.begin();
9301706SN/A
9311706SN/A    if (i == data.end())
9321706SN/A        return;
9331706SN/A
9341706SN/A    // Dump the data every
9351706SN/A    if (!all && data.size() < 10000)
9361706SN/A        return;
9371706SN/A
9382218SN/A    DPRINTF(Annotate, "Writing %d\n", data.size());
9391706SN/A    while (i != data.end()) {
9406701Sgblack@eecs.umich.edu        AnnDataPtr an = *i;
9411706SN/A
9421706SN/A        // If we can't dump this record, hold here
9431706SN/A        if (!an->dump && !all)
9441706SN/A            break;
9451706SN/A
9461999SN/A        ah.num_recs++;
9471999SN/A        if (ah.num_recs % 100000 == 0)
9481999SN/A            annotateIdx.push_back(osbin->tellp());
9493114Sgblack@eecs.umich.edu
9502680Sktlim@umich.edu
9511999SN/A        osbin->write((char*)&(an->time), sizeof(an->time));
9526701Sgblack@eecs.umich.edu        osbin->write((char*)&(an->orig_data), sizeof(an->orig_data));
9536701Sgblack@eecs.umich.edu        osbin->write((char*)&(an->sm), sizeof(an->sm));
9541999SN/A        osbin->write((char*)&(an->stq), sizeof(an->stq));
9551999SN/A        osbin->write((char*)&(an->op), sizeof(an->op));
9561999SN/A        osbin->write((char*)&(an->flag), sizeof(an->flag));
9571999SN/A        osbin->write((char*)&(an->cpu), sizeof(an->cpu));
9581999SN/A        i++;
9592680Sktlim@umich.edu    }
9606701Sgblack@eecs.umich.edu    if (data.begin() != i)
9616701Sgblack@eecs.umich.edu        data.erase(data.begin(), i);
9621999SN/A
9636227Snate@binkert.org    if (all)
9641999SN/A        osbin->flush();
9652461SN/A}
9662461SN/A
9672461SN/Avoid
9682091SN/ACPA::doQ(System *sys, int flags, int cpuid, int sm,
9691999SN/A              string q, int qi, int count)
9702461SN/A{
9712461SN/A    qSize[qi-1]++;
9721999SN/A    qBytes[qi-1] += count;
9731999SN/A    if (qSize[qi-1] > 2501 || qBytes[qi-1] > 2000000000)
9741999SN/A        warn("Queue %s is %d elements/%d bytes, "
9751999SN/A                "maybe things aren't being removed?\n",
9766227Snate@binkert.org                q, qSize[qi-1], qBytes[qi-1]);
9771999SN/A    if (flags & FL_QOPP)
9781999SN/A        qData[qi-1].push_front(add(OP_QUEUE, flags, cpuid, sm, qi, count));
9791999SN/A    else
9802218SN/A        qData[qi-1].push_back(add(OP_QUEUE, flags, cpuid, sm, qi, count));
9811999SN/A    DPRINTFS(AnnotateQ, sys, "Queing in queue %s size now %d/%d\n",
9821999SN/A            q, qSize[qi-1], qBytes[qi-1]);
9831999SN/A    assert(qSize[qi-1] >= 0);
9841999SN/A    assert(qBytes[qi-1] >= 0);
9851999SN/A}
986378SN/A
987378SN/A
988378SN/Avoid
989378SN/ACPA::doDq(System *sys, int flags, int cpuid, int sm,
990378SN/A               string q, int qi, int count)
991378SN/A{
992378SN/A
993378SN/A    StringWrap name(sys->name());
994360SN/A    if (count == -1) {
995378SN/A        add(OP_DEQUEUE, flags, cpuid, sm, qi, count);
996378SN/A        qData[qi-1].clear();
997378SN/A        qSize[qi-1] = 0;
998360SN/A        qBytes[qi-1] = 0;
9991450SN/A        DPRINTF(AnnotateQ, "Dequeing all data in queue %s size now %d/%d\n",
10003114Sgblack@eecs.umich.edu                q, qSize[qi-1], qBytes[qi-1]);
1001360SN/A        return;
10026701Sgblack@eecs.umich.edu    }
10036701Sgblack@eecs.umich.edu
10046701Sgblack@eecs.umich.edu    assert(count > 0);
10056701Sgblack@eecs.umich.edu    if (qSize[qi-1] <= 0 || qBytes[qi-1] <= 0 || !qData[qi-1].size()) {
10066701Sgblack@eecs.umich.edu        dump(true);
10076701Sgblack@eecs.umich.edu        dumpKey();
10086701Sgblack@eecs.umich.edu        fatal("Queue %s dequing with no data available in queue!\n",
1009360SN/A                q);
10105877Shsul@eecs.umich.edu    }
10112544SN/A    assert(qSize[qi-1] >= 0);
10122544SN/A    assert(qBytes[qi-1] >= 0);
10132544SN/A    assert(qData[qi-1].size());
10142544SN/A
10152544SN/A    int32_t need = count;
10162544SN/A    qBytes[qi-1] -= count;
1017360SN/A    if (qBytes[qi-1] < 0) {
1018360SN/A        dump(true);
10192544SN/A        dumpKey();
10202544SN/A        fatal("Queue %s dequing with no bytes available in queue!\n",
10212544SN/A                q);
10222544SN/A    }
10232544SN/A
10242544SN/A    while (need > 0) {
10256672Sgblack@eecs.umich.edu        int32_t head_bytes = qData[qi-1].front()->data;
10266672Sgblack@eecs.umich.edu        if (qSize[qi-1] <= 0 || qBytes[qi-1] < 0) {
10276672Sgblack@eecs.umich.edu            dump(true);
10286672Sgblack@eecs.umich.edu            dumpKey();
10296672Sgblack@eecs.umich.edu            fatal("Queue %s dequing with nothing in queue!\n",
10306672Sgblack@eecs.umich.edu                q);
10316672Sgblack@eecs.umich.edu        }
10322544SN/A
10332544SN/A        if (head_bytes > need) {
10342553SN/A            qData[qi-1].front()->data -= need;
10351969SN/A            need = 0;
10366701Sgblack@eecs.umich.edu        } else if (head_bytes == need) {
1037360SN/A            qData[qi-1].pop_front();
1038360SN/A            qSize[qi-1]--;
10391458SN/A            need = 0;
1040360SN/A        } else {
1041360SN/A            qData[qi-1].pop_front();
1042378SN/A            qSize[qi-1]--;
1043360SN/A            need -= head_bytes;
10441450SN/A        }
10453114Sgblack@eecs.umich.edu    }
10462680Sktlim@umich.edu
1047360SN/A    add(OP_DEQUEUE, flags, cpuid, sm, qi, count);
10486701Sgblack@eecs.umich.edu    DPRINTF(AnnotateQ, "Dequeing in queue %s size now %d/%d\n",
10496701Sgblack@eecs.umich.edu            q, qSize[qi-1], qBytes[qi-1]);
10506701Sgblack@eecs.umich.edu}
1051360SN/A
1052360SN/A
10532064SN/A
10545877Shsul@eecs.umich.eduvoid
10552064SN/ACPA::serialize(std::ostream &os)
10562091SN/A{
10572091SN/A
10582064SN/A    SERIALIZE_SCALAR(numSm);
1059360SN/A    SERIALIZE_SCALAR(numSmt);
10605877Shsul@eecs.umich.edu    arrayParamOut(os, "numSt", numSt);
10615877Shsul@eecs.umich.edu    arrayParamOut(os, "numQ", numQ);
10625877Shsul@eecs.umich.edu    SERIALIZE_SCALAR(numSys);
10635877Shsul@eecs.umich.edu    SERIALIZE_SCALAR(numQs);
10645877Shsul@eecs.umich.edu    SERIALIZE_SCALAR(conId);
10655877Shsul@eecs.umich.edu    arrayParamOut(os, "qSize", qSize);
10665877Shsul@eecs.umich.edu    arrayParamOut(os, "qSize", qSize);
10672064SN/A    arrayParamOut(os, "qBytes", qBytes);
10682064SN/A
10692064SN/A    std::list<AnnDataPtr>::iterator ai;
10702064SN/A
10712064SN/A    SCache::iterator i;
1072360SN/A    int x = 0, y = 0;
1073360SN/A
10742680Sktlim@umich.edu    // smtCache (SCache)
10751458SN/A    x = 0;
1076360SN/A    y = 0;
1077360SN/A    i = smtCache.begin();
1078378SN/A    while (i != smtCache.end()) {
1079360SN/A        paramOut(os, csprintf("smtCache%d.str", x), i->first);
10801450SN/A        paramOut(os, csprintf("smtCache%d.int", x), i->second);
10813114Sgblack@eecs.umich.edu        x++; i++;
10822680Sktlim@umich.edu    }
1083360SN/A
10846701Sgblack@eecs.umich.edu    // stCache  (StCache)
10856701Sgblack@eecs.umich.edu    for (x = 0; x < stCache.size(); x++) {
1086360SN/A        i = stCache[x].begin();
1087360SN/A        y = 0;
1088360SN/A        while (i != stCache[x].end()) {
10896109Ssanchezd@stanford.edu            paramOut(os, csprintf("stCache%d_%d.str", x, y), i->first);
10906109Ssanchezd@stanford.edu            paramOut(os, csprintf("stCache%d_%d.int", x, y), i->second);
1091360SN/A            y++; i++;
10922680Sktlim@umich.edu        }
1093360SN/A    }
10941458SN/A
1095360SN/A    // qCache (IdCache)
1096360SN/A    IdHCache::iterator idi;
1097360SN/A    for (x = 0; x < qCache.size(); x++) {
10981999SN/A        idi = qCache[x].begin();
10991999SN/A        y = 0;
11001999SN/A        while (idi != qCache[x].end()) {
11013114Sgblack@eecs.umich.edu            paramOut(os, csprintf("qCache%d_%d.str", x, y), idi->first.first);
11022680Sktlim@umich.edu            paramOut(os, csprintf("qCache%d_%d.id", x, y), idi->first.second);
11031999SN/A            paramOut(os, csprintf("qCache%d_%d.int", x, y), idi->second);
11041999SN/A            y++; idi++;
11051999SN/A        }
11066701Sgblack@eecs.umich.edu    }
11076701Sgblack@eecs.umich.edu
11086701Sgblack@eecs.umich.edu    // smCache (IdCache)
11096701Sgblack@eecs.umich.edu    for (x = 0; x < smCache.size(); x++) {
11106701Sgblack@eecs.umich.edu        idi = smCache[x].begin();
11111999SN/A        y = 0;
11126701Sgblack@eecs.umich.edu        paramOut(os, csprintf("smCache%d", x), smCache[x].size());
11136701Sgblack@eecs.umich.edu        while (idi != smCache[x].end()) {
11142680Sktlim@umich.edu            paramOut(os, csprintf("smCache%d_%d.str", x, y), idi->first.first);
11151999SN/A            paramOut(os, csprintf("smCache%d_%d.id", x, y), idi->first.second);
11161999SN/A            paramOut(os, csprintf("smCache%d_%d.int", x, y), idi->second);
11171999SN/A            y++; idi++;
11181999SN/A        }
11192091SN/A    }
11202091SN/A
11211999SN/A    // scLinks (ScCache) -- data not serialize
11223669Sbinkertn@umich.edu
11233669Sbinkertn@umich.edu
11243669Sbinkertn@umich.edu    // namecache (NameCache)
11253669Sbinkertn@umich.edu    NameCache::iterator ni;
11261999SN/A
11271999SN/A    ni = nameCache.begin();
11281999SN/A    x = 0;
11291999SN/A    while (ni != nameCache.end()) {
11301999SN/A        paramOut(os, csprintf("nameCache%d.name", x), ni->first->name());
11311999SN/A        paramOut(os, csprintf("nameCache%d.str", x), ni->second.first);
11321999SN/A        paramOut(os, csprintf("nameCache%d.int", x), ni->second.second);
1133378SN/A        x++; ni++;
1134360SN/A    }
11351450SN/A
11363114Sgblack@eecs.umich.edu    // smStack (SmStack)
11372680Sktlim@umich.edu    SmStack::iterator si;
1138360SN/A    si = smStack.begin();
11396701Sgblack@eecs.umich.edu    x = 0;
11406701Sgblack@eecs.umich.edu    paramOut(os, "smStackIdCount", smStack.size());
11416701Sgblack@eecs.umich.edu    while (si != smStack.end()) {
1142360SN/A        paramOut(os, csprintf("smStackId%d.sys", x), si->first.first);
11433670Sbinkertn@umich.edu        paramOut(os, csprintf("smStackId%d.frame", x), si->first.second);
11443670Sbinkertn@umich.edu        paramOut(os, csprintf("smStackId%d.count", x), si->second.size());
1145360SN/A        for (y = 0; y < si->second.size(); y++)
1146360SN/A            paramOut(os, csprintf("smStackId%d_%d", x, y), si->second[y]);
1147360SN/A        x++; si++;
1148360SN/A    }
1149360SN/A
1150360SN/A    // lnMap (LinkMap)
1151360SN/A    x = 0;
1152360SN/A    LinkMap::iterator li;
1153360SN/A    li = lnMap.begin();
1154360SN/A    paramOut(os, "lnMapSize", lnMap.size());
1155360SN/A    while (li != lnMap.end()) {
1156360SN/A        paramOut(os, csprintf("lnMap%d.smi", x), li->first);
1157360SN/A        paramOut(os, csprintf("lnMap%d.lsmi", x), li->second);
1158360SN/A        x++; li++;
1159360SN/A    }
1160360SN/A
1161360SN/A    // swExpl (vector)
11623670Sbinkertn@umich.edu    SwExpl::iterator swexpli;
11633670Sbinkertn@umich.edu    swexpli = swExpl.begin();
11643670Sbinkertn@umich.edu    x = 0;
11653670Sbinkertn@umich.edu    paramOut(os, "swExplCount", swExpl.size());
11663670Sbinkertn@umich.edu    while (swexpli != swExpl.end()) {
11673670Sbinkertn@umich.edu        paramOut(os, csprintf("swExpl%d.sys", x), swexpli->first.first);
11683670Sbinkertn@umich.edu        paramOut(os, csprintf("swExpl%d.frame", x), swexpli->first.second);
11693670Sbinkertn@umich.edu        paramOut(os, csprintf("swExpl%d.swexpl", x), swexpli->second);
11703670Sbinkertn@umich.edu        x++; swexpli++;
11713670Sbinkertn@umich.edu    }
11723670Sbinkertn@umich.edu
11733670Sbinkertn@umich.edu    // lastState (IMap)
11743670Sbinkertn@umich.edu    x = 0;
11753670Sbinkertn@umich.edu    IMap::iterator ii;
11763670Sbinkertn@umich.edu    ii = lastState.begin();
11773670Sbinkertn@umich.edu    paramOut(os, "lastStateSize", lastState.size());
11783670Sbinkertn@umich.edu    while (ii != lastState.end()) {
11793670Sbinkertn@umich.edu        paramOut(os, csprintf("lastState%d.smi", x), ii->first);
11802680Sktlim@umich.edu        paramOut(os, csprintf("lastState%d.sti", x), ii->second);
1181360SN/A        x++; ii++;
11821458SN/A    }
1183360SN/A
1184360SN/A    // smMap (IdMap)
11856683Stjones1@inf.ed.ac.uk    for (x = 0; x < smMap.size(); x++) {
11866683Stjones1@inf.ed.ac.uk        paramOut(os, csprintf("smMap%d.sys", x), smMap[x].first);
11876683Stjones1@inf.ed.ac.uk        paramOut(os, csprintf("smMap%d.smname", x), smMap[x].second.first);
11886683Stjones1@inf.ed.ac.uk        paramOut(os, csprintf("smMap%d.id", x), smMap[x].second.second);
11896683Stjones1@inf.ed.ac.uk    }
11906683Stjones1@inf.ed.ac.uk
11916701Sgblack@eecs.umich.edu    // qMap (IdMap)
11926701Sgblack@eecs.umich.edu    for (x = 0; x < qMap.size(); x++) {
11936683Stjones1@inf.ed.ac.uk        paramOut(os, csprintf("qMap%d.sys", x), qMap[x].first);
11946683Stjones1@inf.ed.ac.uk        paramOut(os, csprintf("qMap%d.qname", x), qMap[x].second.first);
11957823Ssteve.reinhardt@amd.com        paramOut(os, csprintf("qMap%d.id", x), qMap[x].second.second);
11966683Stjones1@inf.ed.ac.uk    }
11976683Stjones1@inf.ed.ac.uk
11986683Stjones1@inf.ed.ac.uk    // qData (vector<AnnotateList>)
11996683Stjones1@inf.ed.ac.uk    for(x = 0; x < qData.size(); x++) {
12006683Stjones1@inf.ed.ac.uk        if (!qData[x].size())
12016683Stjones1@inf.ed.ac.uk            continue;
12026683Stjones1@inf.ed.ac.uk        y = 0;
12036683Stjones1@inf.ed.ac.uk        ai = qData[x].begin();
12046683Stjones1@inf.ed.ac.uk        while (ai != qData[x].end()) {
12056683Stjones1@inf.ed.ac.uk            nameOut(os, csprintf("%s.Q%d_%d", name(), x, y));
12066683Stjones1@inf.ed.ac.uk            (*ai)->serialize(os);
12076683Stjones1@inf.ed.ac.uk            ai++;
12086683Stjones1@inf.ed.ac.uk            y++;
12096683Stjones1@inf.ed.ac.uk        }
12102553SN/A    }
12116684Stjones1@inf.ed.ac.uk}
12126684Stjones1@inf.ed.ac.uk
12136684Stjones1@inf.ed.ac.ukvoid
12146684Stjones1@inf.ed.ac.ukCPA::unserialize(Checkpoint *cp, const std::string &section)
12156684Stjones1@inf.ed.ac.uk{
12166684Stjones1@inf.ed.ac.uk    UNSERIALIZE_SCALAR(numSm);
12176684Stjones1@inf.ed.ac.uk    UNSERIALIZE_SCALAR(numSmt);
12186684Stjones1@inf.ed.ac.uk    arrayParamIn(cp, section, "numSt", numSt);
12196684Stjones1@inf.ed.ac.uk    arrayParamIn(cp, section, "numQ", numQ);
12206684Stjones1@inf.ed.ac.uk    UNSERIALIZE_SCALAR(numSys);
12216701Sgblack@eecs.umich.edu    UNSERIALIZE_SCALAR(numQs);
12226701Sgblack@eecs.umich.edu    UNSERIALIZE_SCALAR(conId);
12236684Stjones1@inf.ed.ac.uk    arrayParamIn(cp, section, "qSize", qSize);
12246684Stjones1@inf.ed.ac.uk    arrayParamIn(cp, section, "qBytes", qBytes);
12256684Stjones1@inf.ed.ac.uk
12266684Stjones1@inf.ed.ac.uk
12276684Stjones1@inf.ed.ac.uk    // smtCache (SCache
12286684Stjones1@inf.ed.ac.uk    string str;
12296684Stjones1@inf.ed.ac.uk    int smi;
12306684Stjones1@inf.ed.ac.uk    for (int x = 0;  x < numSmt; x++) {
12312553SN/A        paramIn(cp, section, csprintf("smtCache%d.str", x), str);
12322553SN/A        paramIn(cp, section, csprintf("smtCache%d.int", x), smi);
12331354SN/A        smtCache[str] = smi;
1234    }
1235
1236    // stCache  (StCache)
1237    stCache.resize(numSmt);
1238    for (int x = 0;  x < numSmt; x++) {
1239        for (int y = 0; y < numSt[x]; y++) {
1240            paramIn(cp, section, csprintf("stCache%d_%d.str", x,y), str);
1241            paramIn(cp, section, csprintf("stCache%d_%d.int", x,y), smi);
1242            stCache[x][str] = smi;
1243        }
1244    }
1245
1246    // qCache (IdCache)
1247    uint64_t id;
1248    qCache.resize(numSys);
1249    for (int x = 0;  x < numSys; x++) {
1250        for (int y = 0; y < numQ[x]; y++) {
1251            paramIn(cp, section, csprintf("qCache%d_%d.str", x,y), str);
1252            paramIn(cp, section, csprintf("qCache%d_%d.id", x,y), id);
1253            paramIn(cp, section, csprintf("qCache%d_%d.int", x,y), smi);
1254            qCache[x][Id(str,id)] = smi;
1255        }
1256    }
1257
1258    // smCache (IdCache)
1259    smCache.resize(numSys);
1260    for (int x = 0;  x < numSys; x++) {
1261        int size;
1262        paramIn(cp, section, csprintf("smCache%d", x), size);
1263        for (int y = 0; y < size; y++) {
1264            paramIn(cp, section, csprintf("smCache%d_%d.str", x,y), str);
1265            paramIn(cp, section, csprintf("smCache%d_%d.id", x,y), id);
1266            paramIn(cp, section, csprintf("smCache%d_%d.int", x,y), smi);
1267            smCache[x][Id(str,id)] = smi;
1268        }
1269    }
1270
1271    // scLinks (ScCache) -- data not serialized, just creating one per sys
1272    for (int x = 0; x < numSys; x++)
1273        scLinks.push_back(ScHCache());
1274
1275    // nameCache (NameCache)
1276    for (int x = 0; x < numSys; x++) {
1277        System *sys;
1278        SimObject *sptr;
1279        string str;
1280        int sysi;
1281
1282        objParamIn(cp, section, csprintf("nameCache%d.name", x), sptr);
1283        sys = dynamic_cast<System*>(sptr);
1284
1285        paramIn(cp, section, csprintf("nameCache%d.str", x), str);
1286        paramIn(cp, section, csprintf("nameCache%d.int", x), sysi);
1287        nameCache[sys] = std::make_pair<std::string,int>(str, sysi);
1288    }
1289
1290    //smStack (SmStack)
1291    int smStack_size;
1292    paramIn(cp, section, "smStackIdCount", smStack_size);
1293    for (int x = 0; x < smStack_size; x++) {
1294        int sysi;
1295        uint64_t frame;
1296        int count;
1297        paramIn(cp, section, csprintf("smStackId%d.sys", x), sysi);
1298        paramIn(cp, section, csprintf("smStackId%d.frame", x), frame);
1299        paramIn(cp, section, csprintf("smStackId%d.count", x), count);
1300        StackId sid = StackId(sysi, frame);
1301        for (int y = 0; y < count; y++) {
1302            paramIn(cp, section, csprintf("smStackId%d_%d", x, y), smi);
1303            smStack[sid].push_back(smi);
1304        }
1305    }
1306
1307    // lnMap (LinkMap)
1308    int lsmi;
1309    int lnMap_size;
1310    paramIn(cp, section, "lnMapSize", lnMap_size);
1311    for (int x = 0;  x < lnMap_size; x++) {
1312        paramIn(cp, section, csprintf("lnMap%d.smi", x), smi);
1313        paramIn(cp, section, csprintf("lnMap%d.lsmi", x), lsmi);
1314        lnMap[smi] = lsmi;
1315    }
1316
1317    // swExpl (vector)
1318    int swExpl_size;
1319    paramIn(cp, section, "swExplCount", swExpl_size);
1320    for (int x = 0; x < swExpl_size; x++) {
1321        int sysi;
1322        uint64_t frame;
1323        bool b;
1324        paramIn(cp, section, csprintf("swExpl%d.sys", x), sysi);
1325        paramIn(cp, section, csprintf("swExpl%d.frame", x), frame);
1326        paramIn(cp, section, csprintf("swExpl%d.swexpl", x), b);
1327        StackId sid = StackId(sysi, frame);
1328        swExpl[sid] = b;
1329    }
1330
1331    // lastState (IMap)
1332    int sti;
1333    int lastState_size;
1334    paramIn(cp, section, "lastStateSize", lastState_size);
1335    for (int x = 0;  x < lastState_size; x++) {
1336        paramIn(cp, section, csprintf("lastState%d.smi", x), smi);
1337        paramIn(cp, section, csprintf("lastState%d.sti", x), sti);
1338        lastState[smi] = sti;
1339    }
1340
1341
1342    //smMap (IdMap)
1343    smMap.resize(numSm);
1344    for (int x = 0; x < smMap.size(); x++) {
1345        paramIn(cp, section, csprintf("smMap%d.sys", x), smMap[x].first);
1346        paramIn(cp, section, csprintf("smMap%d.smname", x), smMap[x].second.first);
1347        paramIn(cp, section, csprintf("smMap%d.id", x), smMap[x].second.second);
1348    }
1349
1350    //qMap (IdMap)
1351    qMap.resize(numQs);
1352    for (int x = 0; x < qMap.size(); x++) {
1353        paramIn(cp, section, csprintf("qMap%d.sys", x), qMap[x].first);
1354        paramIn(cp, section, csprintf("qMap%d.qname", x), qMap[x].second.first);
1355        paramIn(cp, section, csprintf("qMap%d.id", x), qMap[x].second.second);
1356    }
1357
1358
1359    // qData (vector<AnnotateList>)
1360    qData.resize(qSize.size());
1361    for (int x = 0; x < qSize.size(); x++) {
1362        if (!qSize[x])
1363            continue;
1364        for (int y = 0; y < qSize[x]; y++) {
1365            AnnDataPtr a = new AnnotateData;
1366            a->unserialize(cp, csprintf("%s.Q%d_%d", section, x, y));
1367            data.push_back(a);
1368            qData[x].push_back(a);
1369        }
1370    }
1371}
1372
1373void
1374CPA::AnnotateData::serialize(std::ostream &os)
1375{
1376    SERIALIZE_SCALAR(time);
1377    SERIALIZE_SCALAR(data);
1378    SERIALIZE_SCALAR(sm);
1379    SERIALIZE_SCALAR(stq);
1380    SERIALIZE_SCALAR(op);
1381    SERIALIZE_SCALAR(flag);
1382    SERIALIZE_SCALAR(cpu);
1383}
1384
1385void
1386CPA::AnnotateData::unserialize(Checkpoint *cp, const std::string &section)
1387{
1388    UNSERIALIZE_SCALAR(time);
1389    UNSERIALIZE_SCALAR(data);
1390    orig_data = data;
1391    UNSERIALIZE_SCALAR(sm);
1392    UNSERIALIZE_SCALAR(stq);
1393    UNSERIALIZE_SCALAR(op);
1394    UNSERIALIZE_SCALAR(flag);
1395    UNSERIALIZE_SCALAR(cpu);
1396    dump = true;
1397}
1398
1399CPA*
1400CPAParams::create()
1401{
1402    return new CPA(this);
1403}
1404
1405